Certificates(인증서)
인증서는 Kubernetes 클러스터 내 구성 요소(예: kube-apiserver, kubelet, etcd) 간의 TLS 통신을 암호화하고 인증하는 데 사용된다. 각 구성 요소는 인증서를 통해 서로의 신원을 확인하고, 안전하게 통신할 수 있다.
- 클라이언트 인증서:
- 클라이언트(예: kubectl)가 API 서버에 접근할 때 자신의 신원 증명
- kubectl은 --client-certificate와 --client-key 옵션을 사용해 인증서를 지정
- 서버 인증서:
- 서버(API 서버, kubelet, etcd)가 클라이언트에게 자신의 신원 증명
- 서버는 TLS 연결을 암호화하고, CA 인증서를 사용해 신뢰 보장
- CA(Certificate Authority) 인증서:
- 인증서를 발급하고, 클라이언트와 서버의 신뢰 보장
CertificateSigningRequest(CSR)
CSR은 TLS 인증서를 발급받기 위해 생성되는 요청(공개키, CN등 각종 정보)이다.
참고 문서 : https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/
- Private key 만들기
$ openssl genrsa -out myuser.key 2048
$ openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
- CSR 만들기
controlplane ~ ➜ cat akshay.csr | base64 -w 0
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZV3R6YUdGNU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQXovTDFRWnRWM24wTmE1bDlKTEVSQlRTTlRsd0E3enFQTlFScFRBRkQ2djBMCnRka1BtTTVPejl0cEs1VVRiWWI0WXVKQTJqWS9LQmlHM3BHZ2NFWURhNlFsT1I5dTEyeE1wTXgzNHNpSFlWbFAKMU5JNFBVenpTclRqdWxCMmxFZGZKYWd3WjVCaGRsSU8yRTI2cDBZdGV5d1N1KzZmVTlLcEJJNC91Qzd4bjZOSwovRkhyZ0hyTldMdThWc0lCdU1SK2FxVG9COW02dkpoZzU1bXlYT1NPWW5mSS8zeG9POFRraFRWWlhLUy9vZU53CmN1V1hjRXd5TWVGakwrL24xbHZWRWtISlNob045LzRQRG9RVHJsZmwxYkhmOXhXRXVRdnZhK0ppV3dWTHlmYUgKT0dseWtWQlVmdGlhenEyMStFNDA5SnZyN0JWSU9CR0tQWVpJMEJPRG53SURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR01oNjhSZ29XT0t3NGpuM2pFTXhtSUdwa3ZodkpPVWJudTkxcHhEVnJiTVBmTUpwdkVCCmFKbVVoMzdGaVJFaVRYUVdpMjdWdG8yRU9VOXJ1UzRSMXFTT1o4ZHVBY05VSTNYVU9tWkRXdHA1NlpiQi94RW4KS3lMYzlza2x2TE9wUDNhNWtEZlJNZUI3SFc1eDUza1krMUIvOHUzbEUrOWVvVmJJdW9PYVpyMmtPbnRUMWs4TApwakgwSDRtRkZZYTBhaFg0eE5ndU4yZENMR0hrd1ZQQ1J4eDdURmo1bFZ3RTg1VmpHTXJEUDlrYkltTkRYeE4xCjNSTDArM1I3WFZNeVFQb1N2eVl5bHR5emN4ZnF0Mm5saU9Xci91YjRoL2JGV09zUG93cTlNQXVFV1kzK1Iva0sKZ0ZGT0trTUI1aHVXbEh1aEJTL2d3YUJCNUh5dEo1WTE5YnM9Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
controlplane ~ ➜ cat > akshay.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: akshay
spec:
request: <bas64 인코딩된 csr 붙여넣기>
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
controlplane ~ ➜ kubectl create -f akshay.yaml
certificatesigningrequest.certificates.k8s.io/akshay created
controlplane ~ ➜ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
akshay 19s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Pending
csr-4tkvt 12m kubernetes.io/kube-apiserver-client-kubelet system:node:controlplane <none> Approved,Issued
- CSR Approve
controlplane ~ ➜ kubectl certificate approve akshay
certificatesigningrequest.certificates.k8s.io/akshay approved
controlplane ~ ➜ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
akshay 20m kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued
csr-4tkvt 33m kubernetes.io/kube-apiserver-client-kubelet system:node:controlplane <none> Approved,Issued
- CSR로부터 Ceritificate 조회하기
controlplane ~ ➜ kubectl get csr agent-smith -o yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
creationTimestamp: "2025-01-13T07:53:48Z"
name: agent-smith
resourceVersion: "3101"
uid: 5df8a2bc-57ee-490b-9ec1-cf8cc59ec11f
spec:
groups:
- system:masters
- system:authenticated
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1dEQ0NBVUFDQVFBd0V6RVJNQThHQTFVRUF3d0libVYzTFhWelpYSXdnZ0VpTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRE8wV0pXK0RYc0FKU0lyanBObzV2UklCcGxuemcrNnhjOStVVndrS2kwCkxmQzI3dCsxZUVuT041TXVxOTlOZXZtTUVPbnJEVU8vdGh5VnFQMncyWE5JRFJYall5RjQwRmJtRCs1eld5Q0sKeTNCaWhoQjkzTUo3T3FsM1VUdlo4VEVMcXlhRGtuUmwvanYvU3hnWGtvazBBQlVUcFdNeDRCcFNpS2IwVSt0RQpJRjVueEF0dE1Wa0RQUTdOYmVaUkc0M2IrUVdsVkdSL3o2RFdPZkpuYmZlek90YUF5ZEdMVFpGQy93VHB6NTJrCkVjQ1hBd3FDaGpCTGt6MkJIUFI0Sjg5RDZYYjhrMzlwdTZqcHluZ1Y2dVAwdEliT3pwcU52MFkwcWRFWnB3bXcKajJxRUwraFpFV2trRno4MGxOTnR5VDVMeE1xRU5EQ25JZ3dDNEdaaVJHYnJBZ01CQUFHZ0FEQU5CZ2txaGtpRwo5dzBCQVFzRkFBT0NBUUVBUzlpUzZDMXV4VHVmNUJCWVNVN1FGUUhVemFsTnhBZFlzYU9SUlFOd0had0hxR2k0CmhPSzRhMnp5TnlpNDRPT2lqeWFENnRVVzhEU3hrcjhCTEs4S2czc3JSRXRKcWw1ckxaeTlMUlZyc0pnaEQ0Z1kKUDlOTCthRFJTeFJPVlNxQmFCMm5XZVlwTTVjSjVURjUzbGVzTlNOTUxRMisrUk1uakRRSjdqdVBFaWM4L2RoawpXcjJFVU02VWF3enlrcmRISW13VHYybWxNWTBSK0ROdFYxWWllKzBIOS9ZRWx0K0ZTR2poNUw1WVV2STFEcWl5CjRsM0UveTNxTDcxV2ZBY3VIM09zVnBVVW5RSVNNZFFzMHFXQ3NiRTU2Q0M1RGhQR1pJcFVibktVcEF3a2ErOEUKdndRMDdqRytocGtueG11RkFlWHhnVXdvZEFMYUo3anUvVERJY3c9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
signerName: kubernetes.io/kube-apiserver-client
usages:
- digital signature
- key encipherment
- server auth
username: agent-x
status: {}
- CSR 거절하기
controlplane ~ ➜ kubectl certificate deny agent-smith
certificatesigningrequest.certificates.k8s.io/agent-smith denied
controlplane ~ ➜ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
agent-smith 3m43s kubernetes.io/kube-apiserver-client agent-x <none> Denied
# CSR 삭제
controlplane ~ ➜ kubectl delete csr agent-smith
certificatesigningrequest.certificates.k8s.io "agent-smith" deleted
[ 실습 ]
Create a new user called john. Grant him access to the cluster. John should have permission to create, list, get, update and delete pods in the development namespace . The private key exists in the location: /root/CKA/john.key and csr at /root/CKA/john.csr.
- CSR
# private key와 csr이 이미 제공이 되어 있음
controlplane ~/CKA ➜ ls
john.csr john.key use-pv.yaml
# base64 인코딩
controlplane ~/CKA ➜ cat john.csr | base64 | tr -d "\n"
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZEQ0NBVHdDQVFBd0R6RU5NQXNHQTFVRUF3d0VhbTlvYmpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRApnZ0VQQURDQ0FRb0NnZ0VCQU1sdjBFRkpURjlwWk4ySDVMWS9obXhYV0dKemgrZ1hKV2xBTW5ZZUJvNmlBUFJLCjVWaTJLQ1ViellDSnBucWJ2enB2MmNQSmNlZDkzSkRTWlVlaVZDRldPRjVCNjExd21kUG1qbUcwRzlPLzNYN2oKVU5URkppREJwenVWbzIrV2lVRnNrR3ZVdFdHc3pXZGlNemhmYkpMR2pZUWdxTXVjSGZvajhJNkpSWmVyUjFOQwpWRnpBeUpVMW9PeWgwM1UzUm1IRGk2SU9kRVVsR3laMG1pdVU4V0JTNjIyNW8xRWU5M3hrTmNnRHFDUmE1RGxTCllMc3JlVmZqWjFrcjJ6UDN2dXc5SDd2ZGUwR2RTcE52MEZCQ0VSUEx5bDM0RGpwWUZVSEtUUFFYY3BYUmFlbUsKUUVPa3I0R2VPZVlLaExnaXFXVFlQSDZlWFhzU1BQTkZtRkhtbFZjQ0F3RUFBYUFBTUEwR0NTcUdTSWIzRFFFQgpDd1VBQTRJQkFRRERPd3pOZXByUEx2RGdxVlVVVmpxRFZ0N0JNUlpxWFJ4MTFLTFYvc1h0L0hYd25aMXVmNjF5CmNnRm5Vc0JhM2Q2UjE1K0ViNnJDQTA0NTVLZERjYzhLWmMzM3p2Sjd2QThOK0NhSEpIRUN4ckh3cHA1SzNBbEcKek05RVJ3bEE2eEVNQThFcjFTK2sydU9FOWo2UkhFVkthU0hSU0xiY2NOL1plQnRIeU5zbDE0V3Z5Vm54QnptQgpTWmg0RUJucDNJQmF3T3FVM1pGbW1vcVo5Mkh3bUZ0SlR5UkxNYnpRK2k5ajdTSVZUOERHZnAwMHg5K2NkUWo0CndFMmFwYWs1OUVrVXRTLzVqaHgzSE1CUzlQRUpPdlUrc0I2YTA3YnE2bllJZm1ORXFUZ0ZYUitWSzdvRkhtRGMKazE3U3A4YjU5TVJCZHEzL1dRSW4rYno3RWFXVHYxTFgKLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
# 기반으로 csr.yaml 생성
controlplane ~/CKA ➜ cat csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: john-developer
spec:
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZEQ0NBVHdDQVFBd0R6RU5NQXNHQTFVRUF3d0VhbTlvYmpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRApnZ0VQQURDQ0FRb0NnZ0VCQU1sdjBFRkpURjlwWk4ySDVMWS9obXhYV0dKemgrZ1hKV2xBTW5ZZUJvNmlBUFJLCjVWaTJLQ1ViellDSnBucWJ2enB2MmNQSmNlZDkzSkRTWlVlaVZDRldPRjVCNjExd21kUG1qbUcwRzlPLzNYN2oKVU5URkppREJwenVWbzIrV2lVRnNrR3ZVdFdHc3pXZGlNemhmYkpMR2pZUWdxTXVjSGZvajhJNkpSWmVyUjFOQwpWRnpBeUpVMW9PeWgwM1UzUm1IRGk2SU9kRVVsR3laMG1pdVU4V0JTNjIyNW8xRWU5M3hrTmNnRHFDUmE1RGxTCllMc3JlVmZqWjFrcjJ6UDN2dXc5SDd2ZGUwR2RTcE52MEZCQ0VSUEx5bDM0RGpwWUZVSEtUUFFYY3BYUmFlbUsKUUVPa3I0R2VPZVlLaExnaXFXVFlQSDZlWFhzU1BQTkZtRkhtbFZjQ0F3RUFBYUFBTUEwR0NTcUdTSWIzRFFFQgpDd1VBQTRJQkFRRERPd3pOZXByUEx2RGdxVlVVVmpxRFZ0N0JNUlpxWFJ4MTFLTFYvc1h0L0hYd25aMXVmNjF5CmNnRm5Vc0JhM2Q2UjE1K0ViNnJDQTA0NTVLZERjYzhLWmMzM3p2Sjd2QThOK0NhSEpIRUN4ckh3cHA1SzNBbEcKek05RVJ3bEE2eEVNQThFcjFTK2sydU9FOWo2UkhFVkthU0hSU0xiY2NOL1plQnRIeU5zbDE0V3Z5Vm54QnptQgpTWmg0RUJucDNJQmF3T3FVM1pGbW1vcVo5Mkh3bUZ0SlR5UkxNYnpRK2k5ajdTSVZUOERHZnAwMHg5K2NkUWo0CndFMmFwYWs1OUVrVXRTLzVqaHgzSE1CUzlQRUpPdlUrc0I2YTA3YnE2bllJZm1ORXFUZ0ZYUitWSzdvRkhtRGMKazE3U3A4YjU5TVJCZHEzL1dRSW4rYno3RWFXVHYxTFgKLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
controlplane ~/CKA ➜ kubectl create -f csr.yaml
certificatesigningrequest.certificates.k8s.io/john-developer created
controlplane ~/CKA ➜ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-lm9gp 21m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:mod04i <none> Approved,Issued
john-developer 4s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Pending
# Pending 상태임
controlplane ~/CKA ➜ kubectl certificate approve john-developer
certificatesigningrequest.certificates.k8s.io/john-developer approved
# Approve
controlplane ~/CKA ➜ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-lm9gp 21m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:mod04i <none> Approved,Issued
john-developer 33s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued
- Role
controlplane ~/CKA ➜ kubectl create role developer --verb=create,get,list,update,delete --resource=pods -n development
role.rbac.authorization.k8s.io/developer created
controlplane ~/CKA ➜ kubectl describe role -n development
Name: developer
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [create get list update delete]
# 권한 확인
controlplane ~/CKA ➜ kubectl auth can-i get pods --namespace development --as john
no
controlplane ~/CKA ✖ kubectl auth can-i create pods --namespace development --as
john
no
# 아직 모든 권한이 주어지지 않았다.
# -> Rolebinding 생성 필요
controlplane ~/CKA ➜ kubectl create rolebinding john-developer --role=developer --user=john -n development
rolebinding.rbac.authorization.k8s.io/john-developer created
controlplane ~/CKA ➜ kubectl get rolebinding -n development
NAME ROLE AGE
john-developer Role/developer 21s
controlplane ~/CKA ➜ kubectl describe rolebinding -n development
Name: john-developer
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: developer
Subjects:
Kind Name Namespace
---- ---- ---------
User john
# 이제 정상 작동
controlplane ~/CKA ➜ kubectl auth can-i create pods --namespace development --as john
yes
[ 실습 ]
CSR(Certificate Signing Request)를 통해 app-manager 인증서를 발급받은 user app-manager 에게 cluster내 모든 namespace의 deployment, pod, service 리소스를 create, list, get, update, delete 할 수 있는권한을 할당하시오.
참고: https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user
- user name : app-manager
- certificate name: app-manager
- clusterRole name : app-access
- clusterRoleBinding name: app-access-binding
1. 인증서 key 만들기
# 인증서 키 만들기
controlplane $ openssl genrsa -out app-manager.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
............+++++
.......................................................................................................................................................+++++
e is 65537 (0x010001)
# CSR 만들기 (인증서를 요청해주는 파일)
controlplane $ openssl req -new -key app-manager.key -out app-manager.csr -subj "/CN=app-manager"
2. CSR 생성 요청하기
controlplane $ cat app-manager.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: app-manager
spec:
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1d6Q0NBVU1DQVFBd0ZqRVVNQklHQTFVRUF3d0xZWEJ3TFcxaGJtRm5aWEl3Z2dFaU1BMEdDU3FHU0liMwpEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURWR2s0SVZYOHBZdkFzSGVzOEV6K1Zpbzg2WXdCTmxxNU9wS3ZZCkd5MUIzNG9MSGU3MWxPN2xFa0ExbTFHMnBtS1E2bW9IQVFuaGxCQlRVTDNRWkZ2YzVIWjZ1SmY4bjA1L2F2UFQKamlZSkY0Qk5LdGdySzdseGhuUjlhRk1Rdy9SS2pYTnMzUGVYOUxxZm8vbTVySHhjN1V4UHQyWk9GQldkdUhQRwpLMTFDWFRjV3NXbFVST3Y1elpmZDFpRE5qUkN5N2ZMZzhSTFRXTEdUZGpwV2dxeGdCc0d0VEd2Tmlib083QUI1CnMxL0Z3emZma0c5Y2szZmdPNXU3a3lnV1p2aTEvL1lVWndRVHN1bGdnK3NrS09USXl0WTcxTzF1bUgzSzhQSWUKMUowODlDTUVLM3pQUFNvZzROWFBJdlBnbmRtb1BNdzlmUlhuN2ZIeFRtSnlVd3JYQWdNQkFBR2dBREFOQmdrcQpoa2lHOXcwQkFRc0ZBQU9DQVFFQWIxVG9YT3ZJRHRIaldkQ1l4bEIxVUhWV2xoSXgyd2dRY3JGQml0QWRWeTF2Cmp3ejAzdFVyMlRBRlBVd3Q0QkxWQWkrNmsrV3NZdFFhTTUzdXBVYWhLNk5WMkxJcitPakpibFdpaHdHNmtwSU8KbmRkMEdWY3BZWHNFZm1BZCtaWFBnVjA5UGt5R3BzT2dtU2pqOXBJYkt3a0l6OWVQeG0rSWs0TUZKTCsrY05VNQpLYWZLTjRoNzFSMGZtWXlSV2x4dUZKaHgrWHh2WG4xVzdhc0lNcVdRNm93SmhMd0RBdGRBdElYYUwrVmJFZFFaCjNlTEtubzZlUTNTVFRkcWtueHhjNVYwb0ZkY2tLbXBQZ21lbHJZL2hjZjQ4ZEphY2xEaGh1K3haaFZqaVZWaCsKcDdGU24xY1VlNHJIaWdFc3FBZ0NmUXhTMHhvNTRvQmNBV08zVS9FWklRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
controlplane $ kubectl apply -f app-manager.yaml
certificatesigningrequest.certificates.k8s.io/app-manager created
- 승인 요청하기
controlplane $ kubectl certificate approve app-manager
certificatesigningrequest.certificates.k8s.io/app-manager approved
controlplane $ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
app-manager 56s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued
3. CSR로부터 발행된 certificate expose하
controlplane $ kubectl get csr app-manager -o jsonpath='{.status.certificate}'| base64 -d >
app-manager.crt
4. Clusterrole, ClusterRoleBinding 만들기
controlplane $ kubectl create clusterrole app-access --verb=create,list,get,update,delete --resource=deployment,pod,service
clusterrole.rbac.authorization.k8s.io/app-access created
controlplane $ kubectl get clusterrole app-access
NAME CREATED AT
app-access 2025-03-03T08:31:47Z
kubectl create clusterrolebinding app-access-binding --clusterrole=app-access --user=app-manager
clusterrolebinding.rbac.authorization.k8s.io/app-access-binding created
controlplane $ kubectl describe clusterrolebinding app-access-binding
Name: app-access-binding
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: app-access
Subjects:
Kind Name Namespace
---- ---- ---------
User app-manager
5. app-manager.crt 인증서를 사용하는 user app-manager 등록
→ https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#add-to-kubeconfig
'Container > Kubernetes' 카테고리의 다른 글
[K8S] api-resources (0) | 2025.01.23 |
---|---|
[K8S] Authorization (1) | 2025.01.20 |
[K8S] TLS (0) | 2025.01.10 |
[K8S] Encrypting Secret Data at Rest (0) | 2025.01.08 |
[K8S] ConfigMap (0) | 2025.01.08 |