7월 10일 경에 production 클러스터 앱의 성능 이슈가 발생한다는 문의가 들어왔습니다. 이날부터 2주동안, 저를 포함한 DevOps Engineer 3명은 모든 업무를 멈추고 네트워크 이슈 원인 찾기에 돌입하였습니다.
정말 네트워크에 이상이 있는 것인지 확인하기 위해 네트워크 부하테스트를 진행하였습니다.
k6로 확인해보니 정말로 특정 노드로 통하는 외부망에서 request duration이 1분 간격으로 4초간 지연이 발생하였습니다.
지옥의 테스트 무한 반복의 시간이 흐르고 제가 깨달은 것이 몇 가지 있었습니다.
현재 클러스터는 layer2 mode의 metallb를 사용하고 있습니다. bgp 모드와 다르게 하나의 노드(metallb의 leader pod가 존재하는 노드, 이하 leader node)에서 모든 부하를 받는 모드입니다. 메모리 부족이나 네트워크 자원 부족으로 새로운 leader node를 선출할 때 네트워크 지연이 감지되었습니다.
해당 내용을 검증하기 위해 arping을 통해 MAC address를 확인 후 tcp_dump 툴을 이용해 패킷캡쳐를 진행하였습니다. 그런데 여기서 이상한 점을 발견하였습니다. leader node를 확인하기 위해 LB의 ip로 arping을 날리면 하나의 MAC address가 아닌 다수의 MAC address가 응답을 하였습니다.
처음엔 vip를 사용하기 때문에 leader node로 선출됐던 node들이 garp 보내서인 것으로 생각하였는데 아니었습니다.
https://www.reddit.com/r/vmware/comments/y68emx/metallb_vmware_multiple_mac_address_associated/
이것은 저희가 클러스터에 배포한 bitnami metallb의 차트 이상으로 확인되었습니다.
metallb의 차트를 bitnami 에서 배포한 차트에서 공식 차트로 수정하였습니다.
공식차트로 수정하니 정상적으로 MAC address가 찍히는 것을 확인할 수 있습니다.
이후 네트워크 이슈가 해결된 것을 부하테스트 결과로 확인할 수 있었습니다. (req_duration이 1s 미만)
추가로 ai 개발자분들이 모델을 다운로드 받는 시간동안 네트워크 성능이 많이 떨어지는 현상을 확인해 해당 deployment(object storage)에 calico 대역폭 제한을 설정하였습니다.
metadata:
annotations:
kubernetes.io/ingress-bandwidth: 1M
kubernetes.io/egress-bandwidth: 1M
이후 네트워크 대역폭이 안정적으로 유지되었고 성능 이슈가 발생하지 않았습니다.
$ arping
$ tcp_dump
$ mtr (my traceroute)
$ ip neigh show
$ ip route show
테스트는 grafana + influxdb 로 모니터링을 진행하였고
grafana k6 공식 문서를 살펴보면서 여러가지 테스트 가이드가 있는 걸 확인하였습니다.
그 중에서 최소한의 부하에서도 적절하게 작동하는지 확인하기 위해 smoke test를 진행하였습니다.
처음엔 bitnami의 helm chart가 공식 helm chart를 가져온 것인줄로만 알았는데 이번 기회를 통해 전혀 아님을 확인했습니다.
다행히 현재 클러스터엔 metallb만 bitnami를 사용하는 중이었습니다.
쿠버네티스 트래픽 셰이핑 지원을 통해 CNI 플러그인에서 파드 수신 및 송신 트래픽 셰이핑을 지원하는 것을 알게 되었고 이를 클러스터에 적용하였습니다.