어느 날 잘 동작하던 nginx가 갑자기 DNS 리졸빙에 실패하면서 에러가 발생했습니다. nginx를 proxy로 사용하고 있었는데, 특정 서비스로 요청을 보내지 못하고 DNS를 해결하지 못하는 문제가 발생했습니다.
🚨 이슈
nginx의 proxy_pass로 설정된 도메인으로의 요청이 갑자기 모두 실패하기 시작했습니다.
could not be resolved (110: Operation timed out)
🔍 원인
CoreDNS의 재시작이 문제의 원인이었습니다. CoreDNS가 재시작되었지만, nginx는 이전에 연결되어 있던 CoreDNS 정보를 계속 참조했습니다. 이로 인해 nginx는 UDP 통신을 통해 사라진 CoreDNS로 요청을 시도했고, 그 결과 conntrack 테이블에는 이미 삭제된 CoreDNS의 정보가 남게 되었습니다. 특히, nginx가 같은 목적지 포트를 사용해 CoreDNS와 연결을 유지하려고 했기 때문에 conntrack 테이블의 연결 정보는 TTL이 만료되지 않고 계속 갱신되어 문제가 발생했습니다.
🧪 확인 방법
이슈가 발생한 호스트에 접속해 다음과 같은 방법으로 conntrack 테이블을 확인해봅시다. nginx 파드가 실행 중인 호스트에 접근한 후, conntrack 명령어로 nginx 파드와 연결된 테이블 정보를 살펴보세요. 만약 이미 사라진 CoreDNS의 정보가 남아있다면 이 이슈를 겪고 있는 것입니다.
conntrack -L --orig-src < nginx pod ip>
이렇게 확인해봤는데 응답 출발지가 없는 파드의 아이피라면 유사한 이슈일 가능성이 있습니다.
🔨 해결 방법
가장 간단한 해결책은 CoreDNS가 재시작될 때 nginx를 함께 재시작하는 것입니다. 하지만 이는 임시적인 조치일 뿐이고, 근본적인 해결책은 아닙니다. 진짜 문제는 nginx가 더 이상 사라진 DNS 정보를 계속 참조하지 않도록 하는 것입니다.
만약 이번 문제가 CoreDNS의 zone 설정 변경 때문이라면, 변경된 레코드를 알리기 위해 zone 설정의 SOA 시리얼 번호를 업데이트해서ConfigMap을 재배포하는 것만으로도 CoreDNS는 설정을 다시 가져가므로 별도의 재시작은 필요 없습니다.
혹은 추가로 nginx의 리졸버 valid 타임을 ttl 타임보다 짧게 가져가면 이슈가 없습니다.
resolver <coredns ip> ipv6=off valid=10s;
proxy_http_version 1.1;
nginx의 코드를 수정해서 DNS 정보를 더 자주 갱신하도록 하거나, 재시작 시에 conntrack 테이블을 자동으로 정리하는 방식으로 시스템을 개선할 필요가 있습니다. 이렇게 하면 nginx가 더 이상 과거의 정보를 참조하며 헛된 시도를 하지 않게 되겠죠. 참고로, nginx는 이제 GitHub로 넘어왔으니 이 부분에 대한 개선이 필요할 때 적극적으로 기여해볼 수도 있습니다.
🚨🔥 추가 확인 된 내용
https://github.com/kubernetes/kubernetes/issues/126130
Implement a kube-proxy conntrack reconciler · Issue #126130 · kubernetes/kubernetes
What would you like to be added? We'd like to have conntrack reconciler for Services in kube-proxy, for each Service or Endpoint change it should reconcile the Service/Endpoint table with the exist...
github.com
해당 이슈가 udp 프로토콜에 대한 conntrack 의 동작방식의 이슈와 관련이 깊은것 같습니다.
분석에 도움을 주신 ossca 멘토를 해주고 계신 성락님 감사합니다 👍👍
work around로 nginx의 valid 타임을 짧게 가져가는게 베스트일 것 같네요.
💡 참고
찾아보니 유사한 이슈를 겪고있는 분들이 있는것 같습니다.
https://github.com/grafana/loki/issues/14013
Gateway DNS lookup fail after CoreDNS restart · Issue #14013 · grafana/loki
Describe the bug Gateway container/nginx seems to lose it's DNS lookup ability after CoreDNS pods restart. Which is weird because the resolv.conf points at the CoreDNS service IP, not the CoreDNS p...
github.com
https://github.com/cilium/cilium/issues/27300
NGINX always connects to same coredns endpoint, even if it no longer exists · Issue #27300 · cilium/cilium
Is there an existing issue for this? I have searched the existing issues What happened? During the lifetime of an nginx process, each nginx worker (I think?) will always make UDP DNS-requests again...
github.com
'K8S > issue' 카테고리의 다른 글
| "유령" 인터페이스. Calico v3.24의 BIRD CPU 100% 이슈 (1) | 2024.09.09 |
|---|
