앞으로의 스터디 내용은 <Kubernetes in Action>을 기반으로 진행합니다.
자세한 내용은, 해당 책을 확인해주세요!
http://www.yes24.com/Product/Goods/89607047
인증 개념 정리
API 서버는 인증 - 인가 단계를 거치는 과정에서 인증 플러그인이 구성 상 포함됨을 이야기한 바 있다.
아래의 순서 및 과정으로 인증 작업이 진행됨을 참고하자.
- API 서버가 요청을 받음
- 인증 플러그인이 요청인 정보를 추출해 검사
- 요청인 정보, 클라이언트 아이덴티티란 사용자 이름, 사용자 ID, 클라이언트 소속 그룹을 의미.
- 클라이언트 아이덴티티 습득 방법은 : 클라이언트 인증서 / HTTP 헤더를 통해 전달된 인증 토큰 / 기본 HTTP 인증 등
- 인증 플러그인이 API 서버 코어에 반환 -> 사용자가 작업 수행 권한이 있는지 확인
- API 서버의 인증 플러그인 호출 중지
- 인가 단계 진행
사용자와 그룹
쿠버네티스 API 서버에 접속하는 클라이언트는 2종류로 모두 인증 플러그인으로 인증.
실제 사용자이든, 서비스어카운트이든, 각 계정은 하나 이상의 그룹에 소속된다.
- 사용자 (클라이언트)
- 실제 사용자 (사람) : SSO(싱글사인온) 등 외부 시스템으로 인증 관리
- 외부에 의해 관리되고, 사용자 계정 자원이 쿠버네티스에 없으므로 API 서버를 통한 사용자 생성, 업데이트, 삭제 불가
- 파드, 파드 내부 애플리케이션 : 서비스 어카운트 메커니즘 사용한 인증
- 쿠버네티스의 서비스 어카운트 리소스를 클러스터에 생성해 계정 정보 생성, 삭제, 변경 가능
- 실제 사용자 (사람) : SSO(싱글사인온) 등 외부 시스템으로 인증 관리
- 그룹
- 목적 : 한번에 여러 사용자에게 권한을 부여하는 데에 사용
- 의미 :
- 인증 플러그인이 반환하는 그룹 이름 = 임의의 문자열
- 내장된 그룹의 의미
- system:unauthenticated | 어떤 인증 플러그인에서도 인증할 수 없는 요청의 그룹
- system: authenticated | 성공적으로 인증된 사용자 전체가 할당된 그룹
- system:serviceaccounts | 시스템 내 모든 서비스 어카운트의 그룹
- system:serviceaccounts:<namespace> | 특정 네임스페이스 내 모든 서비스 어카운트의 그룹
서비스 어카운트
- 모든 네임스페이스 내 디폴트 서비스 어카운트가 있지만 파드별로 따로 생성해주는 이유
- 클러스터 보안 때문. 파드가 수행해야 하는 작업에 맞게 해당 권한만 보유한 서비스 어카운트를 활용.
파드는 클러스터 내 리소스를 검색/수정하지 못하는 계정으로 실행해야. 리소스의 메타데이터를 검색하는 파드는 해당 오브젝트의 메타데이터만 조회 가능한 서비스 어카운트로 실행. 오브젝트 수정해야 하는 파드는 API 오브젝트 수정 가능한 고유 서비스 어카운트로 실행.
- 클러스터 보안 때문. 파드가 수행해야 하는 작업에 맞게 해당 권한만 보유한 서비스 어카운트를 활용.
- 생성 방법
- kubectl create serviceaccount <service_account_name> 으로 생성
- kubectl describe sa <service_account_name> 으로 생성 결과 확인
$ kubectl create serviceaccount foo
serviceaccount/foo created
$ kubectl describe sa foo
Name: foo
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none> // 서비스 어카운트 사용 파드에 자동으로 해당 필드값 추가
Mountable secrets: foo-token-h6g68 // 마운트 가능한 시크릿이 강제된 경우 이 어카운트를 사용하는 파드만 해당 시크릿 마운트 가능
Tokens: foo-token-h6g68 // 인증 토큰. 컨테이너에 마운트됨.
Events: <none>
- 서비스 어카운트의 시크릿 항목들
- 마운트 가능한 시크릿
- 7장 복습 : 파드는 원하는 시크릿을 마운트할 수 있다
- 12장 : 서비스 어카운트의 마운트 가능한 시크릿 목록에 있는 시크릿만 마운트하도록 파드의 서비스어카운트를 설정할 수 있다. kubernetes.io/enforce-mountable-secrets="true " 라는 어노테이션을 포함해야 한다.
- 이미지 풀 시크릿
- 프라이빗 이미지 레포에서 컨테이너 이미지를 가져오는 데 필요한 자격증명을 보유한 시크릿
- 서비스 어카운트를 사용해 모든 파드에 특정 이미지 풀 시크릿을 자동으로 추가 (서비스 어카운트에 추가하면 자동으로 각 파드에 추가되어 개별 작업을 할 필요 없음)
- 마운트 가능한 시크릿
- 파드에 서비스 어카운트 할당
- 파드 정의 내 spec.service.AccountName 필드에서 이름을 설정
- 파드를 생성할 때 서비스어카운트를 설정해야 한다. 추후 변경 불가능.
$ cat curl-custom-sa.yaml
apiVersion: v1
kind: Pod
metadata:
name: curl-custom-sa
spec:
serviceAccountName: foo
containers:
- name: main
image: tutum/curl
command: ["sleep", "9999999"]
- name: ambassador
image: luksa/kubectl-proxy:1.6.2
$ kubectl create -f curl-custom-sa.yaml
pod/curl-custom-sa created
$ kubectl exec -it curl-custom-sa -c main -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
error: unable to upgrade connection: container not found ("main")
$ kubectl get po
NAME READY STATUS RESTARTS AGE
curl-custom-sa 1/2 ImagePullBackOff 0 86s
kubia-0 1/1 Running 1 7d15h
kubia-1 1/1 Running 1 7d16h
kubia-2 1/1 Running 1 7d16h
$ kubectl describe po curl-custom-sa
(중략)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
(중략)
Warning Failed 25s (x5 over 97s) kubelet Error: ImagePullBackOff
Normal Pulling 10s (x4 over 101s) kubelet Pulling image "tutum/curl"
Warning Failed 7s (x4 over 98s) kubelet Error: ErrImagePull
Warning Failed 7s (x4 over 98s) kubelet Failed to pull image "tutum/curl": rpc error: code = Unknown desc = Error response from daemon: pull access denied for tutum/curl, repository does not exist or may require 'docker login': denied: requested access to the resource i
$ vim curl-custom-sa.yaml
$ cat curl-custom-sa.yaml
apiVersion: v1
kind: Pod
metadata:
name: curl-custom-sa
spec:
serviceAccountName: foo
containers:
- name: main
image: curlimages/curl // tutum/curl 이미지에서 변경
command: ["sleep", "9999999"]
- name: ambassador
image: luksa/kubectl-proxy:1.6.2
$ kubectl delete po curl-custom-sa
pod "curl-custom-sa" deleted
$ kubectl create -f curl-custom-sa.yaml
pod/curl-custom-sa created
$ kubectl exec -it curl-custom-sa -c main -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6Il9nMFVJUjlpMWJBYk9fOGt1dG5PYmZLUEFMaGRnUEo0eFZ0VTBpYlZrbW8ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjc5MDEzMDM5LCJpYXQiOjE2NDc0NzcwMzksImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJjdXJsLWN1c3RvbS1zYSIsInVpZCI6ImQ3MWRjM2UxLTM4NTMtNDlmMy05N2U1LTc0MTFmMGFiMzg1MSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZm9vIiwidWlkIjoiYmYzODNmNzQtNDBkNi00YmMwLTliMDYtNzJjODhkMTYzYTc0In0sIndhcm5hZnRlciI6MTY0NzQ4MDY0Nn0sIm5iZiI6MTY0NzQ3NzAzOSwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Zm9vIn0.c3RkExZR27sumwlulR6tezeYnaxEh34mko3GY5nN2r07JgszvUDW1ciaEwPeeDQ3pjaOsnUWkoc91T6pI6LKSwI-D4RIvUapKGYX_lb47Pl85hB8wviDa6A4aglkbFNbYGU6OwDTH2ri9CfzST_spXb8cTk0Pd6RR29vnjGrMKV6NwORb7V_H0VC1MmykfCRNulypARksT8EOCk5wx5jXqg-7PMl3m7BNZhaCqiFDy4bZWVhxa9DXKn6bNMK241LxTdfL3m0Xbq4Rr_PbmWQRN9G1sy4wASpfKX-u_MEbyQ_flHyPX-VHwy3_U_1lD_akcSKnYiFarUd2HT4XDBMjQ%
- API 서버와 통신하기 위한 서비스어카운트 토큰 활용
- 앰배서더 컨테이너가 서버와 통신 시 토큰을 사용하므로 이를 활용해 실습을 진행
$ kubectl exec -it curl-custom-sa -c main -- curl localhost:8001/api/v1/pods
RBAC을 통한 클러스터 보안
- RBAC, 역할 기반 액세스 제어를 통해, 권한이 없는 사용자가 클러스터 상태를 조회/수정하지 못하도록 한다
RBAC 인가 플러그인
- 인가 플러그인을 통해 액션 요청자의 액션 수행 가능 여부를 점검한다
- API 서버가 REST 인터페이스를 통해 사용자의 HTTP 요청을 받아 액션을 수행하도록 한다
- 사용자는 요청에 자격증명 내용 (인증 토큰, 사용자명, 암호 혹은 클라이언트 인증서) 을 포함시켜 인증한다
- 액션의 종류
- Get, 파드 가져오기 (=HTTP Method GET, HEAD)
- Create, 서비스 생성 (=HTTP Method POST)
- Update, 시크릿 업데이트 (=HTTP Method PUT)
- Patch (=HTTP Method Patch)
- Delete (=HTTP Method DELETE)
- RBAC 규칙 용도
- 전체 리소스 유형에 보안 권한을 적용
- 특정 리소스 인스턴스에 보안 권한을 적용
- 리소스가 아닌 URL 경로에 보안 권한을 적용
- RBAC 플러그인 메커니즘
- 사용자 롤, User Role
- 인가 플러그인의 인가 여부를 결정하는 핵심 요소
- 주체(사람, 서비스 어카운트, 그룹)는 하나 이상의 롤과 연계되어 있다
- 각 롤은 특정 리소스에 특정 액션(동사)을 수행할 수 있다
- 사용자 롤, User Role
RBAC 리소스
- RBAC 인가 규칙은 2개의 그룹, 4개의 리소스로 구성된다
- 롤과 클러스터롤 (Role & ClusterRole) :
리소스에 수행할 수 있는 동사를 지정 - 롤바인딩과 클러스터롤바인딩 (RoleBinding & ClusterRoleBinding) :
롤을 특정 사용자, 그룹, 서비스 어카운트 등 액션 주체에 바인딩
- 롤과 클러스터롤 (Role & ClusterRole) :
수행할 수 있는 작업, 동사를 정의 | 누가 수행하는지 주체를 정의 | |
네임스페이스가 지정된 리소스 | 롤 | 롤바인딩 |
네임스페이스가 지정되지 않는 클러스터 수준의 리소스 | 클러스터롤 | 클러스터롤바인딩 |
- 특징
- 하나의 네임스페이스에 여러 롤, 롤바인딩 존재 가능
- 클러스터롤, 클러스터롤바인딩도 복수로 존재 가능
- 롤바인딩이 네임스페이스가 지정되어도, 클러스터롤도 참조 가능
$ kubectl delete clusterrolebinding permissive-binding
clusterrolebinding.rbac.authorization.k8s.io "permissive-binding" deleted
$ kubectl create ns foo
namespace/foo created
$ kubectl run test --image=luksa/kubectl-proxy -n foo
pod/test created
$ kubectl create ns bar
namespace/bar created
$ kubectl run test --image=luksa/kubectl-proxy -n bar
pod/test created
$ kubectl get po -n foo
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 77s
$ kubectl exec -it test -n foo -- sh
/ # curl localhost:8001/api/v1/namespaces/foo/services
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "services is forbidden: User \"system:serviceaccount:foo:default\" cannot list resource \"services\" in API group \"\" in the namespace \"foo\"",
"reason": "Forbidden",
"details": {
"kind": "services"
},
"code": 403
$ kubectl exec -it test -n bar -- sh
$ cat service-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: foo // 롤에 네임스페이스를 지정 (생략 시 현재 네임스페이스)
name: service-reader
rules:
- apiGroups: [""] // 서비스는 이름 없는 core apiGroup 리소스이므로 ""
verbs: ["get", "list"]
resources: ["services"] // 리소스 지정 시 복수형을 사용해야 함
$ kubectl create -f service-reader.yaml -n foo
role.rbac.authorization.k8s.io/service-reader created
$ kubectl create rolebinding test --role=service-reader --serviceaccount=foo:default -n foo
rolebinding.rbac.authorization.k8s.io/test created
**role을 생성하는 방법은 위의 yaml 파일 사용 외에도 kubectl create role <service-name> --verb=<verb_name> --resource=<resource_name_in_plural> -n <namespace_name>과 같이 명령어를 이용하는 방법이 있다.
**서비스 어카운트 대신 사용자에게 롤을 바인딩하려면 --user 인수로 사용자 이름을 지정하자.
**서비스 어카운트 대신 그룹에 롤을 바인딩하려면 --group 인수를 사용하자.
$ kubectl get rolebinding test -n foo -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2022-03-17T04:41:11Z"
name: test
namespace: foo
resourceVersion: "249977"
uid: 8eb6ace7-0201-4d51-a7b7-fdf0d2ca6bbc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: service-reader
subjects:
- kind: ServiceAccount
name: default
namespace: foo
$ kubectl exec -it test -n foo -- sh
/ # curl localhost:8001/api/v1/namespaces/foo/services
{
"kind": "ServiceList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "250253"
},
"items": []
}
**롤바인딩을 편집해, 다른 네임스페이스에서도 다른 파드의 서비스 어카운트를 추가해서 액션을 수행할 수 있게 할 수 있다. (명령어 : kubectl edit rolebinding <role_binding_name> -n <namespace_name> )
- 클러스터 수준의 RBAC 리소스의 필요성 (클러스터롤, 클러스터롤바인딩)
- 롤은 롤이 위치한 동일 네임스페이스에만 접근 가능. 다른 네임스페이스 리소스에 접근 가능하게 하기 위해서는 해당 네임스페이스마다 롤, 롤바인딩을 생성. 즉, 모든 네임스페이스로 확장하려면 각각 롤, 롤바인딩을 모두 생성해주어야 함.
- 네임스페이스를 지정하지 않는 리소스인, 노드, 퍼시스턴트볼륨, 네임스페이스 등은 일반적인 롤로 권한 부여가 불가능
$ kubectl create clusterrole pv-reader --verb=get,list --resource=persistentvolumes
clusterrole.rbac.authorization.k8s.io/pv-reader created
$ kubectl get clusterrole pv-reader -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2022-03-17T05:05:39Z"
name: pv-reader
resourceVersion: "251205"
uid: 1eb5de54-7748-432b-ae96-dff66ab7e534
rules:
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
$ kubectl exec -it test -n foo -- sh
/ # curl localhost:8001/api/v1/persistentvolumes
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "persistentvolumes is forbidden: User \"system:serviceaccount:foo:default\" cannot list resource \"persistentvolumes\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "persistentvolumes"
},
"code": 403
}/ # exit
$ kubectl create rolebinding pv-test --clusterrole=pv-reader --serviceaccount=foo:default -n foo
rolebinding.rbac.authorization.k8s.io/pv-test created
$ kubectl exec -it test -n foo -- sh
/ # curl localhost:8001/api/v1/persistentvolumes
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "persistentvolumes is forbidden: User \"system:serviceaccount:foo:default\" cannot list resource \"persistentvolumes\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "persistentvolumes"
},
"code": 403
}/ # exit
$ kubectl get rolebindings pv-test -o yaml
Error from server (NotFound): rolebindings.rbac.authorization.k8s.io "pv-test" not found
$ kubectl get rolebindings pv-test -n foo -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2022-03-17T05:07:24Z"
name: pv-test
namespace: foo
resourceVersion: "251293"
uid: 167748e6-98f8-4117-a10d-74fab2c2f841
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pv-reader
subjects:
- kind: ServiceAccount
name: default
namespace: foo
$ kubectl delete rolebinding pv-test
Error from server (NotFound): rolebindings.rbac.authorization.k8s.io "pv-test" not found
$ kubectl delete rolebinding -n foo pv-test
rolebinding.rbac.authorization.k8s.io "pv-test" deleted
$ kubectl create clusterrolebinding pv-test --clusterrole=pv-reader --serviceaccount=foo:default
clusterrolebinding.rbac.authorization.k8s.io/pv-test created
$ kubectl exec -it test -n foo -- sh
/ # curl localhost:8001/api/v1/persistentvolumes
{
"kind": "PersistentVolumeList",
"apiVersion": "v1",
(후략)
**클러스터 단위의 리소스인 퍼시스턴트볼륨을 조회하는 클러스터롤을 생성 후, 롤바인딩을 시도했으나, 클러스터롤바인딩이 아닌 롤바인딩 리소스로는 클러스터 수준 액세스 권한을 부여할 수 없어 여전히 오류가 발생함을 확인하였고, 클러스터롤바인딩까지 무사히 생성한 뒤에는 원활히 접근됨을 확인할 수 있다. 즉, 롤바인딩은 클러스터롤을 참조해도 클러스터롤바인딩을 대체할 수 없다.
리소스가 아닌 URL에 액세스 허용하기
- API 서버는 리소스 외에 URL로도 노출됨. URL 액세스 권한도 명시적으로 부여해야 클라이언트 요청을 받을 수 있다.
- URL 권한의 명시적 부여는 일반적으로 system:discovery 클러스터롤과 클러스터롤바인딩을 통해 자동 수행된다.
$ kubectl get clusterrole system:discovery -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2022-01-25T08:15:15Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:discovery
resourceVersion: "86"
uid: 2da59d58-cfc6-4c66-961e-33445f9af0a3
rules:
- nonResourceURLs:
- /api
- /api/*
- /apis
- /apis/*
- /healthz
- /livez
- /openapi
- /openapi/*
- /readyz
- /version
- /version/
verbs:
- get
**상기 클러스터롤이 리소스 대신 URL을 참조.
**URL의 경우 액션 동사가 create, update 대신 post, put, patch가 활용됨. (소문자)
$ kubectl get clusterrolebinding system:discovery -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2022-01-25T08:15:15Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:discovery
resourceVersion: "151"
uid: 752e4706-6643-462d-91fe-44a0a6c07c7d
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:discovery
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated
** 책의 예시에는 해당 클러스터롤바인딩이 인증 사용자와 미인증 사용자 모두를 바인드하지만, 실제 실습의 경우 인증사용자만을 바인드하는 것으로 보인다. 그래서 아래의 실습의 경우에도, 원래대로라면 미인증 사용자로서의 접근을 허용해서 아래 요청도 성공적이어야 하지만, 이 경우에는 미인증 사용자 접근 권한이 막혀있으므로 요청이 거절되었다. 아래 표를 통해 더 자세히 오류 원인을 확인할 수 있다.
Default ClusterRole | Default ClusterRoleBinding | Description |
system:basic-user | system:authenticated group | Allows a user read-only access to basic information about themselves. Prior to v1.14, this role was also bound to system:unauthenticated by default. |
system:discovery | system:authenticated group | Allows read-only access to API discovery endpoints needed to discover and negotiate an API level. Prior to v1.14, this role was also bound to system:unauthenticated by default. |
system:public-info-viewer | system:authenticated and system:unauthenticated groups |
Allows read-only access to non-sensitive information about the cluster. Introduced in Kubernetes v1.14. |
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
$ curl https://192.168.59.100:8443/api -k
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/api\"",
"reason": "Forbidden",
"details": {},
"code": 403
}%
특정 네임스페이스 리소스에 액세스 권한을 부여하는 데에 클러스터롤 사용하는 방법도 알아보자.
클러스터롤- 일반롤바인딩 연결을 진행해본다.
그 예시로는 아래의 클러스터롤이 존재한다.
$ kubectl get clusterrole view -o yaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2022-01-25T08:15:15Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
rbac.authorization.k8s.io/aggregate-to-edit: "true"
name: view
resourceVersion: "384"
uid: 27c0961d-1d06-4452-a476-c2200ed3a91d
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- persistentvolumeclaims/status
- pods
- replicationcontrollers
- replicationcontrollers/scale
- serviceaccounts
- services
- services/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- controllerrevisions
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- replicasets
- replicasets/scale
- replicasets/status
- statefulsets
- statefulsets/scale
- statefulsets/status
verbs:
- get
- list
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
- horizontalpodautoscalers/status
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- cronjobs/status
- jobs
- jobs/status
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- ingresses
- ingresses/status
- networkpolicies
- replicasets
- replicasets/scale
- replicasets/status
- replicationcontrollers/scale
verbs:
- get
- list
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
- poddisruptionbudgets/status
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- ingresses/status
- networkpolicies
verbs:
- get
- list
- watch
- 클러스터롤바인딩 생성 + 클러스터롤 참조 = 바인딩 주체가 모든 네임스페이스 내 지정 리소스 확인 가능
- 롤바인딩 생성 + 클러스터롤 참조 = 바인딩 주체가 롤바인딩 네임스페이스 내 리소스만 확인 가능
롤, 클러스터롤, 롤바인딩, 클러스터롤바인딩의 조합
접근 | 롤 타입 | 사용할 바인딩 타입 |
클러스터 수준 리소스 (노드, 퍼시스턴트볼륨 등) | 클러스터롤 | 클러스터롤바인딩 |
리소스가 아닌 URL | 클러스터롤 | 클러스터롤바인딩 |
모든 네임스페이스의 네임스페이스로 지정된 리소스 | 클러스터롤 | 클러스터롤바인딩 |
특정 네임스페이스의 네임스페이스로 지정된 리소스 (여러 네임스페이스에 동일한 클러스터롤 재사용) |
클러스터롤 | 롤바인딩 |
특정 네임스페이스의 네임스페이스로 지정된 리소스 (각 네임스페이스에 별도 롤을 정의) |
롤 | 롤바인딩 |
디폴트 클러스터롤과 클러스터롤바인딩
- 쿠버네티스는 API 서버 시작 시 업데이트되는 클러스터롤, 클러스터롤바인딩의 디폴트 세트 제공
- 확인방법 : kubectl get clusterroles OR kubectl get clusterrolebindings
- 디폴트 클러스터롤의 종류
- view 클러스터롤을 사용해 리소스에 읽기 전용 액세스 허용
- 롤, 롤바인딩, 시크릿 제외 거의 모든 리소스를 네임스페이스 내에서 읽을 수 있음
- edit 클러스터롤을 사용해 리소스에 변경 허용
- 네임스페이스 내 리소스 + 시크릿까지 수정 가능.
- 롤, 롤바인딩의 경우 조회 및 수정 불허 (권한 상승 방지)
- admin 클러스터롤을 사용해 네임스페이스 제어 권한 허용
- 클러스터롤 주체에 리소스쿼터, 네임스페이스 리소스 제외 모든 리소스의 조회 및 수정 허용
- edit과 달리 롤, 롤바인딩도 조회 및 수정 대상임이 차이
- cluster-admin 클러스터롤을 사용해 완전 제어 허용
- 롤바인딩이 생성된 네임스페이스의 모든 측면을 완전 제어
- 그외 system: 이라는 접두사로 시작하는 클러스터롤
- system:kube-scheduler ) 스케줄러에서 사용. 해당 롤은 동일 이름의 롤바인딩으로 사용자에게 할당되어 인증됨.
- system:node ) kubelet에서 사용하는 롤
- system:controller ) 컨트롤러매니저가 사용하는 롤
- view 클러스터롤을 사용해 리소스에 읽기 전용 액세스 허용
인가 권한 부여 가이드
- 네임스페이스의 디폴트 서비스 어카운트에는 미인증 사용자의 권한 외 없어 사용자가 전적으로 권한 부여해야.
- 최소 권한의 원칙 : 모든 사람에게 꼭 필요한 권한만 부여하고, 한 가지 초과의 권한을 부여하지 않아야 한다.
- 각 파드를 위한 특정 서비스 어카운트를 생성한 후 롤바인딩으로 맞춤 롤과 연계하자
- 클러스터롤바인딩 사용시 타 네임스페이스 리소스가 접근 가능하므로 사용 지양
- 애플리케이션이 탈취될 가능성을 염두에 두고 서비스어카운트를 제한해야
실전 지식
- 쿠버네티스의 사용자 관리란?
- 쿠버네티스에는 사실 사용자, 유저라는 개념이 따로 정해지지 않았다. 어떤 인증방법으로 인증을 통과할지, 어떤 권한을 받아 리소스에 접근할 지 정도의 차이가 명세된 것이 전부이다. 유저 기준이 명확히 정해진 바가 없다
- 유저는 리소스로 등록되지 않고, 설정 파일 내의 라벨링이다.
- 쿠버네티스 외부의 인증서비스 상의 사용자 개념을 연결지어 사용할 수 있다
- 실전 서비스 상의 인증 과정
- 키클락과 같은 외부 인증 서비스로부터 사용자가 토큰을 받아온다
- 해당 토큰 내에는 해당 외부 인증 서비스 내에 선언된 유저에 대한 그룹 정보를 포함한다
- 받은 토큰을 기반으로 API 요청을 보낸다
- 쿠버네티스는 토큰을 받고 인증을 판단한다
- 키클락과 같은 외부 인증 서비스로부터 사용자가 토큰을 받아온다
- 실전 서비스 상의 인가 과정
- EKS의 경우, 토큰으로 인증이 통과되면, 기존 정의된 클러스터롤을 확인한다
- 롤에 대한 확인은, 먼저 앞선 인증 토큰에 포함된 그룹 정보를 확인한다
- 토큰 내 그룹 정보를 기반으로 정해진 롤을 롤바인딩한다
- 예를 들어 다음과 같은 롤을 개발 및 상용환경에 생성해둘 수 있다
- 리드온리 롤 : 기본 파드나 서비스의 리스트 권한만 보유
- 데브옵스 롤 : 생성, 삭제, 업데이트, 패치 권한 등 보유
- 어드민 롤 : 전체 권한 보유
- 인증된 유저는 다음 롤들에 따라 권한이 부여되고 리소스 접근이 제한된다
- EKS의 경우, 토큰으로 인증이 통과되면, 기존 정의된 클러스터롤을 확인한다
- 참고자료 : https://velog.io/@nigasa12/kubectl-sso-%EC%84%A4%EC%A0%95-%EC%82%BD%EC%A7%88-%EC%9D%BC%EA%B8%B0
참고 문헌
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
https://livebook.manning.com/concept/kubernetes/clusterroles
'기술 공부 > 쿠버네티스' 카테고리의 다른 글
쿠버네티스 (14) | 파드 컴퓨팅 리소스 (0) | 2022.03.23 |
---|---|
쿠버네티스 (13) | 클러스터 노드와 네트워크 보안 (0) | 2022.03.23 |
쿠버네티스 (11) | 쿠버네티스 내부 이해 (0) | 2022.03.10 |
쿠버네티스 (10) | 스테이트풀셋 (0) | 2022.03.09 |
쿠버네티스 (9) | 디플로이먼트 (0) | 2022.03.03 |