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

쿠버네티스 배포판 — 직접 세운다

k0s 설정의 진실은 어디에 있나

TT Lab 에서 이어서 보기

한 줄 요약

k0s 의 클러스터 설정은 정적 구성이면 각 컨트롤러의 파일, 동적 구성이면 API 안의 ClusterConfig 오브젝트에 있습니다. 어느 모드인지 모르고 파일을 고치면 "고쳤는데 아무 일도 없다" 가 됩니다.

왜 이게 필요했나

k0s 는 바이너리 하나와 k0s.yaml 하나로 클러스터를 세운다고 소개됩니다. 그래서 운영자는 설정을 바꿀 때 자연스럽게 /etc/k0s/k0s.yaml 을 엽니다. 여기서 두 가지 사고가 납니다.

첫째, 기본인 정적 구성에서는 k0s 가 파일을 감시하지 않습니다. 구성 문서는 실행 중에 파일을 바꿀 수는 있지만 반영하려면 k0s 를 재시작하라고 적습니다. 컨트롤러가 여러 대라면 모든 컨트롤러의 파일을 똑같이 맞추고 전부 재시작해야 합니다. 한 대만 고치고 잊으면, 다음에 그 노드가 재시작될 때 비로소 설정이 바뀌고 컨트롤러끼리 서로 다른 설정을 들고 있게 됩니다.

둘째, 이 불편을 없애려고 동적 구성(--enable-dynamic-config)을 켜면 반대 방향의 함정이 생깁니다. 동적 구성 문서에 따르면 클러스터를 처음 만들 때 첫 컨트롤러가 파일을 부트스트랩 값으로 한 번 읽어 API 에 저장하고, 그 뒤로는 API 의 오브젝트가 모든 컨트롤러의 진실의 원천입니다. 이제 파일의 클러스터 수준 설정은 고치고 재시작해도 무시됩니다.

어떻게 동작하나

설정 파일은 부분만 써도 된다

k0s config create 는 기본값이 모두 채워진 설정을 출력합니다. 하지만 k0s 는 부분 설정을 받아 빠진 값은 기본값으로 채우므로, 실제 파일에는 바꾸고 싶은 것만 두는 편이 읽기 좋습니다. 기본값을 보는 이유는 "내가 적지 않은 값이 무엇으로 정해지는가" 를 알기 위해서입니다. 이 실습의 VM 에서 기본 출력은 파드 대역 10.244.0.0/16, 서비스 대역 10.96.0.0/12, 저장소 etcd, telemetry 켜짐이었습니다. 이 VM 은 쿠버네티스 위에서 돌기 때문에 기본 대역이 호스트 클러스터와 겹쳐 파일에서 172.20/172.21 로 바꿔 두었습니다.

k0s sysinfo 는 같은 바이너리가 설치 전에 돌리는 사전 점검입니다. 메모리, /var/lib/k0s 파일시스템과 여유 공간, cgroup 판과 컨트롤러, 커널 설정을 항목마다 pass·warning 으로 보여 주고 -o json 으로 기계가 읽을 수도 있습니다.

클러스터 설정과 노드 설정은 다르다

동적 구성에서도 파일이 전부 무시되지는 않습니다. 문서는 spec.api(그 노드의 API 서버), spec.storage(그 노드의 etcd 또는 SQLite), spec.network.controlPlaneLoadBalancing 을 노드별 설정으로 분류해 계속 파일에서 읽는다고 합니다. API 서버와 저장소가 떠야 오브젝트를 읽을 수 있으니 당연한 설계입니다. 또 network.podCIDR, serviceCIDR, provider 등은 클러스터를 만든 뒤 바꿀 수 없는 항목이라, 수동 설치 때 파일에 반드시 적어야 한다고 합니다.

그 밖의 클러스터 수준 설정(워커 프로필, kube-router·kube-proxy 설정, 헬름 확장 등)은 kube-system 네임스페이스의 clusterconfig/k0s 오브젝트가 결정합니다. 컨트롤러는 오퍼레이터 방식으로 이 오브젝트를 지켜보다가 바뀌면 관련 리소스를 다시 만들고, 결과를 이벤트로 남깁니다. k0s config status 가 그 이벤트(SuccessfulReconcile, FailedReconciling)를 보여 줍니다.

정적 구성   파일 수정 ──(재시작해야)──▶ 반영
동적 구성   파일 수정 ──(재시작해도)──▶ 클러스터 수준 설정은 무시
            ClusterConfig 수정 ──(즉시)──▶ 반영, 이벤트 기록

워커 프로필은 ConfigMap 으로 나타난다

워커 노드 구성 문서의 워커 프로필(spec.workerProfiles)은 kubelet 설정 덮어쓰기 묶음입니다. k0s 는 프로필마다 ConfigMap 을 만들고, 워커는 --profile 로 고른 ConfigMap 을 시작할 때 읽습니다. 실측으로는 이름이 worker-config-<프로필>-1.36 처럼 쿠버네티스 마이너 판이 붙었습니다. 그래서 설정이 반영됐는지를 이 ConfigMap 의 존재와 kubeletConfiguration 안의 값으로 눈에 보이게 확인할 수 있습니다.

헬름 확장은 Chart 오브젝트를 만든다

헬름 차트 문서는 두 방법을 설명합니다. Chart 오브젝트를 직접 만드는 방법(권장)과, spec.extensions.helm 에 저장소와 차트를 선언하면 k0s 가 Chart 오브젝트로 바꿔 주는 방법입니다. 저장소는 index.yaml 이 있는 정식 헬름 저장소여야 하고, Chart 가 지워지면 k0s 가 릴리스를 제거합니다. 실측에서 선언으로 만든 Chart 이름은 k0s-addon-chart-<차트 이름> 이었고, 제거용 finalizer 가 붙어 있었습니다.

현장에서 만나는 모습

실측으로 본 장면을 옮깁니다(k0s v1.36.4+k0s.0).

실무에서 진짜 중요한 것

다음 실습에서 할 것

정적 구성으로 뜬 k0s 한 대에서 시작합니다. 기본값과 파일을 비교하고 사전 점검을 읽은 뒤, 파일에 워커 프로필을 넣어 재시작 전후를 비교합니다. 동적 구성으로 바꿔 ClusterConfig 가 생기는 것을 보고, 같은 방식으로 파일을 고치면 이번에는 재시작해도 무시되는 것을 확인합니다. 마지막으로 오브젝트에 워커 프로필과 podinfo 차트를 선언하고, 선언을 지웠을 때 무엇이 남는지 기록합니다.