본문 바로가기
  • 오늘처럼
소프트웨어 아키텍처/Kubernetes

Kubelet authenticatoin/authoziation

by bluefriday 2022. 7. 14.
반응형

Kubernetes cluster 에서 worker node 는 master node 에 있는 controlplane 인 kube-api server 와 통신하여 클러스터를 구성하게 된다. 이 때 노드에서는 kubelet 프로세스가 이 작업을 수행하는데, 여기에서는 kubelet 의 역할과 kubelet 에 대한 authentication(인증) / authorization(권한 관리) 방법에 대하여 알아보고 kubelet 과 worker 노드를 안전하게 지키기 위하여 권장되는 방법을 확인해본다.

kubelet 의 역할

1. kubelet 의 역할

먼저 kubelet 은, kubeadm 등의 도구와 함께 사용되어, kubernetes cluster 에 worker 노드를 등록해주는 역할을 한다. 정상적으로 등록이 된 후 kube-api server 가 파드 생성에 대한 요청을 worker 노드에 있는 kubelet 에게 보내면, kubelet 은 자신이 구동되어 있는 노드에 설치된 Container Runtime(Ex: Docker, Containerd) 에게 파드 생성 요청을 보낸다. 이후 Container Runtime 은 container image 를 내려받고(pulling) 구동(run) 하게 된다. 파드가 구동이 된 이후에도 kubelet 은 지속적으로 파드와 노드의 상태 등을 모니터링 하여 kube-api server 에 주기적으로 상태를 전달하는 역할을 수행한다. 


2. kubelet 의 설치 및 설정

kubelet 은 kubeadm 이나 kubectl 과는 별도로 설치된다. kubeadm 툴에서 kubelet 을 설치해주지 않으므로 개별 설치를 해야 하며 apt, yum 등의 설치관리자를 이용한 방법과, 하단의 wget을 통한 바이너리 다운로드 방식이 있다(설치 관리자를 통한 방식은 다른 포스팅에서 다룰 예정).

wget https://storage.googleapis.com/kubernetes-release/release/v1.20.0/bin/linux/amd64/kubelet

chmod +x kubelet
mv ./kubelet /usr/local/bin/kubelet

이렇게 바이너리 파일을 다운로드 받은 다음에 실행 권한을 주고 사용자 공간에 위치시킨다. 일단 설치가 끝나면 프로세스로 등록하여 실행하게 되는데, 이 때 kubelet 을 실행하면서 동작과 관련된 설정을 파라미터로 전달한다.

Kubelet.service
---
ExecStart=/usr/local/bin/kubelet
  --container-runtime=remote 
  --image-pull-progress-deadline=2m
  --kubeconfig=/var/lib/kubelet/kubeconfig
  --network-plugin=cni
  --register-node=true
  --v=2
  --cluster-domain=cluster.local
  --file-check-frequency=0s
  --healthz-port=10248
  --cluster-dns=10.96.0.10
  --http-check-frequency=0s
  --syn-frequency=0s

이와 같은 설정 값은 실행 시점의 파라미터 뿐 아니라, 별도의 설정 파일을 통하여도 지정 가능하다.

Kubelet.service
---
ExecStart=/usr/local/bin/kubelet
  --container-runtime=remote 
  --image-pull-progress-deadline=2m
  --kubeconfig=/var/lib/kubelet/kubeconfig
  --network-plugin=cni
  --register-node=true
  --v=2
  --config=/var/lib/kubelet/kubelet-config.yaml

위와 같이 '--config' 파라미터로 참조할 설정 파일을 지정해 준 후에 하단과 같이 yaml 파일을 명세해준다. 상단 실행 시의 파라미터가 dash-case 를 사용한 것에 비해 하단 yaml 파일의 경우 camelCase를 사용한 것을 확인할 수 있다.

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDomain: cluster.local
fileCheckFrequency: 0s
healthzPort: 10248
clusterDns:
- 10.96.0.10
httpCheckFrequency: 0s
syncFrequency: 0s

노드를 등록할 때마다 이 config 파일을 준비해줘야 하는데, 여러 대의 노드를 등록할 경우의 번거로움을 줄이기 위해 kubeadm 툴의 명령어 레벨에서 config 파일을 생성해준다.


 

3. kubelet authentication

kubelet 은, health check 를 위해 사용되는 10248 포트를 제외하고, 기본적으로 다음의 2개의 port를 노출한다. 해당 포트는 default 값이나 위의 설정 파일에서 변경 가능하다.

포트 및 설명 설정 파일에서의 변경 파라미터
  10250 포트 : Kube-api Server 와의 통신을 위한 포트  --port, port
  10255 포트 : 읽기전용(Read-Only) 포트 --read-only-port, readOnlyPort

3-1. api 통신 포트

기본 값으로 10250 포트를 사용한다. 이 포트는 기본값으로 별도의 인증이 설정 되어 있지 않고 전체 엑세스(full access)를 허용한다. 따라서 보안성을 높이기 위해 임의 접근(anonymous access)을 비활성화 하고 인증 매커니즘을 지정해 주는 것이 좋다. 임의 접근을 비활성화 하는 옵션은 다음과 같다.

# kubelet.service 의 예
ExecStart=/usr/local/bin/kubelet
  ...
  --anonymoust-auth=false
  ...
--------------------------------------------

# kubelet-config.yaml 의 예
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: false

kubernetes 에서는 kubelet 의 authentication 을 위해 다음의 2개의 매커니즘을 제공한다.

  • Certification-based Authentication : Certificates (x509)
  • Bearer token-based Authentication : API Bearer Tokens

각각은 kubelet 설정으로가능하며, 인증서 기반 인증의 경우 예시는 다음과 같다.

# kubelet.service 의 예
ExecStart=/usr/local/bin/kubelet
  ...
  --client-ca-file=/path/to/ca.crt
  ...
--------------------------------------------

# kubelet-config.yaml 의 예
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  x509:
    clientCaFile: /path/to/ca.crt
    ...

3-2. 읽기 전용 포트

기본 값으로 10255 포트를 사용한다. 이 포트는 읽기 전용이므로, 아무런 인증(authentication)이나 권한 처리(Authorization)가 수행되지 않는다. 주로 metric 등에 대한 정보를 조회할 때 사용되는데 포트 번호는 다음과 같이 변경 가능하다.

# kubelet.service 의 예
ExecStart=/usr/local/bin/kubelet
  ...
  --read-only-port=10255
  ...
--------------------------------------------


# kubelet-config.yaml 의 예
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
readOnlyPort: 10255

이 포트의 값을 0 으로 지정할 경우 해당 포트는 disable 된다. 인증 처리가 적용되지 않은 포트이므로, 보안성을 높이기 위해 disable 모드를 권장한다.


4. kubelet authorization

일단 인증(authentication)에 성공한 사용자는 kubelet 에 대하여 모든 권한이 승인된다. 권한처리로 제공되는 2가지 모드 중 기본 값이, 모든 요청을 허용하는 AlwaysAllow 이기 때문이다. 

  • AlwaysAllow (default)
  • Webhook

권한을 세분화해야 할 경우, kubelet 이 kube-api server 에 webhook 요청을 보내 권한처리를 위임하게 할 수 있다. 설정은 다음과 같다.

# kubelet.service 의 예
ExecStart=/usr/local/bin/kubelet
  ...
  --authorization-mode=webhook
  ...
--------------------------------------------


# kubelet-config.yaml 의 예
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authorization:
  mode: webhook
  ...

위와 같이 kubelet 의 역할과 설치/설정 방법, 인증/권한처리 방식에 대하여 확인해보았다. 외부 공격에 대하여 안전한 클러스터 환경을 만들기 위해 내용을 정리하면 아래와 같다.

  • 임의 사용자 접근은 비활성화 하며 Authentication 은 반드시 설정한다.
  • 인증처리가 없는 읽기 전용 포트는 비활성화 한다.
  • 권한처리를 세분화하고 webhook 을 사용한다.




댓글