K8s 上 pod 中的容器初始化顺序
container initialization order in pod on K8s
我想 运行 一个 pod 上的两个容器。
container1
是一个尝试连接 SQL 服务器数据库的测试,运行 位于 container2
。
如何确保 sql 容器 (container2
) 运行 并在 container1
启动前就绪?
initContainer
在这里不起作用,因为它会在两个容器之前 运行。
这是我的 compose.yaml:
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"
您不能使用 kubernetes
的当前实现来做到这一点:一个 pod 中的所有容器将同时启动(init 容器除外)。
一个解决方案是增强 test container
中的代码以检测 db container
的状态,等待直到准备就绪。
另一种选择是添加 command and args to the container。
如果知道另一个容器启动的大致时间,您可以添加 sleep
命令或在命令中添加一些逻辑(while
循环检查连接,一旦连接,退出循环并运行 主进程 - example).
注意!图片的 entrypoint
将被此命令替换:
The command and arguments that you define in the configuration file
override the default command and arguments provided by the container
image
例如,对于 nginx
和命令容器 spec
将如下所示(由于 entrypoint
被替换,因此有必要提供启动 nginx 服务器的命令):
containers:
- name: test
image: nginx
command: ["/bin/bash", "-c"]
args: ["sleep 30 ; echo sleep ended ; nginx -g \"daemon off;\""]
为了确保 container1
仅在 container2
的 SQL 服务器启动后启动,我发现的唯一方法是使用 postStart
容器的生命周期事件。
postStart
在容器创建之后触发,确实不能保证 postStart 处理程序在调用容器的入口点之前被调用,但事实证明启动容器的 Kubelet 代码会阻塞下一个容器的启动,直到 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"
你可以找到类似的案例here
我想 运行 一个 pod 上的两个容器。
container1
是一个尝试连接 SQL 服务器数据库的测试,运行 位于 container2
。
如何确保 sql 容器 (container2
) 运行 并在 container1
启动前就绪?
initContainer
在这里不起作用,因为它会在两个容器之前 运行。
这是我的 compose.yaml:
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"
您不能使用 kubernetes
的当前实现来做到这一点:一个 pod 中的所有容器将同时启动(init 容器除外)。
一个解决方案是增强 test container
中的代码以检测 db container
的状态,等待直到准备就绪。
另一种选择是添加 command and args to the container。
如果知道另一个容器启动的大致时间,您可以添加 sleep
命令或在命令中添加一些逻辑(while
循环检查连接,一旦连接,退出循环并运行 主进程 - example).
注意!图片的 entrypoint
将被此命令替换:
The command and arguments that you define in the configuration file override the default command and arguments provided by the container image
例如,对于 nginx
和命令容器 spec
将如下所示(由于 entrypoint
被替换,因此有必要提供启动 nginx 服务器的命令):
containers:
- name: test
image: nginx
command: ["/bin/bash", "-c"]
args: ["sleep 30 ; echo sleep ended ; nginx -g \"daemon off;\""]
为了确保 container1
仅在 container2
的 SQL 服务器启动后启动,我发现的唯一方法是使用 postStart
容器的生命周期事件。
postStart
在容器创建之后触发,确实不能保证 postStart 处理程序在调用容器的入口点之前被调用,但事实证明启动容器的 Kubelet 代码会阻塞下一个容器的启动,直到 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"
你可以找到类似的案例here