본문 바로가기

Container/Kubernetes

[K8S] Authorization

쿠버네티스의 Authorization Mode는 클라이언트의 요청이 허가(Authorization)되는 방식을 결정한다.

클라이언트(사용자 또는 서비스)가 Kubernetes API 서버로 요청을 보낼 때, 요청이 허용되거나 거부되는 과정을 제어한다.

kube-apiserver의 `--authorization-config` 옵션을 통해서 설정할 수 있으며, 따로 지정하지 안으면 'AlwaysAllow'로 설정되고 하나 이상의 모드를 조합하여 사용할 수 있다.

 

$ controlplane ~ ➜  ps -aux | grep authorization
root        3212  0.0  0.3 1521124 262820 ?      Ssl  08:08   0:31 kube-apiserver --advertise-address=192.168.100.167 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=172.20.0.0/16 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
# Node,RBAC 모드인 것 확인 가능

(1) Node

  • 역할:
    • Kubernetes 노드(kubelet)가 클러스터의 리소스를 안전하게 요청할 수 있도록 허용한다.
    • 여러 모드가 설정되어 있으면 Node authorizer가 가장 먼저 처리한다.
  • 작동 방식:
    • 노드가 자신에게 예약된 Pod에 대한 정보만 가져올 수 있도록 제한한다.
    • kubelet이 자신의 Pod, Secret, ConfigMap 등을 읽는 요청

(2) RBAC (Role-Based Access Control)

  • 역할:
    • 사용자, 그룹, 서비스 계정에 권한(Role)을 부여하여 리소스에 대한 접근을 제어.
  • 작동 방식:
    • RBAC 정책(Role, RoleBinding, ClusterRole, ClusterRoleBinding)을 기반으로 요청을 허가.
  • 사용 예:
    • 특정 네임스페이스의 Pod을 읽는 권한만 부여.
  • 장점:
    • 세분화된 권한 관리 가능.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role   # Role로 설정(default)
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]  # 비워둘 수 있다.
  resources: ["pods"] # 필수
  verbs: ["get", "list", "watch"]  # 필수 (Action)
- apiGroups: [""]  # 여러 규칙 추가 가능
  resources: ["ConfigMap"] 
  verbs: ["create"]

 

  • 접근 확인
    • auth can-i는 RBAC 정책을 기반으로 현재 사용자 또는 지정된 사용자/그룹이 읽기, 쓰기 등을 수행할 수 있는지 확인하는 데 사용한다.
    • 사용 사례
      • 디버깅: 특정 작업이 실패했을 때, 원인이 권한 부족인지 확인
      • 환경 설정 테스트: 특정 사용자나 서비스 계정의 권한을 테스트
      • 관리자 권한 확인: 클러스터 관리자나 특정 사용자에게 모든 권한이 부여되었는지 확인
# get, list, create, delete 등 조회 가능
$ kubectl auth can-i create deployments
yes  # 요청된 작업에 대한 권한이 있음
$ kubectl auth can-i delete nodes
no

# 네임스페이스 지정
$ kubectl auth can-i get pods --namespace default
# 모든 네임스페이스 확인
$ kubectl auth can-i list pods --all-namespaces

# 특정 사용자, 그룹, 서비스 계정의 권한 확인하려면 --as 또는 --as-group 옵션 사용
$ kubectl auth can-i create pods --as system:serviceaccount:default:my-service-account

 

kubectl create role

kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run=server|client|none]

[예시]
# Create a role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods

# 권한이 없어 조회가 안될 때
$ kubectl get pods --as dev-user 
Error from server (Forbidden): pods is forbidden: User "dev-user" cannot list resource "pods" in API group "" in the namespace "default

# 새로운 롤 생성
$ kubectl create role developer --verb=list,create,delete --resource=pods
role.rbac.authorization.k8s.io/developer created

$  kubectl describe role developer
Name:         developer
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [list create delete]
# 새로운 롤 바인딩 생성 후 dev-user와 바인딩
$ kubectl create rolebinding dev-user-binding --role=developer --user=dev-user
rolebinding.rbac.authorization.k8s.io/dev-user-binding created

$ kubectl describe rolebinding dev-user-binding 
Name:         dev-user-binding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  developer
Subjects:
  Kind  Name      Namespace
  ----  ----      ---------
  User  dev-user

 

  • Role edit
controlplane ~ ➜  kubectl get roles -n blue
NAME        CREATED AT
developer   2025-01-22T06:37:12Z

controlplane ~ ➜  kubectl get rolebinding -n blue
NAME               ROLE             AGE
dev-user-binding   Role/developer   7m58s

controlplane ~ ➜  kubectl describe role developer -n blue
Name:         developer
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 [blue-app]      [get watch create delete]

# detail을 얻고싶은 Pod는 dark-blue-app인데,blue-app으로 resource가 등록되어 있다.
# Edit
controlplane ~ ➜  kubectl edit role developer -n blue
role.rbac.authorization.k8s.io/developer edited

controlplane ~ ➜  kubectl describe role developer -n blue
Name:         developer
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names   Verbs
  ---------  -----------------  --------------   -----
  pods       []                 [dark-blue-app]  [get watch create delete]

# 조회 가능
controlplane ~ ➜  kubectl get pod dark-blue-app -n blue --as dev-user
NAME            READY   STATUS    RESTARTS   AGE
dark-blue-app   1/1     Running   0          16m

 

  •  새로운 권한 추가 
controlplane ~ ➜  kubectl create deployment nginx --image=nginx -n blue --as dev-user
error: failed to create deployment: deployments.apps is forbidden: User "dev-user" cannot create resource "deployments" in API group "apps" in the namespace "blue"
# deployment 권한 이슈 발생
controlplane ~ ✖ kubectl edit role developer -n blue
role.rbac.authorization.k8s.io/developer edited
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: "2025-01-22T07:12:22Z"
  name: developer
  namespace: blue
  resourceVersion: "1251"
  uid: ae8dc725-6b77-45f4-9352-8355d9831600
rules:
- apiGroups:
  - ""
  resourceNames:
  - dark-blue-app
  resources:
  - pods
  verbs:
  - get
  - watch
  - create
  - delete
- apiGroups: ## 새로 추가!
  - apps
  resources:
  - deployments
  verbs:
  - get
  - watch
  - create
  - delete
  
controlplane ~ ➜  kubectl describe role developer -n blue
Name:         developer
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources        Non-Resource URLs  Resource Names   Verbs
  ---------        -----------------  --------------   -----
  pods             []                 [dark-blue-app]  [get watch create delete]
  deployment.apps  []                 []               [get watch create delete]
  
  
controlplane ~ ➜  kubectl create deployment nginx --image=nginx -n blue --as dev-user
deployment.apps/nginx created

(3) ABAC (Attribute-Based Access Control)

  • 역할:
    • 속성 기반 정책 파일(JSON)을 사용하여 요청을 허가.
  • 작동 방식:
    • API 서버가 요청을 검사할 때 정책 파일을 참고하여 승인 여부 결정.
  • 사용 예:
    • 특정 사용자에게 특정 리소스의 읽기/쓰기 권한 부여.

(4) Webhook

  • 역할:
    • 외부 서비스를 통해 동적으로 요청을 승인 또는 거부.
  • 작동 방식:
    • 요청이 외부 Webhook 서비스로 전송되고, 결과에 따라 승인 여부 결정.
  • 사용 예:
    • 복잡한 비즈니스 로직에 기반한 요청 승인.

(5) AlwaysAllow

  • 역할:
    • 모든 요청을 허용.
  • 작동 방식:
    • 요청을 무조건 승인.
  • 사용 예:
    • 개발/테스트 환경(비권장).

(6) AlwaysDeny

  • 역할:
    • 모든 요청을 거부.
  • 작동 방식:
    • 요청을 무조건 거부.
  • 사용 예:
    • 특정 시점에 API 접근을 완전히 차단할 때.

 


2. Authorization Mode 설정

설정 방법

  • API 서버의 --authorization-mode 플래그에 모드 목록을 지정:
     
  • 실행 순서:
    • 여러 모드가 설정된 경우, 요청이 첫 번째 모드에서 거부되면 다음 모드로 넘어간다.
    • 요청이 하나의 모드에서 승인되면 즉시 허가된다.

3. Authorization Mode 비교

  장점 단점 사례
Node 노드의 Pod 제한적인 접근 허용 제한된 사용 사례 kubelet의 리소스 접근 제어
RBAC 세분화된 권한 관리 가능 설정 복잡성 멀티테넌트 클러스터, 팀별 리소스 접근 제어
ABAC 간단한 JSON 기반 정책 정책 관리 어려움 기존 JSON 정책 파일 활용
Webhook 동적이고 복잡한 정책 적용 가능 외부 서비스 의존성 비즈니스 로직 기반 권한 관리
AlwaysAllow 모든 요청 허용 보안 취약 테스트 환경
AlwaysDeny 모든 요청 거부 생산 환경 사용 불가 API 접근을 완전히 차단해야 할 때

4. RBAC 모드의 주요 구성 요소

  • Role:
    • 특정 네임스페이스 내의 리소스에 대한 권한 정의.
    • 예: default 네임스페이스에서 Pod 읽기 권한
$ kubectl get roles

# 세부사항 확인
$ kubectl describe role <role_name>
$ kubectl get roles -A --no-headers
blue          developer                                        2025-01-20T08:10:18Z
kube-public   kubeadm:bootstrap-signer-clusterinfo             2025-01-20T08:08:14Z
kube-public   system:controller:bootstrap-signer               2025-01-20T08:08:14Z
kube-system   extension-apiserver-authentication-reader        2025-01-20T08:08:14Z
kube-system   kube-proxy                                       2025-01-20T08:08:15Z
kube-system   kubeadm:kubelet-config                           2025-01-20T08:08:14Z
kube-system   kubeadm:nodes-kubeadm-config                     2025-01-20T08:08:14Z
kube-system   system::leader-locking-kube-controller-manager   2025-01-20T08:08:14Z
kube-system   system::leader-locking-kube-scheduler            2025-01-20T08:08:14Z
kube-system   system:controller:bootstrap-signer               2025-01-20T08:08:14Z
kube-system   system:controller:cloud-provider                 2025-01-20T08:08:14Z
kube-system   system:controller:token-cleaner                  2025-01-20T08:08:14Z

# kube-system의 kube-proxy role에 주어진 resource 확인
$  kubectl describe role kube-proxy -n kube-system
Name:         kube-proxy
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  configmaps  []                 [kube-proxy]    [get] 
  # kube-proxy role은 오로지 kube-proxy 이름의 configmap을 통해 세부 사항을 get할 수 있다.
  • ClusterRole:
    • 클러스터 전역 리소스에 대한 권한 정의.
    • 예: 모든 네임스페이스에서 Pod 관리 권한.
  • RoleBinding:
    • Role을 사용자, 그룹 또는 서비스 계정에 바인딩(Link)
    • 예: 특정 사용자에게 Role 부여
$ kubectl get rolebindings

# 세부사항 확인
$ kubectl describe rolebinding <rolebinding_name>

 

$ kubectl get rolebindings -n kube-system
NAME                                                ROLE                                                  AGE
kube-proxy                                          Role/kube-proxy                                       26m
kubeadm:kubelet-config                              Role/kubeadm:kubelet-config                           26m
kubeadm:nodes-kubeadm-config                        Role/kubeadm:nodes-kubeadm-config                     26m
system::extension-apiserver-authentication-reader   Role/extension-apiserver-authentication-reader        26m
system::leader-locking-kube-controller-manager      Role/system::leader-locking-kube-controller-manager   26m
system::leader-locking-kube-scheduler               Role/system::leader-locking-kube-scheduler            26m
system:controller:bootstrap-signer                  Role/system:controller:bootstrap-signer               26m
system:controller:cloud-provider                    Role/system:controller:cloud-provider                 26m
system:controller:token-cleaner                     Role/system:controller:token-cleaner                  26m

$ kubectl describe rolebindings kube-proxy -n kube-system
Name:         kube-proxy
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  kube-proxy
Subjects:
  Kind   Name                                             Namespace
  ----   ----                                             ---------
  Group  system:bootstrappers:kubeadm:default-node-token
  # -> 연결된 account 확인 가능
  • ClusterRoleBinding:
    • ClusterRole을 클러스터 전체 사용자, 그룹 또는 서비스 계정에 바인딩.

5. Authorization Mode Best Practices

  1. RBAC 모드 사용:
    • 세분화된 권한 관리와 안정성을 제공.
    • 가장 일반적이고 권장되는 방식.
  2. Webhook 활용:
    • 복잡한 정책이 필요한 경우 외부 Webhook 서비스 사용.
  3. Node 모드 활성화:
    • Kubelet과 같은 노드 수준 요청의 안전한 처리를 보장.
  4. ABAC 최소화:
    • JSON 기반 정책 파일은 관리가 어렵고, 확장성이 떨어짐.
  5. 권한 최소화:
    • Principle of Least Privilege(최소 권한 원칙)에 따라 사용자와 서비스 계정에 필요한 권한만 부여.

참고 자료: https://kubernetes.io/docs/reference/access-authn-authz/authorization/

반응형

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

[K8S] ClusterRole/ClusterRoleBinding  (0) 2025.02.03
[K8S] api-resources  (0) 2025.01.23
[K8S] Certificates API  (0) 2025.01.13
[K8S] TLS  (0) 2025.01.10
[K8S] Encrypting Secret Data at Rest  (0) 2025.01.08