야근하고와서 약간 피곤하긴 한데...
그래도 꾸준히 적어야 이 작고 소중한 블로그에 한 명이라도 더 온다는 마음으로 짧게나마 적어보겠습니다 !
Connection draining은 쿠버네티스 환경에서 배포가 일어날 때
기존 파드가 terminate 되는 과정에서 세션이 빠지기를 기다려 주는, active connection waiting 같은 기능입니다.
Azure application gateway에 국한되는 이야기는 아니고,
물리 L7 장비나 AWS에서 제공하는 로드밸런서에도 (당연히) 존재합니다.
쿠버네티스 환경에서의 배포라고 하면, 새로 파드 생성되면서 신규 파드 헬스체크 완료되고 나서
기존 파드 내리는거니까 이미 무중단이 구현된 것 아니야?(블루 그린 방식이니) 라고 생각하실 수도 있는데요,
쿠버네티스 환경이라 하더라도 완전한 무중단을 구현하기 위해서는 요런 부분을 신경써 주셔야 합니다.
쿠버네티스 환경 위에 올릴 서비스에 signal handler가 달려 있고, SIGTERM에 대한 적절한 처리가 되어 있다면
사실 별 문제는 없는데요, 보통 마이그레이션을 하는 경우에는 기존 IDC든 온프렘환경이든
그런 처리가 모든 서비스에 되어있지 않은 경우가 더!더!더! 많습니다.
그래서, 일반적인 어플리케이션의 경우 Kubelet이 SIGTERM을 보내면
샤따 내려가기 바빠 graceful shutdown 및 무중단 배포가 아니라 connection refused 라는 장애상황이
개발자를 맞이하게 됩니다.
물론 Sigterm이 Sigkill로 전환되는 시간을 조정해 줄 수도 있고(terminationGracePeriodSeconds),
애초에 Signal handler 를 달아서 이런 상황 자체를 미연에 방지할 수도 있습니다.
하지만 전사적인 소스 수정과 재배포가 필요하겠죠...! (사내 프레임워크에서 제공할 수도 있겠지만요...)
이 와중에 잠깐... 🤔 요 Sigterm-Sigkill 전환 익숙한 느낌이 드시죠?? Systemd 에서 보셨던... 맞습니다🤭🤭 둘다 텀-킬로 전환이 이뤄지죠
매니지드가 좋다는 게, 이런 걸 아예 서비스로 제공해서가 아닐까 싶습니다.
Application Gateway에서 제공하는 기능이라 Ingress에 저 두 줄 짜리 annotation만 달면
appgw.ingress.kubernetes.io/connection-draining: "true" 요렇게 Ingress에서 connection draining을 활성화 합니다. appgw.ingress.kubernetes.io/connection-draining-timeout: "60" 요러면 connection draining의 timeout을 지정해줄 수 있습니다. 기본은 30초 입니다.
자동으로 백엔드풀에 적용됩니다.
그렇다 함은, 클러스터에 배포를 하고 난 다음 기존 파드를 terminate 해야 하는 상황에서,
application gateway가 기존 파드가 바로 죽는것을 막고, 신규 inbound traffic은 막은 상태에서
기존에 진행 중이던 요청은 연결이 끊어질 때까지 혹은 timeout 시간이 될 때까지 쭉 처리해 주게 됩니다.
커넥션이 모두 빠지거나, timeout이 되면 그 때가 되어서야 백엔드풀에서 제거된 인스턴스를 내리게 되므로
graceful remove from backendpool이 이뤄지게 됩니다.
저희는 지금 물리 L7 및 Azure Application Gateway에서 모두 요 방식을 사용하고 있는데요,
Application gateway를 쓰신다면 기왕 비싼 돈 주고 쓰시는 것 최대한 기능 활용하시길 바라겠습니다^^
관련 문서:
https://docs.microsoft.com/en-us/azure/application-gateway/configuration-http-settings#connection-draining
Azure Application Gateway HTTP settings configuration
This article describes how to configure Azure Application Gateway HTTP settings.
docs.microsoft.com
'DevOps' 카테고리의 다른 글
[Kubernetes] RBAC을 이용하여 특정 namespace에만 권한 주기 (2) | 2021.12.12 |
---|---|
[Kubernetes & Azure] TLS 인증서(SSL 인증서) Keyvault 연동하기 (1) | 2021.11.13 |
[Kubernetes] Node selector vs. Node affinity, 어떤 것을 사용할까? (1) | 2021.11.07 |
Jenkins에서 API를 이용하여 특정 설정을 가진 Job 생성하기(젠킨스 API 잡 생성, config.xml 주입, Jenkins API 인증) (1) | 2021.10.05 |
DNS 레코드 삭제 후 재생성 시 도메인 질의가 되지 않는 문제 해결하기 (3) | 2021.09.21 |