안녕하세요 서후아빠입니다. ^_^
이번 세션은 AWS Container Platform에 대해서 업무적으로 필요한 최소한의 개념에 대해서 간단히 정리해 보았습니다.
VM (Virtual Machine) vs Container 구조
Container : VM처럼 Guest OS가 필요하지 않으므로 가볍고 빠른데 비해 Host OS에 종속 (Windows Host에 Linux Container 생성 불가) |
Docker 구조
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가 실행되는 논리적 그룹
IAM : Host(Instance(EC2))의 권한을 상속받지 않고, Task에 IAM 역할 할당 |
Kubernetes 구성요소
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 네트워킹 구조
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 미지원
'Compute' 카테고리의 다른 글
[Tip] 종료된 인스턴스 복구하는 방법 알아보기 (0) | 2022.07.12 |
---|---|
[실습] ECS로 Container(EC2, Fargate) 생성하기(With ECR, EFS, SSM, CloudWacth, CodePipeline) (0) | 2022.07.12 |
[이론] Amazon Elastic Compute Cloud(EC2) 기본 개념 (0) | 2022.07.11 |
[Tip] EC2 재부팅하면서 Instance health check failed 발생 시 조치 순서에 대해서 알아보기 (0) | 2022.07.05 |
[Tip] AWS에서 EC2의 Hardware 교체 작업으로 인하여 발생되는 서비스 중단에 대해서 알아보기 (0) | 2022.07.04 |