RBAC Authorization에 대해 공부한 내용을 정리한 글입니다.
쿠버네티스 공식 홈페이지 - Kubernetes RBAC를 참고하여 진행하였습니다.
또한, 마스터 노드1, 워커노드 2로 실습 진행하였습니다.
🤣🤩😊CKA 자격증 준비 및 쿠버네티스 공부 정리입니다.
쿠버네티스는 보안 측면에서 다양한 기능 제공
이 중 Authorization에 대한 내용입니다.
RBAC(Role-Based Access control): 쿠버네티스가 자원에 대한 권한을 지원하는 방법중, 역할 기반으로 권한을 부여하는 방법
ServiceAccount(sa): 사용자 또는 어플리케이션에 해당
Role과 binding되어 자원접근에 사용됨.
쿠버네티스에서 역할 기반 권한부여의 방법은 2가지다.
Role : Namespace에 속하는 리소스에 접근하는 권한 설정, 여러개의 Role을 생성할 수 있다.
Cluster Role: cluster 단위의 리소스들을 지정할 수 있음. Namespace에 속하지 않는 전역적인 쿠버네티스 오브젝트
Role과 ServiceAccount를 연결해주는 역할
RoleBinding과 ClusterRoleBinding이 존재.
RoleBinding: 하나의 Role만 연결이 가능하고, ServiceAccount는 여러개 바인딩 가능
namespace 내부의 Role, RoleBinding을 구성하면 secret의 token이 생성되는데, 이 값으로 외부에서 API서버 접근. token의 권한에 따라 namespace 안에서 인가된 권한만 사용가능
clusterRoleBinding: namespace 안에 존재하는 ServiceAccount를 연결해주면, ServiceAccount가 클러스터 안에 있는 자원에 접근할 수 있게 해줌.
리소스 API 엔드포인트에 대한 요청 동사를 결정하려면 사용된 HTTP 동사와 요청이 개별 리소스 또는 리소스 모음
create
,get
, list
, watch
, update
, patch
, delete
존재
주의점
바인딩을 생성한 후에는 바인딩이 참조하는 Role 또는 ClusterRole을 변경할 수 없습니다. 바인딩의 내용을 변경하려고 하면 roleRef유효성 검사 오류가 발생합니다. 바인딩의 내용을 변경하려면 roleRef 바인딩 개체를 제거하고 대체 개체를 만들어야 합니다.
Role과 RoleBinding을 이용해서 자신의 Namespace 내에 Pod들만 조회하는 권한 부여
my-ns라는 네임스페이스를 사용하겠습니다.
$ kubectl create serviceaacount pod-viewer --namespace=my-ns
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-viewer
namespace: my-ns
$ kubectl create role podreader-role --verb=get,list,watch --resource=pods --namespace=my-ns
# role 생성확인
$ kubectl get role --namespace=my-ns
$ kubectl describe role podreader-role --namespace=my-ns
#podreader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: podreader-role
namespace: my-ns
rules:
- apiGroups:
- ""
resources: # 권한 적용할 리소스
- pods
verbs: # 권한 부여
- get
- watch
- list
$ kubectl create rolebinding podreader-rolebinding --role=podreader-role --serviceaccount=my-ns:pod-viewer --namespace=my-ns
# rolebinding 생성 확인
$ kubectl get rolebinding --namespace=my-ns
$ kubectl describe rolebinding podreader-rolebinding --namespace=my-ns
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: podreader-rolebinding
namespace: my-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: podreader-role
subjects:
- kind: ServiceAccount
name: pod-viewer # 적용할 SA이름
namespace: my-ns
$ kubectl auth can-i {명령어} {리소스} -n {네임스페이스} --as=system:serviceaccount:{네임스페이스}:{서비스어카운트 이름}
출력 결과가 yes면 할당된 권한, no일 경우 없는 권한
ServiceAccount별로 권한이 주어지기 때문에 다음과 같이 사용할 수 있습니다.
$ kubectl {명령어} {리소스} --as system:serviceaccount:{네임스페이스}:{계정명} --namespace={네임스페이스}
$ kubectl get pods --as system:serviceaccount:my-ns:pod-viewer --namespace=my-ns
이외에 다른 리소스로 접근하거나 verb(동작 api)를 다르게 설정하면 forbidden에러가 발생한다!
위에 설명한 것처럼 serviceaccount를 생성하면 토큰이 발행되어야 하는데... 없길래 찾아보았습니다.
찾아보니 1.24v
부터는 보안강화를 이유로 토큰을 자동으로 발행해주지 않는다고 하더군요!! 따라서 수동으로 토큰을 발행해서 사용해보겠습니다.
# my-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: my-ns
annotations:
kubernetes.io/service-account.name: pod-viewer
type: kubernetes.io/service-account-token
$ kubectl get secrets --namespace=my-ns
# 토큰 확인
$ kubectl get secrets --namespace=my-ns -o yaml
cluster 내 모든 namespace의 deployment, pod, service 리소스를 create, list, get, update, delete할 수 있는 권한 할당
serviceAccount 생성
항상 sa는 소문자로 생성!!!
$ kubectl create sa cluster-sa -n my-ns
$ kubectl get sa cluster-sa -n my-ns
$ kubectl create clusterrole my-cluster-role --verb=create,list,get,update,delete --resource=deployment,pod,service
$ kubectl get clusterrole my-cluster-role
$ kubectl describe clusterrole my-cluster-role
cluster role은 role과 다르게 namespace설정을 따로 안해줘도 됨!!
$ kubectl create clusterrolebinding my-cluster-rolebinding --clusterrole=my-cluster-role --serviceaccount=my-ns:cluster-sa
$ kubectl get clusterrolebinding my-cluster-rolebinding
$ kubectl describe clusterrolebindings.rbac.authorization.k8s.io my-cluster-rolebinding
$ kubectl get pods --as system:serviceaccount:my-ns:cluster-sa --namespace=my-ns
아까와 같이 namespace안의 리소스에 대해 접근이 가능합니다.
my-ns2라는 namespace를 만들어서 deployment를 생성하고, 접근해보겠습니다.
$ kubectl create ns my-ns2
$ kubectl create deploy my-deploy --image=nginx --replicas=3 --port=80 -n my-ns2
$ kubectl get pods --as system:serviceaccount:my-ns:cluster-sa --namespace=my-ns2
이처럼 clusterRoleBinding은 namespace에 국한되는 것이 아닌, 전체 클러스터의 리소스에 대해 접근이 가능하다는 것을 알았습니다.
$ kubectl delete pods --all --as system:serviceaccount:my-ns:cluster-sa --namespace=my-ns2
$ kubectl delete deploy --all --as system:serviceaccount:my-ns:cluster-sa --namespace=my-ns2
찾아보니.. verb중에 watch라고 존재하는데, 데이터가 사라짐을 확인하는 걸까요?? watch를 추가해주면 에러가 없어진다고 합니다..
어차피 명령은 잘 실행되기 때문에 크게 상관은 없을 것 같아 보입니다
RBAC에 대해서 공부해보았습니다.
ServiceAccount뿐 아니라, User를 따로 생성해서 하는 방법도 존재하는 것 같습니다. 기회가 된다면 빨리 포스팅해서 올리도록 하겠습니다.