LabHub
배우기 러닝패스 코스

Kubernetesディストリビューション — 自分で立てる

traefik を削除したら再起動後に復活した

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

k3s 서버가 manifests 디렉터리의 파일을 AddOn 으로 적용하고 traefik 을 HelmChart 로 설치하는 구조를 진짜 k3s 에서 확인합니다. kubectl 로 지우기, 재시작, .skip, --disable, HelmChartConfig, 구성 파일과 CLI 플래그의 우선순위가 각각 무엇을 바꾸고 무엇을 남기는지 기록으로 남깁니다.

왜 중요한가

k3s 는 설치 한 줄로 인그레스·DNS·메트릭까지 갖춘 클러스터를 줍니다. 그 편의는 "k3s 가 기동할 때마다 기본 구성요소의 매니페스트를 다시 쓰고 적용한다" 는 설계에서 나옵니다. 그래서 관리형 클러스터에서 하던 대로 kubectl 로 구성요소를 지우면 다음 재시작에 조용히 되살아나고, 반대로 매니페스트 파일을 지워도 클러스터의 객체는 남습니다. 끄는 것은 --disable, 파일만 무시하는 것은 .skip, 값만 바꾸는 것은 HelmChartConfig 입니다. 셋의 차이를 모르면 업그레이드나 재부팅 뒤에 "누가 이걸 다시 깔았지" 를 추적하게 됩니다. 구성 파일도 마찬가지로, 설치 스크립트가 서비스 유닛에 넣은 플래그가 config.yaml 보다 우선한다는 것을 모르면 고친 값이 반영되지 않는 이유를 찾지 못합니다.

단계

  1. /root/k3s-pkg/inventory.jsonversion(노드의 kubeletVersion), addons(kube-system 의 AddOn 이름을 정렬한 배열), helmcharts(kube-system 의 HelmChart 이름을 정렬한 배열), manifest_files(manifests 디렉터리 아래 파일의 상대 경로를 정렬한 배열)를 적으세요.
  2. /var/lib/rancher/k3s/server/manifests/lab-banner.yaml 에 Namespace k3s-pkg 와 ConfigMap banner(네임스페이스 k3s-pkg, msg: v1)를 적어 AddOn 으로 배포하세요. 생긴 ConfigMap 을 kubectl 로 지우고 20초 기다려 돌아오지 않는 것을 확인한 뒤, 파일의 값을 msg: v2 로 바꿔 다시 생기게 하세요. /root/k3s-pkg/banner.jsondeleted_uid(지운 것의 UID), restored_uid(다시 생긴 것의 UID), returned_before_edit(파일을 고치기 전에 돌아왔는지, 불리언)를 적으세요.
  3. kube-system 의 HelmChart traefik 을 kubectl 로 지우고 traefik Deployment 가 사라질 때까지 기다리세요(아직 재시작하지 않습니다). /root/k3s-pkg/gone.jsondeleted_at(지운 시각, UTC RFC3339 예: 2026-01-01T00:00:00Z), manifest_still_there(traefik.yaml 파일이 아직 있는지, 불리언), release_left(남은 traefik 릴리스 Secret 수, 정수)를 적으세요.
  4. systemctl restart k3s 로 k3s 를 재시작하고 traefik Deployment 가 다시 Available 이 될 때까지 기다리세요. /root/k3s-pkg/revive.jsonhelmchart_uid(다시 생긴 HelmChart traefik 의 UID), helmchart_created(그 creationTimestamp), revived(Deployment 가 돌아왔는지, 불리언)를 적으세요.
  5. /var/lib/rancher/k3s/server/manifests/lab-pinned.yaml 로 ConfigMap pinned(네임스페이스 k3s-pkg, v: "1")를 배포하세요. 생긴 것을 확인한 뒤 같은 디렉터리에 lab-pinned.yaml.skip 을 만들고, 파일의 값을 v: "2" 로 바꿔 20초 기다리세요. /root/k3s-pkg/skip.jsonfile_value(파일에 적힌 값), live_value(클러스터 ConfigMap 의 값), addon_still_exists(AddOn lab-pinned 가 남아 있는지, 불리언)를 적으세요.
  6. /etc/rancher/k3s/config.yaml 은 그대로 두고 /etc/rancher/k3s/config.yaml.d/50-disable.yaml 을 만들어 metrics-server 를 끄세요. local-storage 는 계속 꺼져 있어야 합니다. 파일을 쓴 직후 20초 동안 metrics-server 가 그대로인 것을 확인한 뒤 k3s 를 재시작하세요. /root/k3s-pkg/disable.jsonchanged_before_restart(재시작 전에 사라졌는지, 불리언), removed_addons(재시작으로 사라진 AddOn 이름을 정렬한 배열), files_left(manifests/metrics-server 아래 남은 파일 수, 정수)를 적으세요.
  7. /etc/rancher/k3s/config.yaml 에 기존 disable 목록을 유지한 채 write-kubeconfig-mode: "0600" 을 더하고 k3s 를 재시작하세요. /etc/rancher/k3s/k3s.yaml 의 권한이 어떻게 됐는지 보고 /root/k3s-pkg/precedence.jsonconfig_value(config.yaml 에 적은 값, 문자열), effective_mode(재시작 뒤 k3s.yaml 의 8진 권한, 문자열 예: "640"), winner(cli 또는 config), flag_file(이긴 값이 적힌 파일의 절대 경로)를 적으세요.
  8. 재시작하지 않고 /var/lib/rancher/k3s/server/manifests/traefik-config.yaml 에 HelmChartConfig traefik(kube-system)을 두어 traefik 로그 수준을 DEBUG(logs.general.level)로 바꾸세요. /root/k3s-pkg/hcc.jsonrevision_before(적용 전 traefik 릴리스의 가장 큰 리비전, 정수), revision_after(적용 후, 정수), log_arg(traefik 컨테이너 인자 중 로그 수준 인자 전체)를 적으세요.
  9. /root/k3s-pkg/report.jsonneeds_restart(객체: manifest_file·skip_file·helmchartconfig·config_dropin 각각 재시작해야 반영됐는지 불리언), revived_by_restart(3·4단계에서 재시작으로 되살아난 HelmChart 이름), disable_deletes_files(불리언), skip_removes_resources(불리언), current_addons(지금 kube-system 의 AddOn 이름을 정렬한 배열), traefik_revision(지금 traefik 릴리스의 가장 큰 리비전, 정수)을 적으세요.

참고

무엇이 AddOn 으로 깔렸나

/root/k3s-pkg/inventory.jsonversion(노드의 kubeletVersion), addons(kube-system 의 AddOn 이름을 정렬한 배열), helmcharts(kube-system 의 HelmChart 이름을 정렬한 배열), manifest_files(manifests 디렉터리 아래 파일의 상대 경로를 정렬한 배열)를 적으세요.

AddOn 은 k3s.cattle.io 그룹의 CRD 이고 파일 하나가 AddOn 하나입니다. 하위 디렉터리의 파일도 각각 AddOn 이 됩니다. local-storage 는 조리법의 config.yaml 에서 이미 꺼 두었으니 목록에 없어야 정상입니다.

kubectl 로 지운 ConfigMap 은 언제 돌아오나

/var/lib/rancher/k3s/server/manifests/lab-banner.yaml 에 Namespace k3s-pkg 와 ConfigMap banner(네임스페이스 k3s-pkg, msg: v1)를 적어 AddOn 으로 배포하세요. 생긴 ConfigMap 을 kubectl 로 지우고 20초 기다려 돌아오지 않는 것을 확인한 뒤, 파일의 값을 msg: v2 로 바꿔 다시 생기게 하세요. /root/k3s-pkg/banner.jsondeleted_uid(지운 것의 UID), restored_uid(다시 생긴 것의 UID), returned_before_edit(파일을 고치기 전에 돌아왔는지, 불리언)를 적으세요.

배포 컨트롤러는 파일이 바뀌었을 때와 k3s 가 기동할 때 적용합니다. 클러스터의 객체가 지워졌다는 사실은 적용의 계기가 아닙니다. AddOn 은 파일의 체크섬을 기억하므로 touch 처럼 내용이 같은 변경도 계기가 되지 않습니다.

traefik 을 kubectl 로 지웠다

kube-system 의 HelmChart traefik 을 kubectl 로 지우고 traefik Deployment 가 사라질 때까지 기다리세요(아직 재시작하지 않습니다). /root/k3s-pkg/gone.jsondeleted_at(지운 시각, UTC RFC3339 예: 2026-01-01T00:00:00Z), manifest_still_there(traefik.yaml 파일이 아직 있는지, 불리언), release_left(남은 traefik 릴리스 Secret 수, 정수)를 적으세요.

HelmChart 에는 helm-controller 의 finalizer 가 붙어 있어 지우면 helm-delete Job 이 릴리스를 먼저 지웁니다. Helm 릴리스는 kube-system 의 owner=helm,name=traefik 라벨이 붙은 Secret 으로 남습니다. manifests 디렉터리는 클러스터 객체를 지워도 건드려지지 않습니다.

재시작했더니 traefik 이 다시 살아났다

systemctl restart k3s 로 k3s 를 재시작하고 traefik Deployment 가 다시 Available 이 될 때까지 기다리세요. /root/k3s-pkg/revive.jsonhelmchart_uid(다시 생긴 HelmChart traefik 의 UID), helmchart_created(그 creationTimestamp), revived(Deployment 가 돌아왔는지, 불리언)를 적으세요.

k3s 는 기동할 때마다 기본 구성요소의 매니페스트를 디스크에 다시 쓰고 적용합니다. 파일이 만든 HelmChart 가 없으면 새로 만들어지고, 그러면 helm-install Job 이 다시 돕니다. API 가 준비되는 것과 traefik 이 뜨는 것 사이에 20초쯤 차이가 있습니다.

.skip 은 지우지 않고 못 본 척한다

/var/lib/rancher/k3s/server/manifests/lab-pinned.yaml 로 ConfigMap pinned(네임스페이스 k3s-pkg, v: "1")를 배포하세요. 생긴 것을 확인한 뒤 같은 디렉터리에 lab-pinned.yaml.skip 을 만들고, 파일의 값을 v: "2" 로 바꿔 20초 기다리세요. /root/k3s-pkg/skip.jsonfile_value(파일에 적힌 값), live_value(클러스터 ConfigMap 의 값), addon_still_exists(AddOn lab-pinned 가 남아 있는지, 불리언)를 적으세요.

.skip 파일은 내용이 아니라 존재만 봅니다. 이미 적용된 AddOn 과 그것이 만든 객체는 그대로 두고, 이후 그 파일의 변경을 무시합니다.

drop-in 하나로 metrics-server 를 끈다

/etc/rancher/k3s/config.yaml 은 그대로 두고 /etc/rancher/k3s/config.yaml.d/50-disable.yaml 을 만들어 metrics-server 를 끄세요. local-storage 는 계속 꺼져 있어야 합니다. 파일을 쓴 직후 20초 동안 metrics-server 가 그대로인 것을 확인한 뒤 k3s 를 재시작하세요. /root/k3s-pkg/disable.jsonchanged_before_restart(재시작 전에 사라졌는지, 불리언), removed_addons(재시작으로 사라진 AddOn 이름을 정렬한 배열), files_left(manifests/metrics-server 아래 남은 파일 수, 정수)를 적으세요.

drop-in 은 이름순으로 읽히고, 같은 키가 여러 파일에 있으면 마지막 값이 이깁니다. 목록에 덧붙이려면 키 이름 끝에 + 를 붙입니다. --disable 은 AddOn 을 제거할 뿐 아니라 원본 파일도 지웁니다. 구성 파일은 k3s 가 기동할 때 읽습니다.

config.yaml 을 고쳤는데 권한이 그대로다

/etc/rancher/k3s/config.yaml 에 기존 disable 목록을 유지한 채 write-kubeconfig-mode: "0600" 을 더하고 k3s 를 재시작하세요. /etc/rancher/k3s/k3s.yaml 의 권한이 어떻게 됐는지 보고 /root/k3s-pkg/precedence.jsonconfig_value(config.yaml 에 적은 값, 문자열), effective_mode(재시작 뒤 k3s.yaml 의 8진 권한, 문자열 예: "640"), winner(cli 또는 config), flag_file(이긴 값이 적힌 파일의 절대 경로)를 적으세요.

구성 파일과 CLI 인자가 같은 키를 가지면 CLI 가 우선합니다. 설치 스크립트에 넘긴 INSTALL_K3S_EXEC 는 systemd 유닛의 ExecStart 에 인자로 저장됩니다. systemctl cat k3s 로 보세요.

재시작 없이 traefik 값만 바꾼다

재시작하지 않고 /var/lib/rancher/k3s/server/manifests/traefik-config.yaml 에 HelmChartConfig traefik(kube-system)을 두어 traefik 로그 수준을 DEBUG(logs.general.level)로 바꾸세요. /root/k3s-pkg/hcc.jsonrevision_before(적용 전 traefik 릴리스의 가장 큰 리비전, 정수), revision_after(적용 후, 정수), log_arg(traefik 컨테이너 인자 중 로그 수준 인자 전체)를 적으세요.

HelmChartConfig 는 이름과 네임스페이스가 대상 HelmChart 와 같아야 합니다. valuesContent 는 HelmChart 의 valuesContent 보다 우선하고 spec.set 보다는 약합니다. helm-controller 가 helm upgrade 를 돌리므로 릴리스 Secret 이 하나 늘어납니다(sh.helm.release.v1.traefik.vN).

지우기·무시하기·덮어쓰기를 한 표로

/root/k3s-pkg/report.jsonneeds_restart(객체: manifest_file·skip_file·helmchartconfig·config_dropin 각각 재시작해야 반영됐는지 불리언), revived_by_restart(3·4단계에서 재시작으로 되살아난 HelmChart 이름), disable_deletes_files(불리언), skip_removes_resources(불리언), current_addons(지금 kube-system 의 AddOn 이름을 정렬한 배열), traefik_revision(지금 traefik 릴리스의 가장 큰 리비전, 정수)을 적으세요.

앞 단계에서 남긴 json 과 지금 클러스터를 근거로 적습니다. 채점기는 같은 값을 클러스터와 기록 파일에서 다시 계산합니다.