You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes Pod内多Tomcat容器无法通过LoadBalancer访问求助

问题分析与解决方案:同一Pod多Tomcat容器无法通过LoadBalancer访问

我在Kubernetes的同一个Pod中运行3个基于Tomcat的容器,Service配置为LoadBalancer类型,但无法在外部浏览器访问服务。仅运行单个容器时可正常访问。

提供的YAML配置

apiVersion: v1
kind: Namespace
metadata:
  name: tomcat
  labels:
    name: tomcat
---

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: tomcat
  name: tomcat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: jpetstores1
        image: petstoremysql2:latest
        imagePullPolicy: Never
        env:
        - name: sname
          value: petstore1
                                 
      - name: jpetstores2
        image: petstoremysql2:latest
        imagePullPolicy: Never
        env:
        - name: sname
          value: petstore2    
        
      - name: jpetstores3
        image: petstoremysql2:latest
        imagePullPolicy: Never
        env:
        - name: sname
          value: petstore3 
---

apiVersion: v1
kind: Service
metadata:
  namespace: tomcat
  name: tomcat-service
spec:
  selector:
    app: tomcat
  ports:
  - protocol: TCP
    port: 81
    targetPort: 8080
  type: LoadBalancer

---

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: tomcat
  namespace: tomcat
spec:
  maxReplicas: 3
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: tomcat
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 97

---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: tomcat-pdb1
  namespace: tomcat
spec:
  minAvailable: 1
  selector:
    matchLabels:
      run: tomcat   

核心问题原因

同一Pod内的所有容器共享网络命名空间,默认Tomcat镜像都会监听8080端口。当在同一个Pod中启动三个Tomcat容器时,后启动的容器会因8080端口被先启动的容器占用而启动失败,或虽启动但无法正常监听端口,导致Service转发流量时没有可用的后端端口。

解决方案

方案1:为每个容器分配独立端口

修改Deployment和Service配置,让三个Tomcat容器分别使用不同的端口,并通过Service的多端口映射对外暴露:

修改后的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: tomcat
  name: tomcat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: jpetstores1
        image: petstoremysql2:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
        env:
        - name: sname
          value: petstore1
        # 若镜像支持通过环境变量改端口,可添加:
        # - name: TOMCAT_HTTP_PORT
        #   value: "8080"
                                 
      - name: jpetstores2
        image: petstoremysql2:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8081
        env:
        - name: sname
          value: petstore2
        - name: TOMCAT_HTTP_PORT
          value: "8081"
        
      - name: jpetstores3
        image: petstoremysql2:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8082
        env:
        - name: sname
          value: petstore3
        - name: TOMCAT_HTTP_PORT
          value: "8082"

修改后的Service

apiVersion: v1
kind: Service
metadata:
  namespace: tomcat
  name: tomcat-service
spec:
  selector:
    app: tomcat
  ports:
  - protocol: TCP
    port: 81
    targetPort: 8080
  - protocol: TCP
    port: 82
    targetPort: 8081
  - protocol: TCP
    port: 83
    targetPort: 8082
  type: LoadBalancer

此时可通过http://<LoadBalancer-IP>:81、http://<LoadBalancer-IP>:82、http://<LoadBalancer-IP>:83分别访问三个Tomcat服务。

方案2:使用Sidecar代理统一入口(可选)

若希望通过同一个外部端口访问三个服务,可在Pod中添加Nginx作为Sidecar代理,通过路径路由转发到不同Tomcat容器:

  1. 在Deployment中添加Nginx容器,挂载自定义配置文件实现反向代理
  2. 三个Tomcat容器分别监听8081、8082、8083端口
  3. Service的targetPort指向Nginx的8080端口,外部通过http://<LoadBalancer-IP>:81/petstore1/等路径访问

验证步骤

  • 检查Pod状态:kubectl get pods -n tomcat,确保三个容器均为Running状态
  • 查看容器日志:kubectl logs <pod-name> jpetstores2 -n tomcat,确认无端口冲突报错
  • 测试内部连通性:kubectl exec -it <pod-name> -n tomcat -- curl localhost:8081,验证每个Tomcat端口是否正常响应
  • 检查Service状态:kubectl get service tomcat-service -n tomcat,确认EXTERNAL-IP已分配

内容的提问来源于stack exchange,提问作者AnandArc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:17:41