GCP-LB 将流量分配到 HAProxy Ingress Controller Pods
GCP-LB unevenly distributing traffic to HAProxy Ingress Controller Pods
如标题所示,GCP-LB 或公开为 LoadBalancer 类型的 HAProxy Ingress Controller 服务正在不均匀地将流量分配给 HAProxy Ingress Controller Pods。
设置:
我是 运行 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 pods 上的流量分布不均。例如一个 Pods 正在接收 540k requests/sec 而另一个 Pod 正在接收 80k requests/sec。
进一步调查还发现,启动的新 Pods 在接下来的 20-30 分钟内不会开始接收流量。即使在那之后,也只有一小部分流量通过它们。
查看下图:
另一种流量分配不均的版本。这似乎根本不是随机的,看起来像是加权流量分布:
流量分布不均的另一种形式。来自一个 Pod 的流量似乎正在转移到另一个 Pod。
是什么原因导致这种流量分布不均并且长时间不向新 pods 发送流量?
Kubernetes 与 GCP 负载均衡器集成。 K8s 为用户提供入口和服务等原语,以通过 L4/L7 负载均衡器公开 pods。在引入 NEG 之前,负载均衡器将流量分配到 VM 实例和“kube-proxy”程序 iptables 以将流量转发到后端 pods。这可能会导致流量分配不均、负载均衡器运行状况检查不可靠以及网络性能受到影响。
我建议您使用 Container native load balancing,它允许负载均衡器直接以 Kubernetes Pods 为目标,并将流量平均分配到 Pods。使用容器原生负载均衡,负载均衡器流量直接分配到应该接收流量的 Pods,从而消除了额外的网络跃点。它还有助于改进健康检查,因为它直接针对 Pods,您可以看到从 HTTP(S) 负载平衡器到 Pods 的延迟。从 HTTP(S) 负载均衡器到每个 Pod 的延迟是可见的,这是与基于节点 IP 的容器原生负载均衡聚合的。这使得在 NEG 级别对您的服务进行故障排除变得更加容易。
容器原生负载均衡器不支持内部 TCP/UDP 负载均衡器或网络负载均衡器,所以如果你想使用这种负载均衡,你必须将服务拆分为 HTTP(80), HTTPS(443) 和 TCP(1024)。要使用它,您的集群必须启用 HTTP 负载平衡。 GKE 集群默认启用 HTTP 负载均衡;你不能禁用它。
如标题所示,GCP-LB 或公开为 LoadBalancer 类型的 HAProxy Ingress Controller 服务正在不均匀地将流量分配给 HAProxy Ingress Controller Pods。
设置:
我是 运行 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 pods 上的流量分布不均。例如一个 Pods 正在接收 540k requests/sec 而另一个 Pod 正在接收 80k requests/sec。
进一步调查还发现,启动的新 Pods 在接下来的 20-30 分钟内不会开始接收流量。即使在那之后,也只有一小部分流量通过它们。
查看下图:
另一种流量分配不均的版本。这似乎根本不是随机的,看起来像是加权流量分布:
流量分布不均的另一种形式。来自一个 Pod 的流量似乎正在转移到另一个 Pod。
是什么原因导致这种流量分布不均并且长时间不向新 pods 发送流量?
Kubernetes 与 GCP 负载均衡器集成。 K8s 为用户提供入口和服务等原语,以通过 L4/L7 负载均衡器公开 pods。在引入 NEG 之前,负载均衡器将流量分配到 VM 实例和“kube-proxy”程序 iptables 以将流量转发到后端 pods。这可能会导致流量分配不均、负载均衡器运行状况检查不可靠以及网络性能受到影响。
我建议您使用 Container native load balancing,它允许负载均衡器直接以 Kubernetes Pods 为目标,并将流量平均分配到 Pods。使用容器原生负载均衡,负载均衡器流量直接分配到应该接收流量的 Pods,从而消除了额外的网络跃点。它还有助于改进健康检查,因为它直接针对 Pods,您可以看到从 HTTP(S) 负载平衡器到 Pods 的延迟。从 HTTP(S) 负载均衡器到每个 Pod 的延迟是可见的,这是与基于节点 IP 的容器原生负载均衡聚合的。这使得在 NEG 级别对您的服务进行故障排除变得更加容易。
容器原生负载均衡器不支持内部 TCP/UDP 负载均衡器或网络负载均衡器,所以如果你想使用这种负载均衡,你必须将服务拆分为 HTTP(80), HTTPS(443) 和 TCP(1024)。要使用它,您的集群必须启用 HTTP 负载平衡。 GKE 集群默认启用 HTTP 负载均衡;你不能禁用它。