使用 nginx ingress 时是否有 pod 级 nginx 的意义?

Is there a point of having pod-level nginx when using nginx ingress?

我想知道我是否应该在下面的实现中使用 pod 级别的 nginx: 从 VM 迁移后,我以前使用的是普通入口和 kube-lego,现在我使用的是 cert-manager 和 GKE。 我的入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: myapp-static-ip
    kubernetes.io/ingress.class: nginx
    kubernetes.io/ingress.allow-http: "false"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    ingress.kubernetes.io/rewrite-target: /
    certmanager.k8s.io/cluster-issuer: letsencrypt
  namespace: default
spec:
  tls:
  - hosts:
    - myapp.com
    secretName: myapp-crt
  rules:
  - host: 
    http:
      paths:
      - path: /
        backend:
          serviceName: myapp
          servicePort: http

我的服务:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 32111
    protocol: "TCP"
    name: http
  selector:
    app: myapp

我的部署

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: gcr.io/myapp-1/myapp:latest
        imagePullPolicy: Always
        env:
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: username
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: password
            -
              name: STATIC_ROOT
              value: https://storage.googleapis.com/myapp-api/static/
            -
              name: STATIC_URL
              value: https://storage.googleapis.com/myapp-api/static/
            -
              name: MEDIA_ROOT
              value: /myapp/media
            -
              name: MEDIA_URL
              value: http://myapp.com/media/

      -
        name: nginx
        image: nginx
        command: [nginx, -g,'daemon off;']

        imagePullPolicy: Always
        volumeMounts:
          -
            name: api-nginx-config
            mountPath: /etc/nginx/nginx.conf
            subPath: nginx.conf
          -
            name: myapp-media
            mountPath: /myapp/media/

        ports:
        - containerPort: 80

      - image: b.gcr.io/cloudsql-docker/gce-proxy:1.05
        name: cloudsql-proxy
        command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                  "-instances=myapp-1:europe-west1:myapp-api=tcp:5432",
                  "-credential_file=/secrets/cloudsql/credentials.json"]
        volumeMounts:
          - name: cloudsql-oauth-credentials
            mountPath: /secrets/cloudsql
            readOnly: true
          - name: ssl-certs
            mountPath: /etc/ssl/certs
          - name: cloudsql
            mountPath: /cloudsql
          - name: myapp-media
            mountPath: /myapp/media

      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: cloudsql
          emptyDir:
        - name: api-nginx-config
          configMap:
            name: api-nginx-config
        -
          name: myapp-media
          persistentVolumeClaim:
            claimName: myapp-media

我的 nginx 配置文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: api-nginx-config
data:
  nginx.conf: |
    events {
      worker_connections  1024;
    }
    http {
      upstream api {
        server 127.0.0.1:8080 fail_timeout=0;
      }
      server {
        access_log /var/log/nginx/http-access.log;
        error_log /var/log/nginx/http-error.log;
        listen 80;
        listen [::]:80;
        server_name myapp.com;

        location /media/ {
        alias   /myapp/media;
        }

       location = /favicon.ico {
        access_log off;
        log_not_found off;
        }

        location / {
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $host;
          proxy_set_header X-NginX-Proxy true;
          proxy_pass http://127.0.0.1:8080/;
        }
      }
    }

考虑到我可以直接将 myapp/media 直接映射到卷装载中的 /media 并且我的 tls 由入口处理,它是否有任何主要用途。正如我之前强调的那样,我主要关心的是 pod 级别的 nginx,在这种情况下它没用吗?这只是我从以前的实施中遗留下来的包袱吗?

一般来说,拥有一个额外的 nginx pod 并没有什么意义。如果你这样做,你就会有双重进入。 nginx 入口控制器 pod 中已经有 nginx,你可以扩展它 up/down.

你想要保留它的一个原因是为了向后兼容,例如,如果你想使用入口但想以这种方式逐渐推出它:创建新的 nginx 入口 -> 翻转来自你自己的nginx只能通过新的nginx ingress和你自己的nginx,直到你把你所有的pods -> 逐渐移除你自己的nginx,直到你全部移除。

另一个原因是支持 nginx 入口控制器尚不支持的非常具体的 nginx 配置。

您可能需要 运行 您自己的 nginx 作为部署,出于上述答案中列出的原因,另外,您可能需要扩展 nginx 部署,比如说 10 个副本。你不能像那样扩展入口。但无论如何,你只需要其中之一。