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

如何在Kubernetes集群中模拟Docker Compose的网络行为?

Kubernetes模拟Docker Compose内外端口分离的配置方案

背景与问题

你需要在Kubernetes中复刻Docker Compose的以下行为:

  • 集群内部Pod通过http://nginx:80访问Nginx服务
  • 主机仅通过127.0.0.1:8080访问Nginx的容器80端口

你的Docker Compose配置:

services:
  nginx:
    container_name: nginx
    image: nginx:stable-alpine
    restart: always
    ports:
      - 127.0.0.1:8080:80

  curl:
    container_name: curl
    image: curlimages/curl
    command:
      - curl
      - http://nginx
    depends_on:
      - nginx

已完成的Nginx Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:stable-alpine
          ports:
            - containerPort: 80
      restartPolicy: Always

当前Service配置存在两个关键问题:

apiVersion: v1
kind: Service
metadata:
  name: proxy
  labels:
    app: proxy
spec:
  selector:
    app: proxy  # *错误*:与Deployment的Pod标签`app:nginx`不匹配,无法关联到Nginx Pod
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer  # *错误*:LoadBalancer会将端口暴露到外部网络,不符合仅本地访问的需求

解决方案

以下三种方案可实现目标,根据场景选择:

方案1:ClusterIP + Kubectl端口转发(快速验证/临时场景)

完全贴合Docker Compose的本地映射逻辑:

  1. 创建仅集群内部可见的ClusterIP Service:
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80       # 集群内部访问端口
      targetPort: 80 # 容器端口
  type: ClusterIP    # 默认类型,无需显式指定
  1. 在主机执行端口转发,绑定本地8080到Service的80端口:
kubectl port-forward service/nginx-service 127.0.0.1:8080:80
  • 集群内部Pod通过http://nginx-service:80访问Nginx
  • 主机通过curl http://127.0.0.1:8080访问Nginx

方案2:NodePort + 本地绑定(持久化场景)

适合需要长期本地访问的场景:

  1. 创建NodePort Service:
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80       # 集群内部端口
      targetPort: 80 # 容器端口
      nodePort: 30080 # 可选:指定固定NodePort(范围30000-32767)
  type: NodePort
  1. 修改Kubelet配置,让NodePort仅绑定127.0.0.1:
    • 编辑节点上的/var/lib/kubelet/config.yaml,添加:
      nodePortAddresses:
        - 127.0.0.1
      
    • 重启kubelet:systemctl restart kubelet
  • 集群内部通过http://nginx-service:80访问
  • 主机通过curl http://127.0.0.1:30080访问

方案3:ClusterIP + Ingress(多服务统一管理)

如果集群已部署Ingress Controller(如NGINX Ingress),可通过Ingress实现访问控制:

  1. 先创建ClusterIP Service(同方案1)
  2. 创建Ingress资源,限制仅本地访问:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "127.0.0.1/32"
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
  1. 调整Ingress Controller的端口映射,将其监听端口绑定到主机的8080
  • 集群内部通过Service访问,主机通过http://127.0.0.1:8080访问

关于NodePort+Ingress的适用性

NodePort+Ingress并非必要组合:

  • 若仅需简单的本地端口映射,方案1或方案2更直接高效
  • 若需要统一域名管理、路径转发或复杂访问控制,Ingress搭配ClusterIP Service是更优选择,NodePort在此场景下无额外作用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:14:51