3

我使用 GKE 在运行最新版本 Kubernetes 1.18.15-gke.1501(ClusterIP

每当我使用新映像更新部署时,我都会遇到大约 5-15 分钟的停机时间,负载均衡器会返回 502 错误。似乎控制平面创建了新的、更新的 pod,允许通过服务级别的健康检查(不是负载均衡器,它还没有创建 NEG),然后同时杀死旧的 pod是时候设置新的 NEG 了。然后它直到一段时间后才会删除旧的 NEG。

在此处输入图像描述

pod 上的日志显示运行状况检查正在进行,但 GKE 仪表板显示 Ingress 状态的结果不一致。入口将显示正常,但服务将显示 502。

我尝试过的事情

  • 将 pod 的数量从 1 个增加到 3 个。这对某些部署有所帮助,但在其他所有部署中,它都会增加负载均衡器正确解析所需的时间。
  • 尝试设置maxSurge为 1 和maxUnavailable0。这根本没有改善停机时间。
  • 添加lifecycle.preStop.exec.command: ["sleep", "60"]到部署上的容器。这是 GKE 文档中建议的。
  • 多次重新创建入口、服务、部署和集群。
  • 向服务中添加一个BackendConfig会增加其消耗速度的服务。
  • 在文档中添加一个准备门应该可以解决这个问题,但由于某种原因没有?

上述任何一项都没有帮助或对事情下降的时间产生任何明显的影响。

我真的,真的很困惑为什么这不起作用。感觉就像我遗漏了一些非常明显的东西,但这也是一个如此简单的配置,你会认为它......只是工作?有人知道发生了什么吗?

配置文件

部署配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: foundation-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: foundation-web
  template:
    metadata:
      labels:
        app: foundation-web
    spec:
      readinessGates:
        - conditionType: "cloud.google.com/load-balancer-neg-ready"

      serviceAccountName: foundation-database-account
      containers:
        # Run Cloud SQL proxy so we can safely connect to Postgres on localhost.
        - name: cloud-sql-proxy
          image: gcr.io/cloudsql-docker/gce-proxy:1.17
          resources:
            requests:
              cpu: "250m"
              memory: 100Mi
            limits:
              cpu: "500m"
              memory: 100Mi
          command:
            - "/cloud_sql_proxy"
            - "-instances=nine-foundation:us-central1:foundation-staging=tcp:5432"
          securityContext:
            runAsNonRoot: true
        # Main container config
        - name: foundation-web
          image: gcr.io/project-name/foundation_web:latest
          imagePullPolicy: Always
          lifecycle:
            preStop:
              exec:
                command: ["sleep", "60"]
          env:
           # Env variables
          resources:
            requests:
              memory: "500Mi"
              cpu: "500m"
            limits:
              memory: "1000Mi"
              cpu: "1"
          livenessProbe:
            httpGet:
              path: /healthz
              port: 4000
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /healthz
              port: 4000
            initialDelaySeconds: 10
            periodSeconds: 10
          ports:
            - containerPort: 4000

服务配置:

apiVersion: v1
kind: Service
metadata:
  name: foundation-web-service
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
    cloud.google.com/backend-config: '{"ports": {"4000": "foundation-service-config"}}'
spec:
  type: ClusterIP
  selector:
    app: foundation-web
  ports:
    - port: 4000
      targetPort: 4000

后端配置:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: foundation-service-config
spec:
  # sessionAffinity:
  #   affinityType: "GENERATED_COOKIE"
  #   affinityCookieTtlSec: 120
  connectionDraining:
    drainingTimeoutSec: 60

入口配置:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: foundation-web-ingress
  labels:
    name: foundation-web-ingress
spec:
  backend:
    serviceName: foundation-web-service
    servicePort: 4000
4

1 回答 1

1

我认为这可能与云 sql auth 代理边车未正确终止有关,导致负载均衡器出现扭曲。

请注意GCP 文档中的这一点(我已将关键部分设为斜体

症状

502 错误或拒绝连接。潜在原因 新端点通常在将它们附加到负载均衡器后变得可访问,前提是它们响应运行状况检查。如果流量无法到达端点,您可能会遇到 502 错误或连接被拒绝。

502 错误和被拒绝的连接也可能是由不处理 SIGTERM 的容器引起的。如果容器没有明确处理 SIGTERM,它会立即终止并停止处理请求。负载均衡器继续将传入流量发送到终止的容器,从而导致错误。

容器原生负载均衡器只有一个后端端点。在滚动更新期间,旧端点在新端点被编程之前被取消编程。

配置容器原生负载均衡器后,后端 Pod 首次部署到新区域。当区域中至少有一个端点时,负载平衡器基础架构会在该区域中进行编程。将新端点添加到区域时,负载均衡器基础架构会被编程并导致服务中断。

解析度

配置容器以处理 SIGTERM 并在整个终止宽限期内(默认为 30 秒)继续响应请求。将 Pod 配置为在收到 SIGTERM 时开始未通过健康检查。这会向负载均衡器发出信号,在端点解编程过程中停止向 Pod 发送流量。

默认情况下,代理不能很好地处理 SIGTERM,并且不会在 SIGTERM 上正常退出(参见相关问题),但是它现在有一个很好的标志来处理这个,所以你可以使用类似的东西

- name: cloud-sql-proxy
      image: gcr.io/cloudsql-docker/gce-proxy:1.23.1
      command:
        - "/cloud_sql_proxy"
        - "-instances={{ .Values.postgresConnectionName }}=tcp:5432"
        - "-term_timeout=60s"
      securityContext:
        runAsNonRoot: true
      resources:
        requests:
          memory: "2Gi"
          cpu:    "1"

添加 term_timeout 标志主要为我修复了它,但在部署期间仍然看到偶尔出现 502。一旦设置了 term_timeout,将副本增加到 3 个(我的集群是区域性的,所以我想覆盖所有区域)似乎有所帮助。

于 2021-08-10T17:34:48.957 回答