K8s上pod中的容器初始化顺序



我想在一个pod上运行两个容器。

container1是一个尝试连接到在container2上运行的SQL Server数据库的测试。

如何确保sql容器(container2)在container1启动之前运行并准备就绪?

initContainer在这里不起作用,因为它将在两个容器之前运行。

这是我的作文

apiVersion: v1
kind: Pod
metadata:
name: sql-test-pod
labels:
name: sql-test
spec:
restartPolicy: Never
containers:
- name: my-sqldb
image: docker-registry.com/database
imagePullPolicy: Always
resources:
limits:
memory: "4096Mi"
cpu: "750m"
requests:
memory: "4096Mi"
cpu: "750m"
- name: tests
tty: true
stdin: true
image: docker-registry.com/test
imagePullPolicy: Always
resources:
limits:
memory: "4096Mi"
cpu: "750m"
requests:
memory: "4096Mi"
cpu: "750m"
env:
- name: sqlhostname
value: "SqlHostnamePlaceholder"
nodeSelector:
kubernetes.io/os: windows
tolerations:
- key: "windows"
operator: "Equal"
value: "2019"
effect: "NoSchedule"

为了确保container1只有在container2的SQL Server启动后才会启动,我找到的唯一方法是使用postStart容器的生命周期事件。postStart在容器创建后触发,确实不能保证在调用容器的入口点之前调用postStart处理程序,但事实证明,启动容器的Kubelt代码会阻止下一个容器的启动,直到post-start处理程序终止

这就是我的新合成文件的样子:

apiVersion: v1
kind: Pod
metadata:
name: sql-test-pod
labels:
name: sql-test
spec:
restartPolicy: Never
containers:
- name: my-sqldb
image: docker-registry.com/database
imagePullPolicy: Always
lifecycle:
postStart:
exec:
command: ['powershell.exe', '-command', "$connectionString = 'Server=sql-test-pod;User Id=user;Password=password'; $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $connectionString; $i=0; while($i -lt 6) {Try { $i++;$sqlConnection.Open();$sqlConnection.Close(); return}Catch {Write-Error $_; start-sleep 30}}"]
resources:
limits:
memory: "4096Mi"
cpu: "750m"
requests:
memory: "4096Mi"
cpu: "750m"
- name: tests
tty: true
stdin: true
image: docker-registry.com/test
imagePullPolicy: Always
resources:
limits:
memory: "4096Mi"
cpu: "750m"
requests:
memory: "4096Mi"
cpu: "750m"
env:
- name: sqlhostname
value: "sql-test-pod"
nodeSelector:
kubernetes.io/os: windows
tolerations:
- key: "windows"
operator: "Equal"
value: "2019"
effect: "NoSchedule"

类似的情况你可以在这里找到

使用kubernetes的当前实现无法做到这一点:一个pod中的所有容器都将同时启动(init容器除外)。

一种解决方案是增强test container中的代码,以检测db container的状态,保持直到准备就绪。

另一个选项是向容器中添加命令和参数。

如果知道另一个容器启动的大致时间,您可以添加sleep命令,或者在命令中添加一些逻辑(while循环检查连接,一旦连接,退出循环并运行主进程-示例)。

注意!图像的entrypoint将被以下命令取代:

您在配置文件中定义的命令和参数重写容器提供的默认命令和参数图像

例如,对于nginx和命令容器spec,将看起来像(由于entrypoint已被替换,因此有必要提供启动nginx服务器的命令):

containers:
- name: test
image: nginx
command: ["/bin/bash", "-c"]
args: ["sleep 30 ; echo sleep ended ;  nginx -g "daemon off;""]

更多详细信息,请单击此处为容器定义命令和参数。

最新更新