在K8S中,外部如何访问集群内的服务?

在 Kubernetes 中,外部客户端访问集群内部的服务主要通过以下几种机制实现,每种机制适用于不同的场景:


1. NodePort 类型 Service

  • 原理:
    • 在每个集群节点上开放一个静态端口(范围默认为 30000-32767)。
    • 访问任意节点的 IP:NodePort 的流量会被自动转发到后端 Pod。
  • 配置示例:
    apiVersion: v1
    kind: Service
    metadata:
      name: my-nodeport-service
    spec:
      type: NodePort
      selector:
        app: my-app
      ports:
        - port: 80        # Service 的 ClusterIP 端口
          targetPort: 8080 # Pod 的端口
          nodePort: 31000   # (可选) 手动指定节点端口,否则随机分配
    
  • 访问方式: http://<任一节点IP>:31000
  • 优点: 简单,无需额外组件,适合开发测试或简单环境。
  • 缺点:
    • 需手动管理节点 IP 列表(节点故障需切换 IP)。
    • 需配置防火墙规则允许外部访问该端口范围。
    • 端口非标准(非 80/443),不美观。
    • 流量可能经过额外跳转(非目标 Pod 所在节点时)。
  • 适用场景: 临时访问、演示、简单测试、不支持 LoadBalancer 的环境(如本地 Minikube)。

2. LoadBalancer 类型 Service

  • 原理:
    • Kubernetes 向云服务商申请一个外部负载均衡器(如 AWS ELB、GCP LB、Azure LB)。
    • 负载均衡器获得一个公网 IP,并将流量分发到集群节点的 NodePort 或直接路由到 Pod。
  • 配置示例:
    apiVersion: v1
    kind: Service
    metadata:
      name: my-loadbalancer-service
    spec:
      type: LoadBalancer
      selector:
        app: my-app
      ports:
        - port: 80
          targetPort: 8080
    
  • 访问方式: http://<负载均衡器分配的公网IP>
  • 优点:
    • 自动提供稳定公网入口。
    • 云厂商负责负载均衡、健康检查、高可用。
    • 支持 TCP/UDP 和 HTTP(S)。
  • 缺点:
    • 依赖云厂商,本地环境(如 Minikube)通常不支持或需额外插件。
    • 每个 Service 创建一个独立 LB,成本高
    • 无法基于域名或路径路由(需配合 Ingress 使用)。
  • 适用场景: 需要直接暴露 TCP/UDP 服务(如数据库)、或作为 Ingress 的底层支撑。

3. Ingress (配合 Ingress Controller)

  • 原理:
    • Ingress Controller: 部署在集群内的反向代理(如 Nginx、Traefik、AWS ALB),通过 LoadBalancerNodePort 暴露自身。
    • Ingress 资源: 定义路由规则(域名、路径 → 后端 Service)。
  • 配置示例:
    # Ingress 规则 (声明式)
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
    spec:
      rules:
      - host: app.example.com       # 域名
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-svc  # 后端 Service
                port:
                  number: 80
          - path: /api
            backend:
              service:
                name: backend-svc
                port:
                  number: 8080
      tls:                         # HTTPS 配置
      - hosts:
          - app.example.com
        secretName: tls-secret     # 存储证书的 Secret
    
  • 访问方式: http(s)://app.example.comhttp(s)://<Ingress Controller IP>/api
  • 优点:
    • 统一入口:一个 IP 暴露多个服务。
    • 高级路由:基于域名、路径、Header 等路由。
    • TLS 终止:集中管理 HTTPS 证书。
    • 功能丰富:重写、限流、认证等(取决于控制器)。
  • 缺点:
    • 需额外部署和维护 Ingress Controller。
    • 主要用于 HTTP(S) 流量。
  • 适用场景: 生产环境首选,暴露 Web 服务、API 网关。

4. port-forward (临时调试)

  • 原理: 通过 kubectl 将本地端口映射到 Pod 或 Service 端口。
  • 命令示例:
    # 转发到 Service
    kubectl port-forward svc/my-service 8080:80
    
    # 转发到 Pod
    kubectl port-forward pod/my-pod 8080:80
    
  • 访问方式: http://localhost:8080
  • 优点: 快速访问特定 Pod/Service,无需暴露服务。
  • 缺点: 临时性(进程退出即失效),不适合生产访问。
  • 适用场景: 本地开发调试、临时诊断。

5. 其他方式

  • ExternalIP Service:
    • 手动配置 Service 的 .spec.externalIPs 为节点 IP。
    • 类似 NodePort,但使用标准端口(需节点 IP 稳定且可路由)。
  • hostNetwork: true
    • 让 Pod 直接使用宿主机网络命名空间。
    • 极端性能需求场景(如 CNI 网络插件),但牺牲了隔离性和端口管理。
  • SSH 隧道:
    • 通过跳板机建立隧道访问内部服务(安全性高,配置复杂)。

选择策略总结

方式 适用协议 生产适用性 特点 典型场景
NodePort TCP/UDP/HTTP 简单,节点IP+高端口 测试、临时访问
LoadBalancer TCP/UDP/HTTP 中高 云厂商LB,独立公网IP 暴露非HTTP服务、Ingress底层
Ingress HTTP(S) 域名路由、TLS、统一入口 生产Web服务/API网关
port-forward Any 临时本地端口转发 开发调试

最佳实践建议:

  1. 生产环境 HTTP(S) 服务: Ingress + Ingress Controller 是标准方案。
  2. 非 HTTP 或特殊需求: 使用 LoadBalancer
  3. 云厂商集成: 优先选用云提供商的 Ingress Controller(如 AWS ALB Ingress Controller)。
  4. 避免直接暴露 Pod: 始终通过 Service 抽象访问。
posted @ 2025-08-17 15:26  天道酬勤zjh  阅读(113)  评论(0)    收藏  举报