如何解决 Amazon EKS 中负载均衡器运行状况检查失败的问题?
我的负载均衡器一直未能通过 Amazon Elastic Kubernetes Service (Amazon EKS) 运行状况检查。
简短描述
要排查 Amazon EKS 中负载均衡器运行状况检查问题,请完成以下部分中的步骤:
- 检查 pod 的状态
- 检查 pod 和服务标签选择器
- 检查终端节点是否缺失
- 检查 Application Load Balancer 的服务流量策略和集群安全组
- 验证您的 EKS 是否已针对 targetPort 进行配置
- 验证您的 AWS Load Balancer 控制器是否具有正确的权限
- 检查入口注释中是否有 Application Load Balancer 的问题
- 检查 Kubernetes 服务注释中是否有 Network Load Balancer 的问题
- 手动测试运行状况检查
- 检查联网情况
- 重启 kube-proxy
解决方法
检查 pod 的状态
检查 pod 是否处于 Running(正在运行)状态,pod 中的容器是否已准备就绪:
$ kubectl get pod -n YOUR_NAMESPACE
**注意:**请将 YOUR_NAMESPACE 替换为您的 Kubernetes 命名空间。
示例输出:
NAME READY STATUS RESTARTS AGE podname 1/1 Running 0 16s
**注意:**如果 Pod 中的应用程序容器未运行,则负载均衡器运行状况检查不会得到响应,因此将失败。
检查 pod 和服务标签选择器
对于 pod 标签,请运行以下命令:
$ kubectl get pod -n YOUR_NAMESPACE --show-labels
示例输出:
NAME READY STATUS RESTARTS AGE LABELS alb-instance-6cc5cd9b9-prnxw 1/1 Running 0 2d19h app=alb-instance,pod-template-hash=6cc5cd9b9
要验证您的 Kubernetes 服务是否正在使用 pod 标签,请运行以下命令来检查其输出是否与 pod 标签匹配:
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.selector}{"\n"}'
**注意:**请将 SERVICE_NAME 替换为您的 Kubernetes 服务,并将 YOUR_NAMESPACE 替换为您的 Kubernetes 命名空间。
示例输出:
{"app":"alb-instance"}
检查终端节点是否缺失
服务选择器的 Kubernetes 控制器会持续扫描与其选择器匹配的 pod,然后将更新发布到终端节点对象。如果选择了错误的标签,则不会显示任何终端节点。
运行以下命令:
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
示例输出:
Name: alb-instance Namespace: default Labels: <none> Annotations: <none> Selector: app=alb-instance-1 Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.44.151 IPs: 10.100.44.151 Port: http 80/TCP TargetPort: 80/TCP NodePort: http 32663/TCP Endpoints: <none> Session Affinity: None External Traffic Policy: Cluster Events: <none>
检查终端节点是否缺失:
$ kubectl get endpoints SERVICE_NAME -n YOUR_NAMESPACE
示例输出:
NAME ENDPOINTS AGE alb-instance <none> 2d20h
检查服务流量策略和集群安全组中是否有 Application Load Balancer 的问题
导致 Application Load Balancer 目标组中的目标运行状况不佳的原因有两个。服务流量策略 spec.externalTrafficPolicy设置为 Local(本地),而不是 Cluster(集群)。或者,集群中的节点组具有与之关联的不同集群安全组,并且流量无法在节点组之间自由流动。
验证流量策略配置是否正确:
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.externalTrafficPolicy}{"\n"}'
示例输出:
Local
将设置更改为 Cluster(集群):
$ kubectl edit svc SERVICE_NAME -n YOUR_NAMESPACE
检查集群安全组
1. 打开 Amazon EC2 控制台。
2. 选择 healthy instance(运行正常的实例)。
3. 选择 Security(安全)选项卡,然后检查安全组入口规则。
4. 选择 unhealthy instance(运行状况不佳的实例)。
5. 选择 Security(安全)选项卡,然后检查安全组入口规则。
如果每个实例的安全组各不相同,则必须在安全组控制台修改安全入口规则:
1. 在 Security(安全)选项卡中,选择 security group ID(安全组 ID)。
2. 选择 Edit inbound rules(编辑入站规则)按钮以修改入口规则。
3. 添加入站规则以允许来自集群中其他节点组的流量。
验证您的服务是否已针对 TargetPort 进行配置
您的 targetPort 必须与服务正在向其发送流量的 pod 中的 containerPort 相匹配。
要验证 targetPort 配置的目标端口,请运行以下命令:
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath="{.items[*]}{.metadata.name}{'\t'}{.spec.ports[].targetPort}{'\t'}{.spec.ports[].protocol}{'\n'}"
示例输出:
alb-instance 8080 TCP
在前面的示例输出中,targetPort 配置为 8080。但是,由于 ContainerPort 设置为 80,因此必须将 targetPort 配置为 80。
验证您的 AWS Load Balancer 控制器是否具有正确的权限
AWS Load Balancer 控制器必须具有更新安全组的正确权限,才能允许流量从负载均衡器传输到实例或 Pod。如果控制器没有正确的权限,则您会收到错误。
检查 AWS Load Balancer 控制器部署日志中是否有错误:
$ kubectl logs deploy/aws-load-balancer-controller -n kube-system
检查单个控制器 pod 日志中是否有错误:
$ kubectl logs CONTROLLER_POD_NAME -n YOUR_NAMESPACE
**注意:**请将 CONTROLLER_POD_NAME 替换为控制器 pod 名称,并将 YOUR_NAMESPACE 替换为您的 Kubernetes 命名空间。
检查入口注释中是否有 Application Load Balancer 的问题
有关 Application Load Balancer 的问题,请查看 Kubernetes 入口注释:
$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE
**注意:**请将 INGRESS_NAME 替换为 Kubernetes 入口的名称,并将 YOUR_NAMESPACE 替换为您的 Kubernetes 命名空间。
示例输出:
Name: alb-instance-ingress Namespace: default Address: k8s-default-albinsta-fcb010af73-2014729787.ap-southeast-2.elb.amazonaws.com Default backend: alb-instance:80 (192.168.81.137:8080) Rules: Host Path Backends ---- ---- -------- awssite.cyou / alb-instance:80 (192.168.81.137:8080) Annotations: alb.ingress.kubernetes.io/scheme: internet-facing kubernetes.io/ingress.class: alb Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfullyReconciled 25m (x7 over 2d21h) ingress Successfully reconciled
要查找特定于您的使用案例的入口注释,请参阅入口注释(来自 Kubernetes 网站)。
检查 Kubernetes 服务注释中是否有 Network Load Balancer 的问题
有关 Network Load Balancer 的问题,请查看 Kubernetes 服务注释:
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
示例输出:
Name: nlb-ip Namespace: default Labels: <none> Annotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external Selector: app=nlb-ip Type: LoadBalancer IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.161.91 IPs: 10.100.161.91 LoadBalancer Ingress: k8s-default-nlbip-fff2442e46-ae4f8cf4a182dc4d.elb.ap-southeast-2.amazonaws.com Port: http 80/TCP TargetPort: 80/TCP NodePort: http 31806/TCP Endpoints: 192.168.93.144:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
**注意:**请记下 APPLICATION_POD_IP。您需要它来运行运行状况检查命令。
要查找特定于您的使用案例的 Kubernetes 服务注释,请参阅服务注释(来自 Kubernetes 网站)。
手动测试运行状况检查
检查您的应用程序 pod IP 地址:
$ kubectl get pod -n YOUR_NAMESPACE -o wide
运行测试 pod,手动测试集群内的运行状况检查以进行 HTTP 运行状况检查:
$ kubectl run -n YOUR_NAMESPACE troubleshoot -it --rm --image=amazonlinux -- /bin/bash
对于 HTTP 运行状况检查:
# curl -Iv APPLICATION_POD_IP/HEALTH_CHECK_PATH
**注意:**请将 APPLICATION_POD_IP 替换为应用程序 pod IP,将 HEALTH_CHECK_PATH 替换为 ALB 目标组运行状况检查路径。
示例命令:
# curl -Iv 192.168.81.137
示例输出:
* Trying 192.168.81.137:80... * Connected to 192.168.81.137 (192.168.81.137) port 80 (#0) > HEAD / HTTP/1.1 > Host: 192.168.81.137 > User-Agent: curl/7.78.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < Server: nginx/1.21.3 Server: nginx/1.21.3 < Date: Tue, 26 Oct 2021 05:10:17 GMT Date: Tue, 26 Oct 2021 05:10:17 GMT < Content-Type: text/html Content-Type: text/html < Content-Length: 615 Content-Length: 615 < Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT < Connection: keep-alive Connection: keep-alive < ETag: "6137835f-267" ETag: "6137835f-267" < Accept-Ranges: bytes Accept-Ranges: bytes < * Connection #0 to host 192.168.81.137 left intact
检查 HTTP 响应状态代码。如果响应状态代码为 200 OK,则表示您的应用程序在运行状况检查路径上正确响应。
如果 HTTP 响应状态代码为 3xx 或 4xx,则可以更改运行状况检查路径。以下注释可以通过 200 OK 响应:
alb.ingress.kubernetes.io/healthcheck-path: /ping
– 或者 –
您可以在入口资源上使用以下注释来添加成功的运行状况检查响应状态代码范围:
alb.ingress.kubernetes.io/success-codes: 200-399
对于 TCP 运行状况检查,请使用以下命令安装 netcat 命令:
# yum update -y && yum install -y nc
测试 TCP 运行状况检查:
# nc -z -v APPLICATION_POD_IP CONTAINER_PORT_NUMBER
**注意:**请将 APPLICATION_POD_IP 替换为应用程序 pod IP,并将 CONTAINER_PORT_NUMBER 替换为容器端口。
示例命令:
# nc -z -v 192.168.81.137 80
示例输出:
Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 192.168.81.137:80. Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.
检查联网情况
对于联网问题,请验证以下各项:
- EKS 集群中的多个节点组可以自由通信
- 与运行 pod 的子网关联的网络访问控制列表(网络 ACL)允许来自负载均衡器子网 CIDR 范围的流量
- 与负载均衡器子网关联的网络 ACL 应允许从运行 pod 的子网返回临时端口范围内的流量
- 路由表允许来自 VPC CIDR 范围内的本地流量
重启 kube-proxy
如果在每个节点上运行的 kube-proxy 行为不正确,则它可能无法更新服务和终端节点的 iptables 规则。重启 kube-proxy 以强制它重新检查和更新 iptables 规则:
kubectl rollout restart daemonset.apps/kube-proxy -n kube-system
示例输出:
daemonset.apps/kube-proxy restarted
相关信息
如何在 Amazon EKS 中的 Amazon EC2 节点组上使用 AWS Load Balancer 控制器设置 Application Load Balancer?
如何标记 Amazon EKS 集群中的 Amazon VPC 子网以便负载均衡器或入口控制器自动发现子网?
相关内容
- AWS 官方已更新 3 个月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 3 年前