만료된 클러스터 인증서 수동 갱신

이 문서에서는 베어메탈용 GKE에 대해 만료된 인증서를 수동으로 갱신하는 방법을 설명합니다. 전송 계층 보안(TLS) 인증서는 베어메탈용 GKE의 제어 영역 구성요소에서 사용됩니다. 인증서가 만료되면 인증서를 갱신할 때까지 워크로드 및 클러스터 수명 주기를 관리하는 기능이 차단됩니다. 만료된 인증서가 미치는 영향에 대한 자세한 내용은 인증서 만료를 참조하세요.

기본적으로 TLS 인증서의 유효 기간은 1년입니다. 베어메탈용 GKE는 클러스터 업그레이드 중에, 그리고 인증 기관 순환 시에 이러한 인증서를 자동으로 갱신합니다. 보안과 지원을 유지하고 TLS 인증서가 만료되지 않도록 클러스터를 정기적으로 업그레이드하는 것이 좋습니다.

인증서 만료로 인한 오류

클러스터의 TLS 인증서가 만료되면 핵심 컨트롤러가 Kubernetes API 서버와의 TLS 연결을 설정할 수 없습니다. 연결되지 않으면 다음과 같은 오류가 발생합니다.

  • Unable to connect to the server: x509: Unable to connect to the server

    kubectl을 사용하여 클러스터 노드를 가져오면 응답에 인증서 만료를 참조하는 오류가 포함됩니다.

    kubectl get nodes --kubeconfig KUBECONFIG_PATH
    

    KUBECONFIG_PATH를 클러스터의 kubeconfig 파일 경로로 바꾸세요.

    인증서가 만료된 경우 응답은 다음과 같습니다.

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • could not connect: x509 또는 rejected connection

    피어는 서로 통신할 수 없으므로 만료된 인증서가 etcd 클러스터에 대한 액세스를 차단합니다. etcd 로그에는 다음과 같은 오류 항목이 포함될 수 있습니다.

    W | rafthttp: health check for peer 6221a1d241bb2d0a could not connect: x509: certificate
    has expired or is not yet valid
    I | embed: rejected connection from "10.200.0.4:46108" (error "remote error: tls: bad
    certificate", ServerName "")
    

인증서 만료 시간 확인

이 섹션에서는 클러스터에서 사용하는 인증서의 만료 시간을 확인하는 방법을 설명합니다. 각 제어 영역 노드에서 다음 절차르ㄹ 수행하세요.

인증서 만료 시간을 확인하려면 다음 안내를 따르세요.

  1. 제어 영역 노드 머신 중 하나에 로그인하고 다음 명령어를 실행합니다.

    sudo kubeadm certs check-expiration
    

    명령어 결과에는 제어 영역 구성요소에 대해 kubeadm에서 생성한 인증서와 만료가 나열됩니다.

    CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
    admin.conf                 Nov 28, 2021 19:09 UTC   53m                                     no
    apiserver                  Nov 28, 2021 19:09 UTC   53m             ca                      no
    apiserver-etcd-client      Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    apiserver-kubelet-client   Nov 28, 2021 19:09 UTC   53m             ca                      no
    controller-manager.conf    Nov 28, 2021 19:09 UTC   53m                                     no
    etcd-healthcheck-client    Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-peer                  Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-server                Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    front-proxy-client         Nov 28, 2021 19:09 UTC   53m             front-proxy-ca          no
    scheduler.conf             Nov 28, 2021 19:09 UTC   53m                                     no
    
    CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
    ca                      Nov 26, 2031 18:06 UTC   9y              no
    etcd-ca                 Nov 26, 2031 18:06 UTC   9y              no
    front-proxy-ca          Nov 26, 2031 18:06 UTC   9y              no
    
  2. 다음 명령어를 실행하여 kubelet 인증서의 만료 시간을 확인합니다.

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    각 명령어의 응답은 다음 출력과 같습니다.

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

    모든 제어 영역 노드가 동시에 부트스트랩된 경우 각각의 인증서 만료 시간이 몇 분 이내로 차이 납니다. 이러한 시간 관계는 모든 제어 영역 노드에 적용됩니다. 각 제어 영역 노드에서 위의 명령어를 실행하여 만료 시간을 확인할 수 있습니다.

  3. 관리자 워크스테이션에서 다음 명령어를 실행하여 클러스터의 kubeconfig 파일에서 클라이언트 인증서의 만료 시간을 확인합니다.

    grep 'client-certificate-data' KUBECONFIG_PATH | \
        awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    

    응답은 다음 샘플 출력과 같습니다.

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    
  4. 다음 명령어를 실행하여 관리자 클러스터에서 클러스터 kubeconfig의 인증서 만료에 관해 조회합니다.

    kubectl get secret/CLUSTER_NAME-kubeconfig -n CLUSTER_NAMESPACE -o --kubeconfig=ADMIN_KUBECONFIG jsonpath='{.data.value}' | base64 --decode | grep client-certificate-data | awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    
    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

    관리자 클러스터의 kubeconfig 인증서와 관리자 워크스테이션의 kubeconfig 파일 인증서는 동일합니다. 따라서 이 명령어와 이전 단계 명령어의 결과가 일치해야 합니다.

수동으로 인증서 갱신

클러스터의 TLS 인증서를 수동으로 갱신하려면 다음 섹션의 안내를 사용합니다.

각 제어 영역 노드에서 인증서 갱신

영향을 받는 클러스터의 각 제어 영역 노드에서 다음 절차를 수행하세요.

  1. /etc/kubernetes 폴더를 백업합니다.

  2. 다음 kubeadm 명령어를 실행하여 모든 인증서를 갱신합니다.

    이 명령어는 머신에서 기존 인증 기관(CA)을 사용하여 인증서를 갱신합니다.

    sudo kubeadm certs renew all
    

    명령어 결과는 다음 예시와 비슷합니다.

    certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
    certificate for serving the Kubernetes API renewed
    certificate the apiserver uses to access etcd renewed
    certificate for the API server to connect to kubelet renewed
    certificate embedded in the kubeconfig file for the controller manager to use renewed
    certificate for liveness probes to healthcheck etcd renewed
    certificate for etcd nodes to communicate with each other renewed
    certificate for serving etcd renewed
    certificate for the front proxy client renewed
    certificate embedded in the kubeconfig file for the scheduler manager to use renewed
    
  3. 다음 명령어를 실행하여 인증서에 새로운 만료 시간이 있는지 확인합니다.

    sudo kubeadm certs check-expiration
    
  4. 다음 명령어를 사용하여 컨테이너를 다시 시작합니다.

    모든 제어 영역 구성요소가 동적 인증서 새로고침을 지원하지는 않으므로 이 단계에서 kube-apiserver ,kube-scheduler ,kube-controller-manager, etcd 컨테이너를 다시 시작하여 갱신된 인증서를 선택합니다.

    4개의 컨테이너 각각에 대해 다음 단계를 반복합니다.

    1. 각 컨테이너의 컨테이너 ID를 찾습니다.

      sudo crictl ps | grep CONTAINER_NAME
      

      CONTAINER_NAMEkube-apiserver, kube-scheduler, kube-controller-manager 또는 etcd(etcd-defrag 아님) 컨테이너 이름으로 바꿉니다.

      응답은 다음 출력과 유사합니다.

      c331ade490cb6       28df10594cd92      26 hours ago       Running          kube-apiserver ...
      

      컨테이너 ID는 첫 번째 열의 값입니다.

    2. 각 컨테이너를 중지합니다.

      sudo crictl stop CONTAINER_ID
      

      CONTAINER_ID를 이전 단계의 컨테이너 ID로 바꿉니다.

      중지된 컨테이너가 종료되면 kubelet이 해당 위치에 새 컨테이너를 만들고 중지된 컨테이너를 삭제합니다. context deadline exceeded(오류 코드 DeadlineExceeded)와 같은 오류가 발생하면 명령어를 다시 실행합니다.

연결이 복원되었는지 확인

이 단계에서 kubeadm 인증서가 모든 제어 영역 노드에서 갱신되어야 합니다. 만료된 인증서를 갱신하는 경우 다음 단계를 수행합니다.

  • Kubernetes API 서버와의 연결을 확인하려면 제어 영역 노드에서 다음 kubectl 명령어를 실행합니다.

    kubectl get nodes --kubeconfig=/etc/kubernetes/admin.conf
    

응답으로 클러스터의 노드 목록이 반환됩니다. 인증서 갱신이 올바르게 이루어진 경우 TLS 또는 인증서 오류가 반환되지 않습니다.

클러스터 kubeconfig 파일 바꾸기

클러스터의 kubeconfig 파일을 갱신된 인증서가 있는 파일로 바꾸려면 다음 절차를 진행합니다.

  1. 새 kubeconfig 파일을 만들려면 관리자 워크스테이션에서 다음 kubectl 명령어를 실행하세요.

    kubectl --kubeconfig="ADMIN_KUBECONFIG" get secret/CLUSTER_NAME-kubeconfig  \
        -n "CLUSTER_NAMESPACE"  -o jsonpath='{.data.value}'  | base64 --decode > new_kubeconfig.conf
    

    다음을 바꿉니다.

    • ADMIN_KUBECONFIG: 관리자 클러스터 kubeconfig 파일의 경로

    • CLUSTER_NAME: 인증서를 갱신할 클러스터의 이름

    • CLUSTER_NAMESPACE: 인증서를 갱신할 클러스터의 네임스페이스

    new_kubeconfig.conf 파일에는 업데이트된 인증서 데이터가 포함되어 있습니다.

  2. 새 사용자 인증 정보를 사용하여 kubectl 명령어를 실행해 새 kubeconfig가 작동하는지 확인합니다.

    kubectl get nodes --kubeconfig new_kubeconfig.conf
    
  3. 관리자 워크스테이션의 클러스터 디렉터리에 저장된 이전 kubeconfig 파일의 콘텐츠를 새 kubeconfig 파일 new-kubeconfig.conf의 콘텐츠로 바꿉니다.

    기본적으로 클러스터 구성 파일의 경로는 bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig입니다.

kubelet 인증서 확인 및 etcd-defrag 재시작

클러스터 인증서를 수동으로 갱신하는 프로세스를 완료하려면 각 제어 영역 노드에 다음 단계를 수행합니다.

  1. 제어 영역 노드에 로그인하고 다음 명령어를 실행하여 kubelet 클라이언트와 서빙 인증서 만료 시간을 확인합니다.

    kubelet 인증서는 제어 영역에 연결할 수 있는 한 자동으로 순환됩니다. kubelet 인증서의 자동 갱신 기간은 제어 영역 구성요소 인증서의 만료 기간보다 짧습니다. 따라서 kubelet 인증서가 이전에 갱신되었을 가능성이 높습니다.

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    두 명령어의 결과는 다음 예시와 비슷합니다.

    Validity
        Not Before: Nov 28 18:04:57 2022 GMT
        Not After : Nov 28 19:04:57 2023 GMT
    
  2. 다음 명령어를 사용하여 etcd-defrag 컨테이너를 다시 시작합니다.

    etcd-defrag 컨테이너가 apiserver-etcd 클라이언트 인증서를 사용하여 etcd와 통신하며 다시 시작하여 업데이트된 인증서를 선택해야 합니다.

    kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
    

클러스터 인증서를 갱신하기 위한 수동 단계를 완료했습니다. 모든 포드가 올바르게 실행 중이고 제어 영역 컨테이너에 TLS 오류가 보고되지 않는 상태인지 확인합니다.