Open sangw0804 opened 3 years ago
쿠버네티스 클러스터는 실제로 여러 어플리케이션/사용자/팀이 같이 사용하게 되고, 필연적으로 인증/인가에 관련된 기능이 필요하게 되었다.
쿠버네티스의 인증/인가는 리눅스 권한 관리와 비슷하다. 리눅스에도 여러 유저별로 다르게 권한을 세팅하여 관리하는 것처럼, 쿠버네티스에서는 ServiceAccount 및 RBAC(Role Based Access Control)이라는 기능으로 인증/인가를 관리한다.
쿠버네티스 마스터 노드는 kube-apiserver, kube-controller,kube-scheduler, etcd 등과 같은 컴포넌트들로 구성되어 있다.
이중 권한 인증에 관련된 컴포넌트는 kube-apiserver이다.
지금까지 kubectl 로 명령을 실행할 경우 권한이 문제된 적이 없었던 것은 kubectl로 직접 명령어를 kube-apiserver 에 전달할 경우 자동으로 최고 권한(cluster-admin)으로 명령을 전달하기 때문이다.
서비스 어카운트는 권한을 관리하기 위한 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 등)에 대해 권한을 줄 수 있다.
kubectl은 kube-apiserver 에 접근하여 명령을 전달하고 응답을 받아온다. 이렇게 개발자가 직접 명령어를 입력하지 않고 어플리케이션이 쿠버네티스에 명령을 내리려면, kube-apiserver 에 kubectl 이 아닌 다른 방법으로 접근할 것이다.
도커 엔진에 rest api로 요청을 보냈던 것 처럼, kube-apiserver 에도 rest api로 명령을 내릴 수 있다.
물론 이 경우에도 인증/인가가 필요하다.
해당 시크릿의 token 에 저장되어 있는 정보를 base64로 디코딩해서 http 헤더에 넣어 kube-apiserver에 보내면 인증을 할 수 있다.
이 경우에도 http 요청으로 접근한다면 jwt 토큰이 필요하다. 다만 쿠버네티스는 편의를 위해 서비스 어카운트로 생성한 포드에 해당 서비스 어카운트와 연결된 시크릿을 자동으로 마운트 해 준다.
kubectl exec <container-id> ls /var/run/secrets/kubernetes.io/serviceaccount
User 와 Group 은 쿠버네티스 객체가 아닌 추상적인 개념이다.
즉 kubectl get user / kubectl get group 하면 에러가 발생
즉 인증 받은 명령 실행의 주체를 모두 User 라고 하고, 서비스 어카운트 / 인증서 등의 방식으로 인증된 주체는 User 가 된다.
Group 은 이런 User 의 집합을 의미한다.
쿠버네티스 클러스터는 실제로 여러 어플리케이션/사용자/팀이 같이 사용하게 되고, 필연적으로 인증/인가에 관련된 기능이 필요하게 되었다.
쿠버네티스의 인증/인가는 리눅스 권한 관리와 비슷하다. 리눅스에도 여러 유저별로 다르게 권한을 세팅하여 관리하는 것처럼, 쿠버네티스에서는 ServiceAccount 및 RBAC(Role Based Access Control)이라는 기능으로 인증/인가를 관리한다.
1. 쿠버네티스의 권한 인증 과정
쿠버네티스 마스터 노드는 kube-apiserver, kube-controller,kube-scheduler, etcd 등과 같은 컴포넌트들로 구성되어 있다.
이중 권한 인증에 관련된 컴포넌트는 kube-apiserver이다.
2. ServiceAccount와 롤/클러스터 롤
서비스 어카운트
서비스 어카운트는 권한을 관리하기 위한 subject 가 되는 쿠버네티스 object 이다.
특정 서비스 어카운트로 kubectl 명령어를 사용하려면 --as 옵션을 사용하면 된다.
해당 서비스 어카운트에 권한을 부여하려면, 롤/클러스터 롤을 사용하면 된다.
먼저 role 객체를 생성해보자.
여기까지만 했다고 바로 권한이 서비스 어카운트에 부여되는 것이 아니다. 실제 롤과 subject를 연결해주는 롤바인딩이라고 하는 객체가 필요하다.
하나의 Role은 여러 RoleBinding에 참조될 수 있고, 하나의 서비스 어카운트는 여러 RoleBinding 에 참조될 수 있다.
3. 쿠버네티스 API 서버에 접근
kubectl은 kube-apiserver 에 접근하여 명령을 전달하고 응답을 받아온다. 이렇게 개발자가 직접 명령어를 입력하지 않고 어플리케이션이 쿠버네티스에 명령을 내리려면, kube-apiserver 에 kubectl 이 아닌 다른 방법으로 접근할 것이다.
REST api
도커 엔진에 rest api로 요청을 보냈던 것 처럼, kube-apiserver 에도 rest api로 명령을 내릴 수 있다.
물론 이 경우에도 인증/인가가 필요하다.
쿠버네티스는 서비스 어카운트를 생성하면 이에 대응하는 시크릿을 생성해준다. 해당 시크릿에는 HTTP 방식에서 인증을 위한 JWT token / 아마도 ssh 방식 인증을 위한 공개키 / 그래고 해당 서비스 어카운트의 namespace 정보가 저장되어 잇다.
해당 시크릿의 token 에 저장되어 있는 정보를 base64로 디코딩해서 http 헤더에 넣어 kube-apiserver에 보내면 인증을 할 수 있다.
쿠버네티스 클러스터 내부의 포드에서 접근
이 경우에도 http 요청으로 접근한다면 jwt 토큰이 필요하다. 다만 쿠버네티스는 편의를 위해 서비스 어카운트로 생성한 포드에 해당 서비스 어카운트와 연결된 시크릿을 자동으로 마운트 해 준다.
3. 유저와 그룹의 개념
User 와 Group 은 쿠버네티스 객체가 아닌 추상적인 개념이다.
즉 인증 받은 명령 실행의 주체를 모두 User 라고 하고, 서비스 어카운트 / 인증서 등의 방식으로 인증된 주체는 User 가 된다.
Group 은 이런 User 의 집합을 의미한다.