LabHub
배우기 러닝패스 코스

쿠버네티스 배포판 — 직접 세운다 · k0s 구성과 동적 구성 · 이론

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

LabHub 에서 이어서 보기

한 줄 요약

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

왜 이게 필요했나

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

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

둘째, 이 불편을 없애려고 동적 구성(--enable-dynamic-config)을 켜면 반대 방향의 함정이 생깁니다. [동적 구성 문서](https://docs.k0sproject.io/stable/dynamic-configuration/)에 따르면 클러스터를 처음 만들 때 첫 컨트롤러가 파일을 부트스트랩 값으로 한 번 읽어 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 으로 나타난다

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

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

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

현장에서 만나는 모습

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

실무에서 진짜 중요한 것

다음 실습에서 할 것

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