본문 바로가기

Container/Kubernetes

[K8S] RBAC

API 서버에 접근하기 위해서는 인증 작업이 필요하다.

User 인증(Authentication) → 권한 확인(Authorization) 요청 확인(Admission Control)   요청 승인

 

RBAC을 이용한 권한 제어

사용자의 역할에 따라 리소스에 대한 접근 권한 가진다.

 

ex ) Role 예제: default 네임스페이스의 Pod에 대한 get,watch,list 할 수 있는 권한 줄 것

  • Pod는 코어 API기 때문에 apiGroups를 따로 지정하지 않는다. 만약 리소스가 job이라면 apiGroups에 "batch"를 지정
  • resources에는 Pods,deployments,service등 사용할 API resource들을 명시한다.
  • verbs에는 단어 그대로 나열된 API 리소스에 허용할 기능을 나열한다

 

  • User: 클러스터 외부에서 쿠버네티스를 조작하는 사용자 인증
controlplane $ cat ~/.kube/config 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJ..인증서
    server: https://172.30.1.2:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin # User
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
  • Service Account: Pod가 쿠버네티스 API를 다룰 때 사용하는 계정
    • 기본 default 라는 default-token을 사용하는 ServiceAccount가 동작한다.
$ kubectl get pods eshop-cart-app -o yaml | grep -i serviceaccount

Role & Rolebinding을 이용한 권한 제어

  • 특정 유저나 ServiceAccount가 접근하려는 API에 접근 권한을 설정
  • 해당 namespace 안에서 권한이 제한된다.
  • 권한 있는 User만 접근하도록 허용 (권한제어)
  • Role
    • 어떤 API를 이용할 수 있는지의 정의 (pod, service..)
    • 쿠버네티스의 사용 권한을 정의 (get, create, delete..)
    • 지정된 네임스페이스에서만 유효
  • RoleBinding
    • 사용자/그룹 또는 ServiceAccount와 Role 연결

참고: https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#create-role-and-rolebinding

 

1. Role 생성

root@master:~/authorization# kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
role.rbac.authorization.k8s.io/developer created

root@master:~/authorization# kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods --dry-run -o yaml
W0416 20:05:26.257272    4996 helpers.go:704] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: developer
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - create
  - get
  - list
  - update
  - delete

root@master:~/authorization# kubectl get role
NAME        CREATED AT
developer   2024-04-16T11:04:16Z

 

2. Rolebinding 생성 

root@master:~/authorization# kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser --dry-run -o yaml
W0416 20:06:16.972265    5012 helpers.go:704] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: developer-binding-myuser
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: developer
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: myuser
 # developer롤을 myuser에 연결시킨다.
 
root@master:~/authorization# kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
rolebinding.rbac.authorization.k8s.io/developer-binding-myuser created

 

3. 해당 user를 kubeconfig 추가

# 작업 전
root@master:~/authorization# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.100.0.104:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

root@master:~/authorization# kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
User "myuser" set.

root@master:~/authorization# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.100.0.104:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: myuser
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
# myuser등록됨을 확인 가능

 

4. context 추가

root@master:~/authorization# kubectl config set-context myuser --cluster=kubernetes --user=myuser
Context "myuser" created.

root@master:~/authorization# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.100.0.104:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:   # 추가됨
    cluster: kubernetes
    user: myuser
  name: myuser
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: myuser
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

 

5. myuser 로 context 변경하기 

root@master:~/authorization# kubectl config current-context
kubernetes-admin@kubernetes

root@master:~/authorization# kubectl config use-context myuser
Switched to context "myuser".
root@master:~/authorization# kubectl config current-context
myuser
# 변경 완료


root@master:~/authorization# kubectl get pods
NAME      READY   STATUS    RESTARTS      AGE
testpod   1/1     Running   1 (25m ago)   42h
# Pod 조회는 가능

root@master:~/authorization# kubectl get services
Error from server (Forbidden): services is forbidden: User "myuser" cannot list resource "services" in API group "" in the namespace "default"
# Service 조회는 불가능

 

ClusterRole & ClusterRolebinding

자신의 namespace에서 벗어나 다른 namespace의 정보까지 가져올 수 있는 권한제어 방식이다.

clusterrole: 전체 namespace를 대상으로 vs role : 자신이 속해있는 namespace만 대상으로 한다.

 

1. 다시 kubernetes-admin user로 context 변경

root@master:~/authorization# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

root@master:~/authorization# kubectl config current-context
kubernetes-admin@kubernetes

# role과 rolebinding 확인
root@master:~/authorization# kubectl get role
NAME        CREATED AT
developer   2024-04-16T11:04:16Z
root@master:~/authorization# kubectl get rolebindings.rbac.authorization.k8s.io
NAME                       ROLE             AGE
developer-binding-myuser   Role/developer   40m

2. Rolebinding 삭제

root@master:~/authorization# kubectl delete rolebindings.rbac.authorization.k8s.io developer-binding-myuser
rolebinding.rbac.authorization.k8s.io "developer-binding-myuser" deleted

root@master:~/authorization# kubectl delete role developer
role.rbac.authorization.k8s.io "developer" deleted

 

3. clusterrole 생성 : 

root@master:~/authorization# kubectl create clusterrole developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
clusterrole.rbac.authorization.k8s.io/developer created
root@master:~/authorization# kubectl create clusterrolebinding developer-binding-myuser --clusterrole=developer --user=myuser
clusterrolebinding.rbac.authorization.k8s.io/developer-binding-myuser created

# myuser로 전환
root@master:~/authorization# kubectl config use-context myuser
Switched to context "myuser".


root@master:~/authorization# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
myweb   1/1     Running   0          162m
# 다른 namespace 파드 조회 가능
root@master:~/authorization# kubectl get pods -n kube-system
NAME                                         READY   STATUS    RESTARTS         AGE
coredns-76f75df574-lwh6f                     1/1     Running   5 (3h11m ago)    30d
coredns-76f75df574-t88tx                     1/1     Running   5 (3h11m ago)    30d
etcd-master.example.com                      1/1     Running   5 (3h11m ago)    30d
kube-apiserver-master.example.com            1/1     Running   5 (3h11m ago)    30d
kube-controller-manager-master.example.com   1/1     Running   5 (3h11m ago)    30d
kube-proxy-7nvgn                             1/1     Running   5 (3h11m ago)    30d
kube-proxy-fj7b9                             1/1     Running   5 (3h11m ago)    30d
kube-proxy-mvx4j                             1/1     Running   6 (3h10m ago)    30d
kube-proxy-wvz78                             1/1     Running   3 (3h10m ago)    4d6h
kube-scheduler-master.example.com            1/1     Running   5 (3h11m ago)    30d
weave-net-8qzkj                              2/2     Running   7 (3h10m ago)    4d6h
weave-net-f54ws                              2/2     Running   14 (3h10m ago)   30d
weave-net-p4smr                              2/2     Running   11 (3h11m ago)   30d
weave-net-rmbnm                              2/2     Running   11 (3h11m ago)   30d

# 하지만 node 조회 등은 여전히 불가
root@master:~/authorization# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "myuser" cannot list resource "nodes" in API group "" at the cluster scope

 

다시 원복하기

master:~/authorization# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

# clusterrolebindings 삭제
root@master:~/authorization# kubectl delete clusterrolebindings.rbac.authorization.k8s.io developer-binding-myuser
clusterrolebinding.rbac.authorization.k8s.io "developer-binding-myuser" deleted

# clusterrole 삭제
root@master:~/authorization# kubectl delete clusterrole developer
clusterrole.rbac.authorization.k8s.io "developer" deleted

root@master:~/authorization# kubectl config delete-context myuser
deleted context myuser from /root/.kube/config

root@master:~/authorization# kubectl config delete-user myuser
deleted user myuser from /root/.kube/config

root@master:~/authorization# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.100.0.104:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

# User까지 삭제하려면
$ kubectl get csr
$ kubectl delete csr myuser

# sa 삭제
root@master:~/authorization# kubectl get sa
NAME         SECRETS   AGE
default      0         31d
pod-viewer   0         47h
root@master:~/authorization#
root@master:~/authorization# kubectl delete sa pod-viewer
serviceaccount "pod-viewer" deleted

root@master:~/authorization# kubectl delete pod --all
pod "myweb" deleted

root@master:~/authorization# kubectl get clusterrole
NAME                                                                   CREATED AT
admin                                                                  2024-03-16T14:00:48Z
cluster-admin                                                          2024-03-16T14:00:48Z
edit                                                                   2024-03-16T14:00:48Z
kubeadm:get-nodes                                                      2024-03-16T14:00:49Z
system:aggregate-to-admin                                              2024-03-16T14:00:48Z
system:aggregate-to-edit                                               2024-03-16T14:00:48Z
system:aggregate-to-view                                               2024-03-16T14:00:48Z
..
system:public-info-viewer                                              2024-03-16T14:00:48Z
system:service-account-issuer-discovery                                2024-03-16T14:00:48Z
system:volume-scheduler                                                2024-03-16T14:00:48Z
view                                                                   2024-03-16T14:00:48Z
weave-net                                                              2024-03-16T14:06:52Z

root@master:~/authorization# kubectl describe clusterrole view
Name:         view
Labels:       kubernetes.io/bootstrapping=rbac-defaults
              rbac.authorization.k8s.io/aggregate-to-edit=true
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources                                    Non-Resource URLs  Resource Names  Verbs
  ---------                                    -----------------  --------------  -----
  bindings                                     []                 []              [get list watch]
  configmaps                                   []                 []              [get list watch]
  endpoints                                    []                 []              [get list watch]
  events                                       []                 []              [get list watch]
  limitranges                                  []                 []              [get list watch]
  namespaces/status                            []                 []              [get list watch]
...

 

 

[ 실습 ] api-access namespace에 국한된 Role/RoleBinding 예제

  • api-access라는 새로운 namespace에 pod-viewer라는 이름의 Service Account를 만듭니다.
controlplane $ kubectl create ns api-access
namespace/api-access created
controlplane $ kubectl create serviceaccount pod-viewer -n api-access 
serviceaccount/pod-viewer created
controlplane $ kubectl get sa -n api-access 
NAME         SECRETS   AGE
default      0         79s
pod-viewer   0         5s
  • podreader-role이라는 이름의 Role과 podreader-rolebinding이라는 이름의 RoleBinding을 만듭니다.
  • 앞서 생성한 ServiceAccount를 API resource Pod에 대하여 watch, list, get을 허용하도록 매핑하시오.
controlplane $ kubectl create role podreader-role -n api-access --verb=get,list,watch --res
ource=pods
role.rbac.authorization.k8s.io/podreader-role created
controlplane $ kubectl get role -n api-access 
NAME             CREATED AT
podreader-role   2025-03-03T07:46:36Z
controlplane $ kubectl describe role -n api-access podreader-role 
Name:         podreader-role
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]
controlplane $ kubectl create rolebinding podreader-rolebinding --role=podreader-role --ser
viceaccount=api-access:pod-viewer -n api-access 
rolebinding.rbac.authorization.k8s.io/podreader-rolebinding created
controlplane $ kubectl get rolebindings -n api-access             
NAME                    ROLE                  AGE
podreader-rolebinding   Role/podreader-role   17s
controlplane $ kubectl describe rolebinding -n api-access podreader-rolebinding 
Name:         podreader-rolebinding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  podreader-role
Subjects:
  Kind            Name        Namespace
  ----            ----        ---------
  ServiceAccount  pod-viewer  api-access
반응형

'Container > Kubernetes' 카테고리의 다른 글

[K8S] Storage/Volume  (0) 2024.04.19
CKA 시험준비  (0) 2024.04.16
[K8S] cordon & drain  (0) 2024.04.13
[K8S] Taint & Toleration  (0) 2024.04.12
[K8S] Affinity & antiAffinity  (0) 2024.03.25