如何解决 Amazon EKS 中负载均衡器运行状况检查失败的问题?

4 分钟阅读
0

我的负载均衡器未通过 Amazon Elastic Kubernetes Service(Amazon EKS)的运行状况检查。

解决方法

要解决 Amazon EKS 中负载均衡器的运行状况检查问题,请完成以下部分中的步骤。

查看容器组(pod)的状态

检查容器组(pod)是否处于运行状态以及容器组(pod)中的容器是否准备就绪:

$ kubectl get pod -n YOUR_NAMESPACE

**注意:**用您的 Kubernetes 命名空间替换 YOUR_NAMESPACE

输出示例:

NAME                           READY   STATUS    RESTARTS   AGEpodname                        1/1     Running   0          16s

如果容器组(pod)中的应用程序容器的状态不是运行,则负载均衡器运行状况检查未得到答复且会失败。

检查容器组(pod)和服务标签选择器

对于容器组(pod)标签,运行以下命令:

$ kubectl get pod -n YOUR_NAMESPACE --show-labels

输出示例:

NAME                           READY   STATUS    RESTARTS   AGE     LABELSalb-instance-6cc5cd9b9-prnxw   1/1     Running   0          2d19h   app=alb-instance,pod-template-hash=6cc5cd9b9

要验证您的 Kubernetes 服务是否使用容器标签,请运行以下命令来检查输出是否与容器组(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-instanceNamespace:                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                                AGEalb-instance   <none>                                   2d20h

针对应用程序负载均衡器问题,检查服务流量策略和集群安全组

应用程序负载均衡器目标组中出现不正常的目标有两个原因:

  • 服务流量策略 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. 选择运行状况良好的实例。
  3. 选择安全选项卡,然后检查安全组入口规则。
  4. 选择运行状况不佳的实例。
  5. 选择安全选项卡,然后检查安全组入口规则。
    如果每个实例的安全组不同,则必须在安全组控制台中修改安全入口规则:
    安全选项卡中,选择安全组 ID。
    选择编辑入站规则以修改入口规则。
    添加入站规则以允许来自集群中其他节点组的流量。

验证您的服务是否已针对 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 负载均衡器控制器具有正确的权限

AWS 负载均衡器控制器必须具有正确的权限才能更新安全组,以允许流量从负载均衡器流向实例或容器组(pod)。如果控制器没有正确的权限,那么您会收到错误。

检查 AWS 负载均衡器控制器部署日志中是否存在错误:

$ 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 命名空间。

针对应用程序负载均衡器问题,检查入口注释

针对应用程序负载均衡器问题,检查 Kubernetes 入口注释:

$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE

**注意:**将 INGRESS_NAME 替换为您的 Kubernetes 入口的名称,将 YOUR_NAMESPACE 替换为您的 Kubernetes 命名空间。

输出示例:

Name:             alb-instance-ingressNamespace:        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 网站上的 Ingress annotations

针对网络负载均衡器问题,检查 Kubernetes 服务注释

针对网络负载均衡器问题,检查 Kubernetes 服务注释:

$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE

输出示例:

Name:                     nlb-ipNamespace:                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 网站上的 Service annotations

手动测试运行状况检查

检查您的应用程序容器组(pod)IP 地址:

$ kubectl get pod -n YOUR_NAMESPACE -o wide

运行一个测试容器组(pod)以手动测试集群内的运行状况检查:

$ 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 替换为应用程序负载均衡器目标组运行状况检查路径。

命令示例:

# 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 响应状态代码为 3xx4xx,则更改您的运行状况检查路径。以下注释以 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)运行的子网关联的网络访问控制列表允许来自负载均衡器子网 CIDR 范围的流量。
  • 与您的负载均衡器子网关联的网络 ACL 允许在容器组(pod)运行的子网的临时端口范围的返回流量。
  • 路由表允许来自 VPC CIDR 范围内的本地流量。

重启 kube-proxy

如果在每个节点上运行的 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 负载均衡器控制器设置 Application Load Balancer?

如何对 Amazon EKS 中由 Kubernetes 服务控制器创建的负载均衡器进行故障排除?

如何标记 Amazon EKS 集群中的 Amazon VPC 子网以便负载均衡器或入口控制器自动发现子网?