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

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

Upgrades and upstream: 롤링으로 올리고 영어로 알린다

TT Lab 에서 이어서 보기

한 줄 요약

Cluster API 에서 쿠버네티스 판 올리기는 "새 판의 노드 이미지를 가리키는 Machine 으로 하나씩 갈아 끼우는 롤링" 이고, 그 일을 업스트림과 함께하려면 이슈·커밋·리뷰·릴리스 노트를 독자에 맞게 영어로 써야 합니다.

왜 이게 필요했나

kubeadm 으로 판을 올리면 노드마다 들어가 패키지를 올리고 kubeadm upgrade 를 돌립니다. 노드가 많아지면 어느 노드가 어디까지 올라갔는지 추적하는 것이 일이 됩니다. Cluster API 는 판 올리기도 3모듈의 롤링과 같은 동작으로 만듭니다. 판이 바뀌면 새 Machine 을 만들고 옛 Machine 을 지웁니다. 노드 안에서 판을 바꾸지 않으니 중간 상태가 없습니다.

그런데 이 방식에는 대가가 있습니다. 판마다 그 판의 kubelet 과 kubeadm 이 든 노드 이미지가 필요하고, 교체하는 동안 노드 한 대분의 자원을 더 씁니다. 이 코스의 실측 환경에서는 둘 다 걸렸습니다. 다른 판의 노드 디스크 이미지는 수 GB 를 더 받아야 해서 받지 않았고(미실측), 8 GiB VM 에서 컨트롤 플레인 롤링을 시도하자 두 번째 컨트롤 플레인이 Insufficient memory 로 스케줄되지 않았습니다. 그래서 판 올리기는 이 글로 다룹니다.

어떻게 동작하나

판 올리기는 두 단계입니다. 먼저 컨트롤 플레인, 그다음 워커입니다. 쿠버네티스는 kubelet 이 API 서버보다 새 판이면 안 된다는 판 차이 규칙(version skew policy)이 있어서, 순서를 거꾸로 하면 새 워커가 옛 API 서버에 붙게 됩니다.

1. 새 판 노드 이미지를 가리키는 KubevirtMachineTemplate 을 새 이름으로 만든다(템플릿은 immutable)
2. KubeadmControlPlane 의 spec.version 과 machineTemplate 의 참조를 함께 바꾼다
   → KCP 가 새 컨트롤 플레인 Machine 을 하나 만들고(서지), etcd 멤버로 붙인 뒤 옛 것을 지운다
3. 워커도 같은 방식: MachineDeployment 의 template.spec.version 과 infrastructureRef 를 바꾼다
   → MachineDeployment 가 새 MachineSet 으로 하나씩 갈아 끼운다

프로바이더 자체의 판(CAPI v1.14.3, CAPK v0.11.2)을 올리는 일은 별개입니다. clusterctl upgrade plan 이 올릴 수 있는 판을 보여 주고 clusterctl upgrade apply 가 컨트롤러를 바꿉니다. 이때 contract 판이 맞는지가 핵심이라, 1모듈에서 읽은 metadata.yaml 과 CRD 라벨이 여기서 다시 쓰입니다.

업스트림과의 소통도 순서가 있습니다. 이슈로 증상을 재현 가능하게 알리고(2모듈), 고치는 PR 에 커밋 메시지와 PR 설명을 붙이고(3모듈), 리뷰 질문에 답하고, 마지막으로 사용자에게 보일 릴리스 노트를 씁니다. 독자가 다릅니다. 이슈는 재현하려는 메인테이너가, 커밋 메시지는 몇 년 뒤 git blame 을 여는 개발자가, 릴리스 노트는 코드를 보지 않는 사용자가 읽습니다.

현장에서 만나는 모습

이 코스를 만들며 찾은 비호환(CAPK v0.11.2 기본 템플릿의 빈 nodeRegistration)은 이 네 글을 연습하기에 알맞은 크기입니다. 증상이 분명하고(워커가 안 생긴다), 재현이 짧고(판을 고정한 init 과 generate 두 줄), 원인이 한 필드이고, 고치는 길이 하나입니다. 업스트림에 이미 같은 이슈가 있는지는 확인하지 못했습니다. 실제로 올리기 전에는 저장소의 열린 이슈와 닫힌 이슈를 오류 문장으로 먼저 검색하는 것이 예의입니다.

글을 쓸 때 한국어 화자가 자주 걸리는 곳이 셋 있습니다. 첫째, 제목에 증상 대신 감정을 씁니다("It doesn't work"). 둘째, 확인하지 않은 것을 단정합니다. 셋째, 커밋 제목을 과거형으로 씁니다(Fixed ...). 영어권 저장소 대부분은 "이 커밋을 적용하면 무엇을 하는가" 를 명령형으로 씁니다.

English corner

🏓 티티: 마지막 코너는 리뷰에서 매일 보는 줄임말과 동사예요. 뜻보다 "누가 누구에게 무엇을 부탁하는가" 를 읽어 봐요.

triage (동사·명사). 응급실에서 환자를 급한 순서로 가르는 일에서 왔습니다. 오픈소스에서는 새 이슈를 읽고 종류·우선순위·담당 영역을 붙이는 일입니다. "We'll triage this in the next community meeting."

skew. "비틀림, 어긋남" 입니다. version skew 는 구성 요소 사이의 판 차이입니다. "The kubelet must not be newer than the API server; that would break the version skew policy."

cherry-pick / backport. 고친 커밋을 옛 릴리스 갈래에 옮기는 일입니다. "Could this be backported to release-0.11?" 처럼 묻습니다. 블로그의 Backport 편이 자세합니다.

PTAL / LGTM. Please take another look(다시 봐 주세요), Looks good to me(좋아 보입니다). 리뷰를 다시 부탁할 때와 승인할 때 씁니다. 블로그의 PTAL 과 LGTM 편에 예문이 있습니다.

imperative mood (명령형). 커밋 제목의 문법입니다. "Fix ...", "Set ...", "Add ..." 처럼 동사 원형으로 시작합니다. 제목 끝에는 마침표를 찍지 않습니다.

다음 실습에서 할 것

실측 출력 네 가지를 읽어 phase 순서와 경과 시간, 로그 수준과 오류의 주인, 경고가 가리키는 새 API 판, 조건 나무에서 막고 있는 조건을 JSON 으로 정리합니다. 그다음 같은 버그로 명령형 커밋 메시지를 쓰고, 메인테이너의 세 질문에 번호를 맞춰 답하고, 사용자에게 보일 릴리스 노트 한두 문장을 씁니다.