使用GitHub Actions部署GKE时Express容器持续崩溃求助
问题:CI构建的Express容器在GKE中持续崩溃,手动部署正常
我通过GitHub Actions将包含Vue、Express和MongoDB的三容器Pod部署到GKE,手动执行以下命令部署完全正常:
kubectl apply -f deployment-sit.yaml kubectl apply -f vue-service-sit.yaml kubectl apply -f express-service-sit.yaml kubectl apply -f mongodb-service-sit.yaml kubectl apply -f sit-ingress.yaml
但CI流水线使用相同的docker-compose文件和Dockerfile构建镜像后,Express容器持续崩溃,仅能看到以下错误信息:
stream closed EOF for default/seg-dashboard-sit-6c9d6d5798-lscd5 (seg-dashboard-sit-express)
以及:
Warning BackOff 3m30s (x24 over 8m26s) kubelet Back-off restarting failed container seg-dashboard-sit-express in pod seg-dashboard-sit-6c9d6d5798-lscd5_default(7042eb1d-c7bc-455f-bfc5-4159733aa00e)
已确认问题出在构建阶段(CI构建的镜像本地运行也异常),尝试过配置GCP IAM权限、检查环境变量、校验健康检查路径、调整livenessProbe,均未解决。
相关配置文件
Express docker-compose.yaml
version: '3.8' services: api: build: context: . dockerfile: Dockerfile container_name: seg-dashboard-vue env_file: - ./.env.production environment: - NODE_ENV=production - HOSTNAME=0.0.0.0 - BASE_URL=/seg-dashboard/api - OPSGENIE_APIKEY=4075da9d-07b2-4db3-9388-2a1b7c851c78 - OPSGENIE_APIURL=https://api.opsgenie.com/v2 image: asia-east1-docker.pkg.dev/visitor-access-system/tools/seg-dashboard-express:latest platform: linux/amd64
Express Dockerfile
FROM node:lts-jod AS build LABEL maintainer="jackylai327@gmail.com" version="1.0" WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 11200 ENV NODE_ENV=production ENV HOSTNAME=0.0.0.0 ENV BASE_URL=/seg-dashboard/api ENV OPSGENIE_APIKEY=4075da9d-07b2-4db3-9388-2a1b7c851c78 ENV OPSGENIE_APIURL=https://api.opsgenie.com/v2 CMD ["npm", "start"]
CI流水线配置
name: SEG Dashboard CI/CD Pipeline on: push: branches: # - main - develop jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '21' - name: Install Docker Compose run: | sudo apt-get update sudo apt-get install -y docker-compose - name: Build Docker images run: | docker-compose -f vue-app/docker-compose.yaml build --no-cache docker-compose -f express-app/docker-compose.yaml build --no-cache - name: Log in to Google Container Registry uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SA_KEY }} - name: Configure Docker to use the gcloud command-line tool as a credential helper run: gcloud auth configure-docker asia-east1-docker.pkg.dev - name: Push Docker images to Google Container Registry run: | docker push asia-east1-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/tools/seg-dashboard-vue:latest docker push asia-east1-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/tools/seg-dashboard-express:latest deploy: needs: build runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Log in to Google Container Registry uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SA_KEY }} - name: Set up gcloud Cloud SDK environment uses: google-github-actions/setup-gcloud@v2.1.2 with: project_id: ${{ secrets.GCP_PROJECT_ID }} install_components: 'kubectl,gke-gcloud-auth-plugin' - name: Configure gcloud and kubectl run: | gcloud container clusters get-credentials ${{ secrets.GKE_CLUSTER_NAME }} --zone ${{ secrets.GKE_CLUSTER_LOCATION }} --project ${{ secrets.GCP_PROJECT_ID }} gcloud config set project ${{ secrets.GCP_PROJECT_ID }} kubectl config current-context - name: Deploy to Kubernetes run: | kubectl apply -f deployment-sit.yaml kubectl apply -f vue-service-sit.yaml kubectl apply -f express-service-sit.yaml kubectl apply -f mongodb-service-sit.yaml kubectl apply -f sit-ingress.yaml kubectl rollout restart deployment seg-dashboard-sit
排查步骤
- 本地复现CI构建流程:在本地机器上完全模拟CI的构建步骤(使用Node 21,执行
docker-compose build --no-cache),然后运行构建出的镜像,手动启动服务查看详细错误:docker run -it asia-east1-docker.pkg.dev/visitor-access-system/tools/seg-dashboard-express:latest bash # 进入容器后执行 npm start - 核对Node版本差异:CI构建步骤用的是Node 21,但Dockerfile基础镜像是
node:lts-jod(对应Node 20.x),版本不一致可能导致依赖安装异常。可以让CI的Node版本和Dockerfile保持一致,或在Dockerfile中明确指定与CI匹配的Node版本。 - 验证.env.production文件存在性:检查CI环境中是否存在
.env.production文件,如果该文件未提交到仓库,容器会缺少必要环境变量。可以在CI构建步骤中添加文件检查命令,或在Dockerfile中增加验证:# 在Dockerfile的COPY步骤后添加 RUN ls -la .env.production || echo ".env.production file missing" - 检查构建上下文路径:确认CI中构建Express镜像时,
docker-compose -f express-app/docker-compose.yaml build的上下文是否正确,package.json、源码文件是否在指定路径下,避免COPY命令遗漏关键文件。 - 获取GKE容器完整日志:查看崩溃容器的上一次启动日志,通常能找到具体失败原因:
kubectl logs <pod-name> -c seg-dashboard-sit-express --previous - 优化Dockerfile多阶段构建:当前Dockerfile未区分开发依赖和生产依赖,建议使用多阶段构建减少镜像体积并避免依赖冲突:
FROM node:lts-jod AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . # 如果有构建步骤(比如编译TypeScript),添加对应命令 # RUN npm run build FROM node:lts-jod AS production WORKDIR /app COPY --from=builder /app/package*.json ./ RUN npm ci --only=production COPY --from=builder /app ./ # 或仅复制生产需要的文件(如dist目录) EXPOSE 11200 ENV NODE_ENV=production ENV HOSTNAME=0.0.0.0 ENV BASE_URL=/seg-dashboard/api ENV OPSGENIE_APIKEY=4075da9d-07b2-4db3-9388-2a1b7c851c78 ENV OPSGENIE_APIURL=https://api.opsgenie.com/v2 CMD ["npm", "start"]
内容的提问来源于stack exchange,提问作者Jacky
相关产品推荐
相关产品推荐

