DevOps/Kubernetes

[Kubernetes] RBAC (Role-Based Access Control, 역할 기반 접근 제어)

TTOII 2022. 6. 7. 10:35
728x90

🚀 RBAC : Role-Based Access Control

https://contradicto-lee.tistory.com

Using RBAC Authorization | Kubernetes

  • Role: 권한(NS)
  • ClusterRole: 권한(Global)
  • RoleBinding
    • Role ↔ RoleBinding ↔ SA/User
  • ClusterRoleBinding
    • ClusterRole ↔ ClusterRoleBinding ↔ SA/User

 vagrant@k8s-node1  ~/pod  kubectl api-resources | grep rbac                 
clusterrolebindings                            rbac.authorization.k8s.io/v1           false        ClusterRoleBinding
clusterroles                                   rbac.authorization.k8s.io/v1           false        ClusterRole
rolebindings                                   rbac.authorization.k8s.io/v1           true         RoleBinding
roles                                          rbac.authorization.k8s.io/v1           true         Role

roles는 역할이다. 정확히는 권한을 부여하는 것이다.
rolebindingsroles은 네임스페이스를 사용한다. 네임스페이스 내에서만 권한이 부여된다.

ClusterRole은 네임스페이스를 사용하지 않기 때문에 Global하게 클러스터 전체에 권한을 부여한다.

RoleBindingRoleSA/User를 연결 시켜주는 것이다.

ClusterRoleBindingClusterRoleSA/User를 연결 시켜주는 것이다.

 

🚀 Role

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

rules에는 사용자(pod-reader)가 어떤 권한을 사용할 수 있는지를 설정한다.
pods 리소스에 대해서 get, watch, list를 할 수 있다는 것이다.
rulesverbs는 리스트이므로 여러개를 지정할 수 있다.

 

인가 개요 | Kubernetes

요청 동사

 

요청 동사

  • create
    • kubectl create, kubectl apply
  • get
    • kubectl get po myweb
  • list
    • kubectl get pods
  • watch
    • kubectl get po -w
  • update
    • kubectl edit, replace
  • patch
    • kubectl patch
  • delete
    • kubectl delete po myweb
  • deletecollection
    • kubectl delete po --all

 vagrant@k8s-node1  ~/pod  kubectl get po -v=0           
NAME                                      READY   STATUS    RESTARTS   AGE
myweb                                     1/1     Running   0          39m
nfs-client-provisioner-758f8cd4d6-wpjbt   1/1     Running   0          3d10h

-v : 상세정보를 보는 옵션으로 0 ~ 9 사이값을 지정할 수 있으며 9가 가장 상세하다.

9번을 실행시키면 실제로 kubectl이 어떻게 요청하는지 볼 수 있다.

 

 vagrant@k8s-node1  ~/pod  kubectl get po -v=7
I0527 15:58:28.385509   52569 loader.go:372] Config loaded from file:  /home/vagrant/.kube/config
I0527 15:58:28.386425   52569 round_trippers.go:432] GET https://127.0.0.1:6443/api?timeout=32s
I0527 15:58:28.386668   52569 round_trippers.go:438] Request Headers:
I0527 15:58:28.386758   52569 round_trippers.go:442]     Accept: application/json, */*
I0527 15:58:28.386941   52569 round_trippers.go:442]     User-Agent: kubectl/v1.22.8 (linux/amd64) kubernetes/7061dbb
I0527 15:58:28.393631   52569 round_trippers.go:457] Response Status: 200 OK in 6 milliseconds

api-server는 RestAPI 서버이며 kubectl 명령이 HTTP로 통신한다.

 

 vagrant@k8s-node1  ~/pod  kubectl delete -f myweb.yaml -v=7
I0527 16:00:49.612293   54056 loader.go:372] Config loaded from file:  /home/vagrant/.kube/config
I0527 16:00:49.616387   54056 round_trippers.go:432] DELETE https://127.0.0.1:6443/api/v1/namespaces/default/pods/myweb

파드를 삭제할 때의 HTTP 요청 동사는 DELETE임을 확인할 수 있다.

 

🚀 ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Secret
  # objects is "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

ClusterRole은 네임스페이스를 지정하지 않는다. Global하다.

 

🚀 RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
  name: jane # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

subjects의 종류는 User이며 jane이라는 사용자를 가리킨다.

jane~/.kube/config 파일의 users.namejane과 매칭되어야 한다.

roleRef는 사용자와 역할을 연결시켜주는 역할을 한다.

그러면 jane이라는 사용자에 pod-reader(파드의 목록을 확인할 수 있음)라는 Role이 연결된다.

 

🚀 ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding도 네임스페이스를 사용하지 않는다.

subjects.kind에 그룹을 지정할 수 있다.

그리고 roleRef를 통해 secret-reader라는 ClusterRole을 연결시킨다.

 

~/nfs-subdir-external-provisioner/deploy/rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner # sa 계정을 만든다.
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole # 클러스터 전체의 역할 
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner # 해당 이름의 ClusterRole이 만들어진다.
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"] # nfs 파드는 다른 노드의 정보를 볼 수 있어야 한다. 그래야만 해당되는 노드의 어떤 파드에 어떤 pv를 만들어 줄 것인지를 결정할 수 있다.
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"] # 결국 nfs가 pv를 만들어주는 것이므로 
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"] # pvc는 우리가 만들지만 pv를 만들어서 pv와 pvc를 연결시켜줘야 하는데 pvc에는 pv에 대한 정보가 있어야 하고 pvc에서 pv에 대한 정보를 업데이트 할 수 있어야 한다.
pv는 pvc를 가리켜야 한다. pv에 이름을 지정하거나 셀렉터로 지정하거나 결과적으로 pv를 셀렉팅할 수 있어야 하기 때문에 pvc를 업데이트할 수 있어야 한다.    
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"] # describe 명령을 통해 보는 각 리소스마다의 Events 값을 만들고, 업데이트하고, 변경할 수 있어야 한다.
---
kind: ClusterRoleBinding # ClusterRole과 sa 계정을 연결시켜야 한다.
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

그리고 Deploy를 만들 때 sa를 지정해준다.

nfs-subdir-external-provisioner 컨테이너 App이 sa도 확인하고 노드 정보도 확인하고 pvc 정보도 확인해야 하며 최종적으로는 pv를 만들 수 있어야 한다.


이런 모든 것들을 하기위해 api-server에 접근해 권한을 부여 받는다.

sa와 sa의 토큰 정보를 갖고 api-server에 인증을 받고 pv를 만들 수 있게 된다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl get sa                                
NAME                     SECRETS   AGE
default                  1         11d
nfs-client-provisioner   1         3d11h

nfs-client-provisioner sa를 확인할 수 있다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl describe sa nfs-client-provisioner 
Name:                nfs-client-provisioner
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   nfs-client-provisioner-token-xzr7h
Tokens:              nfs-client-provisioner-token-xzr7h
Events:              <none>

nfs-client-provisioner가 사용하는 토큰은 nfs-client-provisioner-token-xzr7h이다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl get secret                            
NAME                                 TYPE                                  DATA   AGE
default-token-h87sc                  kubernetes.io/service-account-token   3      11d
nfs-client-provisioner-token-xzr7h   kubernetes.io/service-account-token   3      3d11h

저장된 토큰 목록도 확인할 수 있다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl get role 
NAME                                    CREATED AT
leader-locking-nfs-client-provisioner   2022-05-24T05:10:49Z

생성한 Role도 확인할 수 있다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl get clusterroles

nfs-client-provisioner-runner                                          2022-05-24T05:10:49Z

Calico, Ingress, METALLB 및 쿠버네티스 설치시 만들어진 ClusterRole 리스트를 볼 수 있다.

 

우리가 일반적으로 사용하는 ClusterRole

  • view: 읽을 수 있는 권한
  • edit: 생성/삭제/변경 할 수 있는 권한
  • admin: 모든것 관리(-RBAC : ClusterRole 제외)
  • cluster-admin: 모든것 관리

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  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                                       []                 []              

Resources 리스트가 있고 Resource Names에 특정 리소스를 지정하지 않았다.

Verbs에는 모든 대상이 보는 것만 가능하다고 되어있다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl describe clusterrole edit
Name:         edit
Labels:       kubernetes.io/bootstrapping=rbac-defaults
              rbac.authorization.k8s.io/aggregate-to-admin=true
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources                                    Non-Resource URLs  Resource Names  Verbs
  ---------                                    -----------------  --------------  -----
  configmaps                                   []                 []              [create delete deletecollection patch update get list watch]

  deployments.apps/rollback                    []                 []              [create delete deletecollection patch update]

  endpoints                                    []                 []              [get list watch]

  serviceaccounts                              []                 []              [impersonate create delete deletecollection patch update get list watch]

다양한 권한이 부여된 것을 확인할 수 있다.
쿠버네티스가 관리하는 리소스들은 Verbs로 [get list watch]를 갖는다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl describe clusterrole admin
Name:         admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources                                       Non-Resource URLs  Resource Names  Verbs
  ---------                                       -----------------  --------------  -----
  rolebindings.rbac.authorization.k8s.io          []                 []              [create delete deletecollection get list patch update watch]

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl describe clusterrole admin | grep role        
  rolebindings.rbac.authorization.k8s.io          []                 []              [create delete deletecollection get list patch update watch]
  roles.rbac.authorization.k8s.io                 []                 []              [create delete deletecollection get list patch update watch]

대부분의 것들을 다 관리할 수 있는데 clusterrole에는 권한이 부여되어있지 않고 rolebindingsroles에는 권한이 부여되어 있다.

 

 vagrant@k8s-node1  ~/nfs-subdir-external-provisioner/deploy  master ±  kubectl describe clusterrole cluster-admin    
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]
             [*]                []              [*]

우리가 현재 부여받은 권한이다.모든 작업을 다 할 수 있다.

 

🚀 SA 생성하기

 vagrant@k8s-node1  ~  kubectl create sa myuser1                 
serviceaccount/myuser1 created

 vagrant@k8s-node1  ~  kubectl get sa           
NAME                     SECRETS   AGE
default                  1         11d
myuser1                  1         4s
nfs-client-provisioner   1         3d11h

 vagrant@k8s-node1  ~  kubectl describe sa myuser1               
Name:                myuser1
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   myuser1-token-qst8z
Tokens:              myuser1-token-qst8z
Events:              <none>

 vagrant@k8s-node1  ~  kubectl get secret         
NAME                                 TYPE                                  DATA   AGE
default-token-h87sc                  kubernetes.io/service-account-token   3      11d
mydata                               Opaque                                2      3d10h
myuser1-token-qst8z                  kubernetes.io/service-account-token   3      22s
nfs-client-provisioner-token-xzr7h   kubernetes.io/service-account-token   3      3d11h
nginx-tls-secret                     kubernetes.io/tls                     2      2d4h

필요한 Role, RoleBinding 또는 ClusterRole과 ClusterRoleBinding을 만들어서 연결시켜줄 수 있다.

 

 vagrant@k8s-node1  ~  kubectl get clusterrolebinding

 vagrant@k8s-node1  ~  kubectl describe clusterrolebinding cluster-admin 
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name            Namespace
  ----   ----            ---------
  Group  system:masters

여러개의 ClusterRole이 만들어져 있다.

cluster-admin에는 system:masters라는 그룹이 있는데 현재 우리가 system:masters라는 그룹에 속해있는 사용자이며 이 사용자가 cluster-admin이라는 ClusterRole을 가지고 있다.

그렇기때문에 우리는 쿠버네티스의 모든 작업을 할 수 있는 것이다.

 

🚀 사용자 생성을 위한 x509 인증서

myuser라는 normal user를 만들어서 테스트해본다.

 

Private Key

openssl genrsa -out myuser.key 2048

 

x509 인증서 요청 생성

openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sohui
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:myuser

Common Name 지정 시에는 ~/.kube/config 파일의 users.name에 지정할 이름과 매칭시켜야한다.

해당 인증서는 자체적으로 만든 인증서이므로 이 인증서로는 인증을 받을 수 없다. 서명을 받아야 한다.

 

 vagrant@k8s-node1  ~/rbac  kubectl api-resources | grep csr                 
certificatesigningrequests        csr          certificates.k8s.io/v1                 false        CertificateSigningRequest

CertificateSigningRequest라는 오브젝트가 있다. 이것을 생성한다.

 

cat myuser.csr | base64 | tr -d "\n"

인코딩 값의 엔터를 모두 잘라내고 한줄로 이어붙여준다.

 

 

csr.yaml

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser-csr
spec:
  usages:
  - client auth # 클라이언트가 인증하기 위함이므로  
  signerName: kubernetes.io/kube-apiserver-client # apiserver가 서명해줘야 apiserver에게 인증받을 수 있다.
  request: LS0tLS1CRUdJTiB # 앞서 만든 인증서의 base64 인코딩 값을 넣어줌
 vagrant@k8s-node1  ~/rbac  kubectl get csr   
No resources found

 vagrant@k8s-node1  ~/rbac  kubectl create -f csr.yaml     
certificatesigningrequest.certificates.k8s.io/myuser-csr created

 vagrant@k8s-node1  ~/rbac  kubectl get csr           
NAME         AGE   SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
myuser-csr   4s    kubernetes.io/kube-apiserver-client   kubernetes-admin   <none>              Pending

Pending 상태이다. 아직 승인을 받기 전이므로 Pending은 정상적인 상태이다.

myuser-csr이며 서명자는 apiserver이며 요청자는 kubernetes-admin(나 자신)이다. 상태가 Pending이다.

 

 vagrant@k8s-node1  ~/rbac  kubectl certificate approve myuser-csr
certificatesigningrequest.certificates.k8s.io/myuser-csr approved

 vagrant@k8s-node1  ~/rbac  kubectl get csr                       
NAME         AGE     SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
myuser-csr   2m21s   kubernetes.io/kube-apiserver-client   kubernetes-admin   <none>              Approved,Issued

인증서의 상태가 Approved,Issued로 변경되었다.

 

 vagrant@k8s-node1  ~/rbac  kubectl get csr myuser-csr -o yaml
apiVersion: certificates.k8s.io/v1

status:
  certificate: 발급된 인증서 내용 

certificate에서 발급된 인증서의 내용을 확인할 수 있다.

 

kubectl get csr myuser-csr -o jsonpath='{.status.certificate}' | base64 -d > myuser.crt

.status.certificate 내용을 jsonpath 방식으로 확인한 뒤 base64 디코딩을 거치고 myuser.crt 파일에 저장한다. 해당 파일은 서명된 인증서가 된다.

 

 vagrant@k8s-node1  ~/rbac  openssl x509 -in myuser.crt --text

x509 인증서를 myuser.crt에 넣어서 텍스트로 출력하는 명령이며 인증서를 해석해서 볼 수 있다.

 

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            36:dd:bd:c1:b4:36:58:7b:f6:3b:7e:7b:41:62:bc:e0
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: May 27 17:12:42 2022 GMT
            Not After : May 27 17:12:42 2023 GMT
        Subject: CN = myuser

발급자는 쿠버네티스의 CA이며 발급 대상은 myuser이다.

 

 vagrant@k8s-node1  ~/rbac  ls
csr.yaml  myuser.crt  myuser.key

이제 해당 인증서와 key를 가지고 인증할 수 있다.

 

Kubeconfig 사용자 생성

kubectl config set-credentials myuser --client-certificate=myuser.crt --client-key=myuser.key --embed-certs=true

--embed-certs=true 옵션을 추가하여 인증서와 key 값에 파일의 위치가 아닌 실제 값이 들어갈 수 있도록 한다.

이는 나중에 인증서와 key 파일의 위치가 변경될 수 있음을 염두에 둔 것이다.

 

Kubeconfig 컨텍스트 생성

kubectl config set-context myuser@cluster.local --cluster=cluster.local --user=myuser --namespace=default
kubectl config get-users
kubectl config get-clusters
kubectl config get-contexts
 vagrant@k8s-node1  ~/rbac  kubectl config get-users
NAME
kubernetes-admin
myuser
 vagrant@k8s-node1  ~/rbac  kubectl config get-contexts
CURRENT   NAME                             CLUSTER         AUTHINFO           NAMESPACE
*         kubernetes-admin@cluster.local   cluster.local   kubernetes-admin   
          myuser@cluster.local             cluster.local   myuser             default
kubectl config use-context myuser@cluster.local
 vagrant@k8s-node1  ~/rbac  kubectl config use-context myuser@cluster.local
Switched to context "myuser@cluster.local".

 vagrant@k8s-node1  ~/rbac  kubectl config get-contexts                                                            
CURRENT   NAME                             CLUSTER         AUTHINFO           NAMESPACE
          kubernetes-admin@cluster.local   cluster.local   kubernetes-admin   
*         myuser@cluster.local             cluster.local   myuser             default

 vagrant@k8s-node1  ~/rbac  kubectl get nodes                                                                      
Error from server (Forbidden): nodes is forbidden: User "myuser" cannot list resource "nodes" in API group "" at the cluster scope

역할을 부여한적이 없기 때문에 Forbidden이다.
apiserver에 인증은 받았으나 어떤 작업을 할 수 있는 권한이 없는 상태이다.

 


 

생성한 사용자(myuser)에게 view 권한을 부여한다.
ClusterRoleBinding을 만들어서 사용자와 ClusterRole을 연결시키고 myuser 사용자로 전환했을 때 정보를 view 할 수 있는지 확인해보자
 vagrant@k8s-node1  ~/rbac  kubectl get clusterrole | grep -v ^system
NAME                                                                   CREATED AT
admin                                                                  2022-05-16T07:31:52Z
calico-kube-controllers                                                2022-05-16T07:33:47Z
calico-node                                                            2022-05-16T07:33:17Z
cluster-admin                                                          2022-05-16T07:31:52Z
edit                                                                   2022-05-16T07:31:52Z
ingress-nginx                                                          2022-05-21T17:01:36Z
kubeadm:get-nodes                                                      2022-05-16T07:31:54Z
metallb-system:controller                                              2022-05-21T07:25:09Z
metallb-system:speaker                                                 2022-05-21T07:25:09Z
nfs-client-provisioner-runner                                          2022-05-24T05:10:49Z
view                                                                   2022-05-16T07:31:52Z

system:으로 시작하는 것들은 kubeadm으로 설치할 때 쿠버네티스가 필요에 의해 만들어놓은 ClusterRole이다.

우리가 사용하는 권한은 view, edit, admin : 역할까지 관리, cluster-admin이 모든 권한을 가진다.

 

ClusterRoleBinding 생성
myuser-view-crb.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: myuser-view-crb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: myuser

참조할 역할은 하나만 지정할 수 있고 역할에 대한 대상은 여러개 지정할 수 있다.

 

 vagrant@k8s-node1  ~/rbac  kubectl describe clusterrolebinding myuser-view-crb 
Name:         myuser-view-crb
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  view
Subjects:
  Kind  Name    Namespace
  ----  ----    ---------
  User  myuser  

view라는 ClusterRolemyuser에게 할당해주었다.

 

 vagrant@k8s-node1  ~/rbac  kubectl config use-context myuser@cluster.local          
Switched to context "myuser@cluster.local".

 vagrant@k8s-node1  ~/rbac  kubectl config get-contexts                    
CURRENT   NAME                             CLUSTER         AUTHINFO           NAMESPACE
          kubernetes-admin@cluster.local   cluster.local   kubernetes-admin   
*         myuser@cluster.local             cluster.local   myuser             default

 vagrant@k8s-node1  ~/rbac  kubectl get pods   
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-758f8cd4d6-wpjbt   1/1     Running   0          3d20h

 vagrant@k8s-node1  ~/rbac  kubectl get deploy          
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           3d20h

 vagrant@k8s-node1  ~/rbac  kubectl get pod -A               
NAMESPACE        NAME                                      READY   STATUS    RESTARTS          AGE
default          nfs-client-provisioner-758f8cd4d6-wpjbt   1/1     Running   0                 3d20h
ingress-nginx    ingress-nginx-controller-2jrhn            1/1     Running   2 (3d23h ago)     6d8h
ingress-nginx    ingress-nginx-controller-2pk4g            1/1     Running   2 (3d23h ago)     6d8h
ingress-nginx    ingress-nginx-controller-cmzt4            1/1     Running   3 (3d23h ago)     6d8h
kube-system      calico-kube-controllers-5788f6558-8sp9c   1/1     Running   12 (3d23h ago)    9d
kube-system      calico-node-2jpkt                         1/1     Running   6 (3d23h ago)     8d
kube-system      calico-node-ft9lf                         1/1     Running   11 (3d23h ago)    11d
kube-system      calico-node-r257f                         1/1     Running   13 (3d23h ago)    11d
kube-system      coredns-8474476ff8-4bmms                  1/1     Running   11 (3d23h ago)    11d
kube-system      coredns-8474476ff8-q7svm                  1/1     Running   13 (3d23h ago)    11d
kube-system      dns-autoscaler-5ffdc7f89d-r45qt           1/1     Running   13 (3d23h ago)    11d
kube-system      kube-apiserver-node1                      1/1     Running   14 (3d23h ago)    11d
kube-system      kube-controller-manager-node1             1/1     Running   16 (3d23h ago)    11d
kube-system      kube-proxy-9d5mw                          1/1     Running   2 (3d23h ago)     6d8h
kube-system      kube-proxy-m2xmr                          1/1     Running   3 (3d23h ago)     6d8h
kube-system      kube-proxy-zmm5n                          1/1     Running   2 (3d23h ago)     6d8h
kube-system      kube-scheduler-node1                      1/1     Running   17 (3d23h ago)    11d
kube-system      metrics-server-c57c76cf4-x9nwj            1/1     Running   3 (3d23h ago)     6d8h
kube-system      nginx-proxy-node2                         1/1     Running   11 (3d23h ago)    11d
kube-system      nginx-proxy-node3                         1/1     Running   7 (3d23h ago)     8d
kube-system      nodelocaldns-hbm44                        1/1     Running   6 (3d23h ago)     8d
kube-system      nodelocaldns-mq9nm                        1/1     Running   153 (3d23h ago)   11d
kube-system      nodelocaldns-qc6vf                        1/1     Running   157 (3d23h ago)   11d
metallb-system   controller-77c44876d-dcv29                1/1     Running   2 (3d23h ago)     6d18h
metallb-system   speaker-987lb                             1/1     Running   2 (3d23h ago)     6d18h
metallb-system   speaker-fnpnb                             1/1     Running   2 (3d23h ago)     6d18h
metallb-system   speaker-zstnm                             1/1     Running   3 (3d23h ago)     6d18h

사용자를 myuser로 변경한 뒤에도 리소스를 view할 수 있다.
ClusterRole이기 때문에 특정 네임스페이스에 구애받지 않고 모든 네임스페이스를 볼 수 있다.

 

 vagrant@k8s-node1  ~/rbac  kubectl describe clusterrole view

 vagrant@k8s-node1  ~/rbac  kubectl describe clusterrole view | grep node
 vagrant@k8s-node1  ~/rbac  kubectl get secrets
Error from server (Forbidden): secrets is forbidden: User "myuser" cannot list resource "secrets" in API group "" in the namespace "default"

 vagrant@k8s-node1  ~/rbac  kubectl get nodes
Error from server (Forbidden): nodes is forbidden User "myuser" cannot list resource "nodes" in API group "" at the cluster scope

node와 secret 관련 권한을 가지지 않으므로 Forbidden

 

 vagrant@k8s-node1  ~/rbac  kubectl run nettool -it --image ghcr.io/c1t1d0s7/network-multitool --rm
Error from server (Forbidden): pods is forbidden: User "myuser" cannot create resource "pods" in API group "" in the namespace "default"

view 권한만을 가지므로 실행은 Forbidden이다.

 

 

📌 auth can-i

 vagrant@k8s-node1  ~/rbac  kubectl auth can-i create pd                                           
Warning: the server doesn't have a resource type 'pd'
no
 👻 vagrant@k8s-node1  ~/rbac  kubectl auth can-i create pod
no
 👻 vagrant@k8s-node1  ~/rbac  kubectl auth can-i get nodes 
Warning: resource 'nodes' is not namespace scoped
no
 👻 vagrant@k8s-node1  ~/rbac  kubectl auth can-i get pods 
yes
 vagrant@k8s-node1  ~/rbac  kubectl auth can-i update pods
no

내가 파드를 만들 수 있는가 ? → no
can-i로 어떤 작업을 할 수 있는지 체크할 수 있다.

728x90