72 / 120 [ k8s ]RBAC(인가) Kubeconfig

RungNyeok·2022년 5월 31일
0

클라우드부트캠프

목록 보기
2/2

RBAC : Role Based Access Control

✔️ Kubeconfig

kubeconfig 파일은 k8s의 설정 파일로,
kubectl 명령어로 apiserver에 접근할 때 사용할 인증 정보를 담고 있다.


이 kubeconfig 는 크게 3가지 부분으로 구성되어 있다.

  • clusters : 쿠버네티스 API 서버 정보(IP 또는 도메인)로, 여러 클러스터를 명시할 수 있다.

  • users : 쿠버네티스 API에 접속하기 위한 사용자 목록으로, 인증방식에 따라 형태가 다를 수 있다.

    • user: 유저 목록
      client-certificate-data: REDACTED : 인증서
      client-key-data: REDACTED : 개인 키
  • context : user와 cluster 사이의 관계를 매핑한 것으로, 어떤 context를 사용하느냐에 따라 cluster와 user가 결졍된다. context를 기반으로 "어떤 Cluster에 어떤 User가 인증을 통해 쿠버네티스를 사용한다." 의미로 해석하면 된다.

    • context에는 여러 종류가 있을 수 있으며, 현재 사용하는 context를 current-context라고 한다.


kubeconfig 파일의 위치

~/.kube/config



kubeconfig 파일 내용 확인

$ kubectl config view           
apiVersion: v1
kind: Config

preferences: {}

clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://127.0.0.1:6443
  name: cluster.local

users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
    
contexts:
- context:
    cluster: cluster.local
    user: kubernetes-admin
  name: kubernetes-admin@cluster.local
  
current-context: kubernetes-admin@cluster.local

/etc/kubernetes/pki 에 인증서와 키가 존재하며 ca.crt 가 발급해준다.
kubectl은 항상 ~/.kube/config를 가장 먼저 찾는다.

위치가 홈 디렉토리가 아니라면 KUBECONFIG 환경 변수를 설정하거나,
--kubeconfig 옵션을 사용하여 다른 kubeconfig파일을 사용할 수 있다.


예시

$ kubectl config view --kubeconfig=gwon-kubeconfig


실제로 ~/.kube/config 파일만 있다면, 즉 서버의 위치만 알려준다면, 쿠버네티스 클러스터에 접근할 수 있다.

다음은 윈도우에 kubeconfig 파일을 추가하고 kubectl get nodes 명령을 실행한 결과이다.


powershall 관리자 권한으로 실행 후 choco 설치

PS C:\Windows\system32> choco install kubernetes-cli --version=1.22.4

kubectl을 사용할 수 있게 된다.


하지만kubectl get nodes 할 시 오류가 발생한다.
kubeconfig 파일이 없기 때문이다.

PS C:\Windows\system32> kubectl get nodes
Unable to connect to the server: dial tcp [::1]:8080: connectex: No connection could be made because the target machine actively refused it.

아래 명령어를 사용하여 config 파일 내용 복사

$ cat ~/.kube/config

윈도우에 파일 생성하기

 PS C:\Users\ParkNeunglyeok> mkdir .kube
 PS C:\Users\ParkNeunglyeok> .kube/config

config 파일 안의 cluster server ip를 control node ip로 바꾼다.
config

- cluster:
    certificate-authority-data: LS0tLS1CR...
    server: https://192.168.100.101:6443
  name: cluster.local

kubectl get nodes 명령을 실행한 결과이다.

PS C:\Users\ParkNeunglyeok> kubectl get nodes
NAME    STATUS   ROLES                  AGE   VERSION
node1   Ready    control-plane,master   22h   v1.22.8
node2   Ready    <none>                 22h   v1.22.8
node3   Ready    <none>                 22h   v1.22.8

서버를 찾아 정삭적으로 결과가 출력되는 것을 확인할 수 있다.



context 확인하기

  • context 목록 확인하기

CURRENT 가 * 인 것은, 현재 사용하고 있는 current-context라는 의미 이다.

$ kubectl config get-contexts
CURRENT   NAME                             CLUSTER         AUTHINFO           NAMESPACE
*         kubernetes-admin@cluster.local   cluster.local   kubernetes-admin   
  • current-context 확인하기
$ kubectl config current-context
kubernetes-admin@cluster.local


cluster 목록 확인하기

$ kubectl config get-clusters   
NAME
cluster.local


⭐context 전환하기⭐

kubeconfig 파일에 임의로 cluster와 user, 그리고 context를 추가해보자.

.kube/config

- cluster:
    server: https://1.1.1.1
  name: mycluster
~~~~~~~~~~~~~~~~~  
- context:
    cluster: mycluster
    user: myadmin
  name: myadmin@mycluster
~~~~~~~~~~~~~~~~~  
- name: myadmin

저장 후 확인하면 cluster와 context가 추가된 것을 확인할 수 있다.

$ kubectl config get-contexts
CURRENT   NAME                             CLUSTER         AUTHINFO           NAMESPACE
*         kubernetes-admin@cluster.local   cluster.local   kubernetes-admin   
          myadmin@mycluster                mycluster       myadmin 
          
$ kubectl config get-clusters
NAME
cluster.local
mycluster

context를 전확하는 방법은,
kubeconfig 파일 내에 다음과 같이 직접 선언하거나

current-context: kubernestes-admin@cluster.local

명령형 커맨드를 통해 current-context를 전환할 수 있다.

$ kubectl config use-context myadmin@mycluster

또 다른 방법으로 kubectx가 있다.

$ kubectx myadmin@mycluster

kubectx는 손쉽게 cluster context를 변경할 수 있는 툴로, 실제로 많이 사용된다.



새로운 Context 만들기

$ kubectl config set-context new-context --cluster=local-kubernetes --user=gwon




✔️ k8s Authenticating ( 인증 )

https://kubernetes.io/docs/reference/access-authn-authz/authentication/

쿠버네티스에는 계정, 사용자라는 개념이 존재하며,
크게 2가지 컨셉 Serviceaccount(SA) 와 NormalUser 가 있다.



1. Service Account ( SA )

쿠버네티스가 관리하는 SA 사용자로, 사용자가 아닌 Pod가 사용한다.

따로 지정하지 않더라도 파드를 만들 때 SA가 default로 성정된다.
파드의 정보를 yaml 형식으로 확인하면 serviceAccount 가 default로 지정되어있는 것을 확인할 수 있다.

$ kubectl get po myweb-rs-454m2 -o yaml | grep serviceAccount
  serviceAccount: default

또한 볼륨을 세팅하지 않더라도 무조건 볼륨 1개가 세팅되고,
볼륨에는 SA 계정의 Token 정보가 들어있다.

그리고 애플리케이션은 이러한 Token 정보로 쿠버네티스에 인증을 받을 수 있다.

$  kubectl describe  po myweb-rs-454m2
~~~~~~~~~
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4qgwr (ro)
~~~~~~~~~
Volumes:
  kube-api-access-4qgwr: # 생성되는 볼륨
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true

모든 Pod 는 만들어질 때, SA계정의 토큰이 /var/run/secrets/kubernetes.io/serviceaccount 에 볼륨으로 할당된다.



정리하자면 SA 계정을 만들고, SA 계정에 권한을 부여한 뒤, 파드를 만들때 해당 SA 계정을 지정하게 되면
그 파드에서 실행되는 애플리케이션이 해당되는 SA권한으로 쿠버네티스 작업을 수행할 수 있게 된다.
( 파드는 SA 계정을 통해서, SA계정에 부여받은 Token 정보를 가지고 작업을 할 수 있게 된다. )


리소스 확인

$ kubectl api-resources | grep serviceacc
serviceaccounts                   sa           v1                                     true         ServiceAccount

SA 생성

$ kubectl create sa <NAME>


2. Normal User

normal user는 쿠버네티스가 관리하지 않는 일반 사용자로, 인증서는 쿠버네티스가 발급해준다.
k8s 에는 normal user account를 직접적으로 관리하는 object가 없고,
normal user account는 API call 을 통해 cluster로 포함될 수 없다.

일반 사용자는 API 호출을 통해 추가할 수 없지만,
클러스터의 인증 기관 ( CA ) 에서 서명한 유효한 인증서를 제시하는 모든 사용자는 인증된 것으로 간주한다.
관련 내용은 실습2에서 확인할 수 있다.



인증 방법

1. x509 인증서

쿠버네티스를 설치할 때 자동으로 생성되는 것으로, kubeconfig 파일에 인증서 내용이 직접 들어가 있다.
이 인증서는 마스터 노드의 /etc/kubernetes/pki 디렉터리에 있는 ca.crt 를 루트 인증서로 하여 만들어진 하위 인증서 중 하나이다.


2. Static Token (정적 토큰)

  • Bearer token : http 헤더에 인증 토큰을 실어서 보낸다

    • 단, 따로 암호화를 하지 않기 때문에, 외부에 노출되기 쉽다. 일반적으로 테스팅을 위한 용도로 사용한다.
      http 헤더 예시: Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
  • Bootstrap Toekn

  • ⭐Service Account Token⭐ : JSON Web Token (JWT) (JSON Web Tokens - https://jwt.io/)

SA 계정의 토큰 정보는 Secret에 저장된다.
secret를 확인하면 token 정보, ca 인증서, namespace를 확인할 수 있다.


3. OpenID Connect(OIDC) Token

외부 인증을 표준화하는 인터페이스로, 중앙 집중화된 통제가 가능해지며, 안정하게 인증을 받을 수 있게된다.

  • okta : 인증 서버 (SaaS)
  • AWS IAM



✔️ RBAC

RBAC ( Role-based Access Control ) 는 조직 내 개별 사용자의 역할에 따라 컴퓨터 또는 네트워크 리소스에 대한 액세스를 규제하는 인 (Authorization) 방식이다.

RBAC 는 누가 (주체), 무엇을 (동사), 어디에 (네임스페이스) 실행할 수 있는지 결정하는 권한 또는 템플릿 집합을 수반하는 Identity 및 엑세스 관리 형식이다.


☁️참고

  • Identification : 식별
  • Authentication : 인증
  • Authorization : 인가 ( 권한을 부여하는 것 )
  • Credential : 자격 증명


리소스 확인

$ 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

rolebindings, roles 는 네임스페이스 (NS)를 사용하고,
clusterrolebinding, clusterroles는 네임스페이스를 사용하지 않는 것을 확인할 수 있다.



Role 과 ClusterRole

  • Role : 특정 네임스페이스에 한정된 정책 (특정 네임스페이스 + '어디서 무엇을 어떻게')

  • ClusterRole : 클러스터 전체에 한정된 정책 (클러스터 전체 + '어디서 무엇을 어떻게')

  • RoleBinding : 역할이 특정 네임스페이스에 한정된 정책을 따르도록 적용 (어떤 역할이 특정 네임스페이스에서 하는가?)

    • Role <--> RoleBinding <--> SA/User
    • Role 리소스와 SA/User를 연결 시켜준다.
  • ClusterRoleBinding : 역할이 클러스터 전체에 한정된 정책을 따르도록 적용 (어떤 역할이 클러스터 전체에서 하는가?)


쿠버네티스에 대한 요청이 처리되는 전체 과정을 요약하면 아래와 같다



RBAC 권한 부여 사용 예제


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)가 어떤 권한을 행사할 수 있는지 설정한다.


요청 동사

HTTP 동사요청 동사예시
POSTcreatekubectl create
kubectl apply
GET, HEADget(개별리소스)
list(전체 오브젝트 내용을 포함한 리소스 모음)
watch(개별 리소스 또는 리소스 모음을 주시)
get : kubectl get po myweb
list : kubectl get pos
watch : kubectl get po -w
PUTupdatekubectl edit
kubectl replace
PATCHpatchkubectl patch
DELETEdelete(개별리소스)
deletecollection(리소스모음)
delete : kubectl delete po myweb
deletecollection : kubectl delete po --all

kubectl 명려 시 -v 옵션을 사용하면 실제로 kubectl이 어떻게 요청하는지 확인할 수 있다.

$ kubectl get po -v=7
$ kubectl delete -f myweb.yaml -v=7

☁️참고
kubectl auth can-i 명령을 통해, 내가 해당 명령에 대한 권한을 가지고 있는지 체크해볼 수 있다.

$ kubectl auth can-i [VERB}

예시

$ kubectl auth can-i create pod

$ kubectl auth can-i get nodes

$ kubectl auth can-i update pods

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

kubectl get clusterroles 명령을 통해 클러스터 내의 clusterrole 들을 확인할 수 있는데, 이때 system: 이 붙은 clusterrole은 쿠버네티스 설치 시에 기본적으로 만들어져 있는 clusterrole 이다.

$ kubectl get clusterroles
NAME                                                                   CREATED AT
admin                                                                  2022-05-30T07:26:54Z
calico-kube-controllers                                                2022-05-30T07:28:34Z
calico-node                                                            2022-05-30T07:28:10Z
cluster-admin                                                          2022-05-30T07:26:54Z
edit                                                                   2022-05-30T07:26:54Z
ingress-nginx                                                          2022-05-30T07:28:41Z
kubeadm:get-nodes                                                      2022-05-30T07:26:56Z
metallb-system:controller                                              2022-05-30T07:29:11Z
metallb-system:speaker                                                 2022-05-30T07:29:11Z
system:aggregate-to-admin                                              2022-05-30T07:26:54Z

많은 clusterrole 중 일반적으로 사용하는 role 은 다음과 같다.
(우리가 사용자에게 사용하라고 만들어 놓은 role 들이다.)

  • view : 읽을 수 있는 권한

  • edit : 생성/ 삭제/ 변경 할 수 있는 권한

  • admin : 모든 것 관리 (-RBAC의 ClusterRole 제외)

  • cluster-admin : 모든 것 관리


RolevBinding 예제

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

사용자의 name (여기서는 jane)은 .kube/config 의 user의 name과 매칭이 되어야한다.
예제 설명 : 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

예제 설명 : manager 에게 secret-reader 라는 ClusterRole이 연결된다.



nfs에서 생성한 nfs-subdir-external-provisionerrbac.yaml 파일을 주석과 함께 살펴보자.

https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/blob/master/deploy/rbac.yaml
rbac 파일 github 주소

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
rules:
  - apiGroups: [""] # core group
    resources: ["nodes"]
    verbs: ["get", "list", "watch"] # nfs파드는 다른 노드의 정보를 볼 수 있어야 한다.
  - apiGroups: [""] # core froup
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"] # pv는 만들고 삭제하는 것까지 가능해야 한다.
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"] # pvc에 pv에 대한 정보를 업데이트 할 수 있어야한다.
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"] # 스토리지 클래스 리소스를 볼 수 있어야 한다
  - apiGroups: [""]
    resources: ["events"] # describe 명령어로 확인하는 Events
    verbs: ["create", "update", "patch"] # 이벤트를 만들고 , 업데이트하고, 변경할 수 있어야 한다.
---
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

deployment를 만들 때 ServuceAccount를 지정하여, 컨테이너의 앱이 Api Server에 요청할 때 SA 계정의 토큰으로 인증을 받고, SA에 부여된 역할들로 수행할 수 있게된다.



💻 실습 1 : SA 만들기

다음과 같이 sa myuser1 을 생성한다.
` kubectl create sa <유저네임>

$ kubectl create sa myuser1
serviceaccount/myuser1 created

sa myuser1 생성 후 kubectl get 명령을 통해 확인할 수 있고,

$ kubectl get sa
NAME      SECRETS   AGE
default   1         47h
myuser1   1         44s

kubectl describe 명령을 통해 확인해보면 Token이 생성된 것을 확인할 수 있다.

$ kubectl describe sa myuser1                        
Name:                myuser1
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   myuser1-token-hbnp7
Tokens:              myuser1-token-hbnp7
Events:              <none>

그리고 해당 토큰이 secret 으로 생성되어있는 것을 확인할 수 있다.
SA 계정의 토큰 정보는 secret에 저장된다.

$ kubectl get secret         
NAME                  TYPE                                  DATA   AGE
myuser1-token-hbnp7   kubernetes.io/service-account-token   3      2m20s


💻 실습 2 : 사용자 생성을 위한 x509인증서를 만든 후, ClusterRoleBinding으로 Role 부여하기

Private Key를 생성한다.

$ openssl genrsa -out myuser.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..................................................................+++++
..........................................................+++++
e is 65537 (0x010001)

x509 인증서 요청을 생성한다.

$ openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"

현재 자체적으로 만든 인증서이기 때문에 이 인증서로는 인증을 받을 수 없다.
따라서 다음과 같은 csr 오브젝트를 이용하여 서명을 받아야한다.

$ kubectl api-resources | grep cer
certificatesigningrequests        csr          certificates.k8s.io/v1                 false        CertificateSigningRequest

CertificateSigningRequest를 생성하는 yaml 파일을 작성하는데, 앞서 만든 인증서를 코딩해줘야한다.

다음 명령어를 통해 한줄로 인코딩 후 % 빼고 복사해야한다.

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

csr.yaml

apiVersion: certificates.k8s.io/v1
kind: CertificateSigninRequest
metadata:
  name: myuser-csr
spec:
  usages: # 사용용도 -> 여러개 지정 가능
    - client auth # 클라이언트 인증
  signerName: kubernetes.io/kube-apiserver-client # 서명하는 사람, 서명하는 이름
  request: LS0tLS1CRU # 인크딩 결고 붙여넣기

생성

$ kubectl create -f csr.yaml
certificatesigningrequest.certificates.k8s.io/myuser-csr created

create 후 kubectl get 명령어로 확인할 수 있다. 이때 REQUESTOR은 '나' 이다.

$ kubectl get csr           
NAME         AGE   SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
myuser-csr   51s   kubernetes.io/kube-apiserver-client   kubernetes-admin   <none>              Pending

현재 상태가 Pending 이다.
다음 명령을 통해 myuser-csr를 허용/승인 해줘야 Pending이 풀린다.

$ kubectl certificate approve myuser-csr
certificatesigningrequest.certificates.k8s.io/myuser-csr approved

다시 상태를 확인해보면 Approved 승인 및 lssued 발급된 것을 확인할 수 있다.

$ kubectl get csr                       
NAME         AGE     SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
myuser-csr   2m52s   kubernetes.io/kube-apiserver-client   kubernetes-admin   <none>              Approved,Issued

yaml 형식으로 상세 정보를 확인할 수 있다.

$ kubectl get csr myuser-csr -o yaml

status.certificates가 발급된 인증서이다.

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  creationTimestamp: "2022-06-01T07:27:46Z"
  name: myuser-csr
  resourceVersion: "159968"
  uid: 54a22e0a-f99e-4a8f-b078-f8fc75cb9102
spec:
  groups:
  - system:masters
  - system:authenticated
  request: LS0tLS1CRUd...
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
  username: kubernetes-admin
status:
  certificate: LS0tLS1CRUd... # 발급된 인증서
  conditions:
  - lastTransitionTime: "2022-06-01T07:30:11Z"
    lastUpdateTime: "2022-06-01T07:30:11Z"
    message: This CSR was approved by kubectl certificate approve.
    reason: KubectlApprove
    status: "True"
    type: Approved

다음 명령으로 jsonpath를 통해 status.certificates만 추출,
파이프라인을 통해 출력을 넘겨받아 디코딩한 후
myuser.crt 파일에 넣으면, myuser.crt 가 바로 서명된 인증서가 된다.

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

myuser.crt x509 인증서를 text로 해석해서 출력해보면 Issuer(발급자) 와 Subject(공급자)가 다른 것을 확인 할 수 있고,
Issuer : kubernetes 즉, 쿠버네티스 CA가 발급해준 인증서인 것이다.

$ openssl x509 -in myuser.crt --text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            45:a4:40:24:44:2d:d8:89:c5:da:c6:12:ec:ff:8c:71
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: Jun  1 07:25:11 2022 GMT
            Not After : Jun  1 07:25:11 2023 GMT
        Subject: CN = myuser

이제 생성한 인증서 myuser.crt를 이용하여 Kubeconfig 사용자를 생성한다.
직접 kubeconfig 파일을 수정하거나, 다음과 같이 커맨드 명령어를 통해 생성할 수 있다.
이때 --embed-certs 옵션을 사용해야 자동으로 인코딩되어 깔끔하게 파일에 작성된다.

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

다음으로 Kubeconfig 컨텍스트를 생성해보자.
마찬가지로 직접 kubeconfig 파일에 작성할 수 있고, 다음과 같이 커맨드 명령어를 통해 생성할 수 있다.

kubectl config set-context --help

$ kubectl config set-context myuser@cluster.local --cluster=cluster.local --user=myuser --namespace=default
Context "myuser@cluster.local" created.

kubectl config 명령을 통해 생성된 user, cluster, context를 확인할 수 있다.

$ kubectl config get-users
NAME
kubernetes-admin
myuser

$ kubectl config get-clusters
NAME
mycluster

$ kubectl config get-contexts
CURRENT   NAME                             CLUSTER         AUTHINFO           NAMESPACE
*         kubernetes-admin@cluster.local   cluster.local   kubernetes-admin   
           myuser@cluster.local             cluster.local   myuser             default

다음 명령어를 통해 current-context로 설정한다.

$ kubectl config use-context myuser@cluster.local 
Switched to context "myuser@cluster.local".

kubectl auth can-i 명령을 통해 내가 권한이 잇는지 체크해볼 수 있는데, 아직 아무런 권한도 부여하지 않았기 때문에 no인 것을 확인할 수 있다.

$ kubectl auth can-i create pod                  
no

clusterrolebinding 을 통해 사용자에게 view Role(역할) 부여해보자.

먼저 원래 context로 다시 전환한다.

$ kubectl config use-context kubernetes-admin@cluster.local
Switched to context "kubernetes-admin@cluster.local".

그리고 다음과 같이 ClusterRoleBinding 파일을 작성한다.
myuser-view-crb.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: myuser-view-crb
roleRef: # 역할 지정 1개만 가능
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole 
  name: view # view 역할 부여
subjects: # 사용자 지정 여러개 가능
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: myuser
$ kubectl create -f myuser-view-crb.yaml
clusterrolebinding.rbac.authorization.k8s.io/myuser-view-crb created

view 역할(Role) 을 myuser 사용자에게 할당한 것을 확인할 수 있다.

$ 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  

다시 사용자를 전환하면

$ kubectl config use-context myuser@cluster.local          
Switched to context "myuser@cluster.local".

view 권한을 부여받은 것을 확인할 수 있다.

$ kubectl get pods                                                                       
No resources found in default namespace.
profile
TIL(Today I Learned)을 실천하기 위한 블로그

0개의 댓글