Kubernetes 개념
Kubernetes 개념
Amazon Elastic Kubernetes Service(Amazon EKS)는 오픈 소스 Kubernetes 프로젝트를 기반으로 하는 AWS 관리형 서비스입니다. Amazon EKS 서비스가 AWS 클라우드와 어떻게 통합되는지 알아야 할 부분(특히 Amazon EKS 클러스터를 처음 생성할 때)이 있지만, 일단 클러스터가 실행되고 나면 다른 Kubernetes 클러스터와 거의 동일한 방식으로 Amazon EKS 클러스터를 사용하게 됩니다. 따라서 Kubernetes 클러스터를 관리하고 워크로드를 배포하려면 Kubernetes 개념에 대한 기본적인 이해가 필요해요.
이 페이지는 Kubernetes 개념을 Why Kubernetes?(왜 Kubernetes인가), Clusters(클러스터), Workloads(워크로드) 세 가지 섹션으로 나눕니다. 첫 번째 섹션은 관리형 서비스(특히 Amazon EKS)로서 Kubernetes 서비스를 실행하는 가치를 설명합니다. Workloads 섹션은 Kubernetes 애플리케이션이 어떻게 구축·저장·실행·관리되는지 다룹니다. Clusters 섹션은 Kubernetes 클러스터를 구성하는 구성 요소들과 클러스터 생성·유지 관리에 대한 책임을 설명합니다.
Topics: Why Kubernetes? / Clusters / Workloads
Next steps: 이 콘텐츠를 진행하면서 링크를 통해 Amazon EKS와 Kubernetes 문서에서 Kubernetes 개념에 대한 더 자세한 설명을 확인할 수 있어요. Amazon EKS가 Kubernetes 컨트롤 플레인과 컴퓨트 기능을 어떻게 구현하는지는 Amazon EKS architecture를 참고하세요.
출처: 문서
본문
Why Kubernetes?
Kubernetes는 미션 크리티컬한 프로덕션 품질의 컨테이너화된 애플리케이션을 실행할 때 가용성과 확장성을 개선하도록 설계되었습니다. 단일 머신에서 Kubernetes를 실행하는 것도 가능하지만, Kubernetes는 수요에 맞게 확장되거나 축소될 수 있는 컴퓨터 집합 위에서 애플리케이션을 실행함으로써 이러한 목표를 달성합니다. Kubernetes에는 다음을 쉽게 해 주는 기능이 포함됩니다.
- 여러 머신에 애플리케이션 배포(Pod에 배포된 컨테이너 사용)
- 컨테이너 상태 모니터링 및 실패한 컨테이너 재시작
- 로드에 따라 컨테이너 확장/축소
- 새 버전으로 컨테이너 업데이트
- 컨테이너 간 리소스 할당
- 머신 간 트래픽 분산
Kubernetes가 이러한 복잡한 작업을 자동화하면 애플리케이션 개발자는 인프라에 신경 쓰는 대신 애플리케이션 워크로드를 구축하고 개선하는 데 집중할 수 있어요. 개발자는 보통 애플리케이션의 원하는 상태(desired state)를 설명하는 YAML 형식의 구성 파일을 만듭니다. 여기에는 실행할 컨테이너, 리소스 제한, Pod 복제본 수, CPU/메모리 할당, 어피니티 규칙 등이 포함될 수 있어요.
Kubernetes의 속성
Kubernetes는 목표를 달성하기 위해 다음과 같은 속성을 갖습니다.
- Containerized(컨테이너화): Kubernetes는 컨테이너 오케스트레이션 도구입니다. Kubernetes를 사용하려면 먼저 애플리케이션을 컨테이너화해야 해요. 마이크로서비스 모음, 배치 작업 등 다양한 형태일 수 있습니다. 그러면 컨테이너를 컨테이너 레지스트리에 이미지로 저장하고, Kubernetes 클러스터에 배포하고, 사용 가능한 노드에서 실행하는 거대한 도구 생태계를 활용할 수 있어요. 로컬 컴퓨터에서 Docker나 다른 컨테이너 런타임으로 개별 컨테이너를 빌드하고 테스트한 뒤 클러스터에 배포할 수도 있어요.
- Scalable(확장 가능): 애플리케이션의 수요가 실행 중인 인스턴스의 용량을 초과하면 Kubernetes는 확장할 수 있습니다. 필요에 따라 애플리케이션이 더 많은 CPU나 메모리를 요구하는지 판단하고, 사용 가능한 용량을 자동으로 확장하거나 기존 용량을 더 사용하는 방식으로 대응해요. 확장은 충분한 컴퓨트가 있어 애플리케이션 인스턴스만 더 실행하면 되는 경우 Pod 수준(수평 Pod 자동 확장), 또는 더 많은 노드를 띄워야 하는 경우 노드 수준(Cluster Autoscaler 또는 Karpenter)에서 이루어집니다. 용량이 더 이상 필요 없어지면 이러한 서비스는 불필요한 Pod를 삭제하고 쓸모없는 노드를 종료할 수 있어요.
- Available(가용): 애플리케이션이나 노드가 비정상이 되거나 사용 불가능해지면 Kubernetes는 실행 중인 워크로드를 다른 사용 가능한 노드로 이동할 수 있습니다. 실행 중인 워크로드 인스턴스나 노드를 그냥 삭제하는 것만으로도 강제할 수 있어요. 요점은 더 이상 그 자리에서 실행할 수 없게 되면 워크로드를 다른 위치에 띄울 수 있다는 것입니다.
- Declarative(선언적): Kubernetes는 능동적 조정(active reconciliation)을 사용해 클러스터에 선언한 상태가 실제 상태와 일치하는지 계속 확인합니다. 보통 YAML 형식의 구성 파일을 통해 Kubernetes 객체를 클러스터에 적용하면, 예를 들어 클러스터에서 실행하려는 워크로드를 시작하도록 요청할 수 있어요. 나중에 구성을 변경해 더 최신 컨테이너 버전을 사용하거나 메모리를 더 할당할 수도 있습니다. Kubernetes는 원하는 상태를 만들기 위해 필요한 작업(노드 올리기/내리기, 워크로드 중지·재시작, 컨테이너 업데이트 가져오기 등)을 수행해요.
- Composable(구성 가능): 애플리케이션은 보통 여러 구성 요소로 이루어지므로 이 구성 요소들(종종 여러 컨테이너로 표현)을 함께 관리하고 싶을 거예요. Docker Compose가 Docker에서 이를 직접 할 수 있는 방법을 제공한다면, Kubernetes에서는 Kompose 명령으로 비슷하게 할 수 있습니다. 예시는 Translate a Docker Compose File to Kubernetes Resources를 참고하세요.
- Extensible(확장 가능): 사유(proprietary) 소프트웨어와 달리 오픈 소스 Kubernetes 프로젝트는 필요에 맞게 어떤 방식으로든 확장할 수 있도록 설계되었습니다. API와 구성 파일은 직접 수정할 수 있어요. 서드파티는 인프라와 최종 사용자 Kubernetes 기능을 모두 확장하기 위해 자체 Controller를 작성하도록 권장됩니다. Webhook을 사용해 클러스터 규칙을 설정해 정책을 적용하고 변화하는 조건에 적응할 수 있어요. 자세한 아이디어는 Extending Kubernetes를 참고하세요.
- Portable(이식 가능): 많은 조직이 모든 애플리케이션 요구를 동일한 방식으로 관리할 수 있기 때문에 운영을 Kubernetes로 표준화했습니다. 개발자는 동일한 파이프라인으로 컨테이너화된 애플리케이션을 빌드하고 저장할 수 있어요. 그런 애플리케이션은 온프레미스, 클라우드, 식당의 POS 단말기, 회사 원격지에 흩어진 IoT 기기 등에서 실행되는 Kubernetes 클러스터에 배포할 수 있습니다. 오픈 소스 특성 덕분에 특수한 Kubernetes 배포판과 이를 관리하는 도구를 개발할 수 있어요.
Kubernetes 관리
Kubernetes 소스 코드는 자유롭게 제공되므로 자체 장비로 Kubernetes를 직접 설치하고 관리할 수 있어요. 하지만 자기 주도(Self-managed) Kubernetes는 깊은 운영 전문성과 유지 관리 시간·노력이 필요합니다. 이런 이유로 프로덕션 워크로드를 배포하는 대부분의 사람은 테스트된 자체 Kubernetes 배포판과 Kubernetes 전문가 지원을 갖춘 클라우드 제공자(예: Amazon EKS)나 온프레미스 제공자(예: Amazon EKS Anywhere)를 선택해요. 이를 통해 클러스터 유지에 필요한 많은 공통 작업(undifferentiated heavy lifting)을 떠넘길 수 있습니다.
- 하드웨어: 요구사항에 맞는 하드웨어가 없다면 AWS Amazon EKS 같은 클라우드 제공자가 초기 비용을 절감해 줄 수 있어요. Amazon EKS에서는 AWS가 제공하는 최고의 클라우드 리소스(컴퓨트 인스턴스 Amazon Elastic Compute Cloud, 프라이빗 환경 Amazon VPC, 중앙 IAM, 스토리지 Amazon EBS)를 사용할 수 있습니다. AWS가 Kubernetes를 실행하는 데 필요한 컴퓨터, 네트워크, 데이터 센터, 기타 물리적 구성 요소를 관리해요. 또한 최대 수요일에 대비해 데이터 센터를 계획할 필요도 없어요. Amazon EKS Anywhere나 다른 온프레미스 Kubernetes 클러스터에서는 Kubernetes 배포에 사용되는 인프라를 직접 관리해야 하지만, Kubernetes를 최신 상태로 유지하는 것은 AWS의 도움을 받을 수 있어요.
- 컨트롤 플레인 관리: Amazon EKS는 AWS 호스팅 Kubernetes 컨트롤 플레인의 보안과 가용성을 관리합니다. 컨트롤 플레인은 컨테이너 스케줄링, 애플리케이션 가용성 관리 등 핵심 작업을 담당하므로 애플리케이션 워크로드에 집중할 수 있어요. 클러스터가 고장 나면 AWS가 클러스터를 실행 상태로 복원할 수단을 갖추고 있어야 해요. Amazon EKS Anywhere에서는 컨트롤 플레인을 직접 관리합니다.
- 테스트된 업그레이드: 클러스터를 업그레이드할 때 Amazon EKS나 Amazon EKS Anywhere가 테스트된 자체 Kubernetes 배포판 버전을 제공하므로 신뢰할 수 있어요.
- 애드온(Add-ons): Kubernetes를 확장하거나 워크로드 실행을 돕는 수백 개의 프로젝트가 있습니다. 직접 구축·관리하는 대신 AWS가 제공하는 Amazon EKS 애드온을 클러스터에 사용할 수 있어요. Amazon EKS Anywhere는 많은 인기 오픈 소스 프로젝트의 빌드를 포함하는 Curated Packages를 제공합니다. 소프트웨어를 직접 빌드하거나 보안 패치·버그 수정·업그레이드를 관리할 필요가 없어요. 기본값이 요구를 충족하면 애드온 구성이 거의 필요 없는 경우가 많습니다. 자세한 내용은 Extend Clusters를 참고하세요.
Kubernetes 실제 활용
아래 다이어그램은 Kubernetes Admin 또는 Application Developer가 Kubernetes 클러스터를 생성·사용하면서 수행하는 주요 활동을 보여 줍니다. 과정에서 Kubernetes 구성 요소들이 어떻게 상호작용하는지 AWS 클라우드를 기본 클라우드 제공자 예시로 설명합니다.
Kubernetes Admin은 클러스터가 구축될 제공자 유형에 특화된 도구를 사용해 클러스터를 생성합니다. 이 예시는 Amazon EKS라는 관리형 Kubernetes 서비스를 제공하는 AWS 클라우드를 사용합니다. 관리형 서비스는 클러스터 생성에 필요한 리소스를 자동으로 할당하는데, 클러스터용 Amazon VPC 두 개 생성, 네트워킹 설정, 클라우드 자산 관리를 위해 Kubernetes 권한을 새 VPC에 직접 매핑하는 것을 포함해요. 또한 컨트롤 플레인 서비스가 실행될 위치를 확보하고 워크로드 실행용 Kubernetes 노드로 Amazon EC2 인스턴스를 0개 이상 할당합니다. AWS는 컨트롤 플레인용 VPC 하나를 자체 관리하고, 다른 VPC에는 워크로드를 실행하는 고객 노드가 있습니다.
이후 Kubernetes Admin의 작업 대부분은 kubectl 같은 Kubernetes 도구로 수행됩니다. 이 도구는 클러스터 컨트롤 플레인에 직접 서비스를 요청해요. 클러스터에 대한 조회·변경 방식은 다른 Kubernetes 클러스터에서 하는 방식과 매우 유사합니다.
워크로드를 배포하려는 애플리케이션 개발자는 여러 작업을 수행할 수 있어요. 개발자는 애플리케이션을 하나 이상의 컨테이너 이미지로 빌드한 뒤, Kubernetes 클러스터가 접근할 수 있는 컨테이너 레지스트리에 이미지를 푸시해야 합니다. AWS는 이를 위해 Amazon Elastic Container Registry(Amazon ECR)을 제공합니다.
애플리케이션을 실행하려면 개발자는 레지스트리에서 어떤 컨테이너를 가져오고 이를 어떻게 Pod로 감쌀지 등 실행 방법을 알려주는 YAML 형식의 구성 파일을 만들 수 있어요. 컨트롤 플레인(스케줄러)은 컨테이너를 하나 이상의 노드에 스케줄링하고, 각 노드의 컨테이너 런타임이 실제로 필요한 컨테이너를 가져와 실행합니다. 개발자는 애플리케이션 로드 밸런서를 설정해 각 노드에서 실행되는 사용 가능한 컨테이너에 트래픽을 분산하고, 애플리케이션을 공용 네트워크로 노출할 수도 있어요. 모든 것이 끝나면 애플리케이션을 사용하려는 사람은 엔드포인트에 연결해 접근할 수 있습니다.
Clusters
클러스터를 시작·관리하는 일을 한다면 Kubernetes 클러스터가 어떻게 생성·강화·관리·삭제되는지 알아야 해요. 또한 클러스터를 구성하는 구성 요소가 무엇인지, 유지 관리 방법도 알아야 합니다.
클러스터 관리 도구는 Kubernetes 서비스와 기본 하드웨어 제공자 사이의 겹치는 부분을 처리합니다. 따라서 이러한 작업의 자동화는 보통 Kubernetes 제공자(예: Amazon EKS, Amazon EKS Anywhere)가 제공자 특화 도구로 수행합니다. 예를 들어 Amazon EKS 클러스터를 시작하려면 eksctl create cluster, Amazon EKS Anywhere는 eksctl anywhere create cluster를 사용할 수 있어요. 이 명령들은 Kubernetes 클러스터를 만들지만 제공자 특화 명령이며 Kubernetes 프로젝트 자체의 일부는 아닙니다.
클러스터 생성 및 관리 도구
Kubernetes 프로젝트는 Kubernetes 클러스터를 수동으로 생성하는 도구를 제공합니다. 단일 머신에 Kubernetes를 설치하거나 컨트롤 플레인을 한 머신에서 실행하고 노드를 수동으로 추가하려면 kind, minikube, kubeadm 같은 CLI 도구를 사용할 수 있어요. 클러스터 생성·관리의 전체 수명 주기를 단순화하고 자동화하려면 Amazon EKS나 Amazon EKS Anywhere 같은 확립된 Kubernetes 제공자가 지원하는 도구를 사용하는 것이 훨씬 쉽습니다.
AWS 클라우드에서는 eksctl 같은 CLI 도구나 Terraform 같은 선언적 도구(Amazon EKS Blueprints for Terraform 참고)로 Amazon EKS 클러스터를 만들 수 있어요. AWS Management Console에서도 클러스터를 생성할 수 있습니다. Amazon EKS가 대신 해 주는 Kubernetes 책임은 다음과 같습니다.
- 관리형 컨트롤 플레인: AWS가 컨트롤 플레인을 관리하고 AWS Availability Zones에 걸쳐 제공하므로 Amazon EKS 클러스터가 항상 사용 가능하고 확장 가능합니다.
- 노드 관리: 노드를 수동으로 추가하는 대신 Amazon EKS가 Managed Node Groups(Simplify node lifecycle with managed node groups 참고)나 Karpenter를 사용해 필요에 따라 노드를 자동으로 생성하게 할 수 있어요. Managed Node Groups는 Kubernetes Cluster Autoscaling과 통합됩니다. 노드 관리 도구를 사용하면 Spot Instances, 노드 통합 같은 비용 절감과, 워크로드 배포 방식과 노드 선택 방식을 정하는 Scheduling 기능을 통한 가용성을 활용할 수 있어요.
- 클러스터 네트워킹:
eksctl은 CloudFormation 템플릿을 사용해 Kubernetes 클러스터의 컨트롤 플레인과 데이터 플레인(노드) 구성 요소 간 네트워킹을 설정합니다. 내부·외부 통신이 이뤄질 수 있는 엔드포인트도 설정해요. 자세한 내용은 De-mystifying cluster networking for Amazon EKS worker nodes 참고. Amazon EKS의 Pod 간 통신은 Amazon EKS Pod Identities(Learn how EKS Pod Identity grants pods access to AWS services 참고)로 수행하며, Pod가 AWS 클라우드의 자격 증명·권한 관리 방식을 활용할 수 있게 합니다. - 애드온: Amazon EKS는 Kubernetes 클러스터를 지원하는 데 흔히 쓰이는 소프트웨어 구성 요소를 직접 빌드·추가하지 않도록 해 줍니다. 예를 들어 AWS Management Console에서 Amazon EKS 클러스터를 만들면 Amazon EKS kube-proxy, Amazon VPC CNI plugin for Kubernetes, CoreDNS 애드온을 자동으로 추가해요. 자세한 내용과 사용 가능한 목록은 Amazon EKS add-ons를 참고하세요.
자체 온프레미스 컴퓨터·네트워크에서 클러스터를 실행하려면 Amazon이 Amazon EKS Anywhere를 제공합니다. AWS 클라우드 대신 자체 장비를 사용해 VMware vSphere, 베어메탈(Tinkerbell 제공자), Snow, CloudStack, Nutanix 플랫폼에서 Amazon EKS Anywhere를 실행할 수 있어요.
Amazon EKS Anywhere는 Amazon EKS가 사용하는 것과 동일한 Amazon EKS Distro 소프트웨어를 기반으로 합니다. 하지만 Amazon EKS Anywhere 클러스터의 머신 전체 수명 주기를 관리하기 위해 Kubernetes Cluster API(CAPI) 인터페이스의 다른 구현(CAPV for vSphere, CAPC for CloudStack 등)을 사용합니다. 전체 클러스터가 자체 장비에서 실행되므로 컨트롤 플레인을 관리하고 데이터를 백업하는 추가 책임이 생겨요(문서 뒷부분의 etcd 참고).
클러스터 구성 요소
Kubernetes 클러스터 구성 요소는 컨트롤 플레인(Control Plane)과 워커 노드(Worker Nodes) 두 영역으로 나뉩니다. 컨트롤 플레인 구성 요소는 클러스터를 관리하고 API 접근을 제공합니다. 워커 노드(때때로 그냥 Node라고도 함)는 실제 워크로드가 실행되는 곳을 제공합니다. 노드 구성 요소는 각 노드에서 실행되어 컨트롤 플레인과 통신하고 컨테이너를 실행하는 서비스로 구성됩니다. 클러스터의 워커 노드 집합을 데이터 플레인(Data Plane)이라고 합니다.
컨트롤 플레인
컨트롤 플레인은 클러스터를 관리하는 서비스 집합입니다. 이 서비스들은 모두 단일 컴퓨터에서 실행되거나 여러 컴퓨터에 분산될 수 있어요. 내부적으로 이를 Control Plane Instances(CPI)라고 합니다. CPI가 실행되는 방식은 클러스터 크기와 고가용성 요구사항에 따라 달라집니다. 클러스터 수요가 증가하면 컨트롤 플레인 서비스가 확장되어 더 많은 인스턴스를 제공하고, 인스턴스 간에 요청을 로드 밸런싱합니다.
Kubernetes 컨트롤 플레인 구성 요소가 수행하는 작업:
- 클러스터 구성 요소와 통신(API server): API server(kube-apiserver)는 Kubernetes API를 노출해 클러스터 안팎에서 클러스터로 요청을 보낼 수 있게 합니다. 즉,
kubectl로 Pod 실행 요청을 보내는 것처럼 외부 명령에서 클러스터 객체(Pod, Services, Nodes 등)를 추가·변경할 수 있어요. 마찬가지로 API server가 클러스터 내 구성 요소에 Pod 상태를 묻는 쿼리 같은 요청을 보낼 수도 있습니다. - 클러스터 데이터 저장(
etcd키-값 저장소):etcd서비스는 클러스터의 현재 상태를 추적하는 중요한 역할을 합니다.etcd에 접근할 수 없게 되면 클러스터 상태를 업데이트하거나 조회할 수 없게 되지만, 워크로드는 한동안 계속 실행돼요. 이런 이유로 크리티컬한 클러스터는 보통 로드 밸런싱된etcd인스턴스 여러 개를 동시에 실행하고, 데이터 손실·손상을 대비해 정기적으로etcd키-값 저장소를 백업합니다. Amazon EKS에서는 기본적으로 이 모든 것이 자동으로 처리된다는 점을 기억하세요. Amazon EKS Anywhere는 etcd 백업·복원 지침을 제공합니다.etcd가 데이터를 관리하는 방법은 etcd Data Model 참고. - Pod를 노드에 스케줄링(Scheduler): Kubernetes에서 Pod 시작·중지 요청은 Kubernetes Scheduler(kube-scheduler)로 전달됩니다. 클러스터에는 Pod를 실행할 수 있는 노드가 여러 개 있을 수 있으므로 Scheduler가 Pod가 실행될 노드(복제본의 경우 여러 노드)를 선택합니다. 기존 노드에 요청된 Pod를 실행할 충분한 용량이 없다면 다른 대비책을 마련하지 않는 한 요청은 실패합니다. 대비책에는 워크로드를 처리할 새 노드를 자동으로 시작하는 Managed Node Groups나 Karpenter 같은 서비스를 활성화하는 것이 포함될 수 있어요.
- 구성 요소를 원하는 상태로 유지(Controller Manager): Kubernetes Controller Manager는 데몬 프로세스(kube-controller-manager)로 실행되어 클러스터 상태를 감시하고 예상 상태를 재수립하기 위해 변경을 수행합니다. 특히 다양한 Kubernetes 객체를 감시하는 여러 컨트롤러가 있는데,
statefulset-controller,endpoint-controller,cronjob-controller,node-controller등이 있습니다. - 클라우드 리소스 관리(Cloud Controller Manager): Kubernetes와, 기본 데이터 센터 리소스 요청을 수행하는 클라우드 제공자 간의 상호작용은 Cloud Controller Manager(cloud-controller-manager)가 처리합니다. 여기에는 경로 컨트롤러(클라우드 네트워크 경로 설정), 서비스 컨트롤러(클라우드 로드 밸런싱 서비스 사용), 노드 수명 주기 컨트롤러(노드를 수명 주기 내내 Kubernetes와 동기화) 등이 포함될 수 있어요.
워커 노드(데이터 플레인)
단일 노드 Kubernetes 클러스터에서는 워크로드가 컨트롤 플레인과 같은 머신에서 실행됩니다. 하지만 더 표준적인 구성은 Kubernetes 워크로드 실행 전용으로 분리된 컴퓨터 시스템(Node)을 하나 이상 두는 것입니다.
Kubernetes 클러스터를 처음 만들 때 일부 생성 도구는 클러스터에 추가할 노드 수를 설정할 수 있게 해 줍니다(기존 컴퓨터 시스템을 지정하거나 제공자가 새로 만들게 함). 워크로드가 추가되기 전에 각 노드에 다음 기능을 구현하는 서비스가 추가됩니다.
- 각 노드 관리(
kubelet): API server는 각 노드에서 실행되는 kubelet 서비스와 통신해 노드가 올바르게 등록되고 Scheduler가 요청한 Pod가 실행되는지 확인합니다. kubelet은 Pod 매니페스트를 읽고 로컬 시스템에 Pod가 필요로 하는 스토리지 볼륨이나 다른 기능을 설정할 수 있어요. 로컬에서 실행되는 컨테이너의 상태도 확인할 수 있습니다. - 노드에서 컨테이너 실행(container runtime): 각 노드의 Container Runtime은 노드에 할당된 각 Pod에 요청된 컨테이너를 관리합니다. 적절한 레지스트리에서 컨테이너 이미지를 가져오고, 컨테이너를 실행·중지하며, 컨테이너에 대한 조회에 응답할 수 있어요. 기본 컨테이너 런타임은 containerd입니다. Kubernetes 1.24부터는 컨테이너 런타임으로 사용할 수 있었던 Docker 특화 통합(
dockershim)이 Kubernetes에서 제거되었습니다. 로컬 시스템에서 Docker로 컨테이너를 테스트·실행하는 것은 여전히 가능하지만, Kubernetes에서 Docker를 사용하려면 이제 각 노드에 Docker Engine을 설치해야 합니다. - 컨테이너 간 네트워킹 관리(
kube-proxy): Kubernetes는 Pod 간 통신을 지원하기 위해 Service라는 기능을 사용해 해당 Pod와 관련된 IP 주소와 포트를 추적하는 Pod 네트워크를 설정합니다. kube-proxy 서비스는 모든 노드에서 실행되어 Pod 간 통신을 가능하게 합니다.
클러스터 확장(Extend Clusters)
Kubernetes에 클러스터를 지원하기 위해 추가할 수 있지만 컨트롤 플레인에서 실행되지 않는 서비스가 있어요. 이 서비스들은 보통 kube-system 네임스페이스의 노드에서 직접 실행되거나 서드파티 서비스 제공자의 경우 자체 네임스페이스에서 실행됩니다. 대표적인 예로 클러스터에 DNS 서비스를 제공하는 CoreDNS가 있어요. 클러스터의 kube-system에서 실행 중인 서비스를 확인하는 방법은 Discovering builtin services를 참고하세요.
클러스터에 추가할 수 있는 다양한 유형의 애드온이 있습니다. 클러스터 건강을 유지하려면 로깅·감사·메트릭 등을 할 수 있는 observability 기능(Monitor your cluster performance and view logs 참고)을 추가할 수 있어요. 이 정보로 문제를 트러블슈팅할 수 있고, 종종 동일한 observability 인터페이스를 사용합니다. 이러한 서비스의 예로 Amazon GuardDuty, CloudWatch(Monitor cluster data with Amazon CloudWatch 참고), AWS Distro for OpenTelemetry, Amazon VPC CNI plugin for Kubernetes, Grafana Kubernetes Monitoring이 있어요. 스토리지(Use application data storage for your cluster 참고)의 경우 Amazon EKS 애드온에는 Amazon Elastic Block Store CSI Driver(Use Kubernetes volume storage with Amazon EBS 참고), Amazon Elastic File System CSI Driver(Use elastic file system storage with Amazon EFS 참고), 그리고 Amazon FSx for NetApp ONTAP CSI driver 같은 여러 서드파티 스토리지 애드온이 있습니다.
Amazon EKS 애드온 전체 목록은 Amazon EKS add-ons를 참고하세요.
Workloads
Kubernetes는 Workload를 "Kubernetes에서 실행되는 애플리케이션"으로 정의합니다. 애플리케이션은 Pod의 컨테이너로 실행되는 마이크로서비스 집합일 수도 있고, 배치 작업이나 다른 유형의 애플리케이션일 수도 있어요. Kubernetes의 역할은 객체를 설정·배포하라는 요청을 수행하는 것입니다. 애플리케이션을 배포한다면 컨테이너가 어떻게 빌드되는지, Pod가 어떻게 정의되는지, 어떤 배포 방법을 쓸 수 있는지 알아야 해요.
컨테이너(Containers)
Kubernetes에서 배포·관리하는 애플리케이션 워크로드의 가장 기본 요소는 Pod입니다. Pod는 애플리케이션의 구성 요소를 담는 방식이자 Pod의 속성을 설명하는 스펙을 정의합니다. Linux 시스템용 소프트웨어를 묶지만 자체적으로 엔티티로 실행되지는 않는 RPM이나 Deb 패키지와 대비됩니다.
Pod는 가장 작은 배포 단위이므로 보통 단일 컨테이너를 담습니다. 하지만 컨테이너들이 긴밀하게 결합된 경우 Pod에 여러 컨테이너가 있을 수 있어요. 예를 들어 웹 서버 컨테이너가 로깅·모니터링 등 웹 서버와 밀접히 연관된 서비스를 제공하는 사이드카 유형의 컨테이너와 함께 한 Pod에 패키징될 수 있습니다. 이 경우 같은 Pod에 있으므로 Pod의 각 실행 인스턴스에서 두 컨테이너가 항상 같은 노드에서 실행됩니다. 마찬가지로 Pod의 모든 컨테이너는 같은 환경을 공유하며, 마치 같은 격리된 호스트에서 실행되는 것처럼 동작합니다. 그 결과 컨테이너들은 Pod에 접근할 수 있는 단일 IP 주소를 공유하고, 마치 자체 localhost에서 실행되는 것처럼 서로 통신할 수 있어요.
Pod 스펙(PodSpec)은 Pod의 원하는 상태를 정의합니다. 워크로드 리소스를 사용해 Pod 템플릿을 관리하면 개별 Pod나 여러 Pod를 배포할 수 있어요. 워크로드 리소스에는 Deployments(여러 Pod 복제본 관리), StatefulSets(데이터베이스 Pod처럼 고유해야 하는 Pod 배포), DaemonSets(모든 노드에서 계속 실행해야 하는 Pod)가 있습니다. 자세한 내용은 아래에서 설명합니다.
Pod는 배포하는 가장 작은 단위이지만, 컨테이너는 빌드·관리하는 가장 작은 단위입니다.
컨테이너 빌드
Pod는 실제로 하나 이상의 컨테이너를 감싸는 구조로, 각 컨테이너가 애플리케이션을 실행하는 파일 시스템, 실행 파일, 구성 파일, 라이브러리 등을 담고 있습니다. Docker Inc.라는 회사가 컨테이너를 대중화했기 때문에 사람들은 컨테이너를 Docker Containers라고 부르기도 해요. 하지만 Open Container Initiative가 이후 업계 표준 컨테이너 런타임·이미지·배포 방법을 정의했습니다. 컨테이너가 많은 기존 Linux 기능에서 만들어졌다는 점을 더해 사람들은 컨테이너를 OCI Containers, Linux Containers, 또는 그냥 Containers라고 부르기도 합니다.
컨테이너를 빌드할 때 보통 Dockerfile(말 그대로 그 이름)에서 시작합니다. Dockerfile 안에서 다음을 지정합니다.
- 베이스 이미지: 베이스 컨테이너 이미지는 보통 운영 체제 파일 시스템의 최소 버전(Red Hat Enterprise Linux, Ubuntu 등)이나 nodejs·python 앱 같은 특정 유형 애플리케이션을 실행할 소프트웨어를 제공하도록 강화된 최소 시스템에서 빌드된 컨테이너입니다.
- 애플리케이션 소프트웨어: Linux 시스템에 소프트웨어를 추가하는 것과 비슷한 방식으로 컨테이너에 애플리케이션 소프트웨어를 추가할 수 있어요. 예를 들어 Dockerfile에서
npm·yarn을 실행해 JavaScript 애플리케이션을 설치하거나yum·dnf로 RPM 패키지를 설치할 수 있습니다. 즉 Dockerfile의 RUN 명령으로 베이스 이미지 파일 시스템에서 사용 가능한 어떤 명령이든 실행해 결과 컨테이너 이미지 안에 소프트웨어를 설치·구성할 수 있어요. - 지침(Instructions): Dockerfile reference는 Dockerfile 구성 시 추가할 수 있는 지침을 설명합니다. 여기에는 컨테이너 안에 무엇을 넣을지 빌드(
ADD·COPY로 로컬 시스템에서 파일 복사), 컨테이너 실행 시 실행할 명령(CMD·ENTRYPOINT), 컨테이너가 실행되는 시스템과의 연결(실행할USER, 마운트할 로컬VOLUME, 노출할 포트EXPOSE지정) 등이 포함됩니다.
컨테이너 빌드에는 전통적으로 docker 명령·서비스(docker build)가 사용됐지만, podman과 nerdctl 같은 도구도 컨테이너 이미지를 빌드할 수 있어요. 자세한 내용은 Building Better Container Images나 Overview of Docker Build를 참고하세요.
컨테이너 저장
컨테이너 이미지를 빌드한 뒤 워크스테이션이나 공용 컨테이너 레지스트리의 컨테이너 배포 레지스트리에 저장할 수 있어요. 워크스테이션에서 프라이빗 컨테이너 레지스트리를 실행하면 컨테이너 이미지를 로컬에 저장해 바로 사용할 수 있습니다.
이미지를 더 공개적으로 저장하려면 공용 컨테이너 레지스트리에 푸시할 수 있어요. 공용 컨테이너 레지스트리는 컨테이너 이미지를 저장·배포하는 중앙 위치를 제공합니다. 예로 Amazon Elastic Container Registry, Red Hat Quay registry, Docker Hub registry가 있어요.
Amazon Elastic Kubernetes Service(Amazon EKS)에서 컨테이너화된 워크로드를 실행할 때는 Amazon Elastic Container Registry에 저장된 Docker Official Images 사본을 가져오는 것을 권장합니다. Amazon ECR은 2021년부터 이 이미지들을 저장해 왔어요. 인기 컨테이너 이미지는 Amazon ECR Public Gallery에서, Docker Hub 이미지는 Amazon ECR Docker Gallery에서 검색할 수 있습니다.
컨테이너 실행
컨테이너는 표준 형식으로 빌드되므로 컨테이너 런타임(예: Docker)을 실행할 수 있고 내용물이 로컬 머신 아키텍처(x86_64·arm 등)와 일치하는 어떤 머신에서도 실행될 수 있어요. docker run이나 podman run 명령으로 localhost에서 컨테이너를 시작해 테스트하거나 로컬 데스크톱에서 실행할 수 있습니다. 하지만 Kubernetes에서는 각 워커 노드에 컨테이너 런타임이 배포되어 있고, 노드가 컨테이너를 실행하도록 요청하는 것은 Kubernetes의 몫입니다.
컨테이너가 노드에서 실행되도록 할당되면 노드는 요청된 버전의 컨테이너 이미지가 이미 존재하는지 확인합니다. 없다면 Kubernetes는 컨테이너 런타임에게 적절한 컨테이너 레지스트리에서 컨테이너를 가져와 로컬에서 실행하라고 지시해요. 컨테이너 이미지는 노트북, 컨테이너 레지스트리, Kubernetes 노드 사이를 이동하는 소프트웨어 패키지를 의미합니다. 컨테이너는 그 이미지의 실행 중인 인스턴스를 말해요.
Pod
컨테이너가 준비되면 Pod를 구성·배포·접근 가능하게 만드는 작업을 합니다.
Pod 구성
Pod를 정의할 때 속성 집합을 할당합니다. 속성에는 최소한 Pod 이름과 실행할 컨테이너 이미지가 포함되어야 해요. 하지만 Pod 정의에 구성하고 싶은 다른 것들도 많습니다(Pod에 넣을 수 있는 항목은 PodSpec 페이지 참고). 여기에는 다음이 포함됩니다.
- 스토리지: 실행 중인 컨테이너가 중지·삭제되면 더 영구적인 스토리지를 설정하지 않는 한 컨테이너의 데이터 스토리지는 사라져요. Kubernetes는 다양한 스토리지 유형을 지원하며 이를 Volumes라는 우산 아래 추상화합니다. 스토리지 유형에는 CephFS, NFS, iSCSI 등이 있고, 로컬 컴퓨터의 로컬 블록 디바이스도 사용할 수 있어요. 클러스터에서 스토리지 유형을 사용할 수 있으면 컨테이너 파일 시스템의 선택한 마운트 지점에 스토리지 볼륨을 마운트할 수 있습니다. Persistent Volume은 Pod 삭제 후에도 계속 존재하지만, Ephemeral Volume은 Pod가 삭제되면 함께 삭제됩니다. 클러스터 관리자가 여러 스토리지 클래스를 만들었다면 볼륨 삭제 여부·재사용, 공간 부족 시 확장 여부, 성능 요구 충족 여부 등 스토리지 속성을 선택할 수 있어요.
- Secrets: Pod 스펙의 컨테이너에 Secrets을 제공하면 컨테이너가 파일 시스템·데이터베이스·기타 보호된 자산에 접근할 권한을 얻을 수 있어요. 키, 비밀번호, 토큰이 secret으로 저장되는 항목에 포함됩니다. Secrets을 사용하면 이 정보를 컨테이너 이미지에 저장할 필요 없이 실행 중인 컨테이너에만 제공하면 됩니다. Secrets과 유사한 것이 ConfigMap입니다.
ConfigMap은 서비스 구성용 키-값 쌍처럼 덜 중요한 정보를 담는 경향이 있어요. - 컨테이너 리소스: 컨테이너를 추가 구성하는 객체는 리소스 구성 형태를 취할 수 있습니다. 각 컨테이너에 사용할 수 있는 메모리·CPU 양을 요청하고, 컨테이너가 사용할 수 있는 총 리소스 양에 제한을 둘 수 있어요. 예시는 Resource Management for Pods and Containers를 참고하세요.
- 디스럽션(Disruptions): Pod는 비자발적으로(노드 다운) 또는 자발적으로(업그레이드 원함) 중단될 수 있어요. Pod disruption budget을 구성하면 중단 발생 시 애플리케이션이 얼마나 사용 가능한지 일부 제어할 수 있습니다. 예시는 Specifying a Disruption Budget for your application 참고.
- 네임스페이스(Namespaces): Kubernetes는 Kubernetes 구성 요소와 워크로드를 서로 격리하는 다양한 방법을 제공합니다. 특정 애플리케이션의 모든 Pod를 같은 Namespace에 실행하는 것은 함께 보안·관리하는 일반적인 방법이에요. 자체 네임스페이스를 만들거나 네임스페이스를 지정하지 않을 수도 있습니다(그러면 Kubernetes가
default네임스페이스 사용). Kubernetes 컨트롤 플레인 구성 요소는 보통 kube-system 네임스페이스에서 실행됩니다.
방금 설명한 구성은 보통 YAML 파일로 모아 Kubernetes 클러스터에 적용합니다. 개인용 Kubernetes 클러스터라면 로컬 시스템에 YAML 파일을 저장할 수 있어요. 하지만 더 중요한 클러스터·워크로드에서는 GitOps가 워크로드와 Kubernetes 인프라 리소스 모두의 저장·업데이트를 자동화하는 인기 있는 방식입니다.
Pod 정보를 모아 배포하는 데 사용되는 객체는 아래 배포 방법 중 하나로 정의됩니다.
Pod 배포
Pod 배포 방법은 Pod로 실행할 애플리케이션 유형에 따라 달라집니다. 선택지는 다음과 같아요.
- 무상태(Stateless) 애플리케이션: 무상태 애플리케이션은 클라이언트 세션 데이터를 저장하지 않으므로 이전 세션을 참조할 필요가 없습니다. 따라서 Pod가 비정상이 되면 새 Pod로 교체하거나 상태 저장 없이 이동하는 것이 더 쉽습니다. 무상태 애플리케이션(예: 웹 서버)을 실행한다면 Deployment로 Pod와 ReplicaSet을 배포할 수 있어요. ReplicaSet은 동시에 실행하려는 Pod 인스턴스 수를 정의합니다. ReplicaSet을 직접 실행할 수도 있지만, 보통 한 번에 실행할 Pod 복제본 수를 정의하기 위해 Deployment 안에서 replicas를 실행하는 것이 일반적입니다.
- 상태유지(Stateful) 애플리케이션: 상태유지 애플리케이션은 Pod의 정체성과 Pod 실행 순서가 중요한 경우입니다. 안정적인 영구 스토리지가 필요하고 일관된 방식으로 배포·확장되어야 해요. Kubernetes에서 상태유지 애플리케이션을 배포하려면 StatefulSets을 사용할 수 있습니다. StatefulSet으로 보통 실행되는 예가 데이터베이스입니다. StatefulSet 안에서 replicas, Pod와 컨테이너, 마운트할 스토리지 볼륨, 데이터가 저장되는 컨테이너 내 위치를 정의할 수 있어요. 예시는 Run a Replicated Stateful Application 참고.
- 노드별(Per-node) 애플리케이션: Kubernetes 클러스터의 모든 노드에서 애플리케이션을 실행하고 싶은 때가 있습니다. 예를 들어 데이터 센터의 모든 컴퓨터에서 모니터링 애플리케이션이나 특정 원격 접근 서비스를 실행해야 할 수 있어요. Kubernetes에서는 DaemonSet을 사용해 선택한 애플리케이션이 클러스터의 모든 노드에서 실행되도록 보장할 수 있습니다.
- 완료까지 실행되는 애플리케이션: 특정 작업을 완료하기 위해 실행하려는 애플리케이션이 있습니다. 월간 상태 보고서를 만들거나 오래된 데이터를 정리하는 작업이 그 예시에요. Job 객체로 애플리케이션이 시작·실행되고 작업이 끝나면 종료되도록 설정할 수 있습니다. CronJob 객체는 Linux crontab 형식 구조를 사용해 특정 시·분·일·월·요일에 실행되도록 애플리케이션을 설정할 수 있게 해 줍니다.
네트워크에서 애플리케이션 접근 가능하게 만들기
애플리케이션이 여러 곳으로 이동하는 마이크로서비스 집합으로 배포되는 경우가 많기 때문에, Kubernetes는 마이크로서비스가 서로를 찾을 수 있는 방법이 필요했어요. 또한 Kubernetes 클러스터 외부에서 애플리케이션에 접근하려면 애플리케이션을 외부 주소·포트에 노출할 방법이 필요했습니다. 이러한 네트워킹 기능은 각각 Service와 Ingress 객체로 수행됩니다.
- Services: Pod는 다른 노드·주소로 이동할 수 있으므로, 다른 Pod가 첫 번째 Pod와 통신하려면 그 위치를 찾기 어려울 수 있어요. 이 문제를 해결하기 위해 Kubernetes는 애플리케이션을 Service로 표현할 수 있게 합니다. Service로 특정 이름의 Pod 또는 Pod 집합을 식별하고, Pod에서 애플리케이션 서비스를 노출하는 포트와 다른 애플리케이션이 서비스에 접촉할 수 있는 포트를 지정할 수 있어요. 클러스터 내 다른 Pod는 이름으로 Service를 요청하기만 하면 Kubernetes가 해당 서비스를 실행하는 Pod 인스턴스의 적절한 포트로 요청을 보냅니다.
- Ingress: Ingress는 Kubernetes Service로 표현되는 애플리케이션을 클러스터 외부 클라이언트가 사용할 수 있게 만드는 기능입니다. Ingress의 기본 기능에는 로드 밸런서(Ingress가 관리), Ingress controller, 컨트롤러에서 Service로 요청을 라우팅하는 규칙이 있어요. Kubernetes에서 선택할 수 있는 Ingress Controller가 여러 개 있습니다.
다음 단계
기본 Kubernetes 개념과 이것이 Amazon EKS와 어떻게 관련되는지 이해하면 Amazon EKS 문서와 Kubernetes 문서를 탐색하며 Amazon EKS 클러스터 관리와 워크로드 배포에 필요한 정보를 찾는 데 도움이 됩니다. Amazon EKS 사용을 시작하려면 다음 중에서 선택하세요.
- Get started with Amazon EKS – eksctl
- Create an Amazon EKS cluster
- Deploy a sample application on Linux
- Organize and monitor cluster resources