我们有一个部署,仅包含一个 pod(包含服务和入口)。它使用 Docker 容器执行自定义运行脚本作为其命令。
当我们推出新版本时,会提取镜像、创建新 pod 并启动该脚本。此时,新 pod 处于“正在运行”状态,而旧 pod 处于“已终止”状态,因为所需 pod 数量仍为 1。
然而,这是我们的问题的核心,这个运行脚本有时需要几分钟才能完成。它包括一些数据库迁移和其他在构建期间无法完成的内容(即放入 Dockerfile 中)。这导致我们的新 pod 运行了几分钟,但尚未准备好处理请求,从而导致我们的服务出现一些停机时间。
我的问题是 - 有没有办法“延迟”旧 Pod 的终止以防止这种情况发生?或者延迟将新 Pod 标记为“正在运行”?
我知道理想的解决方案是拥有超过 1 个 pod,但这目前是不可能的,因为相关服务并非完全无状态。但即使是这样,如果我们有 3 个 pod,它们都会进入“正在运行”状态,而实际上并没有完成任务,而且再次导致一些(尽管较小)停机时间。
我该如何处理这种问题?
答案1
我不能 100% 确定是否可以将 Pod 的终止延迟到作业完成,但您可以设置检查以确保 Pod 已完全准备好工作。有两种类型的检查:活跃度和就绪性
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
活跃度是指当你的应用程序由于某种原因停止接受流量时,重新启动可能会解决这个问题。
您所寻找的是准备就绪状态,应用程序可能需要一点时间才能完全加载并接受流量。
理想的解决方案是设置一个就绪检查,并让应用程序在某些端点足够智能,/
或者/ready
返回200
响应以让 kubernetes 知道可以接受流量。
答案2
添加多个 Pod 并不能解决问题。我所做的是在 docker 文件中添加 readinessProbe,其中包含我的应用程序正在运行的端口。这将停止旧 Pod 的终止,直到新 Pod 准备好接受该端口上的连接。
spec:
containers:
- name: <containerName>
image: <imageName>
readinessProbe:
tcpSocket:
port: 3000
initialDelaySeconds: 5
periodSeconds: 10