OpenShift部署监听80端口、使用8080端口Service的应用及503排查
OpenShift/K8s 端口逻辑通俗说明
不用死记官方文档的抽象定义,把整条访问链路当成快递配送流程,每一层的端口就是对应环节的收件地址,只要前后环节的地址匹配就能通,匹配不上就会丢包报错:
- 最外层是OpenShift默认部署的路由器组件,直接对外暴露80/443公网端口,外部用户访问域名时默认走这两个端口,不需要手动修改配置
- 路由器收到请求后会转发给绑定的Service,此时Route配置里的
targetPort,就是路由器要在Service上找的端口号/端口名,必须和Service中定义的port字段完全匹配,找不到对应端口就会直接返回503错误 - Service收到请求后会转发给后端匹配标签的Pod,此时Service配置里的
targetPort,就是要在Pod上找的容器监听端口,必须和容器内应用实际监听的端口、Deployment中声明的containerPort完全匹配 - 最内层就是你部署的应用进程,必须实打实监听前面配置的容器端口,如果进程只监听8080,前面所有环节都写80,肯定收不到流量
当前配置返回503的根因
你现在的配置存在端口不匹配问题:
- Route中配置的
targetPort是80,但Service中定义的集群内暴露端口port是5000,路由器在Service上找不到80端口,转发链路直接断裂 - 如果你的应用实际监听8080端口,当前Deployment中写的
containerPort: 80也不匹配,会导致Service转发失败
符合需求的正确配置(对外监听80端口、关联8080应用端口)
Deployment 配置
containerPort和应用实际监听端口保持一致,这里应用监听8080就填8080:
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: 你的应用镜像地址 ports: - name: HTTP containerPort: 8080
Service 配置
集群内访问端口设为你需要的80,targetPort指向容器监听的8080:
apiVersion: v1 kind: Service metadata: name: my-app spec: selector: app: my-app ports: - name: HTTP port: 80 protocol: TCP targetPort: 8080
Route 配置
Route默认对外监听80端口,targetPort和Service中定义的端口名/端口值匹配即可,这里直接引用Service里的端口名HTTP避免写错:
apiVersion: route.openshift.io/v1 kind: Route metadata: name: my-app spec: to: kind: Service name: my-app port: targetPort: HTTP
常见503排错步骤
如果配置修改后还是返回503,按顺序排查即可:
- 执行
oc get pods查看Pod状态,确认Pod处于Running状态,没有就绪探针检查失败、启动报错的情况,未就绪的Pod不会被Service加入后端转发列表 - 执行
oc rsh <Pod名称>进入容器,用curl localhost:8080访问应用本地端口,确认应用本身能正常返回响应,排除应用启动失败、端口监听错误的问题 - 执行
oc describe svc my-app查看Endpoints字段,确认Service已经关联到正确的PodIP+端口,如果Endpoints为空,说明Service的selector标签和Pod的标签不匹配 - 执行
oc describe route my-app查看Route关联的Service、端口配置是否正确,确认没有绑定错服务
内容的提问来源于stack exchange,提问作者Justin Reddick
相关产品推荐
相关产品推荐

