添加DATA_MIGRATION环境变量后K8s initContainer无法启动且无日志
问题:环境变量控制Docker容器脚本行为异常
问题背景
我使用单个Docker镜像,内含一个.war文件和一个.jar文件,该镜像可同时作为Kubernetes的initContainer和普通container运行。容器启动脚本/myuser/entry-point.sh的逻辑为:当环境变量DATA_MIGRATION值为true时运行.jar文件;若未设置该变量,则运行.war文件。
当前异常情况:
- 给initContainer添加
DATA_MIGRATION=true环境变量后,容器启动失败且无日志输出; - 移除该环境变量后,initContainer可正常启动,但运行的是.war文件,不符合数据库迁移的预期。
需要解决的核心问题:如何正确传递环境变量,确保脚本按预期切换运行.jar或.war文件?
Kubernetes部署文件
apiVersion: apps/v1 kind: Deployment metadata: labels: app: ref-app name: ref-app spec: replicas: 1 selector: matchLabels: app: ref-app template: metadata: labels: app: ref-app spec: initContainers: - name: ref-app-database-migration image: "artifactory.com/ref-docker-local/dev/ref-proj:dev-0.1.0-SNAPSHOT-851e2d5" ports: - containerPort: 9080 env: - name: DATABASE_USERNAME valueFrom: secretKeyRef: name: db-secret key: username - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password - name: DATA_MIGRATION value: "true" containers: - name: ref-app image: "artifactory.com/ref-docker-local/dev/ref-proj:dev-0.1.0-SNAPSHOT-851e2d5" ports: - containerPort: 9080 env: - name: DATABASE_USERNAME valueFrom: secretKeyRef: name: db-secret key: username - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password
Pod描述片段(kubectl describe pod)
Init Containers: ref-app-database-migration: Container ID: docker://b1ada5e7b8b96c2dca49bca5913d03f313c546f92c112f3910aa1bfc068af9a1 Image: "artifactory.com/ref-docker-local/dev/ref-proj:dev-0.1.0-SNAPSHOT-851e2d5" Image ID: docker://sha256:2366a284564c16e031de5df5fb7c8e78e289f50fe9e2488f654344a5b1cb858a Port: 9080/TCP Host Port: 0/TCP State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Error Exit Code: 1 Started: Mon, 22 May 2023 15:16:16 +0100 Finished: Mon, 22 May 2023 15:16:16 +0100 Ready: False Restart Count: 1 Environment: DATABASE_USERNAME: <set to the key 'username' in secret 'db-secret'> Optional: false DATABASE_PASSWORD: <set to the key 'password' in secret 'db-secret'> Optional: false DATA_MIGRATION: true .. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 13s default-scheduler Successfully assigned default/ref-app-985fd75cd-bz8w6 to docker-desktop Normal Pulled 11s (x2 over 12s) kubelet Container image "artifactory.com/ref-docker-local/dev/ref-proj:dev-0.1.0-SNAPSHOT-851e2d5" already present on machine Normal Created 11s (x2 over 12s) kubelet Created container ref-app-database-migration Normal Started 11s (x2 over 12s) kubelet Started container ref-app-database-migration Warning BackOff 9s (x2 over 10s) kubelet Back-off restarting failed container
日志输出(kubectl logs deployment/ref-app)
Defaulted container "ref-app" out of: ref-app, ref-app-database-migration (init) Error from server (BadRequest): container "ref-app" in pod "ref-app-985fd75cd-mn7f2" is waiting to start: PodInitializing
排查与解决方案
1. 优先获取init容器的真实日志
你之前执行的kubectl logs deployment/ref-app默认查询的是主容器,但主容器因init容器未完成处于等待状态,必须指定init容器才能查看报错日志:
# 替换为实际的Pod名称 kubectl logs ref-app-985fd75cd-bz8w6 -c ref-app-database-migration # 或者通过标签筛选Pod并直接查询 kubectl logs $(kubectl get pods -l app=ref-app -o name) -c ref-app-database-migration
日志会直接暴露.jar启动失败的原因,比如数据库连接失败、文件路径错误、脚本语法问题等。
2. 检查启动脚本的逻辑正确性
脚本常见问题及修复:
- 环境变量判断不严谨:避免直接使用未初始化的变量,建议修改为容错性更强的判断逻辑:
# entry-point.sh 核心逻辑 if [ "${DATA_MIGRATION:-false}" = "true" ]; then # 运行数据库迁移jar java -jar /path/to/your/migration.jar else # 运行war服务(示例为Tomcat启动命令) catalina.sh run fi - 脚本无执行权限:确保Dockerfile中添加了权限配置:
RUN chmod +x /myuser/entry-point.sh - 文件路径错误:验证脚本中指定的.jar路径与镜像内实际路径一致,避免因找不到文件导致报错。
3. 验证环境变量是否正确传递
临时修改init容器的启动命令,直接输出所有环境变量,确认DATA_MIGRATION是否成功传入:
initContainers: - name: ref-app-database-migration image: "artifactory.com/ref-docker-local/dev/ref-proj:dev-0.1.0-SNAPSHOT-851e2d5" # 替换为打印环境变量的命令 command: ["printenv"] env: - name: DATABASE_USERNAME valueFrom: secretKeyRef: name: db-secret key: username - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password - name: DATA_MIGRATION value: "true"
执行kubectl logs查看输出,确认DATA_MIGRATION=true存在。
4. 检查数据库迁移jar的依赖条件
数据库迁移jar通常需要完整的数据库连接参数(如JDBC URL、驱动类等),当前部署仅传递了用户名和密码,可能缺少DATABASE_URL等必要变量,导致jar启动时无法连接数据库直接退出。需要补充对应的环境变量配置。
内容的提问来源于stack exchange,提问作者bobbyrne01
相关产品推荐
相关产品推荐

