Kubernetes Init 容器:实现 Nginx 和 PHP 对 MySQL 的依赖检查
在设计 Kubernetes Pod 时,如果需要在启动 Nginx 和 PHP 之前等待 MySQL 启动完成,可以通过 初始化容器(initC) 来实现。初始化容器可以用于检查 MySQL 是否可用,只有在 MySQL 可用后,才会继续启动主容器(Nginx 和 PHP)。
设计思路
-
初始化容器(initC):
-
使用一个简单的脚本或工具(如
mysql-client
)来检查 MySQL 服务是否可用。 -
如果 MySQL 可用,初始化容器成功退出(返回码
0
),Kubernetes 会继续启动主容器。 -
如果 MySQL 不可用,初始化容器会失败(返回码非
0
),Kubernetes 会重试,直到 MySQL 可用或超时。
-
-
主容器:
-
主容器包括 Nginx 和 PHP,它们会在初始化容器成功完成后启动。
-
具体实现
1. 编写初始化容器的脚本
创建一个脚本(如 wait-for-mysql.sh
),用于检查 MySQL 是否可用。脚本内容如下:
#!/bin/sh
# wait-for-mysql.sh
set -e
host="$1"
port="$2"
shift 2
cmd="$@"
until nc -z -v -w30 "$host" "$port"; do
echo "Waiting for MySQL to be available at $host:$port..."
sleep 5
done
echo "MySQL is up - executing command"
exec $cmd
-
该脚本使用
nc
(netcat)工具检查 MySQL 的端口是否开放。 -
如果 MySQL 不可用,脚本会每 5 秒重试一次,直到 MySQL 可用。
2. 创建 Kubernetes Pod 配置文件
以下是一个示例的 Pod 配置文件,包含初始化容器和主容器:
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
initContainers:
- name: wait-for-mysql
image: busybox:latest
command: ["sh", "-c", "/scripts/wait-for-mysql.sh mysql 3306"]
volumeMounts:
- name: scripts
mountPath: /scripts
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
- name: php
image: php:7.4-fpm
ports:
- containerPort: 9000
volumes:
- name: scripts
configMap:
name: init-scripts
3. 创建 ConfigMap 存储脚本
将 wait-for-mysql.sh
脚本存储到 Kubernetes 的 ConfigMap 中:
apiVersion: v1
kind: ConfigMap
metadata:
name: init-scripts
data:
wait-for-mysql.sh: |
#!/bin/sh
set -e
host="$1"
port="$2"
shift 2
cmd="$@"
until nc -z -v -w30 "$host" "$port"; do
echo "Waiting for MySQL to be available at $host:$port..."
sleep 5
done
echo "MySQL is up - executing command"
exec $cmd
4. 部署 Pod
-
创建 ConfigMap:
kubectl apply -f init-scripts-configmap.yaml
-
创建 Pod:
kubectl apply -f web-app-pod.yaml
5. 运行逻辑
-
初始化容器:
-
初始化容器会运行
wait-for-mysql.sh
脚本,检查 MySQL 服务是否可用。 -
如果 MySQL 可用,初始化容器成功退出。
-
如果 MySQL 不可用,初始化容器会不断重试,直到 MySQL 可用或超时。
-
-
主容器:
-
当初始化容器成功退出后,Kubernetes 会启动主容器(Nginx 和 PHP)。
-
Nginx 和 PHP 可以安全地连接到 MySQL,因为 MySQL 已经可用。
-
6. 注意事项
-
MySQL 服务地址: 确保
wait-for-mysql.sh
脚本中的 MySQL 地址(mysql
)是正确的。如果 MySQL 运行在另一个 Pod 或外部服务中,需要使用正确的服务名称或 IP。 -
超时机制: 如果 MySQL 长时间不可用,初始化容器会一直重试。可以通过设置
activeDeadlineSeconds
来限制初始化容器的最大运行时间。 -
工具依赖: 确保初始化容器中安装了
nc
(netcat)工具,或者使用其他工具(如curl
或自定义脚本)来检查 MySQL 的可用性。
总结
通过初始化容器,可以确保 MySQL 服务可用后再启动 Nginx 和 PHP。这种方式非常适合依赖外部服务的应用场景,能够有效避免主容器启动时依赖服务未就绪的问题。