AWS CDK配置双容器Fargate服务时健康检查失败求助
看起来你在搭建Nginx+PHP的双容器Fargate服务时卡在了健康检查这一步,这种情况我之前也碰到过,大概率是容器连通性、配置或者健康检查规则本身的问题,咱们一步步拆解排查:
最可能的几个原因及解决办法
1. Nginx配置未正确指向PHP容器
因为两个容器在同一Fargate任务里,默认共享网络命名空间,Nginx需要通过localhost:9000访问PHP-FPM。如果你的Nginx配置里fastcgi_pass写的不是localhost:9000(比如错误用了外部服务名),就会导致请求PHP文件时返回502,进而触发ALB健康检查失败。
验证方式:用ECS Exec进入Nginx容器,执行curl -v http://localhost/,如果返回502 Bad Gateway,基本就是这个问题。修改Nginx的站点配置(比如/etc/nginx/conf.d/default.conf),把fastcgi_pass改成localhost:9000后重启Nginx即可。
2. 健康检查规则未匹配实际应用状态
你的CDK代码里既没给容器配置容器级健康检查,也没自定义ALB的健康检查规则,默认的ALB健康检查会访问/路径,但如果:
- Nginx的root目录没指向
/var/www/html /var/www/html下没有index.php或者权限不足- PHP-FPM未正常启动
都会导致/路径返回非200状态码,触发健康检查失败。
CDK代码修改建议:给Nginx容器添加容器级健康检查,同时自定义ALB的健康检查规则:
// 给Nginx容器添加健康检查 const serverContainer = taskDefinition.addContainer("ServerContainer", { image: ContainerImage.fromEcrRepository(nginxRepo), portMappings: [{ containerPort: 80 }], healthCheck: { command: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"], interval: Duration.seconds(30), timeout: Duration.seconds(5), retries: 3, startPeriod: Duration.seconds(60), // 给容器启动留足够缓冲时间 }, }); // 给PHP容器添加健康检查(需要PHP镜像预装cgi-fcgi工具) const appContainer = taskDefinition.addContainer("AppContainer", { image: ContainerImage.fromEcrRepository(phpRepo), portMappings: [{ containerPort: 9000 }], healthCheck: { command: ["CMD-SHELL", "SCRIPT_NAME=/status SCRIPT_FILENAME=/status REQUEST_METHOD=GET cgi-fcgi -bind -connect localhost:9000 || exit 1"], interval: Duration.seconds(30), timeout: Duration.seconds(5), retries: 3, startPeriod: Duration.seconds(60), }, }); // 自定义ALB健康检查规则 const service = new ApplicationLoadBalancedFargateService(this, "Service", { // 保留原有的cluster、taskDefinition等配置 assignPublicIp: true, publicLoadBalancer: true, desiredCount: 1, listenerPort: 80, taskSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS }, enableExecuteCommand: true, // 新增健康检查配置 healthCheck: { path: "/", interval: Duration.seconds(30), timeout: Duration.seconds(5), healthyThresholdCount: 2, unhealthyThresholdCount: 2, port: "traffic-port", }, });
3. 共享卷的权限问题
你挂载了www-data卷到两个容器的/var/www/html,但要注意两个容器的用户权限是否匹配:
- PHP-FPM通常以
www-data用户运行 - Nginx官方镜像默认以
nginx用户运行
如果/var/www/html的所有者是www-data,Nginx用户可能没有读取权限,导致访问/返回403 Forbidden,触发健康检查失败。
解决办法:
- 要么在Nginx的Dockerfile里把运行用户改成
www-data - 要么在容器启动时添加权限修复命令,比如在Nginx容器的
command里追加chown -R nginx:nginx /var/www/html && nginx -g 'daemon off;'
4. 容器启动顺序问题
有时候Nginx启动得比PHP-FPM早,导致Nginx初始化时无法连接PHP,触发健康检查失败。虽然Fargate不支持容器启动依赖,但可以通过延长健康检查的startPeriod(上面代码里已经设置了60秒),给PHP-FPM足够的启动时间。
快速排查步骤
- 用ECS Exec进入Nginx容器:
aws ecs execute-command --cluster FargateCluster --task <你的任务ID> --container ServerContainer --command "/bin/bash" --interactive - 检查Nginx错误日志,定位请求失败原因:
tail -f /var/log/nginx/error.log - 验证PHP-FPM连通性:
# 若容器无cgi-fcgi工具,可先安装:apt-get install -y fcgiwrap SCRIPT_NAME=/status SCRIPT_FILENAME=/status REQUEST_METHOD=GET cgi-fcgi -bind -connect localhost:9000 - 检查共享卷的文件和权限:
ls -l /var/www/html
按这个思路排查下来,应该能很快定位到问题所在。
内容来源于stack exchange

