LabHub
开始
学习 学习路径 课程

用 Kubespray 与 Terraform 搭建集群

续期一年期证书,然后清除并重建

在 LabHub 中继续学习

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

목표

kubeadm 인증서를 손으로 갱신하고 컨트롤 플레인이 새 인증서를 쓰게 만든 뒤, kubespray 의 자동 갱신 타이머를 켜고 그것이 언제 실제로 갱신하는지 확인합니다. 마지막으로 reset.yml 로 클러스터를 지우고 무엇이 남는지 본 뒤, 같은 인벤토리로 처음부터 다시 세웁니다.

왜 중요한가

kubeadm 이 만든 잎 인증서는 1년짜리입니다. 1년 안에 업그레이드를 한 번이라도 하면 kubeadm 이 함께 갱신하지만, 그러지 않은 클러스터는 어느 날 구성요소끼리의 인증이 한꺼번에 거절됩니다. 갱신은 파일을 바꾸는 것으로 끝나지 않습니다 — 그 파일을 읽는 프로세스가 새 인증서를 쓰고 있어야 합니다. 그리고 반쯤 망가진 클러스터를 되살리기보다 지우고 다시 세우는 편이 빠른 날이 있습니다. 그때 reset.yml 이 무엇을 지우고 무엇을 남기는지 알아야 "깨끗한 재설치" 라는 말을 믿을 수 있습니다. 설치 두 번과 초기화 한 번으로 약 15분을 기다리니 필요하면 세션을 연장하세요.

단계

  1. /opt/ks/kubespray 에서 ansible-playbook -i /root/ks/inventory/lab/inventory.ini cluster.yml 을 돌려 출력 전체를 /root/ks/logs/cluster-1.log 에 남기세요(약 7분). PLAY RECAP 의 node1 이 failed=0 이어야 합니다.
  2. /root/ks/certs/before.jsonapiserver_serial(/etc/kubernetes/ssl/apiserver.crt 의 serial, openssl 이 찍는 16진수 그대로), apiserver_not_after(openssl 의 notAfter 문자열 그대로), admin_client_serial(/etc/kubernetes/admin.conf 안 client-certificate-data 의 serial), ca_serial(/etc/kubernetes/ssl/ca.crt 의 serial), node_uid 를 적으세요.
  3. kubeadm certs renew all 로 kubeadm 인증서를 갱신한 뒤, 컨트롤 플레인이 새 인증서를 쓰도록 kube-apiserver·kube-controller-manager·kube-scheduler 정적 파드를 다시 띄우고, /etc/kubernetes/admin.conf/root/.kube/config 로 복사하세요. 끝나면 apiserver.crt 의 serial 이 바뀌고, 6443 이 내주는 인증서가 그 파일과 같고, controller-manager·scheduler 컨테이너가 각자의 kubeconfig 가 바뀐 뒤에 시작된 것이어야 합니다.
  4. /root/ks/inventory/lab/group_vars/k8s_cluster/k8s-cluster.ymlauto_renew_certificatestrue 로 바꾸고, cluster.yml --tags control-plane 으로 그 부분만 다시 돌려 출력 전체를 /root/ks/logs/cp-tags.log 에 남기세요. 끝나면 k8s-certs-renew.timer 가 enabled·active 여야 합니다.
  5. systemctl start k8s-certs-renew.service 로 갱신 서비스를 지금 한 번 돌리고 journalctl -u k8s-certs-renew.service 로 결과를 보세요. /root/ks/certs/timer.jsononcalendar(타이머의 OnCalendar 값), renewed(이번 실행이 인증서를 갱신했는가, 불리언), decision_line(갱신 여부를 말하는 ## 로 시작하는 줄 그대로)을 적으세요.
  6. /opt/ks/kubespray 에서 ansible-playbook -i /root/ks/inventory/lab/inventory.ini reset.yml -e reset_confirmation=yes 를 돌려 출력 전체를 /root/ks/logs/reset.log 에 남기세요(약 1분 반). 그다음 /root/ks/certs/remnants.jsonhostname(지금 호스트 이름), releases_kept(/tmp/releases 가 남았는가, 불리언), left_bins(/usr/local/bin 에 남은 일반 파일 가운데 labhub-agent 를 뺀 이름의 정렬 배열 — 심볼릭 링크는 제외)를 적으세요.
  7. 같은 인벤토리로 cluster.yml 을 다시 돌려 출력 전체를 /root/ks/logs/cluster-2.log 에 남기세요. 끝나면 node1 이 Ready 이고, 새 클러스터라는 증거로 CA serial 과 노드 UID 가 2단계의 기록과 달라야 합니다.

참고

갱신하고 지울 클러스터를 세운다

/opt/ks/kubespray 에서 ansible-playbook -i /root/ks/inventory/lab/inventory.ini cluster.yml 을 돌려 출력 전체를 /root/ks/logs/cluster-1.log 에 남기세요(약 7분). PLAY RECAP 의 node1 이 failed=0 이어야 합니다.

앞 모듈들과 같은 설치입니다. 콘솔이 끊겨도 계속 돌게 systemd-run 이나 tmux 로 띄우고 HOME=/root 를 넘기세요.

갱신 전의 serial

/root/ks/certs/before.jsonapiserver_serial(/etc/kubernetes/ssl/apiserver.crt 의 serial, openssl 이 찍는 16진수 그대로), apiserver_not_after(openssl 의 notAfter 문자열 그대로), admin_client_serial(/etc/kubernetes/admin.conf 안 client-certificate-data 의 serial), ca_serial(/etc/kubernetes/ssl/ca.crt 의 serial), node_uid 를 적으세요.

serial 은 openssl x509 -noout -serialserial=... 로 찍습니다. kubeconfig 안의 인증서는 base64 로 들어 있으니 풀어서 openssl 에 넘깁니다. 이 값들이 뒤에서 '정말 새 인증서인가', '정말 새 클러스터인가' 를 가르는 기준이 됩니다.

갱신하고, 새 인증서를 쓰게 한다

kubeadm certs renew all 로 kubeadm 인증서를 갱신한 뒤, 컨트롤 플레인이 새 인증서를 쓰도록 kube-apiserver·kube-controller-manager·kube-scheduler 정적 파드를 다시 띄우고, /etc/kubernetes/admin.conf/root/.kube/config 로 복사하세요. 끝나면 apiserver.crt 의 serial 이 바뀌고, 6443 이 내주는 인증서가 그 파일과 같고, controller-manager·scheduler 컨테이너가 각자의 kubeconfig 가 바뀐 뒤에 시작된 것이어야 합니다.

kubeadm 은 갱신이 끝나면 '재시작하라' 고 출력합니다. 정적 파드는 kubelet 이 띄우므로, 파드 샌드박스를 지우면(crictl pods --name ... -q | xargs crictl rmp -f) kubelet 이 매니페스트를 보고 다시 띄웁니다. kubespray 의 /usr/local/bin/k8s-certs-renew.sh 가 같은 순서를 씁니다 — 읽어 보세요. 지우고 몇 초 동안 API 가 응답하지 않는 것은 정상입니다.

갱신을 달력에 맡긴다

/root/ks/inventory/lab/group_vars/k8s_cluster/k8s-cluster.ymlauto_renew_certificatestrue 로 바꾸고, cluster.yml --tags control-plane 으로 그 부분만 다시 돌려 출력 전체를 /root/ks/logs/cp-tags.log 에 남기세요. 끝나면 k8s-certs-renew.timer 가 enabled·active 여야 합니다.

이 스위치는 컨트롤 플레인 역할이 systemd 타이머와 서비스를 깔게 합니다. 언제 도는지는 auto_renew_certificates_systemd_calendar 가 정하고, systemctl list-timers 가 다음 실행 시각을 보여 줍니다. 기본값은 매달 첫 월요일입니다.

타이머는 언제 실제로 갱신하나

systemctl start k8s-certs-renew.service 로 갱신 서비스를 지금 한 번 돌리고 journalctl -u k8s-certs-renew.service 로 결과를 보세요. /root/ks/certs/timer.jsononcalendar(타이머의 OnCalendar 값), renewed(이번 실행이 인증서를 갱신했는가, 불리언), decision_line(갱신 여부를 말하는 ## 로 시작하는 줄 그대로)을 적으세요.

스크립트는 다음 타이머 시각에 7일 여유를 더한 시점보다 먼저 만료되는 인증서가 있을 때만 갱신하고 컨트롤 플레인을 다시 띄웁니다. 방금 갱신한 인증서는 1년이 남았으니 어떻게 될지 먼저 예상해 보고 확인하세요. 스크립트 본문은 /usr/local/bin/k8s-certs-renew.sh 에 있습니다.

reset.yml 로 지운다 — 무엇이 남나

/opt/ks/kubespray 에서 ansible-playbook -i /root/ks/inventory/lab/inventory.ini reset.yml -e reset_confirmation=yes 를 돌려 출력 전체를 /root/ks/logs/reset.log 에 남기세요(약 1분 반). 그다음 /root/ks/certs/remnants.jsonhostname(지금 호스트 이름), releases_kept(/tmp/releases 가 남았는가, 불리언), left_bins(/usr/local/bin 에 남은 일반 파일 가운데 labhub-agent 를 뺀 이름의 정렬 배열 — 심볼릭 링크는 제외)를 적으세요.

reset.yml 은 되돌릴 수 없는 작업이라 확인 변수를 요구합니다. 무엇을 지우는지는 roles/reset/tasks/main.yml 의 목록에 있습니다 — 그 목록에 없는 것은 남습니다. 남은 것을 알아 두면 '깨끗이 지웠다' 는 말을 어디까지 믿을지 정할 수 있습니다.

처음부터 다시 세운다

같은 인벤토리로 cluster.yml 을 다시 돌려 출력 전체를 /root/ks/logs/cluster-2.log 에 남기세요. 끝나면 node1 이 Ready 이고, 새 클러스터라는 증거로 CA serial 과 노드 UID 가 2단계의 기록과 달라야 합니다.

reset 은 /etc/kubernetes 를 통째로 지우므로 CA 도 사라집니다. 다시 세우면 새 CA 가 만들어지고, 그 CA 로 서명된 옛 kubeconfig 는 더 이상 쓸 수 없습니다. 받은 파일 캐시(/tmp/releases)가 남아 있어 처음 설치보다 조금 빠릅니다.