我在 GKE 集群中运行 Kubernetes,需要在每次部署时运行数据库迁移脚本。对于分阶段来说,这很容易:我们有一个永久的、独立的 MySQL 服务,有自己的卷。然而,对于生产,我们使用 GCE SQL,导致作业有两个容器 - 一个用于迁移,另一个用于云代理。
由于这个新容器,该作业在运行时始终显示为 1 active
kubectl describe jobs/migration
,我完全不知所措。我尝试重新排序容器,看看它是否默认检查一个容器,但这没有什么区别,我看不到一种方法来 a) 杀死一个容器或 b) 检查作业中一个容器的状态。
有什么想法吗?
我知道已经晚了一年,但最佳实践是为所有应用程序的目的运行单个 cloudsql 代理服务,然后在应用程序的映像中配置数据库访问以将此服务用作数据库主机名。
这样您就不需要将 cloudsql 代理容器放入每个使用 DB 的 pod 中。
原因是容器/进程永远不会终止。
一种可能的解决方法是:将
cloud-sql-proxy
移动到它自己的 deployment
- 并在其前面添加一项服务。因此,您的 job
将不负责运行长时间运行的 cloud-sql-proxy
,因此将终止/完成。
每个 Pod 都可以配置一个 init 容器,这似乎很适合您的问题。因此,您不必让 Pod 包含两个必须永久运行的容器,而是可以定义一个 init 容器来预先进行迁移。例如。像这样:
apiVersion: v1
kind: Pod
metadata:
name: init-container
annotations:
pod.beta.kubernetes.io/init-containers: '[
{
"name": "migrate",
"image": "application:version",
"command": ["migrate up"],
}
]'
spec:
containers:
- name: application
image: application:version
ports:
- containerPort: 80
您还没有发布有关您的具体问题的足够详细信息。但我根据经验进行猜测。
TL;DR:如果容器是独立的,请将它们移至单独的作业中。
--
Kubernetes 作业不断重启,直到作业成功。 仅当其中的每个容器都成功时,kubernetes 作业才会成功。
这意味着您的容器应该以可重新启动的方式返回。一旦容器成功运行,即使再次运行也应该返回成功。否则,假设container1成功,container2失败。作业重新启动。然后,container1 失败(因为它已经成功)。因此,作业不断重新启动。
从 1.29 开始,beta 中为此提供了一个 KEP。 https://kubernetes.io/blog/2023/08/25/native-sidecar-containers/#what-are-sidecar-containers-in-1-28
你可以做的就是让你的side car成为initContainer,并在容器中添加额外的属性
restartPolicy: Always
。
从上面的链接复制:
apiVersion: v1
kind: Pod
spec:
initContainers:
- name: secret-fetch
image: secret-fetch:1.0
- name: network-proxy
image: network-proxy:1.0
restartPolicy: Always
containers:
...
它的作用是,它将作为 initcontainer 启动
network-proxy
容器,并且它将继续沿着主容器运行,一旦主容器完成,pod/作业将终止。