Kubernetes双ClusterIP用80端口,仅一个可通过Ingress访问问题排查
Kubernetes Ingress 502错误排查与配置疑问解答
问题场景
在Kubernetes集群的nxtgen命名空间部署了两个应用:
- App1:容器端口8081,ClusterIP Service暴露80端口
- App2:容器端口8099,ClusterIP Service暴露80端口
本地Docker验证镜像有效,但仅App2可通过Ingress正常访问,访问App1时出现502 bad gateway - nginx错误,提出以下疑问:
- 哪里配置出错了?
- Ingress资源中的端口定义是否正确?
- 两个ClusterIP拥有不同IP,因此均可使用80端口,这一理解是否正确?是否应为ClusterIP设置不同端口?
疑问解答
1. 可能的配置/运行问题
按优先级从高到低排查:
- Pod运行状态检查:执行
kubectl get pods -n nxtgen -l app=app1,确认Pod是否处于Running状态。若出现ImagePullBackOff,检查registrykey镜像拉取密钥是否存在于nxtgen命名空间;若为CrashLoopBackOff,用kubectl logs <app1-pod-name> -n nxtgen查看容器启动失败原因。 - Service与Pod连通性验证:在集群内启动临时测试Pod:
kubectl run tmp-pod --image=busybox:1.28 -n nxtgen --rm -it -- sh,然后在Pod内执行curl app1.nxtgen.svc.cluster.local:80。若无法访问,进入App1 Pod内部kubectl exec -it <app1-pod-name> -n nxtgen -- sh,用ss -tulpn确认容器8081端口是否正在监听(部分镜像无netstat,可用ss替代)。 - Ingress路径路由问题:当前Ingress中App1的路径是
/app1/api/getInfo,Prefix类型会将完整路径转发给App1。如果App1的接口实际是/api/getInfo而非/app1/api/getInfo,会返回404,最终导致Ingress返回502。这种情况需添加Nginx Ingress重写注解,修改Ingress的metadata:
同时将App1的路径修改为:metadata: name: ingress-rules namespace: nxtgen annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2- path: /app1(/|$)(.*) pathType: Prefix backend: service: name: app1 port: number: 80
2. Ingress资源中的端口定义是否正确?
Ingress中的端口定义完全正确。Ingress指向的是Service暴露的80端口,而Service的targetPort已正确映射到App1的8081端口,端口层面配置无问题。
3. ClusterIP端口复用的理解是否正确?
你的理解完全正确。每个ClusterIP Service拥有独立的集群内IP,端口属于Service自身,多个Service使用相同端口(如80)不会冲突,无需为不同ClusterIP设置不同端口,这是Kubernetes Service的标准用法。
配置文件
App1 配置
apiVersion: apps/v1 kind: Deployment metadata: name: app1-deployment namespace: nxtgen labels: app: app1 spec: replicas: 3 selector: matchLabels: app: app1 template: metadata: labels: app: app1 spec: containers: - name: app1 image: artifactory-ik.com:6656/app1:latest ports: - containerPort: 8081 imagePullSecrets: - name: registrykey --- apiVersion: v1 kind: Service metadata: name: app1 spec: type: ClusterIP selector: app: app1 ports: # port - port exposed internally in the cluster # targetPort - the container port to send requests to - targetPort: 8081 port: 80
App2 配置
apiVersion: apps/v1 kind: Deployment metadata: name: app2 namespace: nxtgen labels: app: app2 spec: replicas: 3 selector: matchLabels: app: app2 template: metadata: labels: app: app2 spec: containers: - name: app2 image: artifactory-ik.com:6656/app2:latest ports: - containerPort: 8099 imagePullSecrets: - name: registrykey --- apiVersion: v1 kind: Service metadata: name: app2 spec: type: ClusterIP selector: app: app2 ports: # port - port exposed internally in the cluster # targetPort - the container port to send requests to - targetPort: 8099 port: 80
Ingress 配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-rules namespace: nxtgen spec: ingressClassName: nginx rules: - host: nxthost.com http: paths: - path: / pathType: Prefix backend: service: name: app2 port: #same port of clusterIp number: 80 - path: /app2/info pathType: Prefix backend: service: name: app2 port: #same port of clusterIp number: 80 - path: /app1/api/getInfo pathType: Prefix backend: service: name: app1 port: #same port of clusterIp number: 80
内容的提问来源于stack exchange,提问作者Ohad
相关产品推荐
相关产品推荐

