K8s 服务发现与负载均衡:2 种方案实战

Kubernetes(K8s)是一个开源的容器编排系统,服务发现和负载均衡是其核心功能,用于确保应用的高可用性和可扩展性。服务发现自动检测和注册服务实例,而负载均衡将流量分发到多个后端实例,避免单点故障。本指南将介绍两种主流方案:Service 与 kube-proxy(用于内部流量)和 Ingress Controller(用于外部流量)。我将逐步解析原理、实战配置和适用场景,确保内容基于真实生产经验。


方案一:Service 与 kube-proxy(内部服务发现和负载均衡)

Service 是 K8s 的核心对象,用于定义一组 Pod 的访问端点。kube-proxy 组件在节点上运行,通过 iptables 或 IPVS 实现负载均衡。负载均衡算法通常使用轮询(Round Robin),其中每个后端 Pod 的权重相等,公式表示为:
$$ w_i = \frac{1}{n} \quad \text{(} n \text{ 为 Pod 数量)} $$
这确保了流量均匀分布。

实战步骤
  1. 创建 Deployment:部署一个示例应用(如 Nginx)。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 3  # 启动 3 个 Pod 副本
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
    

  2. 创建 Service:定义一个 ClusterIP Service 来暴露 Pod。

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx  # 匹配 Deployment 的标签
      ports:
        - protocol: TCP
          port: 80  # Service 端口
          targetPort: 80  # Pod 端口
      type: ClusterIP  # 默认类型,仅集群内部访问
    

  3. 验证负载均衡

    • 在集群内运行临时 Pod 测试:
      kubectl run test-pod --image=busybox --restart=Never --rm -it -- sh
      # 在 Pod 内执行:wget -qO- nginx-service:80
      

    • 多次请求后,流量会轮询到不同 Pod(检查日志确认)。

优点:简单易用,适合微服务间内部通信。
缺点:仅支持 L4(TCP/UDP),不支持 HTTP 路径路由。


方案二:Ingress Controller(外部 HTTP/HTTPS 负载均衡)

Ingress 不是直接负载均衡器,而是定义路由规则的 API 对象。Ingress Controller(如 Nginx Ingress)监听这些规则并实现 L7 负载均衡,支持基于域名、路径的流量分发。负载均衡算法可配置,如加权轮询:
$$ w_i = \frac{\text{weight}_i}{\sum \text{weight}} \quad \text{(权重自定义)} $$

实战步骤
  1. 部署 Ingress Controller:以 Nginx Ingress 为例。

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
    

  2. 创建 Ingress 资源:定义路由规则(例如,将流量导向不同 Service)。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
    spec:
      ingressClassName: nginx
      rules:
      - host: myapp.example.com  # 域名
        http:
          paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service  # 后端 Service
                port:
                  number: 80
          - path: /web
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80
    

  3. 验证外部访问

    • 获取 Ingress 外部 IP:kubectl get ingress
    • 访问 http://myapp.example.com/apihttp://myapp.example.com/web,流量会根据路径分发到对应 Service。

优点:支持 L7 协议(HTTP/HTTPS)、SSL 终止和高级路由。
缺点:需额外部署 Controller,复杂度较高。


方案比较与总结

特性Service 与 kube-proxyIngress Controller
适用场景内部服务间通信(如数据库调用)外部 Web 流量(如用户访问 API)
协议支持L4 (TCP/UDP)L7 (HTTP/HTTPS)
负载均衡算法简单轮询可配置(加权、最少连接等)
部署复杂度低(K8s 内置)中(需安装 Controller)
实战推荐优先用于集群内部微服务优先用于对外暴露的 Web 应用

总结:Service 方案简单高效,适合内部负载均衡;Ingress 方案灵活强大,适合处理外部 HTTP 流量。在实际生产中,两者常结合使用:Service 管理内部流量,Ingress 处理入口流量。建议从简单场景开始,逐步扩展。如有具体环境问题,可提供更多细节,我会进一步优化建议!

更多推荐