[Kubernetes] Admission Controller


서론

사용자가 어떤 명령어 전달할 때 kubectl을 통해Kubernetes클러스터에서 다양한 작업을 수행했다.

파드를 생성하는 등의 요청을 보낼 때마다 그 요청은 API 서버로 전달되고, 이후 파드가 생성되며

최종적으로 그 정보는 Etcd 데이터베이스에 저장된다.

이때 사용자의 요청이 API 서버에 도달하면, 먼저 authentication(인증)과정을 거쳐야한다.

인증과정에서는 사용자가 누구인지 식별하고 유효한지 확인하기 위한 과정이다.

.kube/config 파일의 인증서 정보를 가지고 확인한다.

이후에 사용자가 해당 작업을 수행할 권한이 있는지 확인하는 권한 부여(Authorization) 과정을 거쳐야 한다.

권한 부여는 Role-Based Access Control(RBAC)을 통해 이루어진다.

예를 들어 사용자가 developer 역할을 가지고 있다면, 그 사용자는 파드 목록 조회(list), 가져오기(get), 생성(create), 수정(update), 삭제(delete)가 가능하다.

따라서 요청이 이러한 조건 중 하나에 해당한다면 권한이 허용되어 처리되며 그렇지 않으면 거부된다.

RBAC를 통해 우리는 다양한 제한을 설정할 수 있다.

특정 역할을 가진 사용자에게 허용하거나 거부할 수 있고, 파드, 디플로이먼트, 서비스 같은 오브젝트에 대해 생성, 조회, 삭제 권한을 설정할 수 있다.

또한 특정 리소스 이름에 대한 접근도 제한할 수 있다.

예를 들어 developer는 blue 또는 orange라는 이름의 파드만 다룰 수 있도록 제한하거나, 특정 네임스페이스 내부에서만 접근을 허용할 수도 있다.

RBAC는 누가 어떤 API 작업을 할 수 있는가에 초점을 둔 권한 제어 방식이다.

예를 들어, 어떤 사용자가 파드 생성, 삭제, 조회를 할 수 있는지를 정할 수 있다.

또는 특정 네임스페이스 안에서만 작업할 수 있도록 제한할 수도 있다.

그러나 RBAC만으로는 파드의 세부 구성 내용까지는 제어할 수 없다.

  • 외부 Docker Hub가 아닌 내부 레지스트리의 이미지만 사용하게 하기
  • 이미지에 latest 태그 사용 금지
  • 컨테이너가 root 사용자로 실행되지 않도록 제한
  • 파드에 반드시 특정 라벨이 포함되도록 강제
  • 특정 Linux capability만 허용

이처럼 리소스 내부의 구성까지 검사하고 제어하는 정책은 RBAC로는 불가능하며, 이를 해결하기 위해 Admission Controller가 필요하다.


여기서 부터는 Admission Controller에 대해서 알아보겠다.

Admission Controller

Admission Controller는 클러스터 사용 방식을 세부적으로 제어할 수 있게 한다.

예를 들어, 요청 자체를 수정하거나 파드가 생성되기 전에 추가 작업을 실행할 수도 있다.

Kubernetes에는 기본적으로 내장된 여러 Admission Controller가 존재한다.

  • AlwaysPullImages Admission Controller
    • 파드가 생성될 때마다 이미지를 항상 새로 가져오도록 보장한다.
  • DefaultStorageClass Admission Controller
    • PVC가 생성되는 것을 감시하고, 명시된 storage class가 없을 경우, 기본 storage class를 자동으로 할당한다.
  • EventRateLimit Admission Controller
    • API 서버가 동시에 처리할 수 있는 요청 수에 제한을 걸어, API 서버가 요청 폭주로 마비되는 것을 방지한다.
  • NamespaceExists Admission Controller
    • 존재하지 않는 네임스페이스에 대한 요청을 거부한다.

그리고 이 외에도 많은 Admission Controller가 존재하는데 NamespaceExists를 예시로하여 어떻게 동작하는지 알아보겠다.

예를 들어, 사용자는 존재하지 않는 "blue"라는 네임스페이스에 파드를 생성하려 한다고 가정해 보자

이 명령어를 실행하면 "blue 네임스페이스를 찾을 수 없습니다"라는 오류가 발생합니다.

여기서 일어나는 일은, 먼저 내 요청(Authentication)이 인증되고, 그 다음 권한(Authorization)이 확인된 후,

그 다음 Admission Controller 단계를 거친다.

이때 NamespaceExists Admission Controller가 요청을 처리하면서,

blue 네임스페이스가 존재하는지를 확인하고 존재하지 않으면, 요청이 거부된다.

NamespaceExists는 기본으로 활성화되어 있는 내장 Admission Controller이다.

기본적으로 활성화되어 있지 않은 Admission Controller도 있는데 그것은 NamespaceAutoProvision Admission Controller이다.

이 컨트롤러는 네임스페이스가 없으면 자동으로 생성해준다.

기본적으로 활성화된 Admission Controller 목록을 확인하려면 아래의 명령어로 가능하다

kube-apiserver -h | grep enable-admission-plugins

초록색으로 강조된 것들이 기본 활성화된 Admission Controller목록 들이다.

만약 kubeadm 기반으로 클러스터를 구성한 경우에는 kube-apiserver 내부에서 실행해야야 한다 따라서 아래의 명령어로 확인할 수 있다.

아래처럼 kubectl exec 명령어를 통해 kube-apiserver에 진입가능하다.

kubectl exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h | grep enable-admission-plugins

기본적으로 활성화된 것 외에 추가로 Admission Controller를 추가하려면, kube-apiserver 서비스의 --enable-admission-plugins 플래그에 추가할 Admission Controller를 추가하면 된다.

아래 그림에서는 NodeRestriction, NamespaceAutoProvision를 추가한다.

왼쪽 이미지(kube-apiserver.service)는 kube-apiserver를 직접 서비스로 실행하는 경우에 수정하는 방법이다.

오른쪽은 kubeadm으로 클러스터 구성시 수정하는 방법으로 kube-apiserver의 매니페스트 파일 안에 플래그를 수정해야한다. (파일위치는 /etc/kubernetes/manifests/kube-apiserver.yaml)

설정을 완료 후, 사용자가 존재하지 않는 네임스페이스에 파드를 생성하는 명령을 실행하면, 요청은 Authentication(인증), Authorization(권한) 확인 과정을 거친 후, NamespaceAutoProvision 컨트롤러에 진입한다.

그리고 해당 컨트롤러가 네임스페이스가 존재하지 않는다는 것을 인지하고 네임스페이스를 자동으로 생성한다.

최종적으로 요청이 정상적으로 통과되어 파드가 생성된다.

아래 kubectl get namespaces로 네임스페이스를 확인해 보면, blue 네임스페이스가 자동으로 생성되어 있는 것을 확인할 수 있다.

이것이 Admission Controller가 어떻게 동작하는지에 대한 한 가지 예시이다.

Admission Controller는 요청을 검증하고 거부하는 것뿐만 아니라, 백엔드에서 추가적인 작업을 수행하거나, 요청 자체를 수정할 수도 있다.

참고로, NamespaceAutoProvision과 NamespaceExists Admission Controller는 더 이상 권장되지 않으며, 이제는 NamespaceLifecycle Admission Controller로 대체되었다.

NamespaceLifecycle Admission Controller는 존재하지 않는 네임스페이스 대한 요청을 거부하고

default, kube-system, kube-public 같은 기본 네임스페이스가 삭제되지 않도록 보호한다.

Admission Controller Enable/Disable Plugins 명령어

ps -ef | grep kube-apiserver | grep admission-plugins