인증서 API와 KubeConfig
- 16.1 Certificates API
- 16.2 KubeConfig
인증서를 수동으로 서명하던 시절은 끝났어. Kubernetes에는 인증서 발급을 자동화하는 API가 있고, 발급받은 인증서를 편하게 쓰려면 kubeconfig 파일이 필요해. 이번 장에서는 Certificates API로 인증서를 관리하는 흐름과, kubeconfig의 구조를 같이 살펴보자.
CA 서버란 결국 우리가 생성한 키 파일(ca.key)과 인증서 파일(ca.crt) 쌍이야. 이 파일에 접근할 수 있는 사람은 누구든 Kubernetes 환경의 모든 인증서에 서명할 수 있어. 원하는 권한을 가진 사용자를 원하는 만큼 만들 수 있다는 뜻이지. 그래서 이 파일은 안전한 서버에 보관해야 하고, 그 서버가 곧 CA 서버가 돼. 현재는 마스터 노드에 인증서가 배치되어 있으니까 마스터 노드가 CA 서버인 셈이야. kubeadm도 같은 방식으로 CA 쌍 파일을 마스터 노드에 저장해.
새 관리자가 팀에 들어오면 인증서가 필요한데, 수동으로 하는 절차는 이래. 새 관리자가 개인 키를 생성하고 CSR을 만들어서 기존 관리자에게 보내. 기존 관리자가 CA 서버에 로그인해서 CA 키로 서명하고 인증서를 만들어서 돌려줘. 인증서에는 유효 기간이 있으니까 만료될 때마다 이 과정을 반복해야 하고. 사용자가 늘어나면 이걸 수동으로 하기 힘들어지겠지.
Kubernetes에는 이 작업을 자동화하는 Certificates API가 내장되어 있어. API 호출로 인증서 서명 요청을 보내고, 관리자가 kubectl 명령으로 승인하면 끝이야.
동작 흐름은 이래. 사용자가 먼저 키를 만들고 자기 이름이 포함된 CSR을 생성해서 관리자에게 보내. 관리자는 마스터 노드에 로그인해서 직접 서명하는 대신, CertificateSigningRequest라는 Kubernetes API 오브젝트를 만들어.
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: jane
spec:
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 600
usages:
- client auth
request: <base64 인코딩된 CSR>
request 필드에는 사용자가 보낸 CSR을 그대로 넣는 게 아니라 base64로 인코딩해서 넣어야 해. cat jane.csr | base64 | tr -d '\n' 이런 식으로.
오브젝트가 만들어지면 관리자는 모든 CSR을 볼 수 있어.
kubectl get csr
새 요청을 찾아서 승인하면 돼.
kubectl certificate approve jane
Kubernetes가 CA 키 쌍을 사용해서 인증서에 서명하고 사용자에 대한 인증서를 생성해. 인증서를 확인하려면 YAML 형식으로 보면 되는데, 생성된 인증서도 base64 인코딩 형식이야. 디코딩하려면 base64 유틸리티의 디코딩 옵션을 쓰면 일반 텍스트 인증서를 얻을 수 있어. 그걸 사용자에게 공유하면 끝이야.
실제로 이 모든 인증서 관련 작업을 수행하는 건 kube-controller-manager야. 컨트롤러 매니저를 자세히 보면 CSR-Approving, CSR-Signing 같은 컨트롤러가 있어. 인증서에 서명하려면 CA 서버의 루트 인증서와 개인 키가 필요하잖아. 컨트롤러 매니저 설정에 이걸 지정하는 두 가지 옵션이 있어. --cluster-signing-cert-file과 --cluster-signing-key-file이야. 이 옵션이 있어야 컨트롤러 매니저가 인증서에 서명할 수 있어.
인증서를 발급받았으면 이제 그걸 실제로 쓸 차례야. 근데 매번 curl이나 kubectl 명령에 인증서 경로, 키 경로, CA 인증서 경로, 서버 주소를 지정해야 한다면 너무 귀찮지. 그래서 이 정보를 kubeconfig라는 구성 파일에 넣어두면 자동으로 사용되는 거야.
기본적으로 kubectl은 사용자 홈 디렉터리 아래 .kube 폴더에서 config라는 파일을 찾아. ~/.kube/config 경로에 파일을 만들어두면 명령에서 따로 지정할 필요가 없어. 지금까지 kubectl 명령에 옵션을 지정하지 않았던 것도 이 파일 덕분이야.
kubeconfig 파일은 YAML 형식으로, 세 가지 섹션으로 구성돼. Clusters, Users, Contexts야.
Clusters는 접근해야 하는 다양한 Kubernetes 클러스터 목록이야. 개발 환경, 테스트 환경, 프로덕션 환경, 다른 클라우드 공급자 클러스터 등을 여기에 등록해. 서버 주소와 CA 인증서 정보가 들어가.
Users는 이 클러스터들에 접근할 수 있는 사용자 계정이야. 관리자, 개발자, 프로덕션 사용자 등. 각 사용자는 클라이언트 인증서와 키 경로를 갖고 있어. 이 사용자들은 클러스터마다 다른 권한을 가질 수 있어.
Contexts가 이 두 가지를 연결해. 어떤 사용자 계정이 어떤 클러스터에 접근하는 데 사용될지를 정의하는 거야. 예를 들어 "admin@production"이라는 컨텍스트는 관리자 계정으로 프로덕션 클러스터에 접근하겠다는 뜻이야. 여기서 중요한 건, 컨텍스트가 새 사용자를 만들거나 권한을 설정하는 게 아니라는 거야. 기존 권한을 가진 기존 사용자를 사용해서 어떤 클러스터에 접근할지를 매핑하는 거야.
apiVersion: v1
kind: Config
current-context: dev-user@google
clusters:
- name: my-kube-playground
cluster:
certificate-authority: /etc/kubernetes/pki/ca.crt
server: https://my-kube-playground:6443
users:
- name: my-kube-admin
user:
client-certificate: /path/to/admin.crt
client-key: /path/to/admin.key
contexts:
- name: my-kube-admin@my-kube-playground
context:
cluster: my-kube-playground
user: my-kube-admin
namespace: finance
current-context 필드로 기본 컨텍스트를 지정할 수 있어. kubectl이 어떤 컨텍스트부터 시작할지를 결정하는 거지. 컨텍스트에는 namespace 필드를 추가해서 특정 네임스페이스로 자동 전환되게 할 수도 있어.
파일이 준비되면 다른 Kubernetes 오브젝트처럼 kubectl create로 만드는 게 아니야. 파일은 그대로 두고 kubectl이 직접 읽어서 필요한 값을 사용하는 거야.
# 현재 kubeconfig 보기
kubectl config view
# 특정 kubeconfig 파일 사용
kubectl config view --kubeconfig=/path/to/custom-config
# 컨텍스트 전환
kubectl config use-context prod-user@production
kubectl config 명령으로 변경한 내용은 실제로 파일에 반영돼. 파일을 직접 수정해도 되고, 명령을 써서 항목을 수정하거나 삭제할 수도 있어.
인증서를 지정하는 방법도 두 가지가 있어. certificate-authority 필드에 파일 경로를 쓰는 게 하나고, certificate-authority-data 필드에 인증서 내용 자체를 base64 인코딩해서 넣는 게 다른 하나야. 전체 경로를 쓰는 방식이 더 권장되긴 해. base64로 인코딩된 인증서 데이터를 보면 디코딩 옵션으로 원래 인증서를 확인할 수 있어.
정리
16장 읽고 기억할 거 세 가지:
- Certificates API를 쓰면 CSR 오브젝트를 만들고
kubectl certificate approve로 승인하는 것만으로 인증서 발급이 끝나고, 실제 서명은 kube-controller-manager의 CSR-Signing 컨트롤러가 처리한다. - kubeconfig는 Clusters, Users, Contexts 세 섹션으로 구성되며, Context가 "어떤 사용자로 어떤 클러스터에 접근할지"를 매핑하는 역할을 한다.
- kubeconfig 파일은
kubectl create로 만드는 게 아니라~/.kube/config에 두면 kubectl이 자동으로 읽고,kubectl config use-context로 컨텍스트를 전환할 수 있다.