쿠버네티스 환경에서 작업할 때, 클라이언트가 API 서버에 접근하기 위해서는 kubeconfig를 가지고 kubectl 이라는 툴을 사용한다.

이 때 클라이언트는 서버에 접근하기 위해 인증(Authentication) → 인가(Authorization) 단계를 거치게 된다. 더 나아가 Admission Control 단계도 있다.

Untitled

  • Authentication: 어느 페이지에 로그인하는 것과 같다. 해당 사용자를 인증하고 접속하게 되는 것이다. kubeconfig로 사용자를 증명할 수 있다.
  • Authorization: 로그인한 이후에 해당 사용자에 대한 권한에 따라 접근할 수 있는 부분이 달라진다. SA에 바인딩되어 있는 Role에 따라 권한 부여가 가능하다.
  • Admission Control: 인증/인가 단계를 거친 후에 요청을 가로챌 수 있다. 적절한 요청을 했는지 검증하는 단계로, 사용자의 요청에 더 나아가 추가로 설정해 주는 부분이 있다든지, 요청을 거부할 수도 있다.

Admission Control 단계는 Mutating admissionValidating admission을 포함하고 있으며, 이 단계까지 거치고 나면 API 서버에 요청했던 데이터가 etcd에 저장된다.

이 글에서는 Admission Control은 언급되지 않는다.

kubeconfig

kubeconfig는 /$HOME.kube/config에 정의된 환경파일이다.

Untitled 1

[KubeConfig란? devlog.akasai](https://akasai.space/kubernetes/about-kubeconfig/)

kubconfig는 clusters, contexts, users 세 가지로 나뉜다.

  • clusters: API 서버 정보(ip, port, ca 인증서)
  • users: 사용자 인증 정보(클라이언트 키/인증서)
  • contexts: users@clusters로 나타내며, users 정보를 가지고 clusters에 접근하겠다는 접속 정보 조합이다.

kubectl로 위 인증 정보들을 하나하나 옵션으로 주지 않아도 kubeconfig에 정의되어 있다면 간편하게 API를 요청할 수 있다.

인증/인가 실습

테스트 네임스페이스와 파드를 생성하여 Role/RoleBinding이 없는 SA와 있는 SA의 권한 테스트를 진행해 보겠다.

Untitled

** 가시다님 그림 참조*

  1. 네임스페이스 생성 및 확인

     # kubectl create namespace dev-team
     namespace/dev-team created
     # kubectl create ns infra-team
     namespace/infra-team created
    

    Untitled 3

  2. SA 생성 및 확인

     # kubectl create sa dev-k8s -n dev-team
     serviceaccount/dev-k8s created
     # kubectl create sa infra-k8s -n infra-team
     serviceaccount/infra-k8s created
    

    Untitled 4

    Untitled 5

  3. 현재 만들어진 리소스는 네임스페이스와 SA밖에 없다.

    Untitled 6

SA를 지정한 POD 생성

  1. serviceAccountName에 SA를 지정한 POD를 생성한다.

     cat <<EOF | kubectl create -f -
     apiVersion: v1
     kind: Pod
     metadata:
       name: dev-kubectl
       namespace: dev-team
     spec:
       serviceAccountName: dev-k8s
       containers:
       - name: kubectl-pod
         image: bitnami/kubectl:1.28.5
         command: ["tail"]
         args: ["-f", "/dev/null"]
       terminationGracePeriodSeconds: 0
     EOF
    
     cat <<EOF | kubectl create -f -
     apiVersion: v1
     kind: Pod
     metadata:
       name: infra-kubectl
       namespace: infra-team
     spec:
       serviceAccountName: infra-k8s
       containers:
       - name: kubectl-pod
         image: bitnami/kubectl:1.28.5
         command: ["tail"]
         args: ["-f", "/dev/null"]
       terminationGracePeriodSeconds: 0
     EOF
    

    Untitled 7

  2. 테스트 POD에 들어가서 POD를 조회해 보고 auth can-i로 해당 SA가 가진 권한을 확인해 본다. 아직 아무런 권한이 없기 때문에 당연히 POD 조회할 수 없다. 아직 Authentication만 통과된 것이다.

    Untitled 8

    Untitled 9

  3. 리소스 현황을 그림으로 보자면 아래와 같다.

    Untitled 10

Role & RoleBinding

이제 권한을 부여해 주는 작업을 한다. 이 작업이 바로 Authorization이다.

  1. Role 생성

     cat <<EOF | kubectl create -f -
     apiVersion: rbac.authorization.k8s.io/v1
     kind: **Role**
     metadata:
       name: role-dev-team
       namespace: dev-team
     rules:
     - apiGroups: ["*"]
       resources: ["*"]
       verbs: ["*"]
     EOF
    
     cat <<EOF | kubectl create -f -
     apiVersion: rbac.authorization.k8s.io/v1
     kind: **Role**
     metadata:
       name: role-infra-team
       namespace: infra-team
     rules:
     - apiGroups: ["*"]
       resources: ["*"]
       verbs: ["*"]
     EOF
    

    Untitled 11

  2. Rolebinding에서 위에 생성한 RoleSA를 지정해 준다.

     cat <<EOF | kubectl create -f -
     apiVersion: rbac.authorization.k8s.io/v1
     kind: **RoleBinding**
     metadata:
       name: roleB-dev-team
       namespace: dev-team
     roleRef:
       apiGroup: rbac.authorization.k8s.io
       kind: Role
       name: role-dev-team
     subjects:
     - kind: ServiceAccount
       name: dev-k8s
       namespace: dev-team
     EOF
    
     cat <<EOF | kubectl create -f -
     apiVersion: rbac.authorization.k8s.io/v1
     kind: **RoleBinding**
     metadata:
       name: roleB-infra-team
       namespace: infra-team
     roleRef:
       apiGroup: rbac.authorization.k8s.io
       kind: Role
       name: role-infra-team
     subjects:
     - kind: ServiceAccount
       name: infra-k8s
       namespace: infra-team
     EOF
    

    Untitled 12

  3. 권한을 부여한 Role을 RoleBinding 리소스를 통해 SA에게 연결해 주었다.

    Untitled 13

다시 POD 조회하고 권한을 확인해 보면!

Untitled 14

Untitled 15

이제 yes로 권한이 생겼다.

아래와 같은 그림으로 완성되어 이제 해당 POD에서 리소스 확인이 가능하다.

단, Role과 RoleBinding은 네임스페이스 리소스이기 때문에 kubectl get pods하면 각각의 네임스페이스에서 생성한 POD만 보이는 것이다.

Untitled 16

네임스페이스 한정이 아니라 전체를 보고 싶다면 ClusterRole과 ClusterRoleBinding을 사용할 수 있다.

Categories:

Updated:

Leave a comment