본문 바로가기

Compute

[이론] AWS Container Platform (ECS, EKS) 기본 개념

반응형

안녕하세요 서후아빠입니다. ^_^

이번 세션은 AWS Container Platform에 대해서 업무적으로 필요한 최소한의 개념에 대해서 간단히 정리해 보았습니다.


VM (Virtual Machine) vs Container 구조

Container : VM처럼 Guest OS가 필요하지 않으므로 가볍고 빠른데 비해 Host OS에 종속 (Windows Host에 Linux Container 생성 불가)

Docker 구조

[Docker 구조 및 명령어 수행 시 Flow]

Client가 Host(Server)에 접속하여 docker 명령어를 실행하면 Host(Server)와 통신되는 Repository (ECR, Docker Hub 등)을 이용하여 docker 이미지를 다운로드 받아서 container를 구동합니다. 

ECS vs EKS 구조

ECS, EKS는 Container 오케스트레이션으로 K8S 운영 인력이 없는 경우 ECS를 권고합니다.
  - ECS : AWS Only (EKS보다 저렴, 쉬움)
    ※ Fargate (Serverless)는 EC2 OS, ECS Agent, Docker Agent 없습니다.
  - EKS : 범용 K8S

ECR(Elastic Container Registry) : Docker Container의 이미지를 저장하는 Private Repository이며, 이미지는 S3에 저장됨
  - 구성요소 : 레지스트리, 사용자 권한 토큰, 리포지토리, 리포지토리 정책, 이미지
  - AWS 에서 ECR 접근을 위해서는 보안상 VPC Endpoint(Private 통신)를 생성하여 사용을 권고합니다. 

Container Runtime : 간단히 설명하면 Container를 실행하는 엔진
 - 종류 : Containerd, CRI-O 등
   ※ docker-engine : K8S에서 지원 중단, 내부적으로 containerd로 돌기 때문에 docker-engine 고객은 containerd로 전환 필요

ECS (Elastic Container Service)

클러스터 형태 : EC2, Fargate(serverless)

구성요소 : Cluster, Instance(EC2), Service, Task, Task 정의, Container, ECS Agent

  - Task (≒Pod) : 최대 10개 컨테이너 가능, 모두 같은 Host에 배치

  - Task 정의 : EC2 or Fargate, Task 크기, 컨테이너, 볼륨 등 정의

     ※ Fargate : 지원 OS (Amazon Linux, Windows Server 2019), 설정 가능한 CPU/MEM (CPU 0.5~4vCPU, MEM  512~30GB)

  - Service (≒Deployment or Service) : Task 배치 전략 (bin-packing, spread, random)

  - Cluster (≒Namespace) : Task가 실행되는 논리적 그룹 

[Task에 정의된 내용을 Service로 구현할 경우 ECS에서 생성되는 Service Flow]
[Container 배치 전략]

IAM : Host(Instance(EC2))의 권한을 상속받지 않고, Task에 IAM 역할 할당

Kubernetes 구성요소

[K8S 동작 구조]

API server : 모든 요청 처리, 원하는 상태를 etcd에 저장/조회 등 

  ※ 가용성(API server 수량 증설), 백업관리(etcd)는 AWS에서 Auto Scaling group으로 관리 책임

scheduler : 미할당 Pod를 적절한 Node에 할당

controller : kube controller(오브젝트 상태 관리), cloud controller(클라우드 로드 밸런서/볼륨 연결 등)

  ※ Controller Manager : Deployment Controller, ReplicaSet Controller, Node Controller 등 Controller 관리

etcd : 클러스터 데이터 저장소, 분산형 합의 기반 시스템, controller/schduler/kubelet 등의 진행 상황을 저장 및 관리

kubelet : Worker Node에서 구동되는 Agent, Pod 생성, 컨테이너 상태 확인 등

kube-proxy : Worker Node에서 구동되는 Agent, 네트워크 동작 관리(라우팅), DaemonSet 형태

  - userspace : k8s 초기에 운영, 클라이언트의 서비스 요청을 iptables를 거쳐 kube-proxy가 받아서 pod 연결
  - iptables : k8s 현재 운영, service 생성 시 kube-proxy가 iptables 룰을 생성하고, 클라이언트의 서비스 요청을 kube-proxy가 받아서 iptables 룰에 의해 pod 연결
  - IPVS : 리눅스 커널이 지원하는 LB 기술 이용, 별도 IPVS 지원 모듈을 worker node에 설정 필요

  ※ kube-proxy는 Client가 Service를 통해 pod를 접근하기 위한 전달 매개체

EKS Auto Scaling은 Node를 확장하는 개념이고, ECS Auto Scaling은 Task를 확장하는 개념입니다.

K8S의 단점은 업그레이드가 자주 발생하는 것으로 이 부분을 고려해서 접근해야 합니다. 
  - 업그레이드 주체는 API server는 AWS이고, Worker Node는 고객입니다.

Kubernetes 오브젝트 종류

Pod : 배포 가능한 가장 작은 단위, 한개 이상의 컨테이너로 구성

  ※ Fuzzy Container : Pod의 IP를 가지고 있는 컨테이너

Deployment : 배포 버전 관리, 무중단 업데이트/롤백

Service의 Endpoint는 Pod를 의미하며, Pod로 전달하는 부하분산은 Random 

Cluster IP (Default) Node Port LoadBalancer 
- 클러스터 내부 통신(Pod간 Networking)
- 외부 접근을 위해서는 Proxy or Port forwarding 필요
- ALB를 Proxy 위치에 놓고, Ingress 통해 연결 가능
- 노드의 특정 Port를 사용하여 접근
- Port당 하나의 Service만 사용 가능
- 해당 노드가 장애나면 다른 노드를 통해 접근 불가능
- NodePort 앞단에 특정 ELB를 사용하여 접근

Ingress : HTTP/S 트래픽을 도메인 혹은 경로별 라우팅 정책

  - ELB는 Service 수량만큼 생성하기 때문에 Service 수량이 많은 경우 Ingress를 사용하면 편리

  - Ingress가 동작하기 위해서는 Ingress Controller가 필수

  - Ingress controller 종류 : AWS, GCE, Nginx, AKS, Ctrix, Apache, Kong, Istio, HAProxy, Ambassdor 등

Label : 리소스의 특성을 분류, Selector를 이용해서 선택, key-value 한쌍으로 적용

그외 : Namespace, ReplicaSet, DeamonSet, StatefulSets, Job, CronJob, ReplicationController, Volume, ...

EKS 노드(Worker node) 형태

관리형 노드 추천, Fargate는 GPU 미지원

API server(=Master Node)가 위치한 EKS VPC가 별도 구성(보이지 않음) 되며, EKS VPC와 통신하기 위한 EKS-Managed Cross-Account ENI가 Work Node에 생성되어 통신하게 됩니다.

K8S vs EKS 네트워킹 구조

[Kubernetes 네트워킹]
[EKS 네트워킹]

EKS 네트워크 설계 시 고려 사항

EKS는 Overlay가 아닌 일반 VPC 네트워킹하므로 EKS Cluster가 동작하는 Subnet은 여유있게(22 bit 이상) 할당 권고

Work Node instance Max IP 계산 예시 (m5.xlarge 경우)

구분 내용
m5.xlarge에 대한 ENI 수량, ENI당 IP 수량 ENI 4개, ENI당 IP 15개
Max IP (ENI 수 × (ENI 당 IP 수 - 1)) + 2 = (4 x (15 - 1)) + 2 = 58개
예약된 IP CNI Plugin 1개, kube-proxy 1개
유효한 IP 58 - 2 = 56개
Instance별 Max ENI, ENI별 Max IP 개수 확인 : https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/using-eni.html
Instance별 Max Pod 개수 확인 : https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt 

Nitro system계열 인스턴스는 노드당 가용 IP 주소 증가 : https://docs.aws.amazon.com/eks/latest/userguide/choosing-instance-type.html
  - New Max Pods = (ENI 수 x (ENI 당 IP 수 - 1)) x 16
  - 단, 30vCPU 미만 인스턴스는 110으로 제한, 그 외는 250으로 제한

Work Node instance Secondary IP 제한 방법 : Max IP를 모두 활성화하면 네트워크 대역을 차지하므로 경우에 따라 제한

# Secondary IP 제한 예시
kubectl set env ds aws-node -n kube-system WARM_IP_TARGET=1
kubectl set env ds aws-node -n kube-system MINIMUM_IP_TARGET=30
WARM_IP_TARGET : 특정 IP개수만 Warm Pool을 설정, 1은 pod 생성 시마다 secondary IP 1개씩 추가 할당
  ※ Pod 생성이 빈번하면 IP 할당/해제하는 API call횟수가 증가함에 따라 Throttling이 발생할 수 있으므로 MINIMUM_IP_TARGET 함께 설정

MINIMUM_IP_TARGET : Node instance에 일반적으로 유지되는 pod 수, 해당 수만큼 미리 ENI에 secondary IP 할당됨

ALB를 통해 Pod를 노출하는 경우는 ALB > ING(Ingress) > SVC(Service) > App(Pod) 로 구성

NLB를 통해 Pod를 노출하는 경우는 NLB > SVC > App 로 구성

ELB Target Group에서 지원하는 트래픽 모드 : Instance(Default) vs IP

  - Instance : Node를 ALB의 대상으로 등록 (NodePort를 통하여 Pod로 전달)

  - IP : Pod를 ALB 대상으로 등록 (Pod로 직접 라우팅, ingress.yaml 파일에 주석을 사용하여 명시적으로 지정 필요)

kubectl과 kube-proxy 통신 구성 방식

Public Endpoint Only (Default) Public and Private Endpoints Private Endpoint Only (권고)
kubectl이 Public NLB를 통해 
kube-Proxy에게 명령어를 
전달하는 흐름
kubectl이 Public NLB를 통해
API server에게 명령어를 전달하고,
API server에서 kube-proxy에게
명령어를 전달하는 흐름
kubectl과 kube-proxy가 
동일한 VPC에 존재하는 경우, 
보안상 우수

EKS 스토리지 연결

[정적 영구 볼륨 연결]
[동적 영구 볼륨 연결]

emptyDir : Pod 생성/삭제 시 함께 생성/삭제되는 임시 볼륨

hostPath : 노드의 로컬 디스크의 경로를 Pod에서 마운트해서 사용

gitRepo : 물리적으로는 emptyDir 생성, 지정된 Git Repository 내용을 clone으로 다운

영구 볼륨 연결 : CSI 드라이버 통하여 Pod에 연결

CSI (Container Storage Instance) 드라이버 : Container Orchestration System (CO)와 Storage를 제어하는 Plugin
  - AWS EKS 지원 : EBS, EFS, FSx for Lustre, FSx for NetApp ONTAP, Amazon File Cache
storage class : 여러 개의 Physical Disk 타입 (HDD, NFS, SSD, ...)

EKS 확장

구분 내용
Cluster Auto-Scaler (CA) Pod를 배포할 Node 부족한 경우 신규 Node Provisioning (Node 개수)
Pending Pod를 CA가 감지하여 Auto Scaling Group을 이용하여 Node 배포
Horizontal Pod Auto-Scaler (HPA) 서비스를 처리할 Pod 부족한 경우 신규 Pod Provisioning (Pod 개수)
Metric Server Pod에서 발생한 이벤트를 HPA Controller가 감지하여 Pod 배포
Vertical Pod Auto-Scaler (VPA) 서비스를 처리할 Pod 부족한 경우 자동 or 수동으로 Pod 교체 (Pod 성능)
HPA와 VPA는 동시에 사용할 수 없습니다.
일반적으로 HPA를 통해 Pod가 배포되고, Pod 배포 가능한 인스턴스가 없으면 CA를 통해 인스턴스를 생성하고 Pod 배포

Karpenter : Cluster Autoscaler의 단점을 보완하기 위해 AWS 주도로 개발중인 오픈소스 오토 스케일러

EKS 보안 및 기타

인증과 인가

  - K8S는 인증은 없고, 인가만 존재

  - EKS는 인증은 IAM 이용 : Cluster Role (Cluster 자원 통제), Role (Cluster 하위의 NameSpace 자원 통제)

CI/CD

  - EKS는 CodeDeploy 미지원

반응형