IL-0178 Lotte E-commerce · 2022-10-21 (게시일)kubernetesawsnetworking
롯데이커머스는 마이크로서비스 40여 개로 된 롯데온을 Amazon EKS 에서 운영한다. 클라이언트 요청은 ingress 오브젝트로 만든 Application Load Balancer 를 거쳐 워커 노드로 가고, 노드의 iptables 규칙을 따라 파드로 전달된다. 파드 수는 HPA 가 조정하고, 노드 수는 Cluster Autoscaler 가 조정한다.
첫 번째 문제는 스케일 인 때 났다. 파드를 지울 때 Endpoints controller 가 Service 엔드포인트에서 파드를 빼고 kube-proxy 가 각 노드의 iptables 규칙을 고치는 절차와, kubelet 이 컨테이너를 종료하는 절차가 동시에 진행된다. 엔드포인트에서 파드 IP 가 빠지기 전에 컨테이너가 먼저 사라지면 트래픽이 사라진 컨테이너로 가서 502 가 난다. 롯데이커머스는 컨테이너 종료를 늦춰 파드가 엔드포인트에서 빠질 때까지 기다리게 해서 이 문제를 풀었다.
두 번째 문제는 블루/그린 배포 뒤에 났다. 파드가 종료 절차에 들어가면 새 HTTP 연결은 받지 않지만, 노드와 파드 사이의 TCP 연결은 ip_conntrack 이 한동안 기억한다. ip_conntrack 은 iptables 의 연결 상태를 추적하는 모듈이다. 노드에 패킷이 들어오면 저장된 연결과 같은지 보고, 같으면 iptables 규칙을 다시 보지 않고 저장된 목적지로 보낸다. 그래서 iptables 규칙이 갱신돼도 conntrack 에 남은 기록 때문에 지워진 파드로 패킷이 갔고, 클라이언트는 타임아웃을 받았다. ingress 로 만든 ALB 는 기본값이 instance 모드라 NodePort 와 노드 iptables 를 거친다. IP 모드에서는 AWS Load Balancer Controller 가 파드 IP 를 대상 그룹에 바로 등록하므로 iptables 와 ip_conntrack 을 거치지 않는다. 롯데이커머스는 일부 워크로드에 IP 모드를 적용해 문제를 풀었다.
롯데온 서비스에서 HPA 가 파드 수를 줄이는 스케일 인 때마다 일정 시간 동안 요청이 오류로 끝났다. 엔드포인트에서 파드 IP 가 빠지기 전에 컨테이너가 먼저 지워지면, 들어오는 트래픽이 여전히 지워진 컨테이너로 가서 502 에러가 났다.
블루/그린 배포 뒤에는 다른 증상이 나타났다. Service 의 레이블 셀렉터를 그린으로 바꾸고 정상 동작을 확인한 뒤 블루 파드를 지웠다. 파드의 수명 주기 훅이 처리되는 동안에는 문제가 없었지만, 파드가 완전히 사라진 뒤부터 클라이언트에 timeout 오류가 났다. 일부 트래픽이 일정 시간 동안 이미 지워진 파드로 계속 갔다.
노드를 들여다보니 지워진 파드 IP 의 iptables 규칙은 모두 지워졌지만, ip_conntrack 에는 그 연결이 established 상태로 남아 있었다. 클라이언트 요청이 이 기록을 따라 제거된 파드로 계속 들어가고 있었다.
원인 ? DNS·네트워크 장애
–
Kubernetes 에서 엔드포인트 제거와 컨테이너 종료는 동시에 진행되므로, 종료를 늦추지 않으면 스케일 인 때 지워진 컨테이너로 트래픽이 가서 502 가 날 수 있다. preStop 훅으로 기다릴 때는 terminationGracePeriodSeconds 로 최대 대기 시간을 함께 정해야 한다. ALB 를 instance 모드로 쓰면 트래픽이 노드의 iptables 와 conntrack 을 거치므로, 블루/그린 전환 뒤에도 established 연결이 지워진 파드로 갈 수 있다. IP 모드는 이 경로를 없애고 네트워크 홉도 줄이지만, 대상 그룹에 대상을 1000개까지만 넣을 수 있다.
같은 원인 · 공통 conntrack 테이블, kube-proxy
같은 원인 · 공통 conntrack 테이블
같은 원인 · 공통 conntrack 테이블