2017년 한참 IT 공부를 시작할때 쯤, 컨테이너를 처음 접해봤고 학교 졸업 과제로 Docker를 사용한 모니터링 애플리케이션을 만들었다. 이땐 취업용으로 한번 쓰고 말겠지 하면서 공부를 소홀히 하다가, 회사생활을 하면서 컨테이너의 활용도를 많이 접하게 되었고 2020년부터 Docker부터 쿠버네티스까지 다시 한번 공부를 하게 되었다. 첫 직장 다닐땐 Azure를 주로 다뤘는데, 그때만해도 아직 쿠버네티스 서비스가 정식으로 출시되진 않았었고 Service Fabric으로 다른 컨테이너 서비스를 제공했던 기억이 난다.
그러고나서 어느새부터 클라우드 사업자들이 모두 Managed Kubernetes 서비스를 기본으로 제공해주기 시작했다. 그리고 Azure와 NCP의 쿠버네티스를 많이 다뤄봤고, 다른 클라우드 사업자(이하 CSP)의 문서를 살펴봤다. 그리고 공통적으로 내놓는 내부 아키텍처는 아래 그림과 같이 단순하다.
위의 그림을 토대로, CSP의 Managed Kubernetes서비스의 이점을 간단히 살펴보면 다음과 같다.
- 확장 가능한 Managed Control Plane 제공
- 대부분 CSP가 제공하는 Control Plane은 SSH를 통한 직접 접근, etcd 복제 등의 Control Plane 제어가 불가능하다.
- 확장 가능한 Managed Worker Node 제공
- WorkerNode는 책임공유형 모델로, OS Image, 클러스터 조인 등 사용자의 관리를 최소한으로 줄여준다.
- 사용자는 yaml / helm 등을 사용하여 Worker Node에 리소스를 배포한다.
- CSP가 제공하는 다양한 리소스와 통합
- K8S(Kubernetes)의 ServiceType을 Load Balancer로 설정할 경우, CSP가 제공하는 Load Balancer와 통합이 가능하다.
- StorageClass로 CSP가 제공하는 Storage / NAS 상품들을 PV / PVC로 사용 가능하다.
- 이외에 다양한 리소스와 통합이 있다.
CSP마다 제공하는 K8S의 상세 아키텍처는 위의 아키텍처를 토대로 세분화 되므로, 각 CSP의 상세 아키텍처 문서를 보면서 이해하면 된다. 그리고 아마존이 제공하는 Managed K8S 서비스인 EKS를 알아보기 위해 스터디를 시작했고, 그 내용을 블로그에 정리하려고 한다.
오늘은 EKS의 기본 구조에 대한 내용이다.
클러스터 배포
스터디에서 공유한 설치 스크립트 말고, 웹에서 직접 수행하며 다른 CSP와 다른 점을 알아보려고 한다.
배포 방식
클러스터 배포 방식으론 생성과 등록이 있다. 등록의 경우 Rancher / Rafay / Azure Arc등과 같이 멀티클러스 관리를 위한 서비스를 제공하는 것 으로 보인다.
클러스터 등록을 위해선 EKS-Connector역할을 만들어야 한다. YAML 파일을 다운받으면 AWS에 등록을 위한 K8S Workload들과 ServiceAccount등을 만드는 내용이 포함되어 있다.
등록의 경우, 추후에 시간적 여유를 두고 살펴보기 위해 내버려 두고, 생성을 진행한다.
생성 과정
클러스터 기본 정보 입력
먼저 클러스터의 기본 정보를 입력하는 화면이 나온다.
이름 / K8S 버전 / 클러스터 서비스 역할
CSP가 제공하는 k8s를 처음 배포해보는 사용자라면, 클러스터 서비스 역할이 무엇일지 매우 궁금해할 것이다. 간단히 설명하자면 요청을 대신 수행하는 Bot과 같은 존재다. 위에서 간단히 살펴본 아키텍처를 보면 CSP가 제공하는 k8s는 CSP의 다양한 리소스와 손쉽게 통합이 가능하다.
예를 들면 k8s의 LoadBalancer(이하 LB) 타입 Service(이하 SVC) 리소스를 만들었을 경우, 자동으로 CSP의 LB를 만들어주며 연결시켜준다. 여기서 의문이 생겨야 정상이다.
"나는 클러스터에 내 클라우드 리소스를 만들어달라는 권한이 없는데, 자동으로 LB를 만들어준다고? Storage Class를 사용해서 PVC를 만들었는데, 자동으로 Disk나 NAS가 생겨버렸네?" 라는 의문이 들어야 한다. 어떻게 만들어 진걸까?
답은 Bot사용자가 권한을 가지고 있기 때문이다. LB타입 SVC리소스를 만들면 Bot사용자는 k8s내부의 컨트롤러를 통해 CSP API를 호출하여 CSP의 LB를 생성하게 된다. AWS에서는 이것을 클러스터 서비스 역할로 수행하게 되는 것이다.
네트워크 및 API 엔드포인트 지정
기존에 VPC와 Subnet을 만들고 해당 VPC와 서브넷, 보안그룹을 지정한다.
API 엔드포인트 지정
API Endpoint는 총 3가지로 지정 가능하다.
구분 | 설명 |
Public | 외부에서 EKS API를 사용하거나, Worker Node가 API를 사용할 경우, 모두 Public Endpoint를 사용 > Worker Node의 트래픽이 VPC를 벗어남 |
Public & Private | 외부에서 EKS API를 사용할 경우, Public Endpoint사용 Worker Node에서 EKS API를 사용할 경우 Private Endpoint 사용 > Worker Node의 트래픽이 VPC내에 유지됨 |
Private | 모든 EKS API는 VPC를 통해서만 사용 가능 > 모든 트래픽이 VPC내에 유지됨 |
로깅 구성
로깅 구성은 아무것도 하지 않고 넘어간다.
추가 기능 선택
kube-proxy / CoreDNS / Amazone VPC CNI를 기본적으로 사용하도록 선택되어있다.
Amazon VPC CNI
Amazon VPC CNI는 Azure CNI와 마찬가지로 Pod들이 VPC내의 IP 주소를 사용할 수 있게끔 만들어주는 EKS의 CNI다. 이 CNI를 사용하면 EC2에 장착된 ENI의 IP를 Pod가 상속받게 되고, 그만큼 네트워크 홉이 줄어들어 좀더 빠른 네트워크 통신을 가능하게 해준다.
문서에 따르면 AWS VPC CNI는 aws-node 라는 이름을 가진 Daemonset으로 각 노드에 Pod를 배포한다. Pod에는 두가지 핵심 컴포넌트가 있는데, Local IP Address Management(L-IPAM)과 CNI 플러그인이다.
- L-IPAM daemon (lPAMD)
- ENI 생성 및 Worker node에 연결
- Network interface prefix할당
- 스케줄된 Pod에 할당하기 위해, 각 노드에서 IP prefix의 warm pool을 할당한다.
- CNI 플러그인
- 호스트(Worker Node) 네트워크연결과 Pod의 네임스페이스에 올바른 네트워크 인터페이스 추가
- CNI플러그인은 RPC를 통해 lPAMD와 통신한다.
추가 기능의 버전 선택
여기서 다음을 누르면 배포가 시작된다.
Worker Node 추가
Worker Node를 추가하기 전, NAT Gateway를 생성하고 라우팅을 설정했다. 관련 내용은 DEVOCEAN블로그 참조
EKS를 배포하고 보면, kube-system네임스페이스에 core-dns pod가 pending 상태인 것을 확인할 수 있다. describe를 해보면 pod가 스케줄될 node가 없어서 배포에 실패한 것이다. 즉, EKS는 배포하고나면 worker node를 따로 추가해야 한다는 뜻이다.
노드 그룹 추가
노드를 추가하기위해 노드 그룹을 추가한다.
노드 그룹 구성시에도 IAM 역할이 필요하다. 그리고 시작 템플릿을 사용하여 Node에 원하는 애플리케이션 등을 사전에 설치할 수 있다.
웹콘솔에서 Worker node에 Label과 Taint를 지정할수도 있다.
사용 가능한 이미지로 Windows Server를 포함하여 크게 3종류를 선택할 수 있으며, GPU노드도 포함되어있다.
또한 Spot 인스턴스 여부를 이 화면에서 선택할 수 있다.
EC2 사이즈는 t3.medium으로 선택했다.
다음으로 노드의 수를 조정한다.
마지막으로 노드가 배포될 네트워크를 선택한다.
마지막으로 클러스터 생성으로 넘어가고, 그 결과 아래와 같은 형태의 클러스터가 생성되게 된다.
워커노드 부분을 아주 약간 성의 있게 그리면 아래와 같다.
클러스터 살펴보기
클러스터에 배포된 리소스를 살펴보기 위해 aws cli를 사용하여 클러스터 정보를 등록한다.
aws eks update-kubeconfig --region <region-name> --name <cluster-name>
kube-system 네임스페이스 pod 조회
kube-system에 어떤 pod들이 배포되어있는지 확인해본다.
AWS VPC CNI를 제어하는 aws-node / coredns / kube-proxy가 kube-system 네임스페이스에 배포되어 있는걸을 확인할 수 있다.
Worker Node에 접속하여 살펴보기
컨테이너 런타임 확인하기
먼저 컨테이너 런타임을 확인해봤다. AKS의 경우 Moby를 사용하고 있는데, AWS는 containerd를 사용하고 있다.
Static Pod 확인하기
Kubernetes Static Pod는 /etc/kubernetes/manifests 디렉토리에 위치해있다. 확인해봤는데 아무것도 없다.
Pod가 VPC의 IP를 할당받았는지 확인
Pod의 IP는 실제 VPC의 IP를 받아왔다. 위의 사진을 살펴보면, VPC CNI를 제어하는 aws-node와 kube-proxy가 동일한 ip를 사용하고 있다. 냅다 스터디 슬랙에 문의했는데 까맣게 잊고 있었던 Host Network 때문이었다.
마무리
여기까지 EKS의 생성 과정과, 작동 원리 사용되는 컴포넌트 등을 알아봤다. 스터디 하면서 새로 발견되는 내용들이 있으면 주기적으로 업데이트 할 예정이다.