1

正如标题所示,GCP-LB 或作为 LoadBalancer 类型公开的 HAProxy Ingress Controller Service 将流量不均匀地分配给 HAProxy Ingress Controller Pod。

设置:
我在 GCP 中运行 GKE 集群,并使用 HAProxy 作为入口控制器。
HAProxy 服务作为具有静态IP 的负载均衡器类型公开。

HAProxy 服务的 YAML:

apiVersion: v1
kind: Service
metadata:
  name: haproxy-ingress-static-ip
  namespace: haproxy-controller
  labels:
    run: haproxy-ingress-static-ip
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
    networking.gke.io/internal-load-balancer-allow-global-access: "true"
    cloud.google.com/network-tier: "Premium"
    cloud.google.com/neg: '{"ingress": false}'
spec:
  selector:
    run: haproxy-ingress
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  - name: stat
    port: 1024
    protocol: TCP
    targetPort: 1024
  type: LoadBalancer
  loadBalancerIP: "10.0.0.76"                                                                                                                                      

用于 HAProxy 部署的 YAML:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: haproxy-ingress
  name: haproxy-ingress
  namespace: haproxy-controller
spec:
  replicas: 2
  selector:
    matchLabels:
      run: haproxy-ingress
  template:
    metadata:
      labels:
        run: haproxy-ingress 
    spec:
      serviceAccountName: haproxy-ingress-service-account
      containers:
      - name: haproxy-ingress
        image: haproxytech/kubernetes-ingress
        args:
          - --configmap=haproxy-controller/haproxy
          - --default-backend-service=haproxy-controller/ingress-default-backend
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
        - name: stat
          containerPort: 1024
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: run
                      operator: In
                      values: 
                        - haproxy-ingress
                topologyKey: kubernetes.io/hostname

HAProxy 配置图:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: haproxy
  namespace: haproxy-controller
data:

问题:
在调试其他问题时,我发现 HAProxy pod 上的流量分布不均匀。例如,一个 Pod 每秒接收 540k 请求,而另一个 Pod 每秒接收 80k 请求。

在进一步调查中,还发现,新启动的 Pod 在接下来的 20-30 分钟内不会开始接收流量。即使在那之后,也只有一小部分流量通过它们。

检查下图: 在此处输入图像描述

流量分布不均的另一个版本。这似乎根本不是随机的,看起来像是加权流量分布: 在此处输入图像描述

流量分布不均的另一个版本。来自一个 Pod 的流量似乎正在转向另一个 Pod。

在此处输入图像描述

什么可能导致这种不均匀的流量分布并且在很长一段时间内没有向新的 Pod 发送流量?

4

1 回答 1

2

Kubernetes 与 GCP 负载均衡器集成。K8s 提供了 ingress 和 service 等原语,供用户通过 L4/L7 负载均衡器暴露 Pod。在引入 NEG 之前,负载均衡器将流量分配到 VM 实例,“kube-proxy”程序 iptables 将流量转发到后端 Pod。这可能会导致不均匀的流量分布、不可靠的负载均衡器健康检查和网络性能影响。

我建议你使用 容器原生负载均衡,它允许负载均衡器直接针对 Kubernetes Pod 并将流量均匀地分配到 Pod。使用容器原生负载均衡,负载均衡器流量直接分配到应该接收流量的 Pod,消除了额外的网络跃点。它还有助于改进健康检查,因为它直接针对 Pod,您可以看到从 HTTP(S) 负载均衡器到 Pod 的延迟。从 HTTP(S) 负载均衡器到每个 Pod 的延迟是可见的,它与基于节点 IP 的容器原生负载均衡聚合在一起。这使得在 NEG 级别对您的服务进行故障排除变得更加容易。

容器原生负载均衡器不支持内部 TCP/UDP 负载均衡器或网络负载均衡器,因此如果要使用这种负载均衡器,则必须将服务拆分为 HTTP(80)、HTTPS(443) 和 TCP( 1024)。要使用此功能,您的集群必须启用 HTTP 负载平衡。GKE 集群默认启用 HTTP 负载平衡;你不能禁用它。

于 2021-06-22T12:17:54.177 回答