쿠버네티스의 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
- RBAC 모드 사용:
- 세분화된 권한 관리와 안정성을 제공.
- 가장 일반적이고 권장되는 방식.
- Webhook 활용:
- 복잡한 정책이 필요한 경우 외부 Webhook 서비스 사용.
- Node 모드 활성화:
- Kubelet과 같은 노드 수준 요청의 안전한 처리를 보장.
- ABAC 최소화:
- JSON 기반 정책 파일은 관리가 어렵고, 확장성이 떨어짐.
- 권한 최소화:
- 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 |