kubeadm으로 인증서 관리하기

kubeadm으로 인증서 관리하기 (Certificate Management with kubeadm)

kubeadm이 생성한 클라이언트 인증서는 1년 후 만료돼요. 이 페이지는 kubeadm으로 인증서 갱신을 관리하는 방법을 설명해요. 또한 kubeadm 인증서 관리와 관련된 다른 작업도 다뤄요.

쿠버네티스 프로젝트는 최신 패치 릴리스로 신속히 업그레이드하고, 지원되는 minor 릴리스의 쿠버네티스를 실행하고 있는지 확인할 것을 권장해요. 이 권장 사항을 따르면 안전하게 유지하는 데 도움이 돼요.

출처: 문서

본문

시작하기 전에 (Before you begin)

쿠버네티스의 PKI 인증서와 요구 사항에 익숙해야 해요.

구성 파일을 kubeadm 명령에 전달하는 방법에 익숙해야 해요.

이 가이드는 openssl 명령의 사용을 다루지만(수동 인증서 서명을 선택하는 경우), 선호하는 도구를 사용할 수 있어요.

여기서 몇몇 단계는 관리자 접근을 위해 sudo 를 사용해요. 어떤 동등한 도구든 사용할 수 있어요.

커스텀 인증서 사용하기

기본적으로 kubeadm은 클러스터를 실행하는 데 필요한 모든 인증서를 생성해요. 직접 인증서를 제공해 이 동작을 재정의할 수 있어요.

그렇게 하려면 --cert-dir 플래그 또는 kubeadm의 ClusterConfigurationcertificatesDir 필드가 지정하는 디렉토리에 인증서를 배치해야 해요. 기본적으로 이는 /etc/kubernetes/pki 예요.

주어진 인증서와 개인 키 쌍이 kubeadm init 을 실행하기 전에 존재하면 kubeadm은 그것을 덮어쓰지 않아요. 즉 예를 들어 기존 CA를 /etc/kubernetes/pki/ca.crt/etc/kubernetes/pki/ca.key 로 복사할 수 있고, kubeadm은 나머지 인증서를 서명하는 데 이 CA를 사용할 거예요.

암호화 알고리즘 선택하기

kubeadm은 공개·개인 키를 만드는 데 사용되는 암호화 알고리즘을 선택하게 해줘요. 이는 kubeadm 구성의 encryptionAlgorithm 필드로 할 수 있어요:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
encryptionAlgorithm: <ALGORITHM>

<ALGORITHM>RSA-2048(기본값), RSA-3072, RSA-4096 또는 ECDSA-P256 중 하나일 수 있어요.

인증서 유효 기간 선택하기

kubeadm은 CA와 리프 인증서의 유효 기간을 선택하게 해줘요. 이는 kubeadm 구성의 certificateValidityPeriodcaCertificateValidityPeriod 필드로 할 수 있어요:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
certificateValidityPeriod: 8760h # Default: 365 days × 24 hours = 1 year
caCertificateValidityPeriod: 87600h # Default: 365 days × 24 hours * 10 = 10 years

필드의 값은 Go의 time.Duration 값에 대한 허용 형식을 따르며, 가장 긴 지원 단위는 h(시간)이에요.

외부 CA 모드

ca.crt 파일만 제공하고 ca.key 파일은 제공하지 않는 것도 가능해요(이것은 루트 CA 파일에만 사용 가능하며 다른 인증서 쌍에는 없어요). 다른 모든 인증서와 kubeconfig 파일이 준비되어 있으면 kubeadm은 이 상태를 인식하고 "External CA" 모드를 활성화해요. kubeadm은 디스크에 CA 키 없이 진행할 거예요.

대신 컨트롤러-매니저를 --controllers=csrsigner 로 독립 실행하고 CA 인증서와 키를 가리켜요.

외부 CA 모드를 사용할 때 컴포넌트 자격 증명을 준비하는 다양한 방법이 있어요.

컴포넌트 자격 증명의 수동 준비

PKI 인증서와 요구 사항은 kubeadm이 요구하는 모든 컴포넌트 자격 증명을 수동으로 준비하는 방법에 대한 정보를 포함해요.

이 가이드는 openssl 명령의 사용을 다루지만(수동 인증서 서명을 선택하는 경우), 선호하는 도구를 사용할 수 있어요.

kubeadm이 생성한 CSR을 서명해 자격 증명 준비

kubeadm은 openssl 같은 도구와 외부 CA로 수동으로 서명할 수 있는 CSR 파일을 생성할 수 있어요. 이 CSR 파일은 kubeadm이 배포한 컴포넌트가 요구하는 모든 자격 증명 사양을 포함할 거예요.

kubeadm phases를 사용한 컴포넌트 자격 증명의 자동 준비

대안으로 kubeadm phase 명령을 사용해 이 과정을 자동화할 수 있어요.

  • 외부 CA가 있는 kubeadm 제어 플레인 노드로 준비하려는 호스트로 이동해요.
  • 가지고 있는 외부 CA 파일 ca.crtca.key 를 노드의 /etc/kubernetes/pki 에 복사해요.
  • kubeadm init 과 함께 사용할 수 있는 임시 kubeadm 구성 파일 config.yaml 을 준비해요. 이 파일에 ClusterConfiguration.controlPlaneEndpoint, ClusterConfiguration.certSANs, InitConfiguration.APIEndpoint 같은 인증서에 포함될 수 있는 관련 클러스터 전체 또는 호스트별 정보가 포함되어 있는지 확인해요.
  • 같은 호스트에서 kubeadm init phase kubeconfig all --config config.yamlkubeadm init phase certs all --config config.yaml 명령을 실행해요. 이렇게 하면 /etc/kubernetes/ 와 그 pki 하위 디렉토리 아래에 필요한 모든 kubeconfig 파일과 인증서가 생성돼요.
  • 생성된 파일을 검사해요. /etc/kubernetes/pki/ca.key 를 삭제하고 파일 /etc/kubernetes/super-admin.conf 를 삭제하거나 안전한 위치로 이동해요.
  • kubeadm join 이 호출될 노드에서도 /etc/kubernetes/kubelet.conf 를 삭제해요. 이 파일은 kubeadm init 이 호출될 첫 노드에만 필요해요.
  • pki/sa.*, pki/front-proxy-ca.*, pki/etc/ca.* 같은 일부 파일은 제어 플레인 노드 사이에 공유되는 점을 주목해요. 한 번 생성해 kubeadm join 이 호출될 노드에 수동으로 배포하거나, kubeadm init--upload-certs 기능과 kubeadm join--certificate-key 를 사용해 이 배포를 자동화할 수 있어요.

모든 노드에 자격 증명이 준비되면 이 노드들에 kubeadm initkubeadm join 을 호출해 클러스터에 조인해요. kubeadm은 /etc/kubernetes/ 와 그 pki 하위 디렉토리 아래의 기존 kubeconfig·인증서 파일을 사용할 거예요.

인증서 만료와 관리

참고:

check-expiration 하위 명령으로 인증서가 언제 만료되는지 확인할 수 있어요:

kubeadm certs check-expiration

출력은 다음과 비슷해요:

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Dec 30, 2020 23:36 UTC   364d                                    no
apiserver                  Dec 30, 2020 23:36 UTC   364d            ca                      no
apiserver-etcd-client      Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Dec 30, 2020 23:36 UTC   364d            ca                      no
controller-manager.conf    Dec 30, 2020 23:36 UTC   364d                                    no
etcd-healthcheck-client    Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
etcd-peer                  Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
etcd-server                Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
front-proxy-client         Dec 30, 2020 23:36 UTC   364d            front-proxy-ca          no
scheduler.conf             Dec 30, 2020 23:36 UTC   364d                                    no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Dec 28, 2029 23:36 UTC   9y              no
etcd-ca                 Dec 28, 2029 23:36 UTC   9y              no
front-proxy-ca          Dec 28, 2029 23:36 UTC   9y              no

이 명령은 /etc/kubernetes/pki 폴더의 클라이언트 인증서와 kubeadm이 사용하는 kubeconfig 파일(admin.conf, controller-manager.conf, scheduler.conf)에 포함된 클라이언트 인증서에 대한 만료/잔여 시간을 보여줘요.

추가로 kubeadm은 인증서가 외부에서 관리되는지 사용자에게 알려줘요. 이 경우 사용자는 인증서 갱신을 수동으로/다른 도구를 사용해 관리해야 해요.

kubelet.conf 구성 파일은 위 목록에 포함되지 않아요. kubeadm이 /var/lib/kubelet/pki 아래의 회전 가능한 인증서로 kubelet을 자동 인증서 갱신하도록 구성하기 때문이에요. 만료된 kubelet 클라이언트 인증서를 복구하려면 Kubelet 클라이언트 인증서 회전 실패를 참고해요.

참고:

kubeadm 버전 1.17 이전 버전의 kubeadm init 으로 만든 노드에는 kubelet.conf 내용을 수동으로 수정해야 하는 bug가 있어요. kubeadm init 이 끝난 후 kubelet.conf 를 업데이트해 회전된 kubelet 클라이언트 인증서를 가리켜야 해요. client-certificate-dataclient-key-data 를 다음으로 바꿔요:

client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem

자동 인증서 갱신

kubeadm은 제어 플레인 업그레이드 중에 모든 인증서를 갱신해요.

이 기능은 가장 간단한 사용 사례를 해결하기 위해 설계됐어요. 인증서 갱신에 대한 특정 요구 사항이 없고 쿠버네티스 버전 업그레이드를 정기적으로(각 업그레이드 사이 1년 미만) 수행한다면, kubeadm이 클러스터를 최신 상태이고 합리적으로 안전하게 유지하는 것을 처리할 거예요.

인증서 갱신에 대한 더 복잡한 요구 사항이 있다면 kubeadm upgrade apply 또는 kubeadm upgrade node--certificate-renewal=false 를 전달해 기본 동작에서 옵트아웃할 수 있어요.

수동 인증서 갱신

적절한 명령줄 옵션과 함께 kubeadm certs renew 명령으로 언제든지 인증서를 수동으로 갱신할 수 있어요. 복제된 제어 플레인이 있는 클러스터를 실행 중이라면 이 명령을 모든 제어 플레인 노드에서 실행해야 해요.

이 명령은 /etc/kubernetes/pki 에 저장된 CA(또는 front-proxy-CA) 인증서와 키를 사용해 갱신을 수행해요.

kubeadm certs renew 는 기존 인증서를 속성(Common Name, Organization, subject alternative name)의 권위 있는 소스로 사용하며 kubeadm-config ConfigMap에 의존하지 않아요. 그럼에도 쿠버네티스 프로젝트는 혼동의 위험을 피하기 위해 제공되는 인증서와 해당 ConfigMap의 관련 값을 동기화 상태로 유지할 것을 권장해요.

명령 실행 후 제어 플레인 Pod를 재시작해야 해요. 모든 컴포넌트·인증서에 대해 동적 인증서 리로드가 현재 지원되지 않기 때문에 필요해요. 정적 파드는 로컬 kubelet이 관리하고 API 서버가 관리하지 않으므로 kubectl로 삭제·재시작할 수 없어요. 정적 파드를 재시작하려면 일시적으로 /etc/kubernetes/manifests/ 에서 해당 매니페스트 파일을 제거하고 20초를 기다려요(KubeletConfiguration 구조체fileCheckFrequency 값 참고). kubelet은 Pod가 더 이상 매니페스트 디렉토리에 없으면 종료해요. 그런 다음 파일을 다시 옮기고 또 한 번의 fileCheckFrequency 기간 후 kubelet이 Pod를 다시 만들고 컴포넌트의 인증서 갱신이 완료될 수 있어요.

kubeadm certs renew 는 특정 인증서를 갱신하거나 all 하위 명령으로 모두 갱신할 수 있어요:

# If you are running cluster with a replicated control plane, this command
# needs to be executed on all the control-plane nodes.
kubeadm certs renew all

관리자 인증서 복사 (선택 사항)

kubeadm으로 빌드한 클러스터는 kubeadm으로 클러스터 만들기에 안내된 대로 admin.conf 인증서를 $HOME/.kube/config 에 자주 복사해요. 그런 시스템에서 admin.conf 를 갱신한 후 $HOME/.kube/config 의 내용을 업데이트하려면 다음 명령을 실행할 수 있어요:

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

쿠버네티스 인증서 API로 인증서 갱신하기

이 섹션은 쿠버네티스 인증서 API를 사용해 수동 인증서 갱신을 실행하는 방법에 대한 자세한 내용을 제공해요.

주의:

signer 설정하기

쿠버네티스 Certificate Authority는 즉시 동작하지 않아요. cert-manager 같은 외부 signer를 구성하거나 내장 signer를 사용할 수 있어요.

내장 signer는 kube-controller-manager의 일부예요.

내장 signer를 활성화하려면 --cluster-signing-cert-file--cluster-signing-key-file 플래그를 전달해야 해요.

새 클러스터를 만드는 중이라면 kubeadm 구성 파일을 사용할 수 있어요:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
controllerManager:
  extraArgs:
  - name: "cluster-signing-cert-file"
    value: "/etc/kubernetes/pki/ca.crt"
  - name: "cluster-signing-key-file"
    value: "/etc/kubernetes/pki/ca.key"

인증서 서명 요청(CSR) 만들기

쿠버네티스 API로 CSR을 만드는 방법은 CertificateSigningRequest 만들기를 참고해요.

외부 CA로 인증서 갱신하기

이 섹션은 외부 CA를 사용해 수동 인증서 갱신을 실행하는 방법에 대한 자세한 내용을 제공해요.

외부 CA와 더 잘 통합하기 위해 kubeadm은 인증서 서명 요청(CSR)도 생성할 수 있어요. CSR은 클라이언트를 위한 서명된 인증서에 대한 CA 요청을 나타내요. kubeadm 용어로 디스크의 CA가 정상적으로 서명하는 모든 인증서는 CSR로 생성될 수 있어요. 하지만 CA는 CSR로 생성될 수 없어요.

인증서 서명 요청(CSR)을 사용한 갱신

새 CSRs를 생성하고 외부 CA로 서명해 인증서 갱신이 가능해요. kubeadm이 생성한 CSRs 작업에 대한 자세한 내용은 kubeadm이 생성한 인증서 서명 요청(CSR) 서명 섹션을 참고해요.

인증 기관(CA) 회전

Kubeadm은 즉시 사용 가능한 CA 인증서의 회전이나 교체를 지원하지 않아요.

CA의 수동 회전 또는 교체에 대한 자세한 내용은 CA 인증서 수동 회전을 참고해요.

서명된 kubelet serving 인증서 활성화

기본적으로 kubeadm이 배포하는 kubelet serving 인증서는 자체 서명돼요. 이는 metrics-server 같은 외부 서비스의 kubelet으로의 연결이 TLS로 안전하게 보호될 수 없음을 의미해요.

새 kubeadm 클러스터의 kubelet이 제대로 서명된 serving 인증서를 얻도록 구성하려면 kubeadm init 에 다음 최소한의 구성을 전달해야 해요:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
serverTLSBootstrap: true

이미 클러스터를 만들었다면 다음으로 적응해야 해요:

  • kube-system 네임스페이스에서 kubelet-config ConfigMap을 찾아 편집해요. 그 ConfigMap에서 kubelet 키는 KubeletConfiguration 문서를 값으로 가져요. KubeletConfiguration 문서를 편집해 serverTLSBootstrap: true 를 설정해요.
  • 각 노드에서 /var/lib/kubelet/config.yamlserverTLSBootstrap: true 필드를 추가하고 systemctl restart kubelet 로 kubelet을 재시작해요.

serverTLSBootstrap: true 필드는 certificates.k8s.io API에서 요청해 kubelet serving 인증서의 부트스트랩을 활성화할 거예요. 알려진 제한은 이 인증서의 CSRs (Certificate Signing Requests)가 kube-controller-manager의 기본 signer인 kubernetes.io/kubelet-serving에 의해 자동으로 승인될 수 없다는 것이에요. 이는 사용자 또는 서드파티 컨트롤러의 조치가 필요할 거예요.

이 CSRs는 다음을 사용해 볼 수 있어요:

kubectl get csr
NAME        AGE     SIGNERNAME                        REQUESTOR                      CONDITION
csr-9wvgt   112s    kubernetes.io/kubelet-serving     system:node:worker-1           Pending
csr-lz97v   1m58s   kubernetes.io/kubelet-serving     system:node:control-plane-1    Pending

승인하려면 다음을 할 수 있어요:

kubectl certificate approve <CSR-name>

기본적으로 이 serving 인증서는 1년 후 만료돼요. Kubeadm은 KubeletConfiguration 필드 rotateCertificatestrue 로 설정하는데, 이는 만료에 가까워지면 serving 인증서용 새 CSR 집합이 생성되어 회전을 완료하려면 승인되어야 함을 의미해요. 더 이해하려면 인증서 회전을 참고해요.

이 CSRs의 자동 승인 솔루션을 찾고 있다면 클라우드 제공자에게 연락해 노드 정체성을 대역외(out of band) 메커니즘으로 검증하는 CSR signer가 있는지 물어보는 것이 권장돼요.

서드파티 커스텀 컨트롤러를 사용할 수 있어요:

그런 컨트롤러는 CSR의 CommonName만 검증하는 것이 아니라 요청된 IP와 도메인 이름도 검증하지 않으면 안전한 메커니즘이 아니에요. 이는 kubelet 클라이언트 인증서에 접근할 수 있는 악의적인 행위자가 어떤 IP나 도메인 이름에 대한 serving 인증서를 요청하는 CSRs를 만드는 것을 방지해요.

추가 사용자를 위한 kubeconfig 파일 생성

클러스터 생성 중 kubeadm initsuper-admin.conf 의 인증서에 Subject: O = system:masters, CN = kubernetes-super-admin 을 가지도록 서명해요. system:masters 는 인가 계층(예: RBAC)을 우회하는 브레이크-글래스, 슈퍼유저 그룹이에요. 파일 admin.conf 도 kubeadm이 제어 플레인 노드에 만들며 Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin 인 인증서를 포함해요. kubeadm:cluster-admins 는 논리적으로 kubeadm에 속하는 그룹이에요. 클러스터가 RBAC(kubeadm 기본값)를 사용한다면 kubeadm:cluster-admins 그룹은 cluster-admin ClusterRole에 바인딩돼요.

경고:

kubeadm kubeconfig user 명령을 사용해 추가 사용자를 위한 kubeconfig 파일을 생성할 수 있어요. 이 명령은 명령줄 플래그와 kubeadm 구성 옵션의 혼합을 받아들여요. 생성된 kubeconfig는 stdout으로 기록되며 kubeadm kubeconfig user ... > somefile.conf 를 사용해 파일로 파이프할 수 있어요.

--config 와 함께 사용할 수 있는 예시 구성 파일:

# example.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
# Will be used as the target "cluster" in the kubeconfig
clusterName: "kubernetes"
# Will be used as the "server" (IP or DNS name) of this cluster in the kubeconfig
controlPlaneEndpoint: "some-dns-address:6443"
# The cluster CA key and certificate will be loaded from this local directory
certificatesDir: "/etc/kubernetes/pki"

이 설정이 원하는 대상 클러스터 설정과 일치하는지 확인해요. 기존 클러스터의 설정을 보려면:

kubectl get cm kubeadm-config -n kube-system -o=jsonpath="{.data.ClusterConfiguration}"

다음 예시는 appdevs 그룹의 일부인 새 사용자 johndoe 에 대해 24시간 유효한 자격 증명이 있는 kubeconfig 파일을 생성해요:

kubeadm kubeconfig user --config example.yaml --org appdevs --client-name johndoe --validity-period 24h

다음 예시는 1주일 유효한 관리자 자격 증명이 있는 kubeconfig 파일을 생성해요:

kubeadm kubeconfig user --config example.yaml --client-name admin --validity-period 168h

kubeadm이 생성한 인증서 서명 요청(CSR) 서명

kubeadm certs generate-csr 로 인증서 서명 요청을 만들 수 있어요. 이 명령을 호출하면 일반 인증서에 대해 .csr / .key 파일 쌍이 생성돼요. kubeconfig 파일에 포함된 인증서의 경우 이 명령은 키가 이미 .conf 파일에 포함된 .csr / .conf 쌍을 생성해요.

CSR 파일에는 CA가 인증서를 서명하는 데 필요한 모든 관련 정보가 포함돼요. kubeadm은 모든 인증서와 CSRs에 대해 잘 정의된 사양을 사용해요.

기본 인증서 디렉토리는 /etc/kubernetes/pki 이고, kubeconfig 파일의 기본 디렉토리는 /etc/kubernetes 예요. 이 기본값은 각각 --cert-dir--kubeconfig-dir 플래그로 재정의할 수 있어요.

kubeadm certs generate-csr 에 커스텀 옵션을 전달하려면 --config 플래그를 사용해요. 이것은 kubeadm init 같은 명령과 마찬가지로 kubeadm 구성 파일을 받아들여요. 추가 SANs와 커스텀 IP 주소 같은 어떤 사양도 같은 구성 파일에 저장되어 관련 모든 kubeadm 명령에 --config 로 전달되어 사용되어야 해요.

참고:

이 가이드는 기본 쿠버네티스 디렉토리 /etc/kubernetes 를 사용하며, 이는 슈퍼유저가 필요해요. 이 가이드를 따르면서 쓸 수 있는 디렉토리를 사용한다면(보통 --cert-dir--kubeconfig-dirkubeadm 을 실행하는 것을 의미) sudo 명령을 생략할 수 있어요.

그런 다음 만든 파일을 /etc/kubernetes 디렉토리 안으로 복사해서 kubeadm init 이나 kubeadm join 이 찾을 수 있게 해야 해요.

CA와 Service Account 파일 준비

kubeadm init 이 실행될 기본 제어 플레인 노드에서 다음 명령을 호출해요:

sudo kubeadm init phase certs ca
sudo kubeadm init phase certs etcd-ca
sudo kubeadm init phase certs front-proxy-ca
sudo kubeadm init phase certs sa

이렇게 하면 /etc/kubernetes/pki/etc/kubernetes/pki/etcd 폴더가 제어 플레인 노드에 kubeadm이 필요한 모든 자체 서명 CA 파일(인증서와 키)과 Service Account(공개·개인 키)로 채워져요.

참고:

외부 CA를 사용한다면 같은 파일을 대역외로 생성해 기본 제어 플레인 노드의 /etc/kubernetes 에 수동으로 복사해야 해요.

모든 CSRs가 서명되면 External CA mode 섹션에 언급된 대로 루트 CA 키(ca.key)를 삭제할 수 있어요.

보조 제어 플레인 노드(kubeadm join --control-plane)에서는 위 명령을 호출할 필요가 없어요. 고가용성 클러스터를 어떻게 설정하는지에 따라 기본 제어 플레인 노드에서 같은 파일을 수동으로 복사하거나 kubeadm init 의 자동 --upload-certs 기능을 사용해야 해요.

CSRs 생성하기

kubeadm certs generate-csr 명령은 kubeadm이 관리하는 모든 알려진 인증서에 대한 CSRs를 생성해요. 명령이 끝나면 필요하지 않은 .csr, .conf 또는 .key 파일을 수동으로 삭제해야 해요.

kubelet.conf 고려 사항

이 섹션은 제어 플레인과 워커 노드 모두에 적용돼요.

제어 플레인 노드에서 ca.key 파일을 삭제했다면(External CA mode), 이 클러스터의 활성 kube-controller-manager는 kubelet 클라이언트 인증서를 서명할 수 없을 거예요. 설정에 이 인증서를 서명하는 외부 방법(예: external signer)이 없다면 이 가이드에서 설명한 대로 kubelet.conf.csr 를 수동으로 서명할 수 있어요.

이것은 자동 kubelet 클라이언트 인증서 회전이 비활성화됨을 의미하기도 해요. 그런 경우 인증서 만료에 가까워지면 새 kubelet.conf.csr 를 생성하고, 인증서를 서명해 kubelet.conf 에 포함시키고 kubelet을 재시작해야 해요.

이것이 설정에 적용되지 않는다면 보조 제어 플레인과 워커 노드(kubeadm join ... 을 호출하는 모든 노드)에서 kubelet.conf.csr 처리를 건너뛸 수 있어요. 그 이유는 활성 kube-controller-manager가 새 kubelet 클라이언트 인증서를 서명하는 책임을 질 것이기 때문이에요.

참고:

제어 플레인 노드

모든 CSR 파일을 생성하기 위해 기본(kubeadm init) 및 보조(kubeadm join --control-plane) 제어 플레인 노드에서 다음 명령을 실행해요:

sudo kubeadm certs generate-csr

외부 etcd를 사용한다면 kubeadm과 etcd 노드에 어떤 CSR 파일이 필요한지 이해하기 위해 kubeadm의 외부 etcd 가이드를 따라요. /etc/kubernetes/pki/etcd 아래의 다른 .csr.key 파일은 제거할 수 있어요.

kubelet.conf 고려 사항의 설명에 따라 kubelet.confkubelet.conf.csr 파일을 유지하거나 삭제해요.

워커 노드

kubelet.conf 고려 사항의 설명에 따라 선택적으로 다음을 호출해요:

sudo kubeadm certs generate-csr

그리고 kubelet.confkubelet.conf.csr 파일만 유지해요. 또는 워커 노드의 단계를 완전히 건너뛰어도 돼요.

모든 인증서에 대한 CSRs 서명

참고:

외부 CA를 사용하고 이미 openssl 용 CA 일련 번호 파일(.srl)이 있다면 그 파일을 CSRs가 처리될 kubeadm 노드에 복사할 수 있어요. 복사할 .srl 파일은 /etc/kubernetes/pki/ca.srl, /etc/kubernetes/pki/front-proxy-ca.srl, /etc/kubernetes/pki/etcd/ca.srl 이에요. 그런 다음 파일을 CSR 파일이 처리될 새 노드로 옮길 수 있어요.

노드의 CA에 .srl 파일이 없으면 아래 스크립트가 임의 시작 일련 번호로 새 SRL 파일을 생성할 거예요.

.srl 파일에 대해 더 읽으려면 --CAserial 플래그의 openssl 문서를 참고해요.

CSR 파일이 있는 모든 노드에서 이 단계를 반복해요.

/etc/kubernetes 디렉토리에 다음 스크립트를 작성하고 디렉토리로 이동해 스크립트를 실행해요. 스크립트는 /etc/kubernetes 트리에 있는 모든 CSR 파일에 대한 인증서를 생성할 거예요.

#!/bin/bash

# Set certificate expiration time in days
DAYS=365

# Process all CSR files except those for front-proxy and etcd
find ./ -name "*.csr" | grep -v "pki/etcd" | grep -v "front-proxy" | while read -r FILE;
do
    echo "* Processing ${FILE} ..."
    FILE=${FILE%.*} # Trim the extension
    if [ -f "./pki/ca.srl" ]; then
        SERIAL_FLAG="-CAserial ./pki/ca.srl"
    else
        SERIAL_FLAG="-CAcreateserial"
    fi
    openssl x509 -req -days "${DAYS}" -CA ./pki/ca.crt -CAkey ./pki/ca.key ${SERIAL_FLAG} \
        -in "${FILE}.csr" -out "${FILE}.crt"
    sleep 2
done

# Process all etcd CSRs
find ./pki/etcd -name "*.csr" | while read -r FILE;
do
    echo "* Processing ${FILE} ..."
    FILE=${FILE%.*} # Trim the extension
    if [ -f "./pki/etcd/ca.srl" ]; then
        SERIAL_FLAG=-CAserial ./pki/etcd/ca.srl
    else
        SERIAL_FLAG=-CAcreateserial
    fi
    openssl x509 -req -days "${DAYS}" -CA ./pki/etcd/ca.crt -CAkey ./pki/etcd/ca.key ${SERIAL_FLAG} \
        -in "${FILE}.csr" -out "${FILE}.crt"
done

# Process front-proxy CSRs
echo "* Processing ./pki/front-proxy-client.csr ..."
openssl x509 -req -days "${DAYS}" -CA ./pki/front-proxy-ca.crt -CAkey ./pki/front-proxy-ca.key -CAcreateserial \
    -in ./pki/front-proxy-client.csr -out ./pki/front-proxy-client.crt

kubeconfig 파일에 인증서 포함하기

CSR 파일이 있는 모든 노드에서 이 단계를 반복해요.

/etc/kubernetes 디렉토리에 다음 스크립트를 작성하고 디렉토리로 이동해 스크립트를 실행해요. 스크립트는 이전 단계의 CSRs에서 kubeconfig 파일용으로 서명된 .crt 파일을 가져와 kubeconfig 파일에 포함시킬 거예요.

#!/bin/bash

CLUSTER=kubernetes
find ./ -name "*.conf" | while read -r FILE;
do
    echo "* Processing ${FILE} ..."
    KUBECONFIG="${FILE}" kubectl config set-cluster "${CLUSTER}" --certificate-authority ./pki/ca.crt --embed-certs
    USER=$(KUBECONFIG="${FILE}" kubectl config view -o jsonpath='{.users[0].name}')
    KUBECONFIG="${FILE}" kubectl config set-credentials "${USER}" --client-certificate "${FILE}.crt" --embed-certs
done

정리 수행

CSR 파일이 있는 모든 노드에서 이 단계를 수행해요.

/etc/kubernetes 디렉토리에 다음 스크립트를 작성하고 디렉토리로 이동해 스크립트를 실행해요.

#!/bin/bash

# Cleanup CSR files
rm -f ./*.csr ./pki/*.csr ./pki/etcd/*.csr # Clean all CSR files

# Cleanup CRT files that were already embedded in kubeconfig files
rm -f ./*.crt

선택적으로 .srl 파일을 다음에 처리할 노드로 옮겨요.

선택적으로 외부 CA를 사용한다면 External CA node 섹션에서 설명한 대로 /etc/kubernetes/pki/ca.key 파일을 제거해요.

kubeadm 노드 초기화

CSR 파일이 서명되고 필요한 인증서가 노드로 사용하려는 호스트에 준비되면 kubeadm initkubeadm join 명령을 사용해 이 노드들에서 쿠버네티스 클러스터를 만들 수 있어요. initjoin 중에 kubeadm은 호스트의 로컬 파일 시스템 /etc/kubernetes 트리에서 찾는 기존 인증서, 암호화 키, kubeconfig 파일을 사용해요.

더 알아보기 (Learn more)