[K8S] RBAC 의 개념과 Role, RoleBinding, ClusterRole, ClusterRoleBinding

HYEOB KIM·2022년 7월 11일
1

kubernetes

목록 보기
7/14
post-custom-banner

API 인증: RBAC

  • API 서버에 접근하기 위해서는 인증 작업이 필요합니다.
  • Role-based access control(RBAC. 역할 기반 액세스 제어)
  • 사용자의 역할에 따라 리소스에 대한 접근 권한을 가짐
  • User: 클러스터 외부에서 쿠버네티스를 조작하는 사용자 인증

아래 경로에 User 정보와 인증서(client-certificate-data) 정보가 들어있습니다.

% cat .kube/config
  • Service Account: Pod가 쿠버네티스 API를 다룰 때 사용하는 계정
    모든 pod는 Service Account를 가집니다. 따라서 SA(Service Account)에 권한이 어디까지 있는지에 따라서 접근 권한을 가지게 됩니다.

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

Role & RoleBinding을 이용한 권한 제어

역할(Role)

  • 어떤 API를 이용할 수 있는지 정의
  • 쿠버네티스의 사용권한을 정의
  • 지정된 네임스페이스에서만 유효

RoleBinding

  • 사용자/그룹 또는 Service Account와 역할을 연결

Cluster Role과 Cluster Role Binding

  • 일반적인 Role과 Cluster Role의 가장 큰 차이점은 속해있지 않는 네임스페이스에서도 권한이 유효합니다.

CKA 문제 유형 1

  • 작업 클러스터: 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을 허용하도록 매핑하시오.

풀이법

kubernetes 공식 문서 - Using RBAC Authorization를 참고하세요.

1. api-access라는 이름의 네임스페이스 생성

% kubectl config use-context k8s
Switched to context "k8s".

% ssh k8s-master

% kubectl create namespace api-access
namespace/api-access created

2. 네임스페이스 내에 pod-viewer라는 이름의 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

3. podreader-role이라는 이름의 역할 생성(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]

podreader-role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

4. podreader-rolebinding이라는 이름의 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

CKA 문제 유형 2

  • 작업 클러스터: 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

1. deployment-clusterrole라는 이름의 ClusterRole 생성

% 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]

2. cicd-token이라는 이름의 serviceaccount를 api-access 네임스페이스에 생성.

% 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

3. clusterrole과 serviceaccount를 바인딩.

% 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

CKA 문제 유형 3

  • 작업 클러스터: 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

1. app-manager라는 이름의 인증서 생성

(시험에서는 인증서가 다 만들어져있음)

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

2. app-manager라는 이름의 user 생성

Kubernetes 공식 문서 - Add to kubeconfig를 참고하세요.

자격 증명을 생성하고 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".

3. app-access라는 이름의 clusterrole을 생성

% 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]

4. app-access-binding라는 이름의 clusterrolebinding 생성

% 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
profile
Devops Engineer
post-custom-banner

0개의 댓글