최근 워크스테이션에 쿠버네티스를 셋팅하고 있는데, 이 과정에서 쿠버네티스가 어떤 방식으로 통신하고 있는지 자세히 들여다 보았다.
이전에는 퍼블릭 클라우드에서 매니징 해주는 상태에서 쿠버네티스를 사용했기에 쿠버네티스가 어떤 포트를 이용하고 어떤방식으로 통신하고 있는지 생각해 본 적이 없다.
쿠버네티스가 사용하는 포트들
먼저 쿠버네티스가 어떤 포트를 통해서 통신하고 있는지는 쿠버네티스 Docs에 잘 나와있다.
컨트롤 플레인
프로토콜 | 방향 | 포트 범위 | 용도 | 사용 주체 |
---|---|---|---|---|
TCP | 인바운드 | 6443 | 쿠버네티스 API 서버 | 전부 |
TCP | 인바운드 | 2379-2380 | etcd 서버 클라이언트 API | kube-apiserver, etcd |
TCP | 인바운드 | 10250 | Kubelet API | Self, 컨트롤 플레인 |
TCP | 인바운드 | 10259 | kube-scheduler | Self |
TCP | 인바운드 | 10257 | kube-controller-manager | Self |
워커 노드
프로토콜 | 방향 | 포트 범위 | 용도 | 사용 주체 |
---|---|---|---|---|
TCP | 인바운드 | 10250 | Kubelet API | Self, 컨트롤 플레인 |
TCP | 인바운드 | 30000-32767 | NodePort 서비스 | 전부 |
Docs에 나와있는 표 부분을 가져왔다. 당연히 컨트롤 플레인과 워커노드가 사용하는 포트가 살짝 다르다.
여기서 참고를 위해서 Docs에 나와있는 쿠버네티스 컴포넌트를 가져왔다.
제일 먼저, 모든 컴포넌트들이 Control Plane의 API와 연결이 되어 있는데, 이 과정에서 쿠버네티스 API는 6443의 포트를 이용해서 데이터를 받아들이는 듯 하다.
Control Plane에서 나머지 etcd, kubelet, kube-scheduler, kube-controller-manager는 각각의 포트들을 사용한다.
(참고) Control Plane 내부에도 Kubelet이 존재합니다.
그리고 워커노드와 컨트롤 플레인이 통신할 때는, Kubelet을 통해서 통신을 하는데 이 과정에서 10250 포트를 사용한다.
30000 ~ 32767의 포트는 노드포트 서비스라고 나와 있다.
GCP에서는 어떻게 사용하고 있을까?
위를 통해서 특정 포트만 열어주면 쿠버네티스를 사용할 수 있다는 것을 알아냈다.
그래서 궁금해진 것이 “GKE에서는 어떻게 운영하고 있을까?” 이였으며, 몇가지 테스트해보았다.
위는 GKE를 생성했을 때, GCP에서 자동으로 생성해주는 VPC의 방화벽이다.
추가적인 설명을 잠깐 하면, 10.116.0.0/14
의 CIDR는 클러스터 포드 IPv4 범위(기본값) 라고 표기되어있는 CIDR인데 이 영역에서 쿠버네티스 리소스들의 endpoint ip가 할당된다.
10.128.0.0/9
는 GKE에서 컨트롤플레인 및 노드가 할당된다.
GKE에서는 컨트롤 플레인을 GCP에서 운영하고, 워커노드를 노드풀 형식으로 관리하고 있는데, 컨트롤 플레인을 제어영역이라고 부른다. 이러한 이유때문에, 워커노드들을 각각의 VM 인스턴스로 생성하는 것 보다 GKE의 가격이 비싸다.
조금 더 자세히 살펴보면, 먼저 워커노드 및 컨트롤 플레인에 해당하는 CIDR에서 모든 인바운드 포트를 오픈해두었다. 이렇게 되면 위에서 확인한 모든 포트가 오픈되어 있기에 사용하는데 문제가 없다.
여기서 특이하게 위에서 보지 못한 10255 포트가 나오는데, Read-Only Kubelet API로 사용한다고 한다. 어떻게 사용되는지는 조금 더 찾아봐야 할 듯 하다.
하지만 VPC에서 확인되는 방화벽은 GKE를 최초 생성할 때만 적용되는 듯 하다. 그래서 크게 의미 없는 듯 하다.
VPC에 있는 모든 방화벽 규칙을 삭제해도 정상적으로 동작한다.
워커 노드에 대해 코드로 정의된 내용을 보다 보면, 아래와 같이 10250포트를 사용함을 알 수 있다.
daemonEndpoints:
kubeletEndpoint:
Port: 10250
또한 GKE에서 endpoints를 조회해보면, metrics-server
라는 이름으로 10250을 사용하는 것을 알 수 있다.
$ kubectl get endpoints -n kube-system metrics-server
NAME ENDPOINTS AGE
metrics-server 10.32.0.5:10250 8m29s
GKE에서는 따로 컨트롤플레인에 대한 내용을 제공하지 않아서 이에 대한 포트는 확인 할 수 없는 듯 하다.
$ kubectl get endpoints -n kube-system calico-typha
NAME ENDPOINTS AGE
calico-typha 10.178.0.21:5473,10.178.0.22:5473 2m21s
여기서 몇가지 설정을 변경하면 calico가 존재함을 알 수 있는데, 이 또한 알아두면 좋을 듯 하다.
$ kubectl get endpoints kubernetes
NAME ENDPOINTS AGE
kubernetes 10.178.0.20:443 38m
또한, 우리가 입력하는 kubectl
같은 명령어는 https를 이용하는 듯하다. ( http 방식 or gRPC 방식을 이용한다고 함 )
뭔가 확인하고 싶은 내용들을 확인하지 못해서 아쉽다. 결론은, GKE에서는 VPC에서 모든 포트를 열어두고 있는 듯 하며 필요에 따라 NetworkPolicy등을 이용해서 제어하면 될 듯 하다.
몇가지 추가 테스트
이대로 마무리하기 아쉬워서 직접 VM 인스턴스에 쿠버네티스를 띄어서 연결해보았다. ( 이 과정에서는 AWS를 이용했다. )
root@k8s-control-plane:~# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.31.177.8:6443 5m19s
1.26 버전의 쿠버네티스에 containerd기반 노드들로 진행했는데, 위와같이 기대했던 6443포트가 있음을 확인했다.
root@k8s-control-plane:~# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-787d4945fb-6c8fb 1/1 Running 0 8m
coredns-787d4945fb-hmf5f 1/1 Running 0 8m
etcd-k8s-control-plane 1/1 Running 0 8m14s
kube-apiserver-k8s-control-plane 1/1 Running 0 8m12s
kube-controller-manager-k8s-control-plane 1/1 Running 0 8m12s
kube-proxy-ddxrj 1/1 Running 0 8m
kube-proxy-n55x5 1/1 Running 0 3m41s
kube-scheduler-k8s-control-plane 1/1 Running 0 8m12s
이제 컨트롤플레인이 조회가 되기에, etcd, apiserver, controller-manager, scheduler들의 내용을 확인해봤다.
#etcd
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /health?exclude=NOSPACE&serializable=true
port: 2381
scheme: HTTP
# apiserver
livenessProbe:
failureThreshold: 8
httpGet:
host: 172.31.177.8
path: /livez
port: 6443
scheme: HTTPS
# controller-manager
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 10257
scheme: HTTPS
# scheduler
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 10259
scheme: HTTPS
당연한 거지만, Docs에 나와있는 것 처럼, 해당 포트들을 사용하고 있다.
endpoints에서는 조회가 안되지만, pod들의 yaml파일을 열어보면 위와 같이 livenessProbe가 정의되어 있었다.
apiserver를 제외하고 나머지는 127.0.0.1
로 설정되어있는 것 보면, 보안을 극대화하고 싶은신 분은, 컨트롤 플레인의 6443포트만, 워커노드의 10250포트 및 사용하는 앱에 따른 포트만 오픈해주면 될 듯 하다.
마무리
이전 까지 매니지드 서비스만 이용해와서 한번도 생각해 본 적 없었는데, 공부하면서 조금 찾아보니 쿠버네티스랑 조금 더 친해진 듯 하다.
또한, 매니지드 서비스를 사용하는 것이 이렇게 편리한 일 임을 다시 생각하게 되었다.