kubernetes

Kubernetes 구조

Tech Studio 2021. 3. 3. 20:03

 Kubernetes는 오픈소스로서, 수천개 이상의 Container를 관리 운영하는 가장 쉬운 클러스터 관리자 입니다. CNCF의 관리하에 개발이 이루어지고 있고, 상당히 다양한 프로젝트가 있어 서로 경쟁하고 채택되면서 유기적으로 발전하고있습니다. 지금도 많은 제품들이 선정되고 투자를 받아 제품이 만들어지고 있습니다. (CNCF 홈페이지: https://www.cncf.io/ )

  그럼 간단히 Kubernetes를 설명하자면, "Kubernetes란 자동배포, 확장, 그리고 컨테이너화된 어플리케이션을 관리하는 오픈소스 시스템입니다." Kubernetes를 이용하게되면 네트워크, 서버, 스토리지를 기존의 대형인프라에서는 인스턴스별 성능을 고려하고 각각의 설정들을 별도로 관리했던 부분들이 손쉽게 관리되어 대규모 시스템을 우리가 조금더 운영 할 수 있게 되는 것 입니다. 

 그럼 기존의 환경과 얼마나 다른지를 비교해 봐야 할텐데요. 기존의 운영 구성을 물리환경1), 소프트웨어환경2), 기타관리포인트3)로 나누어서 비교해 보겠습니다. 

 물리 환경1)은, 모든 사이트가 동일 하지는 않겠지만 네트워크(L2, L3, L4, F/W)와 Server(WEB/WAS/DB), 그리고 Storage(NAS/SAN/iscsi)등으로 크게 구분이 됩니다. 구조를 보게 된다면, 아래의 기본적인 구성도가 나오게 됩니다. 

 

물리 구성 구조

 

 물리 구성은 상황과 요건에 따라 위 그림에서 상세 혹은 확장으로 다를 수 있습니다만, 위 구성도에서 크게 다르지 않게 구성 된다고 볼 수 있습니다. 그렇다면 Kubernetes를 구축할 경우는 물리 구성이 달라질까요? 물론 아닙니다. 물리 구성은 기존과 현재가 거의 동일합니다. 다만  필수요건들이 존재하게 되는데요. 필수로 들어가야 할 부분으로는 NAS혹은 공유가능한 고속 Storage와 Control-plane이 구성될 3기 이상의 별도 서버, Container가 구동될 2기 이상의 Worker서버가 필요합니다. 기존 엔터프라이즈 환경의 구성과 크게 않음을 알 수 있는데요. Kubernetes는 기존의 Application이 Container화되어 운영되는 관리 시스템이기 때문입니다.  

 그럼 소프트웨어환경2)을 비교해 보겠습니다. 기존의 환경은 DMZ/Private혹은 유사한 형태로 아래의 그림처럼 3Tier구조로 서버군을 나눈다음 각 필요한 Software를 성능에 맞게 미리 분배하여 사용하는 구조라고 볼 수 있습니다. 

 

WEB - WAS 사용을 위한 3Tier 구조중 WEB-WAS 구간

 

 물리 구성은 기존과 동일하게 구성이 가능하지만, 물리 서버를 이용하여 구성되는 소프트웨어 구간은 많이 달라지게 됩니다. 기존의 구성은 WEB Daemon을 통한 Domain분기와 어플리케이션별, 서비스를 처리하는 WAS로 크게 나뉘고, Domain과 서비스 사용에 따라 WEB/WAS를 성능계산하여 사용하게 됩니다. 여기서 WEB의 성능 계산의 어려움과 WAS의 사용량의 지속적인 예측과 계산이 필요하게 되죠. 이에따라 서비스의 성격과 성능에 따라 수시로 튜닝을 해주어야 하며, 관리 포인트가 인터페이스 구간별로 존재하게 됩니다. (*DB부분은 Kubernetes에서 Pod화하여 관리가능하지만 엔터프라이즈 환경에서는 성능관계상 별도로 운영될 것을 가늠하여 설명 기존의 3Tier구조에서 WEB/WAS위주로 설명을 드립니다.)
  WEB은 연동방식에 따라 AJP혹은 Proxy방식을 사용 할 수 있고, 운영 방법을 Worker, Prefork, Event등을 지정하여 사용하여야 합니다. 또한 WAS의 경우 종류에 따라 Domain/Single 방식이 있고, JAVA옵션과 Port혹은 어플리케이션 배포방법에 따라 사용법도 크게 달라집니다. 이때 사용되는 Port의 관리는 별도이지요. 이때 사용하는 포트는 단순 디자인만으로도 아래의 그림과 같이 사용 됩니다.  

 

WEB/WAS 연동에 필요한 Port 구분

 

 위의 그림은 단순히 1기의 WEB과 1기의 WAS가 연동될때 필요한 Port의 종류입니다. 물론 이중 HTTPD의 포트수는 WEB, Sercure Port만 사용 할 수있지만, WAS의 경우는 1기 서버에 1기만 구성되는 경우는 없기에 상당히 많은 고민이 필요하게 됩니다. 10기의 WAS를 구성할 경우, 3개의 포트에 +100을 하여 관리해야 하고 만약 11개 이상의 WAS를 구성해야 할 경우 별도 포트를 확보하여 계산하여야 합니다. 물론 확장에 대비하여서 포트 배정을 미리 해 두어야 합니다. 이렇게 복잡한 디자인을 미리 예상하여 포트의 겹침을 미리 예방 해야 합니다. 하지만 Kubernetes에서는 이러한 부분이 아주 쉽게 컨테이너별 자동 Port배정이 되고, 확장과 축소에 따라 자동으로 관리가 됩니다. 기존의 복잡한 설계단계를 건너 뛸 수 있게 되는것이죠.  

 그럼 Kubernetes의 소프트웨어환경이 어떻게 바뀌는지 보겠습니다. 

 

Kubernetes 구성

 

 아주 심플하게 보이죠? 연계 관계에 있어서 먼저 고민해야 할 인터페이스 라인들 또한 사라지게 됩니다. 이 소프트웨어 구성을 보게 된다면, 크게 Control-plane과 Worker로 구분되고, 이 Node(Kubernetes에서는 서버를 Node로 불리게 됩니다.)들에는 공통으로 kubelet과 Containerd(Container Runtime)가 구성됩니다. 컨트롤플랜은 API, Scheduler, Controller, etcd 등으로 크게 나뉘고 이 Components들은 Kubernetes를 운영하는 핵심 요소입니다. 이를 통해서 Kubernetes는 운영되는 모든 요소들을 지정된 Job Schedule에 따라 관리하게 되고, Kubernetes의 가장 큰 장점이자 특징인 자동배포와 자동복구, 그리고 성능에 따른 수평확장이 이루어지게 됩니다.
 기존 구성 방식과는 크게 다른 부분은 바로 이 Control-Plane을 3기이상 홀수 구성해야 하고, Kubelet과 Containerd를 추가로 설치하는 것이 다입니다. 물론 Container간의 Network를 위한 CNI(Container Network Interface), CSI(Contaner Storage Interface)등이 추가 되지만 기본 Kubernetes의 구조는 위의 그림과 같습니다. 

 다만, Kubernetes는 물리적인 서버의 관리와 물리적인 네트워크의 관리, 그리고 물리적인 스토리지의 관리를 해주지는 않습니다. Container의 '오케스트레이션'이라고 꼭 명심하고 넘어가야 합니다. 

 Kubernetes는 결국 CRI-O 혹은 Containerd 로 구성되는 'Container Runtime을 관리하여 Container를 관리 하는 것' 인데요. 만약 단일 Container 혹은 소수의 WAS를 운영하는 가벼운 시스템이라면, Kubernetes를 구성하는 것은 의미가 없습니다. 오히려 관리의 포인트와 Kubernetes를 구성하기 위한 불필요 성능만 늘어날뿐 노력과 시간에 비해 장점이 사라집니다. 

 소프트웨어환경을 비교해 보았는데요. 기타관리포인트3)로 배포 방식을 비교 해보겠습니다. 기존 WAS배포 방식은 세부 설정만큼 배포방식도 복잡합니다. 우리가 흔히 알고 있는 Blue/Green은 서버의 낭비때문에 사용하기 힘들고, WEB/WAS의 배포는 별도로 배포해야 하며 장애상황 또한 대비가 보장되어야 하므로 Rolling Update를 주로 하게됩니다. (이때 개발구조가 가능하다면 Canari방식으로 하는경우도 있겠죠) 이때, Jenkins와 같은 배포툴이 없다면 엔지니어 혹은 담당자가 10기이든 100기이든 한 기씩 혹은 동시에 명령어를 보내 개발소스 업데이트 후, 수동 재기동을 해야만 합니다. 소수라면 문제가 없지만 대량 배포의 경우 많은 시간과 인적장애를 위험요소로 가지고 가야합니다. 또한 Dev > Staging(TB) > Product 순으로 배포 테스트가 이루어지지만 약간의 차이로 배포에 실패 할 수도 있습니다.

하지만, Kubernetes의 경우에는 유연한 배포 관리가 가능해서 원하는 방식의 배포가 손쉽게 이루어집니다. 

 

 

 배포 방식의 차이를 그림으로 표시 했습니다만, 좌측의 배포 방식을 보게 되면 컨트롤해야 하는 WAS수가 24개 밖에 되지 않습니다만, 벌서 많이 복잡해보이네요. 이미지에 선을 연결하는 작업도 오래 걸리는데요. 반면 우측의 Kubernetes의 배포 방식은 API를 통해 명령만 보내면 서버에서 알아서 이미지를 찾아서 원하는 방식으로 배포를 하게 되는 아주 편리한 방식입니다. 선을 연결하는 작업도 편하네요.  

 Kubernetes의 배포 방법을 가볍게 비교 해 보았습니다만, Kubernetes를 구성/운영전 주의 해야 할 것은 무엇일까요? Kubernetes는 기존 레거시 제품을 구성할때와는 다르게 서버의 성능에 크게 구애 받지 않습니다만, 관리의 용이를 위해서 서버 자체의 크기와 사용수량을 고려해야 합니다. 물론 기존 서비스의 구조에서도 와스의 크기를 계산해서 사용하지만, Container의 사용성능에따라 자동 수평 확장이 가능한 Kubernetes이므로 가용 전체 성능이 아닌 Pod의 크기와 이에대한 서버 크기에 대한 고려입니다. 

 

Server Size 별 배포 예시

 

 위의 그림은 극단적인 예로, 동일 성능의 큰 사이즈의 Node 소수 구성과 작은 사이즈의 Node다수 구성을 예로 들어보겠습니다. 큰사이즈의 Node에 1core 1GMemory의 contaner를 배포하여 사용한다면 IO의 증가와 네트워크 트래픽의 증가가 생길수 있고, 유휴용량이 많이 남을 수 있습니다. 또한 작은 사이즈의 Node에는 대용량 CPU혹은 Memory사용을 요하는 배포는 배정이 되지 않게 됩니다. 

해당 구성에 대한 장단점은 다음과 같습니다. 

구분 장점 단점
큰 노드 소수 물리 장비 관리의 용이
대형 Pod 구동 가능
적은 Port사용으로 네트워크 간편
고용량 Batch 작업 가능
물리적 장애시, 복구 및 대처가 어려움
물리 네트워크의 사용량 과다 발생 가능 높음
작은 노드 다수 물리 장애시, 사이드이펙트 대기 용이
서비스별 구성이 용이 
단순 연산 작업의 IO 사용량 분산 가능
대형 Pod 구동 불가 
장애포인트 과다 
네트워크 구성의 복잡성 높아짐

 

 상당히 고민이 되는 장 단점들인데요. 대용량 연산(GPU를 사용하는 부분 아님)일경우 큰노드 소수를 구성하는것이 유리 하겠고, 많은 스트리밍과 같은 대역트래픽과 소규모 대량의 Pod혹은 Namespace로 서비스를 구분 할 경우 작은 노드 다수를 구성하면 되겠습니다. 물론 Pod의 배포 방법에 따라 원하는 Node에 배포가 가능하므로 큰 노드와 작은 노드를 적절히 혼합하여 구성하는 것 또한 하나의 방법입니다. 

 


 

 기존 시스템과 Kubernetes를 비교하면서 Kubernetes에 대한 기본적인 구조를 알게된것 같은데요. 그럼 Kubernetes의 Components를 자세히 보겠습니다. 

 그럼 Kubernetes의 Node로는 3기 이상의 홀수 구성(Quorum방식)의 Control Plane Node와 2기 이상의 Worker Node에 구성되는 Container를 Namespace단위로 관리 하게 됩니다. 이때 구성되는 Container그룹은 Pod라는 이름으로 불리게 됩니다. Pod는 Namespace안에서 작동됩니다. 

 

구축 개념

 

 Namespace안에서 구성되어 있는 Pod의 모습은 아래 이미지와 같은데요. 그림과 같이 Namespace안에는 다수의 Pod가 구성 될 수 있고, Pod는 다수 혹은 단일 Container로 구성 될 수 있습니다. 

 

Namespace 별 Pod 구성 예시

 

 

 Kubernetes는 위의 설명과 같이 Control Plane Node와 Worker Node로 구분 하여 볼 수 있는데, 수십 수백대의 서버를 이용한 엔터프라이즈 환경도 구성이 가능하고, 단일 서버의 성능이 높은 물리서버에 VM을 이용하여, 가상환경에 Kubernetes를 구성하는 것도 가능하고, 소규모 시스템을 위한 K3s 혹은 microkube 등 작은 단위의 Kubernetes도 공개되어 있습니다. 

 Control Plane의 구성을 보게 되면 다음과 같습니다. 위에서 본 전체 구성도에서 많은것들이 추가 되어 있는데요. Kubernetes는 운영에 필요한 모든 환경을 제공하지 않기 때문에 Kubernetes를 조금더 쉽게 운영하기 위한 Add-On들이 추가 됩니다.   

Control-plane 구조

 

 구성요소들을 면면이 보게 되면, 우리가 엔터프라이즈 환경을 구성할때 사용했던 부분들이 모두 있다는 것을 볼 수 있습니다. 하나의 엔터프라이즈 시스템을 구성 한 것과 같은 모습입니다. 

  Control Plane은 Kubernetes답게 Container화 되어 운영됩니다. Control Plane는 크게 API, Schduler, Controller-manager로 구성되고, 구성정보를 API를 통해 etcd에 저장하여 사용하고, etcd는 quorum 방식으로 운영합니다. (*3중화/다중화는 아닙니다.) 물리 네트워크를 컨트롤하기 위해 Kube-Proxy를 사용하고 Pod간의 Domain사용과 관리를 위해 각 노드별 Nodelocaldns와 사설DNS로 볼 수 있는 CoreDNS, Pod간 네트워크를 연동해주는 Calico(CNI는 여러 프로젝트가 있습니다. 여기에서는 calico로 선정했습니다.), Container를 실행 시킬 Containerd(Container Runtime은 여러 종류가 있습니다. 여기서는 Containerd로 선정했습니다.), Containerd를 확인하고 관리할  Kubelet등이 있습니다. 

 Application들이 Container화 되어 배포될 Worker Node의 구성은 아래의 같습니다. 

 

Worker Node 구조

 

 Worker Node 또한 Container화 되어 있고, Control-Plane보다는 구성요소가 조금 적습니다. Worker Node의 구성요소들 또한 면면이 보게되면, 공유 스토리지를 사용하기 위한 CSI-NFS, 물리 네트워크를 컨트롤하기 위해 Kube-Proxy를 사용하고 Pod간의 Domain사용과 관리를 위해 각 노드별 Nodelocaldns와 사설DNS로 볼 수 있는 CoreDNS, Pod간 네트워크를 연동해주는 Calico, Container를 실행 시킬 Containerd, Containerd를 확인하고 관리할  Kubelet등이 있습니다. Control-Plane과 거의 동일하네요. 

 이중 중요한 몇가지를 뽑아서 본다면 API의 운영방식과 CNI, CSI를 우선 확인해 보겠습니다.  

 Control-Plane의 API서버는 etcd처럼 Qurom방식으로 운영되지는 않지만 etcd를 같은 pod에 운영할 수 있고, Control-Plane에 구성되므로 홀수 구성이 이루어집니다. 작동 방식은 etcd의 정보를 확인하고 기록하며, 유일하게 접근 할 수 있는 서버라고 볼 수 있습니다. 사용자 또한 API를 사용하여 쿠버네티스의 API 오브젝트(예: 파드(Pod), 네임스페이스(Namespace), 컨피그맵(ConfigMap) 그리고 이벤트(Event))를 질의(query)하고 조작할 수 있습니다. 
*참고 :  https://kubernetes.io/ko/docs/concepts/overview/kubernetes-api/

 

 

 Calico는 Pod간의 네트워크 연결을 위한 CNI입니다. 1기의 calico-node-controller에서 각 노드의 calico-node 를 관리 하며, 사용 방식에 따라 IP - IP 방식과 VxLAN방식으로 운영됩니다. 비 터널링 방식도 있으나 별도의 스위치 구성이 필요하므로 두 종류의 방식이 가장 많이 쓰이고 있습니다. ( 버전부터 VxLAN 기본 권장 ) 네트워크 컨트롤로는 iptables 혹은 IPVS를 사용하여 네트워크 정보를 관리 합니다. 
*참고 : https://www.tigera.io/tigera-products/calico/

 

calico 기본 운영 방식


 Calico의 네트워크 중에 IP-IP 방식과 VxLAN방식의 비교는 다음과 같습니다. BGP정보 업데이트를 통한 라우팅 변경은 IP-IP 방식이라고 보면되고, vlan스위칭 기술을 사용한 VxLAN방식이 있고 간단한 비교는 그림처럼 표현 할 수 있습니다.

 

 

 

 노드별 Pod 정보를 유기적으로 주고 받으며, Pod간의 네트워크는 다음과 같이 이루어 집니다. 

 

 

 Kubernetes는 Container사용의 높은 효율을 위해 Storage를 Localhost가 아닌 Network Storage를 사용 할 수 있게 지원합니다. Network Storage가 없다면, 모든 Node에 파드에서 사용하는 모든 데이터를 복사하여 사용해야 하므로 매우 효율적이라고 볼수 있습니다. 이때 빠른 재사용과 공유환경을 위해 SC(Storage Class), PV(Persistent Volumes), PVC(Persistent Volume Claim)을 제공합니다. 

 

 

 


 

 이렇게 Kubernetes를 기존 시스템과 비교 하는 방식으로 알아봤는데요. Kubernetes의 환경은 생각보다 많은 부분들이 준비가 되어있고, 쉽고 편하게 사용 할 수있게 되어 있는것을 알 수 있습니다. 물론 우리가 Kubernetes환경에 익숙해지고 많은 사용을 거쳐서 초급엔지니어도 쉽게 사용 할 수 있는 환경이 되어야 겠죠. 
 제가 보기에는 기존의 WEB/WAS 환경에서 우리는 WEB 혹은 WAS만 관리하던 부분에서는 조금더 인프라 친화적, 그리고 Hardware관점에서는 조금더 Software친화적인 모습이 Kubernetes인것 같습니다. 서비스 환경에서 볼때 많은 부분이 자동화 되어 편하게 느껴지지만 이렇게 편하게 보인다는것은 환경을 구축하고 완성하는데 많은 노력과 시간이 필요하다는것 또한 필수적 이겠죠. 

 제가 업무를 진행하면서 구성한 부분과 학습한 부분을 짧게 써놓은 내용이지만  이 블로그를 보는 많은 분들도 Kubernetes를 시작하거나 리마인드 하는데 도움이 되었으면 좋겠습니다. 

 

 *주의 해야 할 점

 Kubernetes 로 관리되는 Pod 혹은 Container는 너무나도 당연하게 Woker Node들의 물리적인 성능을 벗어날 수 없습니다. 
수평/수직적 확장이 가능하지만, 이것은 성능의 물리적 확장이 있어야 가능한 것이고, 제한된 성능 안에서의 효율적인 관리이지, 100의 성능을 내는 Server가 120의 성능을 낼 수 있게 한다는 것은 아닙니다. 
Pod구성을 서버의 성능보다 높게 혹은 증/가감없는 서비스를 계획했다면, Kubernetes 로 관리하기 보다는 기존의 레거시 구성으로 관리하는것이 더욱 효율 적입니다. 
 Kubernetes는 모든것을 제공하지 않습니다. (Ex: Container Image, Logging, Monitoring, Application, etc.)

'kubernetes' 카테고리의 다른 글

Playce Kube - 설치 확인  (0) 2023.05.13
Playce Kube - 서버 준비  (0) 2023.02.21
Playce Kube - System Design  (0) 2023.01.14
Playce Kube - 설치  (0) 2023.01.14
Playce Kube - 구조  (0) 2022.08.29