首页 > 解决方案 > 当我有运行中的 HTTP 请求时,如何防止我在 Kubernetes 中的 Elixir pod 被删除

问题描述

我们的 Phoenix 应用程序中有一些支付端点的超时时间为 153 秒。这些围绕需要很长超时的 CardConnect Bolt API 端点。

支付端点中断可能会导致双重收费,我们希望尽可能避免这种情况。

我认为这有两个部分。

  1. 一旦我有一个部署了新映像的 Pod,就停止 GKE 向运行旧映像的 Pod 发送新请求
  2. 让旧 pod 保持活动状态,直到 153 秒过去,让所有这些支付端点在那里完成工作。

#1 可能是 Kubernetes 配置,#2 可能是 Kubernetes 和 phoenix 配置。

我看到的唯一部分解决这个问题的是terminationGracePeriodSecondspod https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core

这似乎是一个常见问题,但搜索文档对我来说并没有太大的收获。

标签: kuberneteselixirgoogle-kubernetes-enginephoenix-framework

解决方案


Kubernetes 有服务。服务具有用于匹配 pod 的选择器。匹配记录存储为Endpoint. 你描述的是可能的。让我们看看我们是否可以将需求放在一起:

  1. 您需要确保 K8s 在关闭它之前启动新的 pod。
  2. 您需要确保 K8s 有探针来检查新的何时可以开始服务连接(然后它将被添加到Endpoint对象并删除旧的)。从端点中删除它不会中断打开的 TCP 连接。它只是阻止新的豆荚进入旧豆荚。
  3. 在开始关闭之前,您需要让正在运行的 pod 有足够的时间来完成运行中的请求。
  4. 如果 Pod 超过运行时间加上大量关闭时间,您需要允许 Kubernetes 杀死 Pod。

现在进入 YAML

apiVersion: v1
kind: Service
metadata:
  name: web-app
  namespace: default
spec:
  ports:
    - name: web
      port: 8080
      protocol: TCP
      targetPort: web
  selector:
    app: web-app
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web-app
  name: web-app
  namespace: default
spec:
  revisionHistoryLimit: 1
  replicas: 1
  selector:
    matchLabels:
      app: web-app
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - image: nginx:latest
          imagePullPolicy: IfNotPresent
          name: web-app
          lifecycle:
            # This "sleep" preStop hook delays the
            # Pod shutdown 
            preStop:
              exec:
                command:
                  - /bin/sleep
                  - "154" # The max timeout for in flight requests + plus 1 second
          readinessProbe:
            initialDelaySeconds: 5
            periodSeconds: 3
            failureThreshold: 3
            successThreshold: 1
            httpGet:
              port: web
              path: /
          livenessProbe:
            initialDelaySeconds: 10
            periodSeconds: 10
            failureThreshold: 1
            successThreshold: 1
            httpGet:
              port: web
              path: /
          ports:
            - containerPort: 80
              name: web
              protocol: TCP
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 155  # sleep period plus the shutdown time

试试这个,看看它是否适合你。


推荐阅读