Google Cloud Run部署异常:修订版本无法就绪,容器未监听指定端口
问题描述
部署Cloud Run服务时触发错误:
Deployment failed ERROR: (gcloud.run.services.replace) Revision 'example-on-docker-00001-nl7' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information.
Nginx容器未能在指定的8080端口启动监听,已确认service.yaml和容器镜像配置无明显显性错误,需进一步排查。
提供的配置文件
Nginx Dockerfile
FROM nginx:stable-alpine AS base WORKDIR /app/public EXPOSE 8080 FROM base AS development FROM base AS distribution ARG WORDPRESS ARG CACHE_CONTROL ARG NGINX_LISTEN_PORT ENV NGINX_ENVSUBST_OUTPUT_DIR /etc/nginx/conf.d-from-template/ ADD build/environment/docker/nginx/etc/ /etc/nginx/ RUN /docker-entrypoint.d/20-envsubst-on-templates.sh RUN rm /etc/nginx/conf.d/default.conf ADD build/environment/docker/nginx/dist.tar.gz /app
service.yaml
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example generation: 1 labels: cloud.googleapis.com/location: us-example annotations: run.googleapis.com/ingress: all run.googleapis.com/ingress-status: all run.googleapis.com/launch-stage: BETA spec: template: metadata: labels: run.googleapis.com/startupProbeType: Default annotations: autoscaling.knative.dev/maxScale: '100' run.googleapis.com/startup-cpu-boost: 'true' spec: containerConcurrency: 80 timeoutSeconds: 300 serviceAccountName: example@developer.gserviceaccount.com containers: - name: nginx image: us-east1-docker.pkg.dev/project/repository/image:server-1 ports: - name: http1 containerPort: 8080 env: - name: CACHE_CONTROL value: 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0' - name: WORDPRESS value: wordpress resources: limits: memory: 512Mi cpu: 1000m startupProbe: timeoutSeconds: 240 periodSeconds: 240 failureThreshold: 1 tcpSocket: port: 8080 - name: wordpress image: us-east1-docker.pkg.dev/project/repository/image:fpm-1 env: resources: limits: memory: 512Mi cpu: 1000m startupProbe: timeoutSeconds: 240 periodSeconds: 240 failureThreshold: 1 tcpSocket: port: 9000 traffic: - percent: 100 latestRevision: true
诊断与解决步骤
1. 优先排查容器启动日志
直接获取目标修订版本的日志,定位具体报错:
- 使用gcloud命令:
gcloud run revisions logs example-on-docker-00001-nl7 --region us-example - 或在Cloud Console的Cloud Run服务页面,找到该修订版本后查看「日志」标签页。
重点关注Nginx启动时的配置语法错误、依赖文件缺失、端口冲突等信息。
2. 修正Nginx端口配置匹配问题
从现有配置看,存在两处端口不匹配的潜在问题:
未传递监听端口变量:Dockerfile定义了
ARG NGINX_LISTEN_PORT,但service.yaml未传递该变量,若Nginx模板依赖此变量设置监听端口,会默认使用80端口而非8080。
解决:在service.yaml的nginx容器环境变量中添加:env: - name: CACHE_CONTROL value: 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0' - name: WORDPRESS value: wordpress - name: NGINX_LISTEN_PORT value: '8080'同时确保Nginx模板配置文件(如
/etc/nginx/conf.d/default.conf.template)包含listen ${NGINX_LISTEN_PORT};的变量替换语法。配置文件输出目录错误:Dockerfile设置
NGINX_ENVSUBST_OUTPUT_DIR为/etc/nginx/conf.d-from-template/,但Nginx默认读取/etc/nginx/conf.d/下的配置,导致替换后的配置未被加载。
解决:将NGINX_ENVSUBST_OUTPUT_DIR改为/etc/nginx/conf.d/,或在脚本执行后移动配置文件:RUN /docker-entrypoint.d/20-envsubst-on-templates.sh && \ mv /etc/nginx/conf.d-from-template/* /etc/nginx/conf.d/
3. 调整多容器启动依赖逻辑
服务包含Nginx和WordPress-FPM两个容器,Nginx依赖FPM的9000端口,若FPM启动慢或失败,会导致Nginx启动异常:
- 查看WordPress容器的启动日志,确认其是否正常监听9000端口。
- 修改Nginx启动探针,使用HTTP探针替代TCP探针,同时调整重试策略确保FPM就绪:
该配置会尝试24次连接,总等待时间240秒,和原配置一致,但HTTP探针更能反映服务实际就绪状态。startupProbe: httpGet: path: / port: 8080 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 24
4. 本地验证容器行为
在本地模拟Cloud Run环境运行Nginx容器,排查镜像本身问题:
- 运行命令:
docker run -p 8080:8080 -e NGINX_LISTEN_PORT=8080 -e WORDPRESS=wordpress us-east1-docker.pkg.dev/project/repository/image:server-1 - 用
curl localhost:8080测试访问,或用docker exec <container-id> netstat -tulpn查看端口监听情况。
若本地也无法启动,说明容器镜像存在问题,需修正Dockerfile或配置文件。
5. 对齐Cloud Run自动注入的PORT变量
Cloud Run会自动设置PORT环境变量,值为service.yaml中指定的containerPort(8080)。建议Nginx配置直接引用该变量,避免冲突:
在Nginx模板中写listen ${PORT:-8080};,无需在service.yaml中额外设置PORT变量,Cloud Run会自动注入。
内容的提问来源于stack exchange,提问作者Marcos Vile

