当我将 NGINX 入口控制器与 Amazon EKS 配合使用时,为什么我的 Worker 节点状态为“Unhealthy”(运行状况不佳)?

上次更新时间:2021 年 12 月 13 日

我使用 NGINX 入口控制器来展现入口资源,但我的 Amazon Elastic Kubernetes Service (Amazon EKS) Worker 节点无法使用 Network Load Balancer。

简短描述

NGINX 入口控制器将 spec.externalTrafficPolicy 选项设置为本地以保留客户端 IP。此外,请求不会路由到运行状况不佳的 Worker 节点。以下问题排查方法意味着您无需维持集群 IP 地址或保留客户端 IP 地址。

解决方法

检查 Worker 节点的运行状况

注意:以下示例使用 NGINX 入口控制器 v1.0.2。

1.    在集群中为 NGINX 入口控制器创建必需的资源(来自 Kubernetes 网站):

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.2/deploy/static/provider/aws/deploy.yaml

原定设置情况下,NGINX 入口控制器会创建 Kubernetes 服务 ingress-nginx-controller,并将 .spec.externalTrafficPolicy 选项设置为本地(来自 GitHub 网站)。

2.    检查外部流量策略(来自 Kubernetes 网站)是否设置为本地

$ kubectl -n ingress-nginx describe svc ingress-nginx-controller

输出:

Name:                     ingress-nginx-controller
Namespace:                ingress-nginx
Labels:                   app.kubernetes.io/component=controller
                          app.kubernetes.io/instance=ingress-nginx
                          app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=ingress-nginx
                          app.kubernetes.io/version=1.0.2
                          helm.sh/chart=ingress-nginx-4.0.3
Annotations:              service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
                          service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: true
                          service.beta.kubernetes.io/aws-load-balancer-type: nlb
Selector:                 app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Type:                     LoadBalancer
IP Families:              <none>
IP:                       10.100.115.226
IPs:                      10.100.115.226
LoadBalancer Ingress:     a02245e77404f4707a725d0b977425aa-5b97f717658e49b9.elb.eu-west-1.amazonaws.com
Port:                     http  80/TCP
TargetPort:               http/TCP
NodePort:                 http  31748/TCP
Endpoints:                192.168.43.203:80
Port:                     https  443/TCP
TargetPort:               https/TCP
NodePort:                 https  30045/TCP
Endpoints:                192.168.43.203:443
Session Affinity:         None
External Traffic Policy:  Local
HealthCheck NodePort:     30424
Events:                   <none>

注意:设置为本地会丢弃发送到未运行 NGINX 入口控制器实例的 Kubernetes 节点的数据包。将 NGINX pod(来自 Kubernetes 网站)分配给您想要安排运行 NGINX 入口控制器的节点。

3.    查看在未运行 NGINX 入口控制器实例的节点上设置 DROP 规则的 iptables 命令:

$ sudo iptables-save | grep -i "no local endpoints"
-A KUBE-XLB-CG5I4G2RS3ZVWGLK -m comment --comment "ingress-nginx/ingress-nginx-controller:http has no local endpoints
        " -j KUBE-MARK-DROP
-A KUBE-XLB-EDNDUDH2C75GIR6O -m comment --comment "ingress-nginx/ingress-nginx-controller:https has no local endpoints " -j KUBE-MARK-DROP

设置策略选项

pec.externalTrafficPolicy 选项更新为 Cluster(集群)

$ kubectl -n ingress-nginx patch service ingress-nginx-controller -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
service/ingress-nginx-controller patched

注意:原定设置情况下,NodePort 服务会执行源地址转换(来自 Kubernetes 网站)。对于 NGINX 而言,这意味着 HTTP 请求的源 IP 始终是接收该请求的 Kubernetes 节点的 IP 地址。如果您将 NodePort 设置为集群ingress-nginx 服务规范externalTrafficPolicy 字段的值,那么您将无法保留源 IP 地址。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?