React+Node.js应用本地Docker正常但AKS部署失败求助
本地Docker容器运行正常,但部署到AKS后通过LoadBalancer外部IP无法加载应用,已提供项目结构及相关配置文件,需排查清单配置问题并获取调试方法。
项目结构
--api(后端目录) --dockerfile --my-app(前端目录) --dockerfile --dockercompose.yml
前端Dockerfile
FROM node:10 WORKDIR /my-app COPY . . RUN npm install && npm run build EXPOSE 3000 CMD ["npm", "start"]
后端Dockerfile
FROM node:10 WORKDIR /api COPY ./package*.json . RUN npm install COPY . . EXPOSE 3080 CMD ["node", "--require", "./tracing.js", "./server.js"]
docker-compose.yml
version: '3' services: app-backend: build: ./api container_name: app-backend ports: - "3080:3080" app-frontend: depends_on: - app-backend build: ./my-app container_name: app-frontend ports: - "3000:3000" tty: true
前端package.json
{ "name": "my-app", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", "@testing-library/user-event": "^7.2.1", "bootstrap": "^4.5.0", "react": "^16.13.1", "react-bootstrap": "^1.0.1", "react-dom": "^16.13.1", "react-scripts": "3.4.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "proxy": "http://app-backend:3080", "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
AKS清单文件
apiVersion: apps/v1 kind: Deployment metadata: name: app-backend spec: replicas: 1 selector: matchLabels: app: app-backend template: metadata: labels: app: app-backend spec: containers: - name: app-backend image: danpoc0acr.azurecr.io/react-nodejs-aks-app-backend:v1 ports: - containerPort: 3080 --- apiVersion: v1 kind: Service metadata: name: app-backend spec: ports: - port: 3080 selector: app: app-backend --- apiVersion: apps/v1 kind: Deployment metadata: name: app-frontend spec: replicas: 1 selector: matchLabels: app: app-frontend template: metadata: labels: app: app-frontend spec: containers: - name: app-frontend image: danpoc0acr.azurecr.io/react-nodejs-aks-app-frontend:v1 ports: - containerPort: 3000 --- apiVersion: v1 kind: Service metadata: name: app-frontend spec: type: LoadBalancer ports: - port: 3000 selector: app: app-frontend
一、清单文件潜在问题
前端Service端口映射缺失
targetPort
当前前端Service仅指定port: 3000,虽Kubernetes默认会将port与targetPort设为相同值,但显式配置可避免歧义,确保流量正确转发到容器端口3000。修改后的前端Service配置:apiVersion: v1 kind: Service metadata: name: app-frontend spec: type: LoadBalancer ports: - port: 3000 targetPort: 3000 protocol: TCP selector: app: app-frontend前端容器开发服务器绑定限制
前端Dockerfile使用npm start启动开发服务器,该模式默认绑定localhost,导致容器外部无法访问。需修改启动命令让服务器监听所有网卡:- 修改前端Dockerfile的CMD:
CMD ["npm", "start", "--", "--host", "0.0.0.0"] - 或直接在package.json的scripts中配置:
"scripts": { "start": "react-scripts start --host 0.0.0.0", ... }
注意:生产环境建议用Nginx等静态文件服务器托管build产物,而非开发服务器。
- 修改前端Dockerfile的CMD:
后端Service配置验证
后端Service默认是ClusterIP类型,前端容器在集群内部可通过http://app-backend:3080访问后端,此部分配置正常,但需确认后端容器是否正常监听3080端口。
二、调试步骤
检查Pod状态
执行kubectl get pods查看所有Pod是否处于Running状态,若出现CrashLoopBackOff或Error,查看Pod日志:kubectl logs <pod-name> # 查看最近20条日志 kubectl logs --tail=20 <pod-name> # 查看容器重启前的日志 kubectl logs --previous <pod-name>验证容器内部服务可用性
进入前端Pod内部,测试后端访问:kubectl exec -it <frontend-pod-name> -- /bin/bash curl http://app-backend:3080同时测试前端服务在容器内是否可访问:
curl localhost:3000检查Service与Endpoint关联
确认Service是否正确关联到Pod的Endpoint:kubectl describe service app-backend kubectl describe service app-frontend确保
Endpoints字段显示Pod的IP和对应端口,若为空则说明标签选择器不匹配。检查LoadBalancer状态
执行kubectl get service app-frontend查看外部IP是否已分配、状态是否为Ready。若外部IP长时间处于<pending>,需检查AKS集群所在区域的负载均衡器资源,或集群网络配置。测试集群内部访问
在集群内临时启动测试Pod,访问前端Service:kubectl run -it --rm --image=curlimages/curl test-curl -- curl http://app-frontend:3000若能正常访问,说明问题出在外部流量转发,需检查AKS节点的网络安全组(NSG)是否允许3000端口的入站流量。
检查AKS网络安全组
登录Azure门户,找到AKS集群的节点资源组(通常命名为MC_<资源组名>_<集群名>_<区域>),查看节点NSG规则,确保存在允许3000端口入站的规则。
内容的提问来源于stack exchange,提问作者bunny

