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

能否为多个Kubernetes服务暴露同一外部IP地址?

问题描述

我有多个实现不同功能的镜像,目前通过以下命令部署并暴露服务:

kubectl create deployment work_deployment_1 --image=username/work_image_1:0.0.1-SNAPSHOT
kubectl expose deployment work_deployment_1 --type=LoadBalancer --port=8000

随后执行:

kubectl create deployment work_deployment_2 --image=username/work_image_2:0.0.1-SNAPSHOT
kubectl expose deployment work_deployment_2 --type=LoadBalancer --port=9000

部署并暴露完成后,执行kubectl get service查看,结果如下:

NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
work_deployment_1      LoadBalancer   10.245.197.226   159.65.210.104   8000:30798/TCP   30m
work_deployment_2      LoadBalancer   10.245.168.156   159.65.129.201   9000:32105/TCP   51s

请问能否通过部署配置,让这些服务通过same_external-ip:8000和same_external-ip:9000暴露,而非当前的不同外部IP端口组合?

解决方案

完全可以实现,下面是两种常用的落地方法:

方法一:无Selector LoadBalancer + Endpoints(通用TCP/UDP场景)

这种方式适合所有TCP/UDP类型的服务,不需要依赖额外的Ingress组件:

  1. 先清理现有LoadBalancer服务,把两个服务转为ClusterIP类型(默认就是ClusterIP,无需额外指定):
kubectl delete service work_deployment_1 work_deployment_2
kubectl expose deployment work_deployment_1 --name=service1 --port=8000
kubectl expose deployment work_deployment_2 --name=service2 --port=9000
  1. 创建一个不带Pod选择器的LoadBalancer服务,定义需要暴露的两个端口:
    新建文件unified-lb.yaml:
apiVersion: v1
kind: Service
metadata:
  name: unified-lb
spec:
  type: LoadBalancer
  ports:
    - name: service1-port
      port: 8000
      protocol: TCP
    - name: service2-port
      port: 9000
      protocol: TCP

执行创建:

kubectl apply -f unified-lb.yaml
  1. 创建Endpoints资源,手动将LoadBalancer的端口映射到对应的ClusterIP服务:
    先执行kubectl get service service1 service2拿到两个服务的ClusterIP,然后新建unified-endpoints.yaml:
apiVersion: v1
kind: Endpoints
metadata:
  name: unified-lb  # 必须和上面的LoadBalancer服务同名
subsets:
  - addresses:
      - ip: <service1的ClusterIP>  # 替换成实际的ClusterIP值
    ports:
      - name: service1-port
        port: 8000
        protocol: TCP
  - addresses:
      - ip: <service2的ClusterIP>  # 替换成实际的ClusterIP值
    ports:
      - name: service2-port
        port: 9000
        protocol: TCP

执行创建:

kubectl apply -f unified-endpoints.yaml

完成后,unified-lb服务会分配一个唯一的外部IP,访问外部IP:8000会转发到service1,外部IP:9000转发到service2。

方法二:Ingress Controller(HTTP/HTTPS优先,部分支持TCP/UDP)

如果你的服务是HTTP/HTTPS类型,推荐用这种方式,这是Kubernetes统一暴露服务的标准方案:

前提:集群已部署Ingress Controller(比如NGINX Ingress)

  1. 同样先清理现有LoadBalancer服务,转为ClusterIP:
kubectl delete service work_deployment_1 work_deployment_2
kubectl expose deployment work_deployment_1 --name=service1 --port=8000
kubectl expose deployment work_deployment_2 --name=service2 --port=9000

针对HTTP服务:

新建unified-ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: unified-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx  # 匹配你的Ingress Controller的className
  rules:
    - http:
        paths:
          - path: /service1
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 8000
          - path: /service2
            pathType: Prefix
            backend:
              service:
                name: service2
                port:
                  number: 9000

执行创建:

kubectl apply -f unified-ingress.yaml

此时访问Ingress Controller的外部IP,外部IP/service1会转发到service1,外部IP/service2转发到service2。如果想用域名访问,只需在rules里添加host字段即可。

针对TCP服务(以NGINX Ingress为例):

需要额外配置Ingress Controller的TCP端口映射:

  1. 新建TCP配置的ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-tcp
  namespace: ingress-nginx  # 替换成你的Ingress Controller所在命名空间
data:
  "8000": "default/service1:8000"  # 格式:"外部端口": "服务命名空间/服务名:服务端口"
  "9000": "default/service2:9000"

执行创建:

kubectl apply -f nginx-tcp-config.yaml
  1. 修改Ingress Controller的Deployment,添加端口挂载:
    找到Ingress Controller的Deployment(通常在ingress-nginx命名空间),在容器的ports部分添加:
- name: tcp-8000
  containerPort: 8000
  protocol: TCP
- name: tcp-9000
  containerPort: 9000
  protocol: TCP
  1. 修改Ingress Controller的Service(LoadBalancer类型),添加端口映射:
    在Service的ports部分添加:
- name: tcp-8000
  port: 8000
  targetPort: 8000
  protocol: TCP
- name: tcp-9000
  port: 9000
  targetPort: 9000
  protocol: TCP

完成后,Ingress Controller的外部IP就可以通过外部IP:8000和外部IP:9000分别访问两个服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:47:16