CertificateSigningRequest로 쿠버네티스 API 클라이언트용 인증서 발급하기
CertificateSigningRequest로 쿠버네티스 API 클라이언트용 인증서 발급하기 (Issue a Certificate for a Kubernetes API Client Using a CertificateSigningRequest)
쿠버네티스는 공개 키 인프라(PKI)를 사용해 클라이언트로 클러스터에 인증할 수 있게 해줘요.
일반 사용자가 인증하고 API를 호출할 수 있으려면 몇 단계가 필요해요. 먼저 그 사용자는 쿠버네티스 클러스터가 신뢰하는 기관이 발급한 X.509 인증서를 가져야 해요. 그런 다음 클라이언트가 그 인증서를 쿠버네티스 API에 제시해야 해요.
이 과정의 일부로 CertificateSigningRequest를 사용하며, 사용자나 다른 프린시펄이 요청을 승인해야 해요.
개인 키를 만들고, 인증서를 발급받고, 마지막으로 그 개인 키를 클라이언트에 구성하게 돼요.
출처: 문서
본문
시작하기 전에 (Before you begin)
이 페이지는 쿠버네티스 역할 기반 접근 제어 (RBAC)를 사용한다고 가정해요. 인가에 대한 대안적이거나 추가적인 보안 메커니즘이 있다면 그것들도 고려해야 해요.
개인 키 만들기
이 단계에서 개인 키를 만들어요. 이 개인 키를 비밀로 유지해야 해요. 그것을 가진 사람은 누구나 사용자를 사칭할 수 있어요.
# Create a private key
openssl genrsa -out myuser.key 3072
X.509 인증서 서명 요청 만들기
참고:
CSR의 CN과 O 속성을 설정하는 것이 중요해요. CN은 사용자의 이름이고 O는 이 사용자가 속할 그룹이에요. 표준 그룹은 RBAC를 참고할 수 있어요.
# Change the common name "myuser" to the actual username that you want to use
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
쿠버네티스 CertificateSigningRequest 만들기
이 명령으로 CSR 문서를 인코딩해요:
cat myuser.csr | base64 | tr -d "\n"
CertificateSigningRequest를 만들고 kubectl로 쿠버네티스 클러스터에 제출해요. 아래는 CertificateSigningRequest를 생성하는 데 사용할 수 있는 셸 스니펫이에요.
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser # example
spec:
# This is an encoded CSR. Change this to the base64-encoded contents of myuser.csr
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
EOF
대안으로 YAML 매니페스트 파일을 만들고 kubectl 로 적용할 수도 있어요:
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser # example
spec:
# This is an encoded CSR. Change this to the base64-encoded contents of myuser.csr
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
매니페스트를 적용해요:
kubectl apply -f myuser.yaml --server-side
주의할 몇 가지 점:
usages는client auth여야 해요expirationSeconds는 더 길게(10일의 경우864000) 또는 더 짧게(1시간의 경우3600) 설정할 수 있어요. 10분보다 짧은 기간은 요청할 수 없어요.request는 CSR 파일 내용의 base64 인코딩 값이에요.
CertificateSigningRequest 승인하기
kubectl로 만든 CSR을 찾아 수동으로 승인해요.
CSR 목록을 가져와요:
kubectl get csr
CSR을 승인해요:
kubectl certificate approve myuser
인증서 얻기
CSR에서 인증서를 검색해 괜찮아 보이는지 확인해요.
kubectl get csr/myuser -o yaml
인증서 값은 .status.certificate 아래 Base64 인코딩 형식이에요.
CertificateSigningRequest에서 발급된 인증서를 내보내요.
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
인증서를 kubeconfig로 구성하기
다음 단계는 이 사용자를 kubeconfig 파일에 추가하는 것이에요.
먼저 새 자격 증명을 추가해야 해요:
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
그런 다음 컨텍스트를 추가해요:
kubectl config set-context myuser --cluster=kubernetes --user=myuser
테스트하려면:
kubectl --context myuser auth whoami
자신이 "myuser"라는 것을 확인하는 출력이 보여야 해요.
Role과 RoleBinding 만들기
참고:
인증서가 생성됐으니 이제 이 사용자가 쿠버네티스 클러스터 리소스에 접근할 수 있도록 Role과 RoleBinding을 정의할 차례예요.
이 새 사용자를 위한 Role을 만드는 샘플 명령은 다음과 같아요:
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
동등한 YAML:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "update", "delete"]
이 새 사용자를 위한 RoleBinding을 만드는 샘플 명령은 다음과 같아요:
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
동등한 YAML:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding-myuser
subjects:
- kind: User
name: myuser
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
더 알아보기 (Learn more)
- 클러스터에서 TLS 인증서 관리 읽기
- X.509 자체의 세부 사항은 RFC 5280 섹션 3.1 참고
- PKCS#10 인증서 서명 요청 문법에 대한 정보는 RFC 2986 참고
- ClusterTrustBundles 읽기