本文目录导读:

在Shell脚本中配置容器生命周期钩子,主要涉及Kubernetes的postStart和preStop钩子,以下是详细的配置方法:
基本配置示例
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'Container started' > /tmp/start.log"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'Container stopping' > /tmp/stop.log && sleep 10"]
使用Shell脚本实现复杂逻辑
postStart钩子脚本示例
#!/bin/bash
# postStart.sh
set -e
echo "PostStart hook executing..."
echo "Container started at $(date)" > /tmp/container_started.log
# 检查依赖服务
if ! curl -s http://dependency-service:8080/health; then
echo "Dependency service not ready, waiting..."
sleep 5
fi
# 初始化配置
if [ -f /config/init.sh ]; then
/config/init.sh
fi
echo "PostStart hook completed"
preStop钩子脚本示例
#!/bin/bash # preStop.sh set -e echo "PreStop hook executing..." SERVICE_NAME="my-service" GRACEFUL_SHUTDOWN_TIMEOUT=30 # 通知负载均衡器 echo "Deregistering from service registry..." curl -X POST http://registry:8500/v1/agent/service/deregister/$SERVICE_NAME # 优雅关闭服务 echo "Gracefully shutting down application..." kill -TERM $(cat /var/run/app.pid) 2>/dev/null || true # 等待连接关闭 sleep $GRACEFUL_SHUTDOWN_TIMEOUT # 清理临时文件 rm -rf /tmp/app_* echo "PreStop hook completed"
Kubernetes配置引用
YAML配置
apiVersion: v1
kind: Pod
metadata:
name: app-with-hooks
spec:
containers:
- name: app-container
image: myapp:latest
lifecycle:
postStart:
exec:
command: ["/bin/bash", "/scripts/postStart.sh"]
preStop:
exec:
command: ["/bin/bash", "/scripts/preStop.sh"]
volumeMounts:
- name: scripts
mountPath: /scripts
volumes:
- name: scripts
configMap:
name: lifecycle-scripts
ConfigMap定义
apiVersion: v1
kind: ConfigMap
metadata:
name: lifecycle-scripts
data:
postStart.sh: |
#!/bin/bash
echo "Container started at $(date)"
# 其他初始化逻辑
preStop.sh: |
#!/bin/bash
echo "Container stopping at $(date)"
# 其他清理逻辑
Dockerfile集成
FROM alpine:latest # 安装必要工具 RUN apk add --no-cache curl bash # 复制钩子脚本 COPY hooks/postStart.sh /hooks/postStart.sh COPY hooks/preStop.sh /hooks/preStop.sh # 设置执行权限 RUN chmod +x /hooks/*.sh # 启动脚本 COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
高级使用技巧
使用环境变量控制行为
apiVersion: v1
kind: Pod
metadata:
name: app-with-env-hooks
spec:
containers:
- name: app-container
image: myapp:latest
env:
- name: GRACEFUL_TIMEOUT
value: "30"
- name: HEALTH_CHECK_URL
value: "http://health-endpoint:8080/ready"
lifecycle:
postStart:
exec:
command: ["/bin/bash", "-c",
"echo 'Health check: ${HEALTH_CHECK_URL}'; \
curl -f ${HEALTH_CHECK_URL} || exit 1; \
echo 'Container is ready'"]
preStop:
exec:
command: ["/bin/bash", "-c",
"echo 'Graceful shutdown with timeout ${GRACEFUL_TIMEOUT}s'; \
sleep ${GRACEFUL_TIMEOUT}"]
添加超时和错误处理
#!/bin/bash
# robust-poststart.sh
set -e
MAX_RETRIES=10
RETRY_INTERVAL=2
COMMAND=$1
retry_command() {
local retries=0
until $COMMAND; do
retries=$((retries + 1))
if [ $retries -ge $MAX_RETRIES ]; then
echo "Command failed after $MAX_RETRIES attempts"
exit 1
fi
sleep $RETRY_INTERVAL
done
}
# 使用重试机制
retry_command "curl -f http://service:8080/health"
echo "Dependency ready, continuing..."
注意事项
postStart关键点
- 与主进程同时执行,不是等待它完成
- 不支持使用
sleep等待主进程 - 如果命令失败,容器会被杀死
preStop关键点
- 执行完成后发送
SIGTERM - 默认等待30秒(可通过
terminationGracePeriodSeconds修改) - 适合做清理和优雅关闭
潜在问题处理
#!/bin/bash
# handle-errors.sh
# 避免postStart长时间阻塞
timeout 10 /bin/bash -c "
echo 'Short-lived initialization'
# 快速完成的任务
"
# preStop中处理多个信号
trap 'echo "Received SIGTERM, exiting..."; exit 0' SIGTERM
trap 'echo "Received SIGINT, ignoring in preStop"' SIGINT
# 检查文件是否存在
if [ -f /tmp/lockfile ]; then
rm -f /tmp/lockfile
fi
测试验证
#!/bin/bash # test-lifecycle.sh # 创建测试Pod kubectl create -f lifecycle-test.yaml # 查看日志 kubectl logs lifecycle-demo # 检查启动文件 kubectl exec lifecycle-demo -- cat /tmp/start.log # 测试preStop(删除Pod) kubectl delete pod lifecycle-demo # 查看preStop日志 kubectl logs lifecycle-demo --previous
通过以上配置,你可以实现灵活且健壮的容器生命周期管理。