Flask+Postgres部署Kubernetes时entrypoint.sh文件缺失问题排查
Kubernetes中API Pod出现CrashLoopBackOff:entrypoint.sh找不到的原因分析
问题背景
我有一个Flask+Postgres应用,通过docker-compose容器化,使用entrypoint.sh调用manage.py完成数据库初始化,本地Docker环境运行正常。部署到Kubernetes后,Postgres Pod正常运行,但API Pod出现CrashLoopBackOff错误,提示无法找到/usr/src/app/api/entrypoint.sh。不过直接从Docker Hub拉取镜像运行时,能正常找到该文件,仅出现数据库连接失败问题。
相关配置
docker-compose配置
services: database: image: postgres:latest container_name: hse-database volumes: - postgres_data:/var/lib/postgresql/data/ environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=hse-app-db expose: - "5432" ports: - "5432:5432" restart: always api: build: ./hse_api container_name: hse_api ports: - "5000:5000" env_file: ./hse_api/.env volumes: - ./hse_api:/usr/src/app/api depends_on: - database restart: always
Kubernetes API Deployment配置
apiVersion: apps/v1 kind: Deployment metadata: name: hse-api namespace: hse-app spec: replicas: 1 selector: matchLabels: app: hse-api template: metadata: labels: app: hse-api spec: containers: - name: hse-api image: imranoshpro/hse-api:v0.2.1 imagePullPolicy: Always ports: - containerPort: 5000 envFrom: - secretRef: name: hse-api-secrets volumeMounts: - name: api-volume mountPath: /usr/src/app/api volumes: - name: api-volume persistentVolumeClaim: claimName: api-pvc imagePullSecrets: - name: docker-hub-secret
Pod错误信息
Port: 5000/TCP Host Port: 0/TCP State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: ContainerCannotRun Message: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/usr/src/app/api/entrypoint.sh": stat /usr/src/app/api/entrypoint.sh: no such file or directory: unknown
问题原因
- PVC挂载覆盖了容器镜像内的核心目录:
你的Kubernetes Deployment将PVC挂载到了容器的/usr/src/app/api路径,而这个PVC是新创建的空存储卷。挂载操作会完全覆盖容器镜像中该路径下的原有内容——entrypoint.sh原本是打包在镜像里的,被空PVC覆盖后自然无法找到。 - 本地docker-compose正常的原因:本地挂载的是开发机器上的
./hse_api目录,该目录本身包含entrypoint.sh,因此容器能读取到脚本。 - 直接拉镜像运行正常的原因:此时没有挂载任何卷,容器使用的是镜像内自带的
/usr/src/app/api目录及其中的entrypoint.sh,所以能找到脚本,仅因缺少Postgres服务导致数据库连接失败。
解决办法
- 移除不必要的PVC挂载(推荐):如果镜像已经包含完整的应用代码和entrypoint.sh,无需在K8s中挂载PVC到核心目录。删除Deployment中的
volumeMounts和volumes部分即可,修改后的Deployment示例:
apiVersion: apps/v1 kind: Deployment metadata: name: hse-api namespace: hse-app spec: replicas: 1 selector: matchLabels: app: hse-api template: metadata: labels: app: hse-api spec: containers: - name: hse-api image: imranoshpro/hse-api:v0.2.1 imagePullPolicy: Always ports: - containerPort: 5000 envFrom: - secretRef: name: hse-api-secrets imagePullSecrets: - name: docker-hub-secret
- 若必须挂载卷:不要将PVC挂载到包含应用核心文件(如entrypoint.sh、manage.py)的目录,改为挂载到子目录(比如用于存储上传文件的
/usr/src/app/api/uploads),避免覆盖镜像内的关键文件。
内容的提问来源于stack exchange,提问作者Imran Said
相关产品推荐
相关产品推荐

