当我有正在进行的 HTTP 请求时,如何防止 Kubernetes 中的 Elixir pod 被关闭
How do I prevent my Elixir pod in Kubernetes from getting taken down while I have in flight HTTP requests
我们的 Phoenix 应用程序中有一些支付端点的超时时间为 153 秒。这些环绕 CardConnect Bolt API 需要很长超时的端点。
支付端点中断会导致双重收费,我们希望尽可能避免这种情况。
我认为这有两个部分。
- 停止 GKE 向 pods 运行 旧图像发送新请求,一旦我有一个部署了新图像的 pod
- 让旧的 pod 保持活动状态,直到 153 秒过去,让所有这些支付端点在那里完成工作。
#1 可能是 Kubernetes 配置,#2 可能是 Kubernetes 和 phoenix 配置。
我看到的唯一能部分解决这个问题的是 pod https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core.
的 terminationGracePeriodSeconds
这似乎是一个常见问题,但搜索文档对我来说并没有什么收获。
Kubernetes 有服务。服务具有用于匹配 pods 的选择器。匹配记录存储为 Endpoint
。你所描述的是可能的。让我们看看是否可以一起满足要求:
- 你需要确保 K8s 在关闭这个 pod 之前启动新的 pod。
- 你需要确保 K8s 有探测器来检查新的何时可以开始服务连接(然后它将被添加到
Endpoint
对象并删除旧的)。从 Endpoint 中删除它不会断开打开的 TCP 连接。它只是阻止新的进入旧的 pod。
- 您需要让 运行 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
试试这个,看看它是否适合你。
我们的 Phoenix 应用程序中有一些支付端点的超时时间为 153 秒。这些环绕 CardConnect Bolt API 需要很长超时的端点。
支付端点中断会导致双重收费,我们希望尽可能避免这种情况。
我认为这有两个部分。
- 停止 GKE 向 pods 运行 旧图像发送新请求,一旦我有一个部署了新图像的 pod
- 让旧的 pod 保持活动状态,直到 153 秒过去,让所有这些支付端点在那里完成工作。
#1 可能是 Kubernetes 配置,#2 可能是 Kubernetes 和 phoenix 配置。
我看到的唯一能部分解决这个问题的是 pod https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core.
的terminationGracePeriodSeconds
这似乎是一个常见问题,但搜索文档对我来说并没有什么收获。
Kubernetes 有服务。服务具有用于匹配 pods 的选择器。匹配记录存储为 Endpoint
。你所描述的是可能的。让我们看看是否可以一起满足要求:
- 你需要确保 K8s 在关闭这个 pod 之前启动新的 pod。
- 你需要确保 K8s 有探测器来检查新的何时可以开始服务连接(然后它将被添加到
Endpoint
对象并删除旧的)。从 Endpoint 中删除它不会断开打开的 TCP 连接。它只是阻止新的进入旧的 pod。 - 您需要让 运行 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
试试这个,看看它是否适合你。