sangw0804 / study-docker

0 stars 1 forks source link

10. ServiceAccount & RBAC #8

Open sangw0804 opened 3 years ago

sangw0804 commented 3 years ago

쿠버네티스 클러스터는 실제로 여러 어플리케이션/사용자/팀이 같이 사용하게 되고, 필연적으로 인증/인가에 관련된 기능이 필요하게 되었다.

쿠버네티스의 인증/인가는 리눅스 권한 관리와 비슷하다. 리눅스에도 여러 유저별로 다르게 권한을 세팅하여 관리하는 것처럼, 쿠버네티스에서는 ServiceAccount 및 RBAC(Role Based Access Control)이라는 기능으로 인증/인가를 관리한다.

1. 쿠버네티스의 권한 인증 과정

쿠버네티스 마스터 노드는 kube-apiserver, kube-controller,kube-scheduler, etcd 등과 같은 컴포넌트들로 구성되어 있다.

image

이중 권한 인증에 관련된 컴포넌트는 kube-apiserver이다.

지금까지 kubectl 로 명령을 실행할 경우 권한이 문제된 적이 없었던 것은 kubectl로 직접 명령어를 kube-apiserver 에 전달할 경우 자동으로 최고 권한(cluster-admin)으로 명령을 전달하기 때문이다.

2. ServiceAccount와 롤/클러스터 롤

image

서비스 어카운트

서비스 어카운트는 권한을 관리하기 위한 subject 가 되는 쿠버네티스 object 이다.

kubectl get sa

kubectl create sa sangw0804

특정 서비스 어카운트로 kubectl 명령어를 사용하려면 --as 옵션을 사용하면 된다.

kubectl get services --as sangw0804

해당 서비스 어카운트에 권한을 부여하려면, 롤/클러스터 롤을 사용하면 된다.

role 은 특정 네임스페이스에 속하고, cluster role 은 전역적인(not-namespaced) 오브젝트이다.

먼저 role 객체를 생성해보자.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: service-reader
rules:
  - apiGroup: [""]
    resources: ["services"]
    verbs: ["get", "list"]

여기까지만 했다고 바로 권한이 서비스 어카운트에 부여되는 것이 아니다. 실제 롤과 subject를 연결해주는 롤바인딩이라고 하는 객체가 필요하다.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: service-reader-rolebinding
  namespace: default
subjects:
  - kind: ServiceAccount
    name: sangw0804
    namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io/v1
  kind: Role
  name: service-reader

하나의 Role은 여러 RoleBinding에 참조될 수 있고, 하나의 서비스 어카운트는 여러 RoleBinding 에 참조될 수 있다.

클러스터 롤의 사용법은 롤과 같으나, namespaced 되지 않는 객체(노드/persistence volume 등)에 대해 권한을 줄 수 있다.

3. 쿠버네티스 API 서버에 접근

kubectl은 kube-apiserver 에 접근하여 명령을 전달하고 응답을 받아온다. 이렇게 개발자가 직접 명령어를 입력하지 않고 어플리케이션이 쿠버네티스에 명령을 내리려면, kube-apiserver 에 kubectl 이 아닌 다른 방법으로 접근할 것이다.

REST api

도커 엔진에 rest api로 요청을 보냈던 것 처럼, kube-apiserver 에도 rest api로 명령을 내릴 수 있다.

물론 이 경우에도 인증/인가가 필요하다.

해당 시크릿의 token 에 저장되어 있는 정보를 base64로 디코딩해서 http 헤더에 넣어 kube-apiserver에 보내면 인증을 할 수 있다.

쿠버네티스 클러스터 내부의 포드에서 접근

이 경우에도 http 요청으로 접근한다면 jwt 토큰이 필요하다. 다만 쿠버네티스는 편의를 위해 서비스 어카운트로 생성한 포드에 해당 서비스 어카운트와 연결된 시크릿을 자동으로 마운트 해 준다.

kubectl exec <container-id> ls /var/run/secrets/kubernetes.io/serviceaccount

3. 유저와 그룹의 개념

image

User 와 Group 은 쿠버네티스 객체가 아닌 추상적인 개념이다.

즉 kubectl get user / kubectl get group 하면 에러가 발생

즉 인증 받은 명령 실행의 주체를 모두 User 라고 하고, 서비스 어카운트 / 인증서 등의 방식으로 인증된 주체는 User 가 된다.

Group 은 이런 User 의 집합을 의미한다.

image