【问题标题】:GKE ignores readiness probe from pod during high loadGKE 在高负载期间忽略来自 pod 的就绪探测
【发布时间】:2021-02-01 10:57:21
【问题描述】:

我有一个在 kubernetes 中运行的应用程序,在几个 pod 上。我正在尝试改善我们的部署体验(我们正在使用滚动部署),这目前正在引起痛苦。

我想要达到的目标:

  • 每个 pod 首先没有准备好,所以它没有更多的流量
  • 然后它将完成当前正在处理的请求
  • 然后就可以删除了

这一切都应该是可能的,并且可以正常工作 - 您创建一个包含就绪和活跃度探针的部署。负载均衡器将选择这些并相应地路由流量。但是,当我测试我的部署时,即使切换到未准备好,我也会看到 pod 收到请求。具体来说,当大量流量进入时,负载均衡器似乎不会更新。当我向它们发出信号时,我可以看到 Pod 处于“未就绪”状态——如果它们在切换状态时没有获得流量,它们就不会之后接收流量。但如果他们在切换时获得流量,负载均衡器就会忽略状态变化。

我开始想知道如何处理这个问题,因为我看不出我缺少什么 - 必须可以在 Kubernetes 上托管一个高流量应用程序,而 pod 会“未准备好”而不会丢失大量请求.

我的配置

部署

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: my-service
  name: my-service
  namespace: mine
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-service
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
    app: my-service
    env: production
    spec:
      containers:
      - name: my-service
    image: IMAGE ID
    imagePullPolicy: Always
    volumeMounts:
    - name: credentials
      mountPath: "/run/credentials"
      readOnly: true
    securityContext:
      privileged: true
    ports:
    - containerPort: 8080
      protocol: TCP
    lifecycle:
      preStop:
        exec:
          command: ["/opt/app/bin/graceful-shutdown.sh"]
    readinessProbe:
      httpGet:
         path: /ready
         port: 8080
      periodSeconds: 1
      initialDelaySeconds: 5
      failureThreshold: 1
    livenessProbe:
      httpGet:
         path: /alive
         port: 8080
      periodSeconds: 1
      failureThreshold: 2
      initialDelaySeconds: 60
    resources:
      requests:
        memory: "500M"
        cpu: "250m"
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 60
      nodeSelector:
    cloud.google.com/gke-nodepool: stateful

服务/负载均衡器

apiVersion: v1
kind: Service
metadata:
  name: stock-service-loadbalancer
  namespace: stock
spec:
  selector:
    app: stock-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

【问题讨论】:

    标签: google-kubernetes-engine load-balancing kubernetes-health-check


    【解决方案1】:

    结果证明这是一种效果或长期连接,而不是流量。原因似乎是负载均衡器不会关闭打开的连接 - 对于我们的服务,我们使用的是使用长时间运行连接池的测试设置。因此,负载均衡器正在更新它的路由,但现有连接继续向终止的 pod 发送数据。

    结果是,这种零停机策略确实奏效了:

    • 使用 preStop 挂钩使您的 pod 无法通过就绪探测
    • 确保等待几秒钟
    • 然后让您的 pod 通过 SIGTERM 优雅地终止
    • 确保您的 terminateGracePeriodSeconds 足够大以涵盖 preStop 和实际终止期

    【讨论】:

      猜你喜欢
      • 2021-08-29
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2019-11-21
      • 2018-11-30
      • 2019-12-05
      • 2019-05-21
      相关资源
      最近更新 更多