TT Lab
블로그 시작하기
배우기 러닝패스 코스

영어로 배우는 Cluster API: KubeVirt 위에 클러스터 찍어 내기

Replace, don't repair: 2일차 운영

TT Lab 에서 이어서 보기

한 줄 요약

Cluster API 에서 늘리기·줄이기·교체·자동 복구·템플릿 변경은 모두 "새 Machine 을 만들고 옛 Machine 을 지운다" 이고, 누가 그 결정을 내리는지(MachineSet, MachineDeployment, MachineHealthCheck)만 다릅니다.

왜 이게 필요했나

예전 방식의 노드 운영은 ssh 로 들어가 고치는 것이었습니다. 패키지를 올리고, 설정을 바꾸고, 재부팅합니다. 노드가 열 대일 때는 버틸 만하지만, 백 대가 되면 노드마다 조금씩 다른 상태(드리프트)가 쌓이고, 고장 난 노드 하나를 살리느라 밤을 새웁니다. 클라우드는 다른 답을 냈습니다. 고장 난 것은 고치지 말고 버리고, 같은 템플릿으로 새로 만듭니다. Cluster API 는 이 태도를 쿠버네티스 오브젝트로 옮겼습니다. 그래서 노드에 들어갈 일이 줄고, 대신 "지금 어느 템플릿에서 복제된 Machine 이 몇 대인가" 를 보게 됩니다.

어떻게 동작하나

MachineSet 은 ReplicaSet 처럼 "이 템플릿으로 N 대" 를 지킵니다. 하나가 사라지면 새로 만들고, 많으면 지웁니다. 줄일 때 누구를 지울지는 deletion order 로 정하는데 기본은 Random 입니다. 실측에서 2→1 은 6초, Machine 하나를 지운 뒤 새 노드가 Ready 가 되기까지는 72초였습니다.

MachineDeployment 는 Deployment 처럼 템플릿이 바뀌면 새 MachineSet 을 만들어 옛것과 갈아 끼웁니다. 실측 VM 의 기본 전략은 RollingUpdate, maxSurge 1, maxUnavailable 0 이었습니다. 새 Machine 하나를 먼저 띄우고(그동안 메모리를 한 대만큼 더 씁니다), Ready 가 되면 옛 Machine 하나를 drain 하고 지웁니다. 워커 템플릿을 바꾼 롤링은 112초였습니다. 이때 템플릿은 고치지 않고 새로 만듭니다. 인프라 템플릿은 immutable 로 다룬다는 것이 Cluster API 의 약속이고, 바뀐 이름이 곧 롤링의 신호입니다. CAPK 는 이 약속을 웹훅으로 강제합니다. 실측에서 옛 템플릿의 cores 를 그 자리에서 고치려 하자 admission webhook ... denied the request: KubevirtMachineTemplateSpec is immutable 으로 거부됐습니다.

MachineHealthCheck(MHC) 는 고치지 않습니다. 노드 조건(예: Ready 가 False 나 Unknown 으로 60초)을 보고 Machine 에 unhealthy 표시만 하고, 실제 교체는 소유자(MachineSet 이나 KubeadmControlPlane)가 합니다. 한꺼번에 너무 많이 바꾸지 않도록 표시할 수 있는 수에도 제한이 있습니다. 실측에서 노드 VM 을 멈추자 52초에 노드가 NotReady 가 됐고, 60초 시한이 지난 113초에 교체가 시작됐고, 155초에 새 Machine 이 Running 이었습니다. 이벤트에는 Machine default/... has been marked as unhealthy by default/...-mhc 가 남았습니다.

컨트롤 플레인도 같은 원리로 KubeadmControlPlane 이 롤링하지만, 8 GiB VM 에서는 시도해 보니 두 번째 컨트롤 플레인(2Gi)이 0/1 nodes are available: 1 Insufficient memory 로 스케줄되지 않았습니다. 서지(surge)는 공짜가 아니라는 것을 보여 주는 실측이라 실습에서는 읽기로만 다룹니다.

현장에서 만나는 모습

이 코스의 관리 VM 은 노드가 한 대인 k3s 입니다. 워커 둘(1Gi)과 컨트롤 플레인(2Gi)이 뜬 상태에서 VM 메모리 사용이 6.8GiB, 남은 것이 약 1GiB 였습니다. 현장의 관리 클러스터는 이보다 크지만 같은 계산이 필요합니다. 롤링과 MHC 교체는 잠깐 동안 노드 한 대분의 자원을 더 쓰고, 그 자리가 없으면 교체가 Pending 에서 멈춥니다. 이 상태는 조용합니다. 옛 노드는 계속 돌기 때문에 장애처럼 보이지 않다가, 그 옛 노드에 진짜 문제가 생긴 날 드러납니다.

MHC 를 처음 거는 팀이 자주 하는 실수는 시한을 너무 짧게 잡는 것입니다. 노드가 잠깐 바빠 kubelet 신호가 늦은 것만으로 교체가 시작되고, 교체가 또 다른 부하를 만들어 연쇄 교체가 납니다. 그래서 MHC 는 표시할 수 있는 수를 제한하는 장치를 함께 둡니다.

English corner

🏓 티티: 2일차 운영의 영어는 동사가 핵심이에요. 누가 무엇을 하는지 주어를 꼭 챙겨요.

remediate / remediation. "문제를 바로잡다" 입니다. MHC 문서에서는 "MachineHealthCheck remediates unhealthy machines" 처럼 쓰지만, 실제로 바꾸는 주체는 소유자라서 정확히 말하면 "MHC marks the Machine as unhealthy, and the owning MachineSet replaces it." 입니다. 이슈에서 이 둘을 구별해 쓰면 메인테이너가 어느 컨트롤러를 볼지 바로 압니다.

mark as unhealthy. 실측 이벤트 has been marked as unhealthy by ... 의 꼴입니다. be marked as(으로 표시되다)는 상태를 붙이는 동작이지 지우는 동작이 아닙니다.

roll out / rollout. 동사는 띄어 쓴 roll out, 명사는 붙여 쓴 rollout 입니다. "We rolled out the new template." / "The rollout took two minutes." 처럼 씁니다.

immutable. "바뀌지 않는" 입니다. "Templates are immutable, so create a new one and point the MachineDeployment at it." 리뷰에서 "Why not edit it in place?" 라는 질문에 가장 짧게 답하는 단어입니다. in place 는 "그 자리에서, 새로 만들지 않고" 라는 뜻입니다.

surge. "한꺼번에 밀려들다" 에서 왔고, 롤링에서는 "원래 수보다 잠깐 더 만드는 수" 입니다. maxSurge 1 은 "한 대까지 더 만들어도 된다" 입니다.

리뷰 답글의 말투는 블로그 「오늘의 영어 표현」의 Good catch 와 Fair point 편이 다룹니다.

다음 실습에서 할 것

도우미로 클러스터를 세운 뒤 워커를 둘로 늘렸다가 하나로 줄이며 누가 사라졌는지 기록합니다. Machine 하나를 지워 새로 생기는 것을 보고, MachineHealthCheck 를 건 뒤 노드 VM 을 멈춰 자동 교체를 지켜봅니다. 마지막으로 vCPU 를 줄인 새 템플릿으로 롤링 교체하고, 그 변경을 영어 PR 설명과 리뷰 답글로 씁니다.