이전 포스팅에 이어서 kubernetes 내부의 TLS 통신에 대해 정리하고자 함.
K8s 클러스터를 구성하는 서버들 사이에서 암호화 통신을 해야합니다. 또한 kube-apiserver는 통신하고 있는 Client가 누구인지 알야합니다.
따라서 Kubernetes 내부의 모든 Component(kube-apiserver, etcd, kubelet...) 간 통신은 HTTPS 기반의 암호화 통신으로 이루어지게됩니다.
그 결과 모든 트래픽은 암호화되어 데이터의 신뢰성과 보안을 보장할 수 있게 됩니다.
HTTPS 프로토콜을 사용한 통신을 진행하기 위해서는 Server측과 Client 양쪽 모두 TLS 인증서가 필요합니다. 그리고 모든 인증서는 CA(Certificate Authority)에 의해 서명되어야 합니다.
따라서 크게 3종류의 인증서가 필요합니다.
K8s 내부에는 이런 인증서를 기반으로 독자적인 PKI를 구성하고 있습니다.
그림을 통해 순서대로 알아보겠습니다.
ROOT CA(Kubernetes CA)
Master 1번 노드에서 최초 K8s를 구성할 때 ca.key 파일이 생성되고 CSR 요청을 통해 ca.crt 파일이 생성됩니다. 이제 이 파일은 Kubernetes의 ROOT certificate 역할을 하게 되고 새로운 노드가 Join될 때 해당하는 노드로 전달됩니다.
key파일과 crt파일은 /etc/kubernetes/pki 디렉토리에 위치합니다.
ETCD CA
Master 1번 노드에서 최초로 K8s를 구성할 때 ca.key 파일이 생성되고 CSR 요청을 통해 ca.crt 파일이 생성됩니다. 이제 이 파일은 ETCD의 ROOT Certificate 역할을 하게 되고 새로운 Master노드가 Join될 때 해당하는 노드로 전달됩니다.
key파일과 crt파일은 /etc/kubernetes/pki/etcd 디렉토리에 위치합니다.
kube-apiserver, kubelet, ETCD는 K8s 내부에서 Server 역할을 하는 Component들입니다.
따라서 세가지 Component들은 Server Certificate를 가져야합니다.
Server Certificate를 발급받기 위해 각각 key 파일을 생성합니다. 이후 kube-apiserver와 kubelet은 Kubernetes CA를 통해 crt 파일을 발급받고, ETCD는 ETCD CA를 통해 crt 파일을 발급받습니다.
K8s 내부에서 위에서 알아본 Server(kube-apiserver, kubelet, ETCD)들과 통신하는 Client는 kubectl, kube-apiserver, kubelet, kube-scheduler, kube-controller-manager, kube-proxy가 있습니다.
모든 kube-apiserver를 제외한 모든 Client Component들은 각자 key파일을 생성하고 Kubernetes CA를 통해 crt 파일을 발급받습니다.
kubelet은 이전 과정에서 Server Certificate를 발급 받았는데 여기서는 Client Certificate를 발급받습니다. 이는 kubelet이 Server로의 역할뿐 아니라 Client로 다른 Server와 통신하여 작업하는 과정이 있기 때문입니다.
kube-apiserver의 Client Certificate
kube-apiserver도 kubelet과 동일하게 Server의 역할과 Client로 다른 Server와 통신하는 작업들이 있기 때문에 Client Certificate를 발급받게 됩니다. 이때 kube-apiserver는 두 개의 Client Certificate를 발급 받게 되는데 하나는 Kubernetes CA를 통해 발급받는 apiserver-kubelet.crt 파일이고 다른 하나는 ETCD CA를 통해 발급받는 apiserver-etcd-client.crt 파일입니다.
지금까지 K8s 내부의 TLS 인증서 발급에 대해 알아보았습니다.
이제 발급 받은 인증서를 통해 TLS통신이 어떻게 진행되는지 그림을 통해 알아보겠습니다.
K8s를 구성하는 Component들이 각자 통신에 필요한 Client Certificate와 Server Certificate를 CA(kubernetes CA, ETCD CA)를 통해 발급받아 암호화 통신이 이루어짐을 확인할 수 있습니다.
각 Component간의 통신에 대해 조금 더 자세히 알아보겠습니다.
kube-apiserver => ETCD
kube-apiserver는 ETCD에 접근 가능한 유일한 Component입니다. 클러스터의 상태를 key-value 형식으로 etcd에 저장합니다.
kubelet => kube-apiserver
Worker 노드의 kubelet은 자신이 생성해야 할 Pod의 정보를 kube-apiserver로부터 가져옵니다.
kube-apiserver => kubelet
kubelet은 자신이 위치한 Worker 노드와 해당 노드에 떠 있는 Pod의 상태를 kube-apiserver에 알려줍니다.
kubectl => kube-apiserver
User가 입력한 Command 및 Manifest(yaml)파일을 JSON 형식으로 변형하여 kube-apiserver에 전달합니다.
kube-scheduler => kube-apiserver
kube-apiserver로부터 Node가 배정되지 않은 Pod(Unscheduled)의 정보를 가져와 적절한 Node를 배정하고 결과를 kube-apiserver로 전달합니다.
kube-controller-manager => kube-apiserver
K8s 클러스터에 존재하는 Object들의 desired state와 현재 상태를 kube-apiserver로부터 가져와 desired state로 맞추는 작업을 수행합니다.
kube-proxy => kube-apiserver
K8s의 Service와 Endpoint 정보를 가져와 자신이 위치한 Node의 Netfilter Rule(iptables or ipvs)를 업데이트합니다.
좋은 글 감사합니다. 자주 방문할게요 :)