GKE部署Node.js/MongoDB应用出现CrashLoopBackOff错误问询
问题原因确认
你观察到的MongoDB连接失败确实是触发CrashLoopBackOff和Does not have minimum availability报错的直接原因:Node.js应用启动时如果数据库连接失败且未做异常捕获兜底,进程会直接退出,Kubernetes检测到进程异常终止后会反复重启容器,最终进入CrashLoopBackOff状态;副本数始终达不到配置要求,就会触发最小可用性报错。
排查与修复步骤
第一步:先确认MongoDB Pod运行状态
执行命令kubectl get pods mongodb查看Pod状态是否为Running,如果状态异常,执行kubectl logs mongodb查看MongoDB本身的启动报错,比如端口占用、权限不足、存储挂载失败等问题。你当前用裸Pod部署MongoDB本身就存在稳定性问题,一旦Pod异常退出不会自动重建,测试环境可以临时使用,生产环境建议改用StatefulSet部署。第二步:验证MongoDB服务连通性
启动临时调试Pod测试服务解析:kubectl run debug --image=mongo --rm -it -- bash进入容器后执行
mongosh --host mongodb --port 27017,如果无法连通,先确认MongoDB Pod的标签和Service的selector是否匹配,以及两个资源是否部署在同一个命名空间下:跨命名空间访问服务的话,连接地址需要写为mongodb://mongodb.<部署Mongo的命名空间>.svc.cluster.local:27017,不能直接用服务名。第三步:修正Node.js应用配置
- 检查代码中的MongoDB连接串,确认和集群内的服务地址完全匹配,不要硬编码本地测试用的
localhost:27017地址; - 给Deployment添加启动探针,避免应用在MongoDB就绪前启动导致连接失败,参考配置如下:
apiVersion: apps/v1 kind: Deployment metadata: name: journal-api-deployment spec: selector: matchLabels: app: journal-api tier: backend replicas: 1 template: metadata: labels: app: journal-api tier: backend spec: containers: - image: shulaa/journal-api:v1 name: journal-api ports: - containerPort: 8080 name: http-port # 添加启动探针,检测8080端口是否就绪,允许最多30秒的启动时间 startupProbe: httpGet: path: /healthz # 建议在代码里加一个健康检查接口,能正常返回即代表数据库连接成功 port: http-port failureThreshold: 10 periodSeconds: 3如果暂时不想加健康检查接口,也可以添加initContainer等待MongoDB就绪后再启动应用:
spec: initContainers: - name: wait-for-mongo image: busybox:1.28 command: ['sh', '-c', 'until nc -z mongodb 27017; do echo waiting for mongodb; sleep 2; done;']- 检查代码中的MongoDB连接串,确认和集群内的服务地址完全匹配,不要硬编码本地测试用的
第四步:验证服务可访问性
应用启动正常后,执行kubectl get svc journal-api-service查看LoadBalancer的外部IP,访问http://<外部IP>:8080即可,注意GKE的LoadBalancer配置生效需要1-2分钟。
内容的提问来源于stack exchange,提问作者Aso Amarachi

