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

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

Your first management cluster: clusterctl init

TT Lab 에서 이어서 보기

목표

k3s 한 대를 Cluster API 의 관리 클러스터(management cluster)로 만듭니다. 프로바이더 넷의 판과 contract 를 읽고, 컨트롤러가 얼마나 동시에 reconcile 하는지 로그에서 찾고, 워크로드 클러스터 매니페스트를 만들어 둡니다. 마지막으로 오늘 한 일을 영어 진행 보고로 씁니다.

왜 중요한가

Cluster API 는 "클러스터를 만드는 일" 자체를 쿠버네티스 오브젝트로 바꿉니다. 그래서 클러스터를 만들고 고치는 쪽(관리 클러스터)이 따로 있어야 하고, 그 안에서 core·bootstrap·control-plane·infrastructure 네 종류의 컨트롤러가 각자 자기 오브젝트를 맡습니다. 어느 컨트롤러가 무엇을 맡는지 알아야 나중에 "Machine 이 왜 안 생기지" 를 볼 때 어느 로그를 열지 압니다. 이 코스는 그 과정에서 실제로 찍히는 영어 표현을 함께 익힙니다.

🏓 티티: 오늘의 영어 한 줄은 "The management cluster has been initialized successfully." 입니다. 2단계가 끝나면 화면에서 직접 찾아보세요!

단계

  1. Check that KubeVirt is ready to run VMs. 관리 클러스터의 KubeVirt 상태를 읽어 /root/capi/m1/kubevirt.json 에 version(KubeVirt CR 의 status.observedKubeVirtVersion), phase(status.phase), kvm_allocatable(노드 allocatable 의 devices.kubevirt.io/kvm 값, 화면에 보이는 문자열 그대로)을 적으세요.
  2. clusterctl init 으로 이 k3s 를 관리 클러스터(management cluster)로 만드세요. 판은 core·bootstrap·control-plane 모두 v1.14.3, infrastructure 는 kubevirt:v0.11.2 로 못 박고, 출력 전체를 /root/capi/m1/init.log 에 남깁니다. 끝나면 로그에 Your management cluster has been initialized successfully! 가 있고, 프로바이더 넷이 각자의 네임스페이스에 떠 있어야 합니다.
  3. 설치된 프로바이더를 정리해 /root/capi/m1/providers.json 에 적으세요. 키는 CoreProvider, BootstrapProvider, ControlPlaneProvider, InfrastructureProvider 이고 값은 각 Provider 오브젝트의 판입니다. 여기에 infra_api_version(KubevirtCluster CRD 가 저장에 쓰는 API 판, 예: group/version 꼴)과 contract_labels(그 CRD 의 라벨 가운데 cluster.x-k8s.io/v 로 시작하는 키의 정렬된 목록)를 더합니다.
  4. core 컨트롤러(capi-system 의 capi-controller-manager)가 뜰 때 남긴 Starting workers 로그 줄을 읽고, 컨트롤러 이름(controller= 값)마다 worker count 를 /root/capi/m1/workers.json 에 {"machine": 10, ...} 꼴로 적으세요. 로그에 나온 컨트롤러는 빠짐없이 적어야 합니다. controllerKind 가 아니라 controller 이름을 키로 쓰는 이유도 로그에서 찾아보세요(같은 Kind 를 보는 컨트롤러가 둘인 경우가 있습니다).
  5. KubeVirt 기본 클러스터 템플릿이 요구하는 변수를 확인하세요. clusterctl generate cluster capi-demo --infrastructure kubevirt:v0.11.2 --list-variables 의 Required Variables 목록을 한 줄에 하나씩, 정렬해서 /root/capi/m1/required-vars.txt 에 적습니다.
  6. 워크로드 클러스터 매니페스트를 만들어 /root/capi/m1/capi-demo.yaml 에 저장하세요(적용은 하지 않습니다). 클러스터 이름 capi-demo, 네임스페이스 default, 쿠버네티스 v1.34.1, 컨트롤 플레인 1대·워커 1대, 노드 디스크 이미지 quay.io/capk/ubuntu-2404-container-disk:v1.34.1, CRI 소켓 /var/run/containerd/containerd.sock 입니다.
  7. 오늘 한 일을 팀 채널에 올리는 영어 진행 보고로 /root/capi/m1/standup.md 에 쓰세요. 문법은 채점하지 않고 정보만 봅니다. 반드시 들어갈 것: 무엇을 했는지(management cluster 와 clusterctl init), 판 두 개(v1.14.3, v0.11.2), 다음에 할 일을 밝히는 Next: 로 시작하는 줄 하나, 그리고 막힌 것이 있는지 밝히는 Blockers: 로 시작하는 줄 하나. 글은 영어로(라틴 문자 90% 이상), 전체 25단어 이상 쓰세요.

참고

KubeVirt is deployed

Check that KubeVirt is ready to run VMs. 관리 클러스터의 KubeVirt 상태를 읽어 /root/capi/m1/kubevirt.json 에 version(KubeVirt CR 의 status.observedKubeVirtVersion), phase(status.phase), kvm_allocatable(노드 allocatable 의 devices.kubevirt.io/kvm 값, 화면에 보이는 문자열 그대로)을 적으세요.

KubeVirt 는 operator 가 KubeVirt 라는 사용자 정의 자원 하나를 보고 나머지(virt-api, virt-controller, virt-handler)를 세웁니다. kubectl -n kubevirt get kv kubevirt -o yaml 의 status 를 보세요. KVM 장치가 노드에 광고되어 있어야 VM 이 소프트웨어 에뮬레이션이 아니라 하드웨어 가속으로 뜹니다. 노드의 allocatable 은 kubectl get node -o json 으로 볼 수 있습니다.

Initialize the management cluster

clusterctl init 으로 이 k3s 를 관리 클러스터(management cluster)로 만드세요. 판은 core·bootstrap·control-plane 모두 v1.14.3, infrastructure 는 kubevirt:v0.11.2 로 못 박고, 출력 전체를 /root/capi/m1/init.log 에 남깁니다. 끝나면 로그에 Your management cluster has been initialized successfully! 가 있고, 프로바이더 넷이 각자의 네임스페이스에 떠 있어야 합니다.

clusterctl init 은 프로바이더마다 --core, --bootstrap, --control-plane, --infrastructure 에 이름:판 을 받습니다. 판을 적지 않으면 최신 판을 고르는데, 그러면 오늘과 내일의 결과가 달라질 수 있습니다. --wait-providers 를 주면 컨트롤러가 뜰 때까지 기다립니다. 이 VM 의 clusterctl 은 GitHub API 대신 로컬 저장소(~/.config/cluster-api/clusterctl.yaml)에서 프로바이더 파일을 읽습니다.

Read the provider contract

설치된 프로바이더를 정리해 /root/capi/m1/providers.json 에 적으세요. 키는 CoreProvider, BootstrapProvider, ControlPlaneProvider, InfrastructureProvider 이고 값은 각 Provider 오브젝트의 판입니다. 여기에 infra_api_version(KubevirtCluster CRD 가 저장에 쓰는 API 판, 예: group/version 꼴)과 contract_labels(그 CRD 의 라벨 가운데 cluster.x-k8s.io/v 로 시작하는 키의 정렬된 목록)를 더합니다.

clusterctl 은 설치한 것을 Provider 라는 오브젝트로 남깁니다(kubectl get providers -A). core 가 인프라 프로바이더의 API 판을 찾는 방법이 CRD 라벨입니다. kubectl get crd kubevirtclusters.infrastructure.cluster.x-k8s.io -o yaml 의 metadata.labels 와 spec.versions 가운데 storage: true 인 판을 보세요. 라벨 키가 contract 판이고 값이 그 contract 에 맞는 프로바이더 API 판입니다.

Starting workers

core 컨트롤러(capi-system 의 capi-controller-manager)가 뜰 때 남긴 Starting workers 로그 줄을 읽고, 컨트롤러 이름(controller= 값)마다 worker count 를 /root/capi/m1/workers.json 에 {"machine": 10, ...} 꼴로 적으세요. 로그에 나온 컨트롤러는 빠짐없이 적어야 합니다. controllerKind 가 아니라 controller 이름을 키로 쓰는 이유도 로그에서 찾아보세요(같은 Kind 를 보는 컨트롤러가 둘인 경우가 있습니다).

controller-runtime 으로 만든 컨트롤러는 시작할 때 Starting EventSource → Starting Controller → Starting workers 순서로 로그를 남깁니다. worker count 는 그 컨트롤러가 동시에 reconcile 하는 오브젝트 수(concurrency)입니다. kubectl -n capi-system logs deploy/capi-controller-manager | grep 'Starting workers' 로 시작해 보세요.

Required variables

KubeVirt 기본 클러스터 템플릿이 요구하는 변수를 확인하세요. clusterctl generate cluster capi-demo --infrastructure kubevirt:v0.11.2 --list-variables 의 Required Variables 목록을 한 줄에 하나씩, 정렬해서 /root/capi/m1/required-vars.txt 에 적습니다.

템플릿은 ${VAR} 자리표시자가 든 YAML 이고, clusterctl 이 환경 변수로 그 자리를 채웁니다. --list-variables 는 채우지 않고 목록만 보여 줍니다. Optional 은 기본값이 있는 변수입니다. 목록 앞의 - 와 들여쓰기는 빼고 이름만 적습니다.

Generate, but do not apply

워크로드 클러스터 매니페스트를 만들어 /root/capi/m1/capi-demo.yaml 에 저장하세요(적용은 하지 않습니다). 클러스터 이름 capi-demo, 네임스페이스 default, 쿠버네티스 v1.34.1, 컨트롤 플레인 1대·워커 1대, 노드 디스크 이미지 quay.io/capk/ubuntu-2404-container-disk:v1.34.1, CRI 소켓 /var/run/containerd/containerd.sock 입니다.

5단계에서 찾은 Required 변수는 환경 변수로 주고, 개수·판·네임스페이스는 --control-plane-machine-count, --worker-machine-count, --kubernetes-version, --target-namespace 플래그로 줍니다. 결과는 Cluster, KubevirtCluster, KubeadmControlPlane, MachineDeployment 등 여러 문서가 이어진 YAML 입니다. 채점기는 이 파일만 읽고 클러스터에는 아무것도 없어야 합니다.

Write a stand-up update in English

오늘 한 일을 팀 채널에 올리는 영어 진행 보고로 /root/capi/m1/standup.md 에 쓰세요. 문법은 채점하지 않고 정보만 봅니다. 반드시 들어갈 것: 무엇을 했는지(management cluster 와 clusterctl init), 판 두 개(v1.14.3, v0.11.2), 다음에 할 일을 밝히는 Next: 로 시작하는 줄 하나, 그리고 막힌 것이 있는지 밝히는 Blockers: 로 시작하는 줄 하나. 글은 영어로(라틴 문자 90% 이상), 전체 25단어 이상 쓰세요.

진행 보고(stand-up update)는 Done / Next / Blockers 세 칸이 기본입니다. 짧은 평서문으로, 판 번호와 명령처럼 확인할 수 있는 사실을 넣으면 읽는 사람이 다시 묻지 않습니다. 막힌 것이 없으면 Blockers: none. 이라고 적는 것이 관례입니다.