从外部访问 Kubernetes 中的 Pod

在 Kubernetes 集群中,Pod 默认只能在集群内部访问。为了让外部用户能够访问集群中的应用,我们需要采用适当的网络暴露方式。本文将介绍几种主要的外部访问方法,每种方法都有其特定的使用场景和优缺点。

访问方式概览

Kubernetes 提供了多种从外部访问 Pod 和 Service 的方式:

  • hostNetwork - 直接使用宿主机网络
  • hostPort - 将容器端口映射到宿主机端口
  • NodePort - 通过节点端口暴露服务
  • LoadBalancer - 使用云平台负载均衡器
  • Ingress - HTTP/HTTPS 路由和负载均衡

需要注意的是,暴露 Pod 和暴露 Service 本质上是一回事,因为 Service 就是 Pod 的抽象层。

hostNetwork 模式

工作原理

当在 Pod 规格中设置 hostNetwork: true 时,Pod 将直接使用宿主机的网络命名空间。这意味着 Pod 中的应用程序可以直接绑定到宿主机的网络接口上。

配置示例

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  hostNetwork: true
  containers:
    - name: influxdb
      image: influxdb:1.8
      ports:
        - containerPort: 8086

使用方法

# 部署 Pod
kubectl apply -f influxdb-hostnetwork.yaml

# 获取 Pod 所在节点 IP
kubectl get pod influxdb -o wide

# 直接访问宿主机 IP 和端口
curl -v http://<NODE_IP>:8086/ping

适用场景与注意事项

适用场景:

  • 网络插件的 DaemonSet 部署
  • 需要访问宿主机网络资源的系统级应用
  • 对网络性能要求极高的应用

注意事项:

  • Pod 调度位置不固定,外部访问 IP 会变化
  • 可能与宿主机端口冲突
  • 安全性较低,应谨慎使用

hostPort 端口映射

工作原理

hostPort 将容器端口直接映射到宿主机端口,类似于 Docker 的端口映射功能。

配置示例

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  containers:
    - name: influxdb
      image: influxdb:1.8
      ports:
        - containerPort: 8086
          hostPort: 8086
          protocol: TCP

访问方法

# 通过任意节点 IP + hostPort 访问
curl http://<NODE_IP>:8086/ping

适用场景

  • Nginx Ingress Controller 等入口控制器
  • 需要固定端口的应用
  • 开发和测试环境

NodePort 服务

工作原理

NodePort 是 Kubernetes Service 的一种类型,它会在每个节点上开放一个端口(默认范围 30000-32767),将外部流量转发到对应的 Pod。

配置示例

# Pod 定义
apiVersion: v1
kind: Pod
metadata:
  name: influxdb
  labels:
    app: influxdb
spec:
  containers:
    - name: influxdb
      image: influxdb:1.8
      ports:
        - containerPort: 8086
---
# Service 定义
apiVersion: v1
kind: Service
metadata:
  name: influxdb
spec:
  type: NodePort
  ports:
    - port: 8086
      targetPort: 8086
      nodePort: 30086  # 可选,不指定则自动分配
  selector:
    app: influxdb

访问方法

# 通过任意节点 IP + NodePort 访问
curl http://<NODE_IP>:30086/ping

# 或通过 ClusterIP 在集群内访问
curl http://<CLUSTER_IP>:8086/ping

优缺点

优点:

  • 简单易用,无需额外组件
  • 支持负载均衡
  • 适合开发测试环境

缺点:

  • 端口范围受限
  • 每个服务占用一个端口
  • 不适合生产环境的多服务场景

LoadBalancer 负载均衡器

工作原理

LoadBalancer 类型的 Service 会自动创建云平台提供的负载均衡器,并为 Service 分配一个外部 IP。

配置示例

apiVersion: v1
kind: Service
metadata:
  name: influxdb
spec:
  type: LoadBalancer
  ports:
    - port: 8086
      targetPort: 8086
  selector:
    app: influxdb

查看和访问

# 查看服务状态
kubectl get svc influxdb
# NAME       TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
# influxdb   LoadBalancer   10.97.121.42   203.0.113.123   8086:30051/TCP   1m

# 通过外部 IP 访问
curl http://203.0.113.123:8086/ping

# 也可以通过 NodePort 访问
curl http://<NODE_IP>:30051/ping

适用场景

  • 云平台环境(AWS、GCP、Azure 等)
  • 生产环境的关键服务
  • 需要高可用和自动故障转移的应用

Ingress 入口控制器

工作原理

Ingress 是 Kubernetes 中用于管理外部访问集群内服务的 API 对象。它提供 HTTP 和 HTTPS 路由功能,支持基于域名和路径的流量分发。

前提条件

使用 Ingress 前需要部署 Ingress Controller,常用的有:

  • NGINX Ingress Controller
  • Traefik
  • HAProxy Ingress
  • Istio Gateway

配置示例

# 基础 Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: influxdb
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: influxdb.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: influxdb
                port:
                  number: 8086

高级配置示例

# 支持 HTTPS 和多路径的 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-service-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
    - hosts:
        - api.example.com
      secretName: api-tls
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /influxdb
            pathType: Prefix
            backend:
              service:
                name: influxdb
                port:
                  number: 8086
          - path: /grafana
            pathType: Prefix
            backend:
              service:
                name: grafana
                port:
                  number: 3000

访问方法

# 通过域名访问
curl http://influxdb.example.com/ping

# HTTPS 访问
curl https://api.example.com/influxdb/ping

Ingress 优势

  • 统一入口:单一负载均衡器处理多个服务
  • 灵活路由:支持基于域名、路径的路由规则
  • SSL 终结:集中处理 HTTPS 证书
  • 高效转发:直接转发到 Pod,无需经过 kube-proxy
  • 功能丰富:支持限流、认证、重写等高级功能

方案对比与选择

方式复杂度性能灵活性适用场景
hostNetwork最高系统级应用、网络插件
hostPort简单应用、开发环境
NodePort开发测试、内部服务
LoadBalancer云环境生产服务
Ingress最高生产环境、多服务场景

最佳实践建议

生产环境推荐

  1. Web 应用:优先选择 Ingress + TLS
  2. API 服务:使用 Ingress 进行路由和负载均衡
  3. 数据库等有状态服务:使用 LoadBalancer(云环境)或 NodePort
  4. 监控和日志系统:根据访问需求选择合适方式

安全考虑

  • 使用 NetworkPolicy 限制 Pod 网络访问
  • 为 Ingress 配置适当的认证和授权
  • 定期更新 TLS 证书
  • 避免在生产环境使用 hostNetwork

监控和排错

# 检查服务状态
kubectl get svc,ingress,endpoints

# 查看 Ingress Controller 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

# 测试服务连通性
kubectl run test-pod --rm -it --image=busybox -- sh

总结

选择合适的外部访问方式需要考虑多个因素:

  • 简单性:hostPort 和 NodePort 配置简单,适合开发测试
  • 灵活性:Ingress 提供最大的灵活性,支持复杂的路由规则
  • 性能:hostNetwork 性能最高,Ingress 在功能和性能间取得平衡
  • 生产就绪性:LoadBalancer 和 Ingress 更适合生产环境

在现代云原生应用中,Ingress 已成为暴露 HTTP/HTTPS 服务的主流方式,它不仅提供了强大的路由功能,还与服务网格、API 网关等技术很好地集成,是构建可扩展微服务架构的重要组件。

参考资料

文章导航

章节内容

这是章节的内容页面。

章节概览

评论区