NGINX Ingress Controller를 사용하여 인그레스 리소스를 노출합니다. 하지만 Amazon Elastic Kubernetes Service(Amazon EKS) 워커 노드가 Network Load Balancer를 사용하지 못합니다.
간략한 설명
NGINX Ingress Controller는 클라이언트 IP를 보존하기 위해 spec.externalTrafficPolicy 옵션을 Local로 설정합니다. 또한 요청을 정상 워커 노드로만 라우팅합니다.
워커 노드의 상태 문제를 해결하고 트래픽 정책을 업데이트하려면 다음 단계를 참조하세요.
참고: 클러스터 IP 주소를 유지하거나 클라이언트 IP 주소를 보존할 필요는 없습니다.
해결 방법
워커 노드의 상태 확인
참고: 다음 예시에서는 EKS 클러스터 v1.23에서 실행되는 NGINX Ingress Controller v1.5.1을 사용합니다.
1. 클러스터에서 (Kubernetes 웹 사이트에서) NGINX Ingress Controller에 대한 필수 리소스를 생성합니다.
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/aws/deploy.yaml
기본적으로 NGINX Ingress Controller는 (GitHub 웹 사이트에서) .spec.externalTrafficPolicy 옵션이 Local로 설정된 Kubernetes Service ingress-nginx-controller를 생성합니다.
2. Kubernetes 웹 사이트에서 외부 트래픽 정책이 Local로 설정되어 있는지 확인합니다.
$ 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>
참고: Local 설정은 Kubernetes 노드로 전송되는 패킷을 삭제하며 NGINX Ingress Controller의 인스턴스를 실행할 필요가 없습니다. NGINX Ingress Controller를 예약하려는 노드에는 Kubernetes 웹 사이트에서 NGINX 포드를 할당하세요.
3. NGINX Ingress Controller의 인스턴스를 실행하지 않는 노드에서 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
정책 옵션 설정
spec.externalTrafficPolicy 옵션을 Cluster로 업데이트합니다.
$ kubectl -n ingress-nginx patch service ingress-nginx-controller -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
service/ingress-nginx-controller patched
기본적으로 NodePort 서비스는 (Kubernetes 웹 사이트에서) 소스 IP 주소 변환을 수행합니다. NGINX의 경우 이는 HTTP 요청의 소스 IP 주소가 항상 요청을 수신한 Kubernetes 노드의 IP 주소라는 것을 의미합니다. ingress-nginx 서비스 사양에서 externalTrafficPolicy (.spec.externalTrafficPolicy)를 Cluster로 설정하면 들어오는 트래픽이 소스 IP 주소를 보존하지 않습니다. 자세한 내용은 Kubernetes 웹 사이트의 클라이언트 소스 IP 주소 보존을 참조하세요.