[CKA] Kubernetes 인증서 생성
Kubernetes 인증서 생성의 핵심 개념과 구성 방법, 실습 풀이를 정리합니다.
해당 문서에서는 openSSL을 통한 쿠버네티스 인증서를 생성하는 과정을 알아봅니다.
- Root Certificate: 클러스터의 CA 인증서로, 모든 다른 인증서의 유효성을 검증하는 데 사용됩니다.
- Client Certificate: 각 컴포넌트(예: kubelet, kube-proxy) 또는 사용자가 API 서버에 인증할 때 사용하는 인증서입니다.
Root Certificate
openssl genrsa -out ca.key 2048
openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
openSSL에서 키와 인증서를 생성하고 인증서에 서명하는 방식입니다.
Client Certificate
Admin User
openssl genrsa -out admin.key 2048
openssl req -new -key admin.key -subj "/CN=kube-admin/O=system:masters" -out admin.csr
openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out admin.crt -days 365
- 용도:
- 첫 번째는 CA 인증서를 생성 (신뢰의 루트)
- 두 번째는 관리자 인증서를 생성 (CA에 의해 신뢰됨)
- 서명 방식:
- CA 인증서는 자체 서명됨 (-signkey ca.key)
- 관리자 인증서는 CA에 의해 서명됨 (–CA ca.crt -CAkey ca.key)
- 두 번째 인증서는 앞서 생성한 CA로 인해 클러스터 내 유효한 인증서가 됩니다.
일반 사용자의 인증서도 관리자 인증서가 아니라 CA 개인 키 또는 클러스터에 구성된 signer가 서명합니다.
X.509 인증서의 Organization(O) 필드는 Kubernetes 사용자 그룹으로 해석됩니다. 예제의 O=system:masters는 관리자에게 사실상 무제한 권한을 부여하기 위한 선택이며 일반 사용자 인증서에 반드시 넣는 값이 아닙니다.
그 외 kubeapi-server에 대해 엑세스하는 클라이언트 인증서를 생성하는 프로세스는 같습니다.
openssl genrsa -out controller-manager.key 2048
openssl req -new -key controller-manager.key -subj "/CN=system:kube-controller-manager" -out controller-manager.csr
openssl x509 -req -in controller-manager.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out controller-manager.crt -days 365
- 클라이언트는 자신의 인증서(client-certificate)와 개인 키(client-key)를 사용해 서버에 인증합니다.
- 동시에 CA 인증서(certificate-authority)를 사용해 서버의 인증서가 신뢰할 수 있는지 확인합니다.
- 키(private key):
- 자신의 신원을 증명하는 데 사용됩니다.
- 비공개로 유지되며, 절대 공유되지 않습니다.
- 인증서(certificate):
- 공개 키와 신원 정보를 포함합니다.
- CA에 의해 서명되어 있습니다.
- 통신 상대방에게 제공하여 자신의 신원을 증명합니다.
- CA 인증서(ca-cert):
- 인증 기관(CA)의 공개 인증서입니다.
- 통신 상대방의 인증서가 신뢰할 수 있는 CA에 의해 서명되었는지 확인하는 데 사용됩니다.
- 이를 통해 제시된 인증서의 유효성을 검증할 수 있습니다.
ca-cert
기본적으로 웹 브라우저에는 모든 CA 기관에 대한 인증서의 사본이 존재합니다.
하지만 쿠버네티스로 생성한 커스텀한 CA 인증서의 경우 사용자의 환경에 없기 때문에 CA 루트 인증서 복사본을 넣어 자체 인증 기관(CA)에서 발급한 인증서라는 것을 명시해야합니다.
etcd 고가용성
추가 피어 인증서를 생성해야합니다.
etcd 서버를 시작하는 동안 지정하며 피어 인증서를 지정하는 옵션이 존재합니다.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: etcd
tier: control-plane
name: etcd
namespace: kube-system
spec:
containers:
- command:
- etcd
- --advertise-client-urls=https://192.0.2.10:2379
- --cert-file=/etc/kubernetes/pki/etcd/server.crt #
- --client-cert-auth=true
- --data-dir=/var/lib/etcd
- --initial-advertise-peer-urls=https://192.0.2.10:2380
- --initial-cluster=control-plane=https://192.0.2.10:2380
- --key-file=/etc/kubernetes/pki/etcd/server.key #
- --listen-client-urls=https://127.0.0.1:2379,https://192.0.2.10:2379
- --listen-metrics-urls=http://127.0.0.1:2381
- --listen-peer-urls=https://192.0.2.10:2380
- --name=control-plane
- --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt #
- --peer-client-cert-auth=true #
- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key #
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt #
- --snapshot-count=10000
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt #
kube-apiserver
kube-apiserver의 경우 많은 작업들이 이루어지는 만큼 Kube API 서버용 인증서에는 kube-apiserver를 지칭하는 모든 이름과 별칭이 포함되어야 합니다.
아래 구성을 전달하여 루트 인증서를 통해 최종 서명해야합니다.
특히 api server의 경우 etcd와 kubelet간 연결에 클라언트로 활용될 수 있어 클라이언트에서 오는 요청들과 etcd, kubelet간 연결을 고려하여 인증서를 입력해야합니다.
kubelet의 경우
kubelet은 각 노드에 실행되며 노드 관리에 책임이 있기에 클러스터상 각 노드에 대해 키와 인증서 쌍이 필요합니다. 인증서의 이르은 각 노드별 이름으로 구성하여 kubelet 설정을 구성해야합니다.
특히 어떤 노드가 어떤 작업을 하는지 알아야하며 올바른 권한 세트를 할당하기 위해서 노드의 이름은 중요하며 노드 또한 마찬가지로 시스템 노드라는 그룹에 노드를 추가하여 구성합니다.