[CKS] 1-15. Cluster Roles and Role Bindings
쿠버네티스 클러스터 역할과 바인딩은 클러스터 범위 리소스의 접근 제어를 통해 전체 시스템의 안정적 운영과 보안을 지원합니다.
개요
클러스터 역할과 클러스터 역할 바인딩을 알아보겠습니다.
특정 네임스페이스(또는 아무것도 지정되지 않은 경우 기본 네임스페이스) 내에서 권한을 부여하는 네임스페이스 역할과 달리, 클러스터 역할은 클러스터 범위 리소스에 대한 액세스를 제어하는 데 사용됩니다.
k8s 리소스 분류
쿠버네티스는 구조적으로 2가지 그룹으로 분류할 수 있습니다.
1. Namespace Scope Resource
- Pod, Replicas, jobs, deployments, service, PVC, secrets.. 등이 대표적입니다
- Namespace를 지정하지 않으면 default namespace를 사용합니다.
2. Cluster Scope Resource
- Nodes, PV, certificatesigningrequests, namespace..가 대표적입니다.
- Namespace를 지정하지 않고 생성합니다.
- 반드시 Cluster Scope에 대해서만 만들 수 있는 것은 아닙니다.
- Cluster Role로 Namesapce Scope Resource를 지정하게 된다면 Namespace 관련없이 허락된 모든 Namespace 리소스에 대해서 접근이 가능합니다.
다음 명령어를 통해 확인해볼 수 있습니다. 결론적으로 네임스페이스 리소스에는 역할과 역할 바인딩이 사용. 클러스터 전체 리소스에 대한 권한을 부여해야 하는 경우에는 클러스터 역할과 클러스터 역할 바인딩을 사용할 수 있도록 구성해야합니다.
kubectl api-resources --namespaced=true
kubectl api-resources --namespaced=false
Cluster Role
Node를 관리하기 위한 Cluster admin을 예시로 들어보겠습니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-administrator
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "get", "create", "delete"]
Cluster Role Binding
역할을 생성하고 binding하는 것은 동일합니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-role-binding
subjects:
- kind: User
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-administrator
apiGroup: rbac.authorization.k8s.io
PV / PVC
PVC의 경우 사용자가 스토리지 자원을 요청하는 명세입니다. 특정 네임스페이스 내에서 생성되고 관리하므로 Namespace scope을 가지지만, PV에 경우 관리자가 프로비저닝한 스토리지의 한 부분으로, 클러스터 전체 리소스입니다.
Hands-on
한 사용자에게 2개의 역할을 한 번에 할당할 수 없습니다.
두번에 YAML 작성을 요구합니다.
# 바인딩 1: user-A에게 pod-reader 권한 부여
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: user-a-pod-reader-binding
subjects:
- kind: User
name: user-A
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
# 바인딩 2: user-A에게 configmap-editor 권한 부여
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: user-a-configmap-editor-binding
subjects:
- kind: User
name: user-A
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: configmap-editor
apiGroup: rbac.authorization.k8s.io
Hands-on(ABAC)
- 쿠버네티스에서 ABAC 정책을 정의하는 데 사용되는 파일 구성 형식은 무엇인가요?
- 쿠버네티스의 ABAC(속성 기반 접근 제어) 정책은 한 줄에 하나의 JSON 객체가 들어가는 파일 형식을 사용하여 정의됩니다. 이 형식은 흔히 JSON Lines(
.jsonl
)라고 불립니다. - 파일의 각 줄은 단일 정책을 나타냅니다. API 서버는
--authorization-policy-file=파일_경로
플래그와 함께 시작될 때 이 파일을 읽어 권한을 결정합니다.
- 쿠버네티스의 ABAC(속성 기반 접근 제어) 정책은 한 줄에 하나의 JSON 객체가 들어가는 파일 형식을 사용하여 정의됩니다. 이 형식은 흔히 JSON Lines(
{"apiVersion": "abac.authorization.k8s.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "project-a", "resource": "pods", "readonly": true}}
- ABAC 설정하기
controlplane /etc/kubernetes/abac ➜ crictl logs 58d9851ac1171
W0608 07:05:55.110611 1 registry.go:256] calling componentGlobalsRegistry.AddFlags more than once, the registry will be set by the latest flags
I0608 07:05:55.111188 1 options.go:238] external host was not specified, using 192.168.58.153
I0608 07:05:55.113408 1 server.go:143] Version: v1.32.0
I0608 07:05:55.113436 1 server.go:145] "Golang settings" GOGC="" GOMAXPROCS="" GOTRACEBACK=""
E0608 07:05:55.487303 1 run.go:72] "command failed" err="invalid authorization config: open /etc/kubernetes/abac/abac-policy.jsonl: no such file or directory"
controlplane /etc/kubernetes/abac ➜ ls
abac-policy.jsonl
컨테이너와 호스트(물리 서버)의 파일 시스템이 분리되어 있기 때문에 Volume 마운트가 필요합니다.
spec:
containers:
- command:
- kube-apiserver
# ...
- --authorization-mode=Node,RBAC,ABAC # ABAC 모드가 활성화되어 있는지 확인
- --authorization-policy-file=/etc/kubernetes/abac/abac-policy.jsonl
...
volumeMounts:
- name: abac-policy-volume # 아래 volumes에 정의할 이름과 일치해야 합니다.
mountPath: /etc/kubernetes/abac # 컨테이너 내부에서 접근할 경로
readOnly: true # 정책 파일이므로 읽기 전용이 안전합니다.
...
volumes:
- name: abac-policy-volume # 위 volumeMounts의 이름과 일치해야 합니다.
hostPath:
path: /etc/kubernetes/abac # 호스트(물리 서버)의 실제 파일 경로
type: DirectoryOrCreate
cat /var/log/containers/kube-apiserver
- Service Account Token 없이 생성
k create sa john
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: build-robot-secret
annotations:
kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token
EOF
- Config 등록
kubectl config set-credentials john --token=$(cat john-secret.txt)
k config set-context john-context --cluster kubernetes --user john --namespace=default
k config use-context john-context
- ABAC 권한 업데이트
- ABAC을 위한 JSONL 파일을 업데이트하면 재시작이 필요합니다.
- API 서버를 재시작하려면
/etc/kubernetes/manifests/kube-apiserver.yaml
파일을 수정하면 됩니다. 실제 설정 변경 없이 재시작을 유발하기 위해 아무 값이나 업데이트했다가 나중에 다시 원래대로 되돌리는 방법을 사용할 수 있습니다.