인증 작업
이 필요합니다.RBAC
. 역할 기반 액세스 제어)User
: 클러스터 외부에서 쿠버네티스를 조작하는 사용자 인증아래 경로에 User
정보와 인증서(client-certificate-data
) 정보가 들어있습니다.
% cat .kube/config
Service Account
: Pod가 쿠버네티스 API를 다룰 때 사용하는 계정pod의 SA를 확인하는 방법은 아래와 같습니다.
% kubectl run podtest --image=nginx
pod/podtest created
% kubectl get pod podtest -o yaml | grep -i serviceaccount
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
serviceAccount: default
serviceAccountName: default
- serviceAccountToken:
어떤 인증 정보(토큰)를 가지고 있는지 확인하는 방법은 아래와 같습니다.
(pod는 토큰을 통해서 API 인증을 거칩니다)
% kubectl get secrets default-token-gvdn7
NAME TYPE DATA AGE
default-token-gvdn7 kubernetes.io/service-account-token 3 167d
% kubectl describe secrets default-token-gvdn7
지정된 네임스페이스
에서만 유효속해있지 않는 네임스페이스에서도 권한이 유효
합니다.작업 클러스터: k8s
애플리케이션 운영 중 특정 namespace의 Pod들을 모니터할 수 있는 서비스가 요청되었습니다. api-access 네임스페이스의 모든 pod를 view할 수 있도록 다음의 작업을 진행하시오.
api-access라는 새로운 namespace에 pod-viewer라는 이름의 Service Account를 만듭니다.
podreader-role이라는 이름의 Role과 podreader-rolebinding이라는 이름의 RoleBinding을 만듭니다.
앞서 생성한 Service Account를 API resource Pod에 대해서 watch, list, get을 허용하도록 매핑하시오.
네임스페이스 생성
% kubectl config use-context k8s
Switched to context "k8s".
% ssh k8s-master
% kubectl create namespace api-access
namespace/api-access created
Service Account 생성
% kubectl create serviceaccount pod-viewer --namespace api-access
serviceaccount/pod-viewer created
% kubectl get serviceaccount --namespace api-access
NAME SECRETS AGE
default 1 102s
pod-viewer 1 13s
역할 생성
(Pod에 대해 watch, list, get 허용)% kubectl create role podreader-role --verb=get --verb=list --verb=watch --resource=pods --namespace=api-access
role.rbac.authorization.k8s.io/podreader-role created
% kubectl get role --namespace=api-access
NAME CREATED AT
podreader-role 2022-07-11T03:50:19Z
% kubectl describe role podreader-role --namespace=api-access
Name: podreader-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
RoleBinding 생성
후 Service Account와 Role을 연결
% kubectl create rolebinding podreader-rolebinding --role=podreader-role --serviceaccount=api-access:pod-viewer --namespace=api-access
rolebinding.rbac.authorization.k8s.io/podreader-rolebinding created
% kubectl get rolebinding --namespace=api-access
NAME ROLE AGE
podreader-rolebinding Role/podreader-role 32s
% kubectl describe rolebinding podreader-rolebinding --namespace=api-access
Name: podreader-rolebinding
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: podreader-role
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount pod-viewer api-access
작업 클러스터: k8s
작업 Context에서 애플리케이션 배포를 위해 새로운 ClusterRole을 생성하고 특정 namespace의 ServiceAccount를 바인드하세요.
다음의 resource type에서만 Create가 허용된 ClusterRole deployment-clusterrole을 생성합니다.
Resource Type: Deployment StatefulSet DaemonSet
미리 생성된 namespace api-access에 cicd-token이라는 새로운 ServiceAccount를 만듭니다.
ClusterRole deployment-clusterrole을 namespace api-access로 제한된 새 ServiceAccount cicd-token에 바인딩합니다.
% ssh k8s-master
% kubectl create clusterrole deployment-clusterrole --verb=create --resource=Deployment,StatefulSet,DaemonSet
clusterrole.rbac.authorization.k8s.io/deployment-clusterrole created
% kubectl get clusterrole deployment-clusterrole
NAME CREATED AT
deployment-clusterrole 2022-07-11T04:10:01Z
% kubectl describe clusterrole deployment-clusterrole
Name: deployment-clusterrole
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
daemonsets.apps [] [] [create]
deployments.apps [] [] [create]
statefulsets.apps [] [] [create]
% kubectl create serviceaccount cicd-token --namespace=api-access
serviceaccount/cicd-token created
% kubectl get sa --namespace=api-access
NAME SECRETS AGE
cicd-token 1 16s
default 1 28m
pod-viewer 1 27m
% kubectl create clusterrolebinding deployment-clusterrolebinding --clusterrole=deployment-clusterrole --serviceaccount=api-access:cicd-token
clusterrolebinding.rbac.authorization.k8s.io/deployment-clusterrolebinding created
% kubectl get clusterrolebindings.rbac.authorization.k8s.io deployment-clusterrolebinding
NAME ROLE AGE
deployment-clusterrolebinding ClusterRole/deployment-clusterrole 2s
% kubectl describe clusterrolebindings.rbac.authorization.k8s.io deployment-clusterrolebinding
Name: deployment-clusterrolebinding
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: deployment-clusterrole
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount cicd-token api-access
작업 클러스터: k8s
CSR(Certificate Signing Request)를 통해 app-manager 인증서를 발급받은 user app-manager에게 cluster내 모든 namespace의 deployment, pod, service 리소스를 create, list, get, update, delete 할 수 있는 권한을 할당하세요.
user name: app-manager
certificate name: app-manager
clusterRole name: app-access
clusterRoleBinding name: app-access-binding
% ssh k8s-master
인증서 생성
(시험에서는 인증서가 다 만들어져있음)
Kubernetes 공식 문서 - Normal user를 참고하세요.
맨 뒤에 -subj
옵션은 공식 문서에 없는 내용으로 외우면 됩니다.
% openssl genrsa -out app-manager.key 2048
% openssl req -new -key app-manager.key -out app-manager.csr -subj "/CN=app-manager"
request
의 내용에는 발급받은 키의 내용을 입력해야 합니다. 아래 명령으로 내용을 확인한 후 EOF에 붙여넣습니다.
% cat app-manager.csr | base64 | tr -d "\n"
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1d6Q0NBVU1DQVFBd0ZqRVVNQklHQTFVRUF3d0xZWEJ3TFcxaGJtRm5aWEl3Z2dFaU1BMEdDU3FHU0liMwpEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURnbW5HWXN1SEJXbmpaSVlFOW5PTFJPQldXT0p1MTMwOEFsMTl0Cm5xMHN6ZDJ1WUhjU2dGNmpYampZZDJkR0NlYzlBQkM0cTduaFdYaVU1QmpsOXk3MXlRZGlsMHo5eFRLaHBGbE4KMzQ3SzJudGJ0dTEvZEdvck0ycHc3aVVHWkEyUXFBYktkSXMyVXJRZ0FMMGs3Y01hZnlqTUVJZDQ1ZldubkNGMQpVcHZsZHBoK3pxeEx2ajRUSDZZRGc1dDJibThYWldJS2gwaC8xeVd2UU1iYTJ5WXJ6M0RLZVYwR3E2dHpUZkZvCkt1eWpuNjBjVm1DS2ZhWDR1TzgzM1Nuc1hxcmRQY0p0MVl4YTU1UkU5ZU1JbGhDcVRvZ2JCZWNYSFpZYUV4NzAKcGRiVE1qVDVyalBtNnZnbTBlcUNpMVpSKzlOODB6cTJDeUloa1RIRDU3SVlrL3BUQWdNQkFBR2dBREFOQmdrcQpoa2lHOXcwQkFRc0ZBQU9DQVFFQTMvdkxmd1Izby9GbU0vdlQrRy9RUWt4TmRCcXJBejlIUHZ6K2FXVGVIVnBqCit3dHBFUHRqSDQ2cDFrSU5KUDJnWjJleHFkZlVUQXJjYnZPek9rYlA5SURCcm9LbWhsUlBuVWlYeW9BNGZoL0QKMldhVWk4VEMwNnhEZ2h1K2hBTHFzUlp4bzgxdjZ5YTdYVzdOK1FYUk42V1pxM0RVQlNKTFpXQW4rZ2JOa0ZkdQpVL014Z0dZNzFURkZLNGZETUF5amlra05udlBudVR1L3UyMzJCMmJ1REJ5VS9DaDlFVEpnVVNaYUErVXVnd0p0Ck00VVlYT1pVMGVBT0dqdXlyUXAzME1mMVAzclBZNGM4bWlzSjQzQzN5aWRkZWVTN1pkWFBkWVYvb0FsSWVETGsKZHN1MjJYQ1VNdVlSSExOUnA4cEdySVZRUGF3RncwaEZ4QXVnWk9HT1FBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
% cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: app-manager
spec:
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1d6Q0NBVU1DQVFBd0ZqRVVNQklHQTFVRUF3d0xZWEJ3TFcxaGJtRm5aWEl3Z2dFaU1BMEdDU3FHU0liMwpEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURnbW5HWXN1SEJXbmpaSVlFOW5PTFJPQldXT0p1MTMwOEFsMTl0Cm5xMHN6ZDJ1WUhjU2dGNmpYampZZDJkR0NlYzlBQkM0cTduaFdYaVU1QmpsOXk3MXlRZGlsMHo5eFRLaHBGbE4KMzQ3SzJudGJ0dTEvZEdvck0ycHc3aVVHWkEyUXFBYktkSXMyVXJRZ0FMMGs3Y01hZnlqTUVJZDQ1ZldubkNGMQpVcHZsZHBoK3pxeEx2ajRUSDZZRGc1dDJibThYWldJS2gwaC8xeVd2UU1iYTJ5WXJ6M0RLZVYwR3E2dHpUZkZvCkt1eWpuNjBjVm1DS2ZhWDR1TzgzM1Nuc1hxcmRQY0p0MVl4YTU1UkU5ZU1JbGhDcVRvZ2JCZWNYSFpZYUV4NzAKcGRiVE1qVDVyalBtNnZnbTBlcUNpMVpSKzlOODB6cTJDeUloa1RIRDU3SVlrL3BUQWdNQkFBR2dBREFOQmdrcQpoa2lHOXcwQkFRc0ZBQU9DQVFFQTMvdkxmd1Izby9GbU0vdlQrRy9RUWt4TmRCcXJBejlIUHZ6K2FXVGVIVnBqCit3dHBFUHRqSDQ2cDFrSU5KUDJnWjJleHFkZlVUQXJjYnZPek9rYlA5SURCcm9LbWhsUlBuVWlYeW9BNGZoL0QKMldhVWk4VEMwNnhEZ2h1K2hBTHFzUlp4bzgxdjZ5YTdYVzdOK1FYUk42V1pxM0RVQlNKTFpXQW4rZ2JOa0ZkdQpVL014Z0dZNzFURkZLNGZETUF5amlra05udlBudVR1L3UyMzJCMmJ1REJ5VS9DaDlFVEpnVVNaYUErVXVnd0p0Ck00VVlYT1pVMGVBT0dqdXlyUXAzME1mMVAzclBZNGM4bWlzSjQzQzN5aWRkZWVTN1pkWFBkWVYvb0FsSWVETGsKZHN1MjJYQ1VNdVlSSExOUnA4cEdySVZRUGF3RncwaEZ4QXVnWk9HT1FBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
signerName: kubernetes.io/kube-apiserver-client
# expirationSeconds: 86400 # one day
usages:
- client auth
EOF
certificatesigningrequest.certificates.k8s.io/app-manager created
생성된 csr이 승인(approve
)되도록 해줍니다.
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
app-manager 44s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Pending
% kubectl certificate approve app-manager
certificatesigningrequest.certificates.k8s.io/app-manager approved
% kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
app-manager 108s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued
.crt
파일로 csr
을 추출합니다.
% kubectl get csr app-manager -o jsonpath='{.status.certificate}'| base64 -d > app-manager.crt
자격 증명을 생성하고 config 정보를 봅니다.
% kubectl config set-credentials app-manager --client-key=app-manager.key --client-certificate=app-manager.crt --embed-certs=true
User "app-manager" set.
% kubectl config view
...
users:
- name: app-manager
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: hk8s-admin
...
context
를 등록하고 config 정보를 봅니다.
% kubectl config set-context app-manager --cluster=kubernetes --user=app-manager
Context "app-manager" created.
% kubectl config view
...
contexts:
- context:
cluster: kubernetes
user: app-manager
name: app-manager
- context:
...
% kubectl config use-context app-manager
Switched to context "app-manager".
% kubectl create clusterrole app-access --verb=create,list,get,update,delete --resource=deployment,pod,service
clusterrole.rbac.authorization.k8s.io/app-access created
% kubectl get clusterrole app-access
NAME CREATED AT
app-access 2022-07-11T05:01:47Z
% kubectl describe clusterrole app-access
Name: app-access
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [create list get update delete]
services [] [] [create list get update delete]
deployments.apps [] [] [create list get update delete]
% kubectl create clusterrolebinding app-access-binding --clusterrole=app-access --user=app-manager
clusterrolebinding.rbac.authorization.k8s.io/app-access-binding created
% kubectl get clusterrolebindings.rbac.authorization.k8s.io app-access-binding
NAME ROLE AGE
app-access-binding ClusterRole/app-access 28s
% kubectl describe clusterrolebindings.rbac.authorization.k8s.io app-access-binding
Name: app-access-binding
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: app-access
Subjects:
Kind Name Namespace
---- ---- ---------
User app-manager