2

基本上我有这个 django 应用程序,它的 Pod 和负载均衡器服务在 GKE 中成功运行。但我无法通过负载均衡器中的外部 IP 访问应用程序。

首先这是我的 pod 和负载均衡器状态:

Justins-MacBook-Pro-166:Django-RealEstate qingyuan$ kubectl get svc polls
NAME    TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)          AGE
polls   LoadBalancer   10.108.2.157   104.155.130.204   8000:30575/TCP   3m24s
Justins-MacBook-Pro-166:Django-RealEstate qingyuan$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
polls-db68f9d76-8mgrw   2/2     Running   0          3m43s
polls-db68f9d76-k85rw   2/2     Running   0          3m43s
polls-db68f9d76-qjsbt   2/2     Running   0          3m43s

这是我的dockerfile:


FROM gcr.io/google_appengine/python
LABEL maintainer qm28@georgetown.edu

# Create a virtualenv for the application dependencies.
RUN virtualenv -p python3 /env
ENV PATH /env/bin:$PATH

#Prevents Python from writing pyc files to disc (equivalent to python -B option)#
ENV PYTHONDONTWRITEBYTECODE 1
# So the logs can always write to container logs and not get buffered at first place
ENV PYTHONUNBUFFERED 1

WORKDIR /app
ADD requirements.txt /app/requirements.txt
RUN /env/bin/pip install --upgrade pip && /env/bin/pip install -r /app/requirements.txt
ADD . /app

CMD gunicorn realestate.wsgi:application --bind 0.0.0.0:8000

这是我的 yml 文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: polls
  labels:
    app: polls
spec:
  replicas: 3
  # selector: when deployment create the pods, it will actually created by the kubernetes master
  # After the master create the pods, the deployment will ask: 'how do I know which of the pods are
  # the one I want?' Then the match label here tells the deployment object which pods belong to it
  selector:
    matchLabels:
      app: polls
  template:
    metadata:
      labels:
        app: polls
    spec:
      containers:
        - name: polls-app
          image: gcr.io/django-realestate/polls
          imagePullPolicy: Always
          env:
            - name: DATABASE_USER
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: username
            - name: DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: password
          ports:
            - containerPort: 8080
        
        # container for cloudsql proxy
        - image: gcr.io/cloudsql-docker/gce-proxy:1.16
          name: cloudsql-proxy
          command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                    "-instances=django-realestate:us-central1:myinstance=tcp:5432",
                    "-credential_file=/secrets/cloudsql/credentials.json"]
          # mount the volume from pods to container file system
          volumeMounts:
            - name: cloudsql-oauth-credentials
              mountPath: /secrets/cloudsql
              readOnly: true
            - name: ssl-certs
              mountPath: /etc/ssl/certs
            - name: cloudsql
              mountPath: /cloudsql
 
      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir: {}

---
apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: LoadBalancer
  selector:
    app: polls
  ports:
  # here I use the name to expose the port 8080 to 80
    - port: 8000
      targetPort: 8080
      protocol: TCP

任何人都可以提供一些解决方案或指导,我将不胜感激!我整天都在寻找解决方案和测试......

4

1 回答 1

1

TL;博士

您在以下各项之间存在不匹配:

  • gunicorn在港口8000
    • CMD gunicorn realestate.wsgi:application --bind 0.0.0.0:8000
  • targetPort在港口8080
    • targetPort: 8080

要解决此问题,您需要更改其中一个以匹配第二个,例如:

  • gunicorn在港口8000
  • targetPort在端口8000# <-从 更改80808000

我在下面提供了更多解释。


解释

关注YAML用于公开应用程序的定义部分:

  type: LoadBalancer
  ports:
    - port: 8000 # <-- PORT TO CONNECT TO
      targetPort: 8080 # <-- PORT LISTENING ON POD 
      protocol: TCP

更多关于:

  • port- 这是您在使用服务(内部和外部)时需要将流量发送到的端口。
  • targetPort- 这是 aPod正在监听的端口(在你的情况下8000来自 gunicorn)

例子:

假设你有:

  • nginxpod 监听端口80
  • nginx与具有以下参数 的 pod 关联的服务:
    • namenginx-service
    • typeLoadBalancer
    • port1234
    • targetPort80

要从外部源访问它,您需要运行:

  • $ curl EXTERNAL_IP:1234 - 它将请求路由到nginxpod 到 port 80

小费!

您还可以通过运行以下命令从内部源连接到此服务:

  • $ curl nginx-service:1234

我还鼓励您查看其他资源:

于 2020-11-23T11:56:21.677 回答