Fargate
Fargate란?
EKS Fargate는 AWS에서 제공하는 서버리스 Kubernetes 컴퓨팅 서비스입니다. 일반 EKS는 컨트롤 플레인만 AWS가 관리하지만, Fargate는 데이터 플레인까지 관리해 주므로 인프라 걱정 없이 애플리케이션 개발에 집중할 수 있습니다.

하지만, AWS에서 데이터플레인까지 관리하는 영역이 넓어진 만큼, 여러 가지 제약사항과 고려사항이 존재합니다.
- CPU와 메모리는 정해진 단위(예: 0.25, 0.5, 1.0 vCPU 및 512MB, 1GB 등)로만 할당할 수 있습니다.
- 데몬 셋은 Fargate에서 지원하지 않습니다.
- 특권 컨테이너(Privileged containers)가 지원되지 않습니다.
- HostPort 또는 HostNetwork를 지정할 수 없습니다
- Fargate는 GPU를 사용할 수 없습니다.
- Fargate Spot을 지원하지 않습니다.
이러한 특징으로 보아 Fargate는 단기간 또는 일시적인 유형의 워크로드에 적합할 것 같습니다.
Firecracker
Firecracker는 AWS가 개발한 오픈소스 가상화 기술로, 서버리스 컴퓨팅을 위해 설계된 경량화된 MicroVM을 제공합니다.
Firecracker는 여러 수준(Layer)의 격리와 보호를 사용하기 떄문에 거의 완벽한 보안을 자랑합니다. 또한 경량화된 설계로 1초도 되지 않는 시간 안에 경량 microVM(마이크로 가상 머신)을 시작할 수 있기 때문에 리소스를 효율적으로 사용할 수 있습니다.

Fargate에서 파드를 생성하면 Firecracker를 통해 MicroVM(노드)이 생성되고, 각 파드는 이 MicroVM에 스케줄링됩니다. 이 구조는 VM 수준의 격리를 제공하므로, 파드가 보안 침해를 당하더라도 해당 파드가 실행 중인 노드는 보안적으로 완벽하게 격리되어 있어 추가적인 위험을 방지합니다.

MicroVM 마다 Kubelet, Kube-proxy, Containerd가 동작하기 때문에, 256 RAM 반드시 필요하다고 합니다.
Fargate 배포하기(Terraform)
Terraform blueprints를 통해서 fargate eks 배포합니다.
Fargate를 배포하는 테라폼 코드를 클론 받습니다.
git clone https://github.com/aws-ia/terraform-aws-eks-blueprints
tree terraform-aws-eks-blueprints/patterns
cd terraform-aws-eks-blueprints/patterns/fargate-serverless
main.tf 수정 : 실습 편리를 위해 Sample App을 배포하는 부분을 삭제합니다.
provider "aws" {
region = local.region
}
provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}
provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}
}
data "aws_availability_zones" "available" {
# Do not include local zones
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
locals {
name = basename(path.cwd)
region = "ap-northeast-2"
vpc_cidr = "10.10.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Blueprint = local.name
GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints"
}
}
################################################################################
# Cluster
################################################################################
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.11"
cluster_name = local.name
cluster_version = "1.30"
cluster_endpoint_public_access = true
# Give the Terraform identity admin access to the cluster
# which will allow resources to be deployed into the cluster
enable_cluster_creator_admin_permissions = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
# Fargate profiles use the cluster primary security group so these are not utilized
create_cluster_security_group = false
create_node_security_group = false
fargate_profiles = {
study_wildcard = {
selectors = [
{ namespace = "study-*" }
]
}
kube_system = {
name = "kube-system"
selectors = [
{ namespace = "kube-system" }
]
}
}
fargate_profile_defaults = {
iam_role_additional_policies = {
additional = module.eks_blueprints_addons.fargate_fluentbit.iam_policy[0].arn
}
}
tags = local.tags
}
################################################################################
# EKS Blueprints Addons
################################################################################
module "eks_blueprints_addons" {
source = "aws-ia/eks-blueprints-addons/aws"
version = "~> 1.16"
cluster_name = module.eks.cluster_name
cluster_endpoint = module.eks.cluster_endpoint
cluster_version = module.eks.cluster_version
oidc_provider_arn = module.eks.oidc_provider_arn
# We want to wait for the Fargate profiles to be deployed first
create_delay_dependencies = [for prof in module.eks.fargate_profiles : prof.fargate_profile_arn]
# EKS Add-ons
eks_addons = {
coredns = {
configuration_values = jsonencode({
computeType = "Fargate"
# Ensure that the we fully utilize the minimum amount of resources that are supplied by
# Fargate https://docs.aws.amazon.com/eks/latest/userguide/fargate-pod-configuration.html
# Fargate adds 256 MB to each pod's memory reservation for the required Kubernetes
# components (kubelet, kube-proxy, and containerd). Fargate rounds up to the following
# compute configuration that most closely matches the sum of vCPU and memory requests in
# order to ensure pods always have the resources that they need to run.
resources = {
limits = {
cpu = "0.25"
# We are targeting the smallest Task size of 512Mb, so we subtract 256Mb from the
# request/limit to ensure we can fit within that task
memory = "256M"
}
requests = {
cpu = "0.25"
# We are targeting the smallest Task size of 512Mb, so we subtract 256Mb from the
# request/limit to ensure we can fit within that task
memory = "256M"
}
}
})
}
vpc-cni = {}
kube-proxy = {}
}
# Enable Fargate logging this may generate a large ammount of logs, disable it if not explicitly required
enable_fargate_fluentbit = true
fargate_fluentbit = {
flb_log_cw = true
}
enable_aws_load_balancer_controller = true
aws_load_balancer_controller = {
set = [
{
name = "vpcId"
value = module.vpc.vpc_id
},
{
name = "podDisruptionBudget.maxUnavailable"
value = 1
},
]
}
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
tags = local.tags
}
테라폼을 배포합니다. Terraform을 실행하는 호스트에서 AWS 자격증명이 설정되어 있어야 합니다.
# init 초기화
terraform init
tree .terraform
cat .terraform/modules/modules.json | jq
tree .terraform/providers/registry.terraform.io/hashicorp -L 2
# plan
terraform plan
terraform apply -auto-approve
Fargate 클러스터 정보 확인
일반 EKS와 달리, 파드가 노드와 1:1로 매핑되어 있습니다. (노드의 IP와 파드의 개수가 동일)

일정한 리소스 사용량을 확인할 수 있습니다.

fargate가 사용하는 스케줄러를 확인할 수 있습니다.
kubectl get pod -n kube-system -l k8s-app=kube-dns -o yaml

AWS 콘솔 확인
EC2 인스턴스가 존재하지 않음.

네트워크 인터페이스의 소유자, 요청자, 인스턴스 소유자가 다름

새로운 파드 배포 시, schedulerName이 다른 경우는 왜 그럴까? -> admission control이 동작했음을 알 수 있음.

Fargate 워크로드 배포하기
fargate에 netshoot 디플로이먼트(파드) 배포
파드 배포 시, 노드가 프로비저닝 되면서 스케줄링이 이루어지므로 일반 클러스터보다는 속도가 느려집니다.

노드가 프로비저닝 되는 이벤트 로그를 확인할 수 있습니다.
kubectl get events -w --sort-by '.lastTimestamp'
31m Normal Starting node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Starting kubelet.
31m Warning InvalidDiskCapacity node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal invalid capacity 0 on image filesystem
31m Normal RegisteredNode node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Node fargate-ip-10-10-40-197.ap-northeast-2.compute.internal event: Registered Node fargate-ip-10-10-40-197.ap-northeast-2.compute.internal in Controller
31m Normal NodeReady node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Node fargate-ip-10-10-40-197.ap-northeast-2.compute.internal status is now: NodeReady
31m Normal Synced node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Node synced successfully
11m Warning InvalidDiskCapacity node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal invalid capacity 0 on image filesystem
11m Normal Starting node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Starting kubelet.
11m Normal NodeReady node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeReady
11m Normal Synced node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node synced successfully
11m Normal NodeAllocatableEnforced node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Updated Node Allocatable limit across pods
11m Normal NodeHasSufficientPID node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeHasSufficientPID
11m Normal NodeHasNoDiskPressure node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeHasNoDiskPressure
11m Normal NodeHasSufficientMemory node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeHasSufficientMemory
11m Normal RegisteredNode node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal event: Registered Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal in Controller
2m35s Normal NodeHasNoDiskPressure node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeHasNoDiskPressure
2m35s Normal NodeHasSufficientMemory node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeHasSufficientMemory
2m35s Normal NodeReady node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeReady
2m35s Normal Synced node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node synced successfully
2m35s Normal NodeAllocatableEnforced node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Updated Node Allocatable limit across pods
2m35s Normal Starting node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Starting kubelet.
2m35s Warning InvalidDiskCapacity node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal invalid capacity 0 on image filesystem
2m35s Normal NodeHasSufficientPID node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeHasSufficientPID
2m31s Normal RegisteredNode node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal event: Registered Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal in Controller
# 메모리 할당 확인
kubectl get pod -n study-aews -o jsonpath='{.items[0].metadata.annotations.CapacityProvisioned}'
0.5vCPU 1GB
AWS ALB(Ingress)
Fargate에서 AWS ALB(Ingress)를 사용하여 애플리케이션에 대한 외부 접근을 관리합니다.
# 게임 디플로이먼트와 Service, Ingress 배포
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: study-aews
name: deployment-2048
spec:
selector:
matchLabels:
app.kubernetes.io/name: app-2048
replicas: 2
template:
metadata:
labels:
app.kubernetes.io/name: app-2048
spec:
containers:
- image: public.ecr.aws/l6m2t8p7/docker-2048:latest
imagePullPolicy: Always
name: app-2048
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: study-aews
name: service-2048
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
selector:
app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: study-aews
name: ingress-2048
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-2048
port:
number: 80
EOF
파드 권한과 호스트 네임스페이스 공유로 호스트 탈취 시도
Fargate가 아닌 권한이 충분한 환경에서는 아래와 같이 호스트 네임스페이스에 접근할 수 있지만, Fargate에서는 실패합니다.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: root-shell
namespace: study-aews
spec:
containers:
- command:
- /bin/cat
image: alpine:3
name: root-shell
securityContext:
privileged: true
tty: true
stdin: true
volumeMounts:
- mountPath: /host
name: hostroot
hostNetwork: true
hostPID: true
hostIPC: true
tolerations:
- effect: NoSchedule
operator: Exists
- effect: NoExecute
operator: Exists
volumes:
- hostPath:
path: /
name: hostroot
EOF
kubectl get pod -n study-aews root-shell
kubectl describe pod -n study-aews root-shell | grep Events: -A 10
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 95s fargate-scheduler Pod not supported on Fargate: fields not supported: HostNetwork, HostPID, HostIPC, volumes not supported: hostroot is of an unsupported volume Type, invalid SecurityContext fields: Privileged
Fargate Logging
Fargate의 Amazon EKS는 Fluent Bit 기반의 내장 로그 라우터를 제공합니다. 즉, 사용자가 Fluent Bit 컨테이너를 사이드카로 명시적으로 실행할 필요 없이 Amazon에서 자동으로 실행됩니다. 로그 라우터를 구성하기만 하면 됩니다.
로그를 발생시킬 nginx 배포하여 faragte logging을 확인해 보도록 합니다.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app
namespace: study-aews
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
name: http
resources:
requests:
cpu: 500m
memory: 500Mi
limits:
cpu: 2
memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: sample-app
namespace: study-aews
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
EOF
# 확인
kubectl get pod -n study-aews -l app=nginx
kubectl describe pod -n study-aews -l app=nginx
해당 nginx로 반복 접속하여 로그를 발생시킵니다.
# 반복 접속
kubectl exec -it deploy/netshoot -n study-aews -- curl sample-app | grep title
while true; do kubectl exec -it deploy/netshoot -n study-aews -- curl sample-app | grep title; sleep 1; echo ; date; done;
# 로그 확인
kubectl stern -n study-aews -l app=nginx
ConfigMap을 통해 Fargate의 Amazon EKS가 자동으로 이를 감지하고 로그 라우터를 구성합니다.
kubectl get cm -n aws-observability
kubectl get cm -n aws-observability aws-logging -o yaml
data:
filters.conf: |
[FILTER]
Name parser
Match *
Key_name log
Parser crio
[FILTER]
Name kubernetes
Match kube.*
Merge_Log On
Keep_Log Off
Buffer_Size 0
Kube_Meta_Cache_TTL 300s
flb_log_cw: "true" # Ships Fluent Bit process logs to CloudWatch.
output.conf: |+
[OUTPUT]
Name cloudwatch
Match kube.*
region ap-northeast-2
log_group_name /fargate-serverless/fargate-fluentbit-logs2025031600585521800000000c
log_stream_prefix fargate-logs-
auto_create_group true
[OUTPUT]
Name cloudwatch_logs
Match *
region ap-northeast-2
log_group_name /fargate-serverless/fargate-fluentbit-logs2025031600585521800000000c
log_stream_prefix fargate-logs-fluent-bit-
auto_create_group true
parsers.conf: |
[PARSER]
Name crio
Format Regex
Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>P|F) (?<log>.*)$
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
Time_Keep On
수집된 파드 로그를 확인하려면, CloudWatch Log Streams에서 nginx로 검색 필터링을 하고, Fluent Bit 로그도 포함되었는지 체크한 후, First event time 중 가장 최근의 항목을 클릭합니다.

해당 로그 스트림 화면에서 아래와 같이 상세 로그 정보를 확인하여 curl 접속 로그를 확인합니다.

EKS Auto Mode
EKS Auto Mode란?
최근 출시된 EKS AutoMode는 Fargate와 같이 컨트롤플레인 및 데이터플레인뿐만이 아니라, 클러스터를 운영하면서 사용되는 Addon과 같은 AWS의 리소스까지도 관리해 주는 완전체형 AWS 서비스라고 할 수 있습니다.

Auto Mode는 특징은 다음과 같습니다.
- EKS Auto Mode에서 생성된 EC2 인스턴스는 다른 EC2 인스턴스와 다르며 관리되는 인스턴스입니다. 이러한 관리되는 인스턴스는 EKS가 소유하고 있으며 더 제한적입니다.
- 노드에 대해 불변으로 취급되는 AMI를 사용(bottle rocket) 합니다.
- EKS Auto Mode에서 관리하는 인스턴스 SSH 또는 SSM 액세스를 허용하지 않음으로써 노드에 대한 직접 액세스를 방지합니다.
그 중 가장 큰 특징은 아래 6가지 구성요소가 파드로 구성되는 것이 아니고, 해당 노드의 sysemd 데몬(agent)으로 실행됩니다.
- kube-proxy, kubelet, eks-pod-identity-agent, eks-node-monitor-agent, eks-healthcheck, eks-ebs-csi-driver,
- csi-node-driver-registrar, coredns, containerd, aws-network-policy-agent, apiserver, ipam

EKS Auto Mode 배포하기(Terraform)
테라폼 코드 클론 : aws에서 제공하는 auto-mode 샘플 레포지토리를 클론 합니다.
git clone https://github.com/aws-samples/sample-aws-eks-auto-mode.git
cd sample-aws-eks-auto-mode/terraform
variables.tf 수정 : 환경에 맞는 변수로 수정합니다
variable "name" {
description = "Name of the VPC and EKS Cluster"
default = "automode-cluster"
type = string
}
variable "region" {
description = "region"
default = "ap-northeast-2"
type = string
}
variable "eks_cluster_version" {
description = "EKS Cluster version"
default = "1.31"
type = string
}
# VPC with 65536 IPs (10.0.0.0/16) for 3 AZs
variable "vpc_cidr" {
description = "VPC CIDR. This should be a valid private (RFC 1918) CIDR range"
default = "10.20.0.0/16"
type = string
}
테라폼 코드 배포
# Get the code : 배포 코드에 addon 내용이 읍다!
git clone https://github.com/aws-samples/sample-aws-eks-auto-mode.git
cd sample-aws-eks-auto-mode/terraform
# eks.tf : "system" 은 '전용인스턴스'로 추가하지 않는다
...
cluster_compute_config = {
enabled = true
node_pools = ["general-purpose"]
}
...
# Initialize and apply Terraform
terraform init
terraform plan
terraform apply -auto-approve
클러스터 확인
배포된 클러스터의 리소스를 확인해 보면 놀랍게도 아무것도 조회되지 않음을 확인할 수 있습니다. kube-system이나 addon과 같은 핵심 컴포넌트를 aws에서 데몬을 통해 관리가 되기 때문입니다.

카펜터를 통해 노드를 관리하기 때문에 관련 crd들이 존재합니다. 또한 AutoMode는 노드에 접근할 수 없기 때문에 NodeDiagnostic과 같은 CRD를 통해 노드의 상태를 관리할 수 있는 기능들도 제공하는 것 같습니다.

AWS 관리 콘솔에서 확인
네트워크 인터페이스 확인

EKS 확인

EKS에는 Addon이 존재하지 않음을 확인

EKS Auto Mode 워크로드 배포하기
파드 생성 시, pending 상태이지만, Karpenter에 의해 노드가 프로비저닝 되면 파드가 스케줄링되는 것을 확인할 수 있다.

karpenter 동작 확인
Karpenter 동작 확인을 위해 아래와 같이 inflate Deployment 배포합니다. eks.amazonaws.com/compute-type: auto 노드 선택기를 사용하여 Karpenter가 자동으로 프로비저닝 한 노드에서 실행되도록 합니다.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 1
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
nodeSelector:
eks.amazonaws.com/compute-type: auto
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 1
securityContext:
allowPrivilegeEscalation: false
EOF
# Step 3: Watch Kubernetes Events
kubectl get events -w --sort-by '.lastTimestamp'
kubectl get nodes
infate 디플로이먼트의 레플리카를 100개까지 증가시키면, 필요한 리스소의 스펙에 맞게 노드가 프로비저닝 되는 것을 확인할 수 있다.


Graviton Workloads 배포
Graviton(arm 프로세스) 노드 인스턴스에 2048 game 애플리케이션을 배포하는 실습을 진행합니다.
Graviton Workloads를 위해 커스텀 NodeClass와 NodePool을 사용하여 설정합니다.
kubectl apply -f ../nodepools/graviton-nodepool.yaml
---
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
name: graviton-nodeclass
spec:
role: automode-cluster-eks-auto-20250314121820950800000003
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "automode-demo"
securityGroupSelectorTerms:
- tags:
kubernetes.io/cluster/automode-cluster: owned
tags:
karpenter.sh/discovery: "automode-demo"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: graviton-nodepool
spec:
template:
spec:
nodeClassRef:
group: eks.amazonaws.com
kind: NodeClass
name: graviton-nodeclass
requirements:
- key: "eks.amazonaws.com/instance-category"
operator: In
values: ["c", "m", "r"]
- key: "eks.amazonaws.com/instance-cpu"
operator: In
values: ["4", "8", "16", "32"]
- key: "kubernetes.io/arch"
operator: In
values: ["arm64"]
taints:
- key: "arm64"
value: "true"
effect: "NoSchedule" # Prevents non-ARM64 pods from scheduling
limits:
cpu: 1000
disruption:
consolidationPolicy: WhenEmpty
consolidateAfter: 30s
#
kubectl get NodeClass
NAME ROLE READY AGE
default automode-cluster-eks-auto-20250314121820950800000003 True 64m
graviton-nodeclass automode-cluster-eks-auto-20250314121820950800000003 True 3m4s
kubectl get NodePool
NAME NODECLASS NODES READY AGE
general-purpose default 0 True 64m
graviton-nodepool graviton-nodeclass 0 True 3m32s
deployment 배포 - 2048 game
kubectl apply -f ../examples/graviton/game-2048.yaml
c7gd.xlarge의 스팟 인스턴스가 선택된 것을 확인할 수 있습니다.

'AWS > EKS' 카테고리의 다른 글
AWS EKS 업그레이드, In-place부터 Blue/Green 마이그레이션까지 (1) | 2025.04.02 |
---|---|
EKS Karpenter 기본 사용(Node AutoScaling) (1) | 2025.03.05 |
EKS 기본 스토리지(EBS + EFS CSI Driver, Instance Store) (0) | 2025.02.23 |
EKS 기본 네트워크(AWS VPC CNI + AWS LoadBalancer Controller) (0) | 2025.02.16 |
EKS 설치 및 클러스터 엔드포인트(EKS Cluster Endpoint) (2) | 2025.02.09 |
Fargate
Fargate란?
EKS Fargate는 AWS에서 제공하는 서버리스 Kubernetes 컴퓨팅 서비스입니다. 일반 EKS는 컨트롤 플레인만 AWS가 관리하지만, Fargate는 데이터 플레인까지 관리해 주므로 인프라 걱정 없이 애플리케이션 개발에 집중할 수 있습니다.

하지만, AWS에서 데이터플레인까지 관리하는 영역이 넓어진 만큼, 여러 가지 제약사항과 고려사항이 존재합니다.
- CPU와 메모리는 정해진 단위(예: 0.25, 0.5, 1.0 vCPU 및 512MB, 1GB 등)로만 할당할 수 있습니다.
- 데몬 셋은 Fargate에서 지원하지 않습니다.
- 특권 컨테이너(Privileged containers)가 지원되지 않습니다.
- HostPort 또는 HostNetwork를 지정할 수 없습니다
- Fargate는 GPU를 사용할 수 없습니다.
- Fargate Spot을 지원하지 않습니다.
이러한 특징으로 보아 Fargate는 단기간 또는 일시적인 유형의 워크로드에 적합할 것 같습니다.
Firecracker
Firecracker는 AWS가 개발한 오픈소스 가상화 기술로, 서버리스 컴퓨팅을 위해 설계된 경량화된 MicroVM을 제공합니다.
Firecracker는 여러 수준(Layer)의 격리와 보호를 사용하기 떄문에 거의 완벽한 보안을 자랑합니다. 또한 경량화된 설계로 1초도 되지 않는 시간 안에 경량 microVM(마이크로 가상 머신)을 시작할 수 있기 때문에 리소스를 효율적으로 사용할 수 있습니다.

Fargate에서 파드를 생성하면 Firecracker를 통해 MicroVM(노드)이 생성되고, 각 파드는 이 MicroVM에 스케줄링됩니다. 이 구조는 VM 수준의 격리를 제공하므로, 파드가 보안 침해를 당하더라도 해당 파드가 실행 중인 노드는 보안적으로 완벽하게 격리되어 있어 추가적인 위험을 방지합니다.

MicroVM 마다 Kubelet, Kube-proxy, Containerd가 동작하기 때문에, 256 RAM 반드시 필요하다고 합니다.
Fargate 배포하기(Terraform)
Terraform blueprints를 통해서 fargate eks 배포합니다.
Fargate를 배포하는 테라폼 코드를 클론 받습니다.
git clone https://github.com/aws-ia/terraform-aws-eks-blueprints
tree terraform-aws-eks-blueprints/patterns
cd terraform-aws-eks-blueprints/patterns/fargate-serverless
main.tf 수정 : 실습 편리를 위해 Sample App을 배포하는 부분을 삭제합니다.
provider "aws" {
region = local.region
}
provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}
provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}
}
data "aws_availability_zones" "available" {
# Do not include local zones
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
locals {
name = basename(path.cwd)
region = "ap-northeast-2"
vpc_cidr = "10.10.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Blueprint = local.name
GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints"
}
}
################################################################################
# Cluster
################################################################################
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.11"
cluster_name = local.name
cluster_version = "1.30"
cluster_endpoint_public_access = true
# Give the Terraform identity admin access to the cluster
# which will allow resources to be deployed into the cluster
enable_cluster_creator_admin_permissions = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
# Fargate profiles use the cluster primary security group so these are not utilized
create_cluster_security_group = false
create_node_security_group = false
fargate_profiles = {
study_wildcard = {
selectors = [
{ namespace = "study-*" }
]
}
kube_system = {
name = "kube-system"
selectors = [
{ namespace = "kube-system" }
]
}
}
fargate_profile_defaults = {
iam_role_additional_policies = {
additional = module.eks_blueprints_addons.fargate_fluentbit.iam_policy[0].arn
}
}
tags = local.tags
}
################################################################################
# EKS Blueprints Addons
################################################################################
module "eks_blueprints_addons" {
source = "aws-ia/eks-blueprints-addons/aws"
version = "~> 1.16"
cluster_name = module.eks.cluster_name
cluster_endpoint = module.eks.cluster_endpoint
cluster_version = module.eks.cluster_version
oidc_provider_arn = module.eks.oidc_provider_arn
# We want to wait for the Fargate profiles to be deployed first
create_delay_dependencies = [for prof in module.eks.fargate_profiles : prof.fargate_profile_arn]
# EKS Add-ons
eks_addons = {
coredns = {
configuration_values = jsonencode({
computeType = "Fargate"
# Ensure that the we fully utilize the minimum amount of resources that are supplied by
# Fargate https://docs.aws.amazon.com/eks/latest/userguide/fargate-pod-configuration.html
# Fargate adds 256 MB to each pod's memory reservation for the required Kubernetes
# components (kubelet, kube-proxy, and containerd). Fargate rounds up to the following
# compute configuration that most closely matches the sum of vCPU and memory requests in
# order to ensure pods always have the resources that they need to run.
resources = {
limits = {
cpu = "0.25"
# We are targeting the smallest Task size of 512Mb, so we subtract 256Mb from the
# request/limit to ensure we can fit within that task
memory = "256M"
}
requests = {
cpu = "0.25"
# We are targeting the smallest Task size of 512Mb, so we subtract 256Mb from the
# request/limit to ensure we can fit within that task
memory = "256M"
}
}
})
}
vpc-cni = {}
kube-proxy = {}
}
# Enable Fargate logging this may generate a large ammount of logs, disable it if not explicitly required
enable_fargate_fluentbit = true
fargate_fluentbit = {
flb_log_cw = true
}
enable_aws_load_balancer_controller = true
aws_load_balancer_controller = {
set = [
{
name = "vpcId"
value = module.vpc.vpc_id
},
{
name = "podDisruptionBudget.maxUnavailable"
value = 1
},
]
}
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
tags = local.tags
}
테라폼을 배포합니다. Terraform을 실행하는 호스트에서 AWS 자격증명이 설정되어 있어야 합니다.
# init 초기화
terraform init
tree .terraform
cat .terraform/modules/modules.json | jq
tree .terraform/providers/registry.terraform.io/hashicorp -L 2
# plan
terraform plan
terraform apply -auto-approve
Fargate 클러스터 정보 확인
일반 EKS와 달리, 파드가 노드와 1:1로 매핑되어 있습니다. (노드의 IP와 파드의 개수가 동일)

일정한 리소스 사용량을 확인할 수 있습니다.

fargate가 사용하는 스케줄러를 확인할 수 있습니다.
kubectl get pod -n kube-system -l k8s-app=kube-dns -o yaml

AWS 콘솔 확인
EC2 인스턴스가 존재하지 않음.

네트워크 인터페이스의 소유자, 요청자, 인스턴스 소유자가 다름

새로운 파드 배포 시, schedulerName이 다른 경우는 왜 그럴까? -> admission control이 동작했음을 알 수 있음.

Fargate 워크로드 배포하기
fargate에 netshoot 디플로이먼트(파드) 배포
파드 배포 시, 노드가 프로비저닝 되면서 스케줄링이 이루어지므로 일반 클러스터보다는 속도가 느려집니다.

노드가 프로비저닝 되는 이벤트 로그를 확인할 수 있습니다.
kubectl get events -w --sort-by '.lastTimestamp'
31m Normal Starting node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Starting kubelet.
31m Warning InvalidDiskCapacity node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal invalid capacity 0 on image filesystem
31m Normal RegisteredNode node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Node fargate-ip-10-10-40-197.ap-northeast-2.compute.internal event: Registered Node fargate-ip-10-10-40-197.ap-northeast-2.compute.internal in Controller
31m Normal NodeReady node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Node fargate-ip-10-10-40-197.ap-northeast-2.compute.internal status is now: NodeReady
31m Normal Synced node/fargate-ip-10-10-40-197.ap-northeast-2.compute.internal Node synced successfully
11m Warning InvalidDiskCapacity node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal invalid capacity 0 on image filesystem
11m Normal Starting node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Starting kubelet.
11m Normal NodeReady node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeReady
11m Normal Synced node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node synced successfully
11m Normal NodeAllocatableEnforced node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Updated Node Allocatable limit across pods
11m Normal NodeHasSufficientPID node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeHasSufficientPID
11m Normal NodeHasNoDiskPressure node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeHasNoDiskPressure
11m Normal NodeHasSufficientMemory node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal status is now: NodeHasSufficientMemory
11m Normal RegisteredNode node/fargate-ip-10-10-45-95.ap-northeast-2.compute.internal Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal event: Registered Node fargate-ip-10-10-45-95.ap-northeast-2.compute.internal in Controller
2m35s Normal NodeHasNoDiskPressure node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeHasNoDiskPressure
2m35s Normal NodeHasSufficientMemory node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeHasSufficientMemory
2m35s Normal NodeReady node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeReady
2m35s Normal Synced node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node synced successfully
2m35s Normal NodeAllocatableEnforced node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Updated Node Allocatable limit across pods
2m35s Normal Starting node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Starting kubelet.
2m35s Warning InvalidDiskCapacity node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal invalid capacity 0 on image filesystem
2m35s Normal NodeHasSufficientPID node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal status is now: NodeHasSufficientPID
2m31s Normal RegisteredNode node/fargate-ip-10-10-20-15.ap-northeast-2.compute.internal Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal event: Registered Node fargate-ip-10-10-20-15.ap-northeast-2.compute.internal in Controller
# 메모리 할당 확인
kubectl get pod -n study-aews -o jsonpath='{.items[0].metadata.annotations.CapacityProvisioned}'
0.5vCPU 1GB
AWS ALB(Ingress)
Fargate에서 AWS ALB(Ingress)를 사용하여 애플리케이션에 대한 외부 접근을 관리합니다.
# 게임 디플로이먼트와 Service, Ingress 배포
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: study-aews
name: deployment-2048
spec:
selector:
matchLabels:
app.kubernetes.io/name: app-2048
replicas: 2
template:
metadata:
labels:
app.kubernetes.io/name: app-2048
spec:
containers:
- image: public.ecr.aws/l6m2t8p7/docker-2048:latest
imagePullPolicy: Always
name: app-2048
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: study-aews
name: service-2048
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
selector:
app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: study-aews
name: ingress-2048
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-2048
port:
number: 80
EOF
파드 권한과 호스트 네임스페이스 공유로 호스트 탈취 시도
Fargate가 아닌 권한이 충분한 환경에서는 아래와 같이 호스트 네임스페이스에 접근할 수 있지만, Fargate에서는 실패합니다.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: root-shell
namespace: study-aews
spec:
containers:
- command:
- /bin/cat
image: alpine:3
name: root-shell
securityContext:
privileged: true
tty: true
stdin: true
volumeMounts:
- mountPath: /host
name: hostroot
hostNetwork: true
hostPID: true
hostIPC: true
tolerations:
- effect: NoSchedule
operator: Exists
- effect: NoExecute
operator: Exists
volumes:
- hostPath:
path: /
name: hostroot
EOF
kubectl get pod -n study-aews root-shell
kubectl describe pod -n study-aews root-shell | grep Events: -A 10
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 95s fargate-scheduler Pod not supported on Fargate: fields not supported: HostNetwork, HostPID, HostIPC, volumes not supported: hostroot is of an unsupported volume Type, invalid SecurityContext fields: Privileged
Fargate Logging
Fargate의 Amazon EKS는 Fluent Bit 기반의 내장 로그 라우터를 제공합니다. 즉, 사용자가 Fluent Bit 컨테이너를 사이드카로 명시적으로 실행할 필요 없이 Amazon에서 자동으로 실행됩니다. 로그 라우터를 구성하기만 하면 됩니다.
로그를 발생시킬 nginx 배포하여 faragte logging을 확인해 보도록 합니다.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app
namespace: study-aews
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
name: http
resources:
requests:
cpu: 500m
memory: 500Mi
limits:
cpu: 2
memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: sample-app
namespace: study-aews
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
EOF
# 확인
kubectl get pod -n study-aews -l app=nginx
kubectl describe pod -n study-aews -l app=nginx
해당 nginx로 반복 접속하여 로그를 발생시킵니다.
# 반복 접속
kubectl exec -it deploy/netshoot -n study-aews -- curl sample-app | grep title
while true; do kubectl exec -it deploy/netshoot -n study-aews -- curl sample-app | grep title; sleep 1; echo ; date; done;
# 로그 확인
kubectl stern -n study-aews -l app=nginx
ConfigMap을 통해 Fargate의 Amazon EKS가 자동으로 이를 감지하고 로그 라우터를 구성합니다.
kubectl get cm -n aws-observability
kubectl get cm -n aws-observability aws-logging -o yaml
data:
filters.conf: |
[FILTER]
Name parser
Match *
Key_name log
Parser crio
[FILTER]
Name kubernetes
Match kube.*
Merge_Log On
Keep_Log Off
Buffer_Size 0
Kube_Meta_Cache_TTL 300s
flb_log_cw: "true" # Ships Fluent Bit process logs to CloudWatch.
output.conf: |+
[OUTPUT]
Name cloudwatch
Match kube.*
region ap-northeast-2
log_group_name /fargate-serverless/fargate-fluentbit-logs2025031600585521800000000c
log_stream_prefix fargate-logs-
auto_create_group true
[OUTPUT]
Name cloudwatch_logs
Match *
region ap-northeast-2
log_group_name /fargate-serverless/fargate-fluentbit-logs2025031600585521800000000c
log_stream_prefix fargate-logs-fluent-bit-
auto_create_group true
parsers.conf: |
[PARSER]
Name crio
Format Regex
Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>P|F) (?<log>.*)$
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
Time_Keep On
수집된 파드 로그를 확인하려면, CloudWatch Log Streams에서 nginx로 검색 필터링을 하고, Fluent Bit 로그도 포함되었는지 체크한 후, First event time 중 가장 최근의 항목을 클릭합니다.

해당 로그 스트림 화면에서 아래와 같이 상세 로그 정보를 확인하여 curl 접속 로그를 확인합니다.

EKS Auto Mode
EKS Auto Mode란?
최근 출시된 EKS AutoMode는 Fargate와 같이 컨트롤플레인 및 데이터플레인뿐만이 아니라, 클러스터를 운영하면서 사용되는 Addon과 같은 AWS의 리소스까지도 관리해 주는 완전체형 AWS 서비스라고 할 수 있습니다.

Auto Mode는 특징은 다음과 같습니다.
- EKS Auto Mode에서 생성된 EC2 인스턴스는 다른 EC2 인스턴스와 다르며 관리되는 인스턴스입니다. 이러한 관리되는 인스턴스는 EKS가 소유하고 있으며 더 제한적입니다.
- 노드에 대해 불변으로 취급되는 AMI를 사용(bottle rocket) 합니다.
- EKS Auto Mode에서 관리하는 인스턴스 SSH 또는 SSM 액세스를 허용하지 않음으로써 노드에 대한 직접 액세스를 방지합니다.
그 중 가장 큰 특징은 아래 6가지 구성요소가 파드로 구성되는 것이 아니고, 해당 노드의 sysemd 데몬(agent)으로 실행됩니다.
- kube-proxy, kubelet, eks-pod-identity-agent, eks-node-monitor-agent, eks-healthcheck, eks-ebs-csi-driver,
- csi-node-driver-registrar, coredns, containerd, aws-network-policy-agent, apiserver, ipam

EKS Auto Mode 배포하기(Terraform)
테라폼 코드 클론 : aws에서 제공하는 auto-mode 샘플 레포지토리를 클론 합니다.
git clone https://github.com/aws-samples/sample-aws-eks-auto-mode.git
cd sample-aws-eks-auto-mode/terraform
variables.tf 수정 : 환경에 맞는 변수로 수정합니다
variable "name" {
description = "Name of the VPC and EKS Cluster"
default = "automode-cluster"
type = string
}
variable "region" {
description = "region"
default = "ap-northeast-2"
type = string
}
variable "eks_cluster_version" {
description = "EKS Cluster version"
default = "1.31"
type = string
}
# VPC with 65536 IPs (10.0.0.0/16) for 3 AZs
variable "vpc_cidr" {
description = "VPC CIDR. This should be a valid private (RFC 1918) CIDR range"
default = "10.20.0.0/16"
type = string
}
테라폼 코드 배포
# Get the code : 배포 코드에 addon 내용이 읍다!
git clone https://github.com/aws-samples/sample-aws-eks-auto-mode.git
cd sample-aws-eks-auto-mode/terraform
# eks.tf : "system" 은 '전용인스턴스'로 추가하지 않는다
...
cluster_compute_config = {
enabled = true
node_pools = ["general-purpose"]
}
...
# Initialize and apply Terraform
terraform init
terraform plan
terraform apply -auto-approve
클러스터 확인
배포된 클러스터의 리소스를 확인해 보면 놀랍게도 아무것도 조회되지 않음을 확인할 수 있습니다. kube-system이나 addon과 같은 핵심 컴포넌트를 aws에서 데몬을 통해 관리가 되기 때문입니다.

카펜터를 통해 노드를 관리하기 때문에 관련 crd들이 존재합니다. 또한 AutoMode는 노드에 접근할 수 없기 때문에 NodeDiagnostic과 같은 CRD를 통해 노드의 상태를 관리할 수 있는 기능들도 제공하는 것 같습니다.

AWS 관리 콘솔에서 확인
네트워크 인터페이스 확인

EKS 확인

EKS에는 Addon이 존재하지 않음을 확인

EKS Auto Mode 워크로드 배포하기
파드 생성 시, pending 상태이지만, Karpenter에 의해 노드가 프로비저닝 되면 파드가 스케줄링되는 것을 확인할 수 있다.

karpenter 동작 확인
Karpenter 동작 확인을 위해 아래와 같이 inflate Deployment 배포합니다. eks.amazonaws.com/compute-type: auto 노드 선택기를 사용하여 Karpenter가 자동으로 프로비저닝 한 노드에서 실행되도록 합니다.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 1
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
nodeSelector:
eks.amazonaws.com/compute-type: auto
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 1
securityContext:
allowPrivilegeEscalation: false
EOF
# Step 3: Watch Kubernetes Events
kubectl get events -w --sort-by '.lastTimestamp'
kubectl get nodes
infate 디플로이먼트의 레플리카를 100개까지 증가시키면, 필요한 리스소의 스펙에 맞게 노드가 프로비저닝 되는 것을 확인할 수 있다.


Graviton Workloads 배포
Graviton(arm 프로세스) 노드 인스턴스에 2048 game 애플리케이션을 배포하는 실습을 진행합니다.
Graviton Workloads를 위해 커스텀 NodeClass와 NodePool을 사용하여 설정합니다.
kubectl apply -f ../nodepools/graviton-nodepool.yaml
---
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
name: graviton-nodeclass
spec:
role: automode-cluster-eks-auto-20250314121820950800000003
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "automode-demo"
securityGroupSelectorTerms:
- tags:
kubernetes.io/cluster/automode-cluster: owned
tags:
karpenter.sh/discovery: "automode-demo"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: graviton-nodepool
spec:
template:
spec:
nodeClassRef:
group: eks.amazonaws.com
kind: NodeClass
name: graviton-nodeclass
requirements:
- key: "eks.amazonaws.com/instance-category"
operator: In
values: ["c", "m", "r"]
- key: "eks.amazonaws.com/instance-cpu"
operator: In
values: ["4", "8", "16", "32"]
- key: "kubernetes.io/arch"
operator: In
values: ["arm64"]
taints:
- key: "arm64"
value: "true"
effect: "NoSchedule" # Prevents non-ARM64 pods from scheduling
limits:
cpu: 1000
disruption:
consolidationPolicy: WhenEmpty
consolidateAfter: 30s
#
kubectl get NodeClass
NAME ROLE READY AGE
default automode-cluster-eks-auto-20250314121820950800000003 True 64m
graviton-nodeclass automode-cluster-eks-auto-20250314121820950800000003 True 3m4s
kubectl get NodePool
NAME NODECLASS NODES READY AGE
general-purpose default 0 True 64m
graviton-nodepool graviton-nodeclass 0 True 3m32s
deployment 배포 - 2048 game
kubectl apply -f ../examples/graviton/game-2048.yaml
c7gd.xlarge의 스팟 인스턴스가 선택된 것을 확인할 수 있습니다.

'AWS > EKS' 카테고리의 다른 글
AWS EKS 업그레이드, In-place부터 Blue/Green 마이그레이션까지 (1) | 2025.04.02 |
---|---|
EKS Karpenter 기본 사용(Node AutoScaling) (1) | 2025.03.05 |
EKS 기본 스토리지(EBS + EFS CSI Driver, Instance Store) (0) | 2025.02.23 |
EKS 기본 네트워크(AWS VPC CNI + AWS LoadBalancer Controller) (0) | 2025.02.16 |
EKS 설치 및 클러스터 엔드포인트(EKS Cluster Endpoint) (2) | 2025.02.09 |