[AWS EKS] EKS Mode/Nodes 2 - Auto Mode

주영·2025년 3월 21일
0

AWS EKS Workshop Study 3기

목록 보기
26/31

이 글은 CloudNet@팀의 AWS EKS Workshop Study(AEWS) 3기 스터디 내용을 바탕으로 작성되었습니다.
AEWS는 CloudNet@의 '가시다'님께서 진행하는 스터디로, EKS를 학습하는 과정입니다.
EKS를 깊이 있게 이해할 기회를 주시고, 소중한 지식을 나눠주시는 가시다님께 다시 한번 감사드립니다.
이 글이 EKS를 학습하는 분들께 도움이 되길 바랍니다.

1. EKS Auto Mode 기반 클러스터 배포 및 구성 확인 실습

이 실습은 AWS에서 제공하는 EKS Auto Mode 샘플 레포지토리를 사용하여 Terraform을 통해 Auto Mode 기반의 EKS 클러스터를 배포하는 과정입니다.
기존 EC2 또는 Fargate 기반과는 다르게, Auto Mode는 노드 구성/운영 자동화, Karpenter 기반 동적 노드 생성, 세분화된 정책 관리 등의 특성을 지닙니다.

1.1 Terraform 구성 및 클러스터 배포

1.1.1 Terraform 코드 준비

# Get the code
git clone https://github.com/aws-samples/sample-aws-eks-auto-mode.git
cd sample-aws-eks-auto-mode/terraform

1.1.2 variables.tf 수정

region ap-northeast-2, vpc_cidr 10.20.0.0/16 로 변경합니다.

...
variable "region" {
  description = "region"
  default     = "ap-northeast-2" 
  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
}

1.1.3 eks.tf 구성 확인

# eks.tf : "system" 은 '전용인스턴스'로 추가하지 않는다
...
  cluster_compute_config = {
    enabled    = true
    node_pools = ["general-purpose"]
  }
...
  • system 노드는 생성하지 않고, general-purpose NodePool만 사용
  • 별도의 addons 구성은 포함되어 있지 않음(Auto Mode가 관리하기 때문)

1.1.4 Terraform 명령 실행

# Initialize and apply Terraform
terraform init
terraform plan
terraform apply -auto-approve
...
null_resource.create_nodepools_dir: Creating...
null_resource.create_nodepools_dir: Provisioning with 'local-exec'...
null_resource.create_nodepools_dir (local-exec): Executing: ["/bin/sh" "-c" "mkdir -p ./../nodepools"]
...
  • null_resource.create_nodepools_dir 작업에서 ../nodepools 디렉토리가 생성됨
  • 클러스터 및 관련 리소스가 완전 자동화로 생성됨

1.2 kubectl 설정 및 클러스터 확인

# Configure kubectl
cat setup.tf
ls -l ../nodepools
$(terraform output -raw configure_kubectl)

# kubectl context 이름 변경
kubectl ctx
kubectl config rename-context "arn:aws:eks:ap-northeast-2:$(aws sts get-caller-identity --query 'Account' --output text):cluster/automode-cluster" "automode-lab"
kubectl ns default

# 아래 IP의 ENI 찾아보자
kubectl get svc,ep 
# 출력 예시
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   27m

NAME                   ENDPOINTS                           AGE
endpoints/kubernetes   10.20.22.204:443,10.20.40.216:443   27m

#
terraform state list
terraform show
terraform state show 'module.eks.aws_eks_cluster.this[0]'
# 출력 예시
...
    compute_config {
        enabled       = true
        node_pools    = [
            "general-purpose",
        ]
        node_role_arn = "arn:aws:iam::911283464785:role/automode-cluster-eks-auto-20250316042752605600000003"
    }
...
  • 클러스터 IP: 172.20.0.1
  • EKS가 자동으로 생성한 ENI IP 확인: 10.20.26.9, 10.20.6.61

=> 노드와 파드에 아무것도 뜨지 않습니다.

1.3 AWS 콘솔에서 리소스 확인

1.3.1 EC2 콘솔

  • ENI가 EKS에 의해 생성된 EKS-Owned 유형임을 확인 가능

1.3.2 EKS 콘솔

  • IAM Roles: Cluster Role, Node Role 확인
  • Compute: general-purpose NodePool 구성 확인
  • Add-ons: 없음 (기본 설정에 포함되지 않음)
  • Access: IAM Access Entries 확인 가능

1.4 EKS Auto Mode 리소스(CRD) 확인

kubectl get crd
# 출력 예시
NAME                                         CREATED AT
cninodes.eks.amazonaws.com                   2025-03-14T12:27:23Z
cninodes.vpcresources.k8s.aws                2025-03-14T12:23:31Z
ingressclassparams.eks.amazonaws.com         2025-03-14T12:27:23Z
nodeclaims.karpenter.sh                      2025-03-14T12:27:23Z
nodeclasses.eks.amazonaws.com                2025-03-14T12:27:23Z
nodediagnostics.eks.amazonaws.com            2025-03-14T12:27:23Z
nodepools.karpenter.sh                       2025-03-14T12:27:23Z
policyendpoints.networking.k8s.aws           2025-03-14T12:23:31Z
securitygrouppolicies.vpcresources.k8s.aws   2025-03-14T12:23:31Z
targetgroupbindings.eks.amazonaws.com        2025-03-14T12:27:23Z

kubectl api-resources | grep -i node
# 출력 예시
nodes                               no           v1                                false        Node
cninodes                            cni,cnis     eks.amazonaws.com/v1alpha1        false        CNINode
nodeclasses                                      eks.amazonaws.com/v1              false        NodeClass
nodediagnostics                                  eks.amazonaws.com/v1alpha1        false        NodeDiagnostic
nodeclaims                                       karpenter.sh/v1                   false        NodeClaim
nodepools                                        karpenter.sh/v1                   false        NodePool
runtimeclasses                                   node.k8s.io/v1                    false        RuntimeClass
csinodes                                         storage.k8s.io/v1                 false        CSINode
cninodes                            cnd          vpcresources.k8s.aws/v1alpha1     false        CNINode

# 노드에 Access가 불가능하니, 분석 지원(CRD)제공
kubectl explain nodediagnostics
# 출력 예시
GROUP:      eks.amazonaws.com
KIND:       NodeDiagnostic
VERSION:    v1alpha1

DESCRIPTION:
    The name of the NodeDiagnostic resource is meant to match the name of the
    node which should perform the diagnostic tasks
  • NodeDiagnostics는 노드에 SSH 접근이 불가한 Auto Mode 환경에서 분석을 지원함

1.5 Auto Mode 구성 리소스 확인

kubectl get nodeclasses.eks.amazonaws.com
NAME      ROLE                                                   READY   AGE
default   automode-cluster-eks-auto-20250314121820950800000003   True    29m

kubectl get nodeclasses.eks.amazonaws.com -o yaml
...
  spec:
    ephemeralStorage:
      iops: 3000
      size: 80Gi
      throughput: 125
    networkPolicy: DefaultAllow
    networkPolicyEventLogs: Disabled
    role: automode-cluster-eks-auto-20250314121820950800000003
    securityGroupSelectorTerms:
    - id: sg-05d210218e5817fa1
    snatPolicy: Random # ???
    subnetSelectorTerms:
    - id: subnet-0539269140458ced5
    - id: subnet-055dc112cdd434066
    - id: subnet-0865f60e4a6d8ad5c
  status:
    ...
    instanceProfile: eks-ap-northeast-2-automode-cluster-4905473370491687283
    securityGroups:
    - id: sg-05d210218e5817fa1
      name: eks-cluster-sg-automode-cluster-2065126657
    subnets:
    - id: subnet-0539269140458ced5
      zone: ap-northeast-2a
      zoneID: apne2-az1
    - id: subnet-055dc112cdd434066
      zone: ap-northeast-2b
      zoneID: apne2-az2
    - id: subnet-0865f60e4a6d8ad5c
      zone: ap-northeast-2c
      zoneID: apne2-az3

#
kubectl get nodepools
NAME              NODECLASS   NODES   READY   AGE
general-purpose   default     0       True    33m

kubectl get nodepools -o yaml
...
  spec:
    disruption:
      budgets:
      - nodes: 10%
      consolidateAfter: 30s
      consolidationPolicy: WhenEmptyOrUnderutilized
    template:
      metadata: {}
      spec:
        expireAfter: 336h # 14일
        nodeClassRef:
          group: eks.amazonaws.com
          kind: NodeClass
          name: default
        requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values:
          - on-demand
        - key: eks.amazonaws.com/instance-category
          operator: In
          values:
          - c
          - m
          - r
        - key: eks.amazonaws.com/instance-generation
          operator: Gt
          values:
          - "4"
        - key: kubernetes.io/arch
          operator: In
          values:
          - amd64
        - key: kubernetes.io/os
          operator: In
          values:
          - linux
        terminationGracePeriod: 24h0m0s
...

1.6 Webhook 구성 확인

kubectl get mutatingwebhookconfiguration
kubectl get validatingwebhookconfiguration
  • Auto Mode에서 리소스 변형 및 검증을 위한 Webhook 구성 여부 확인 가능

2. kube-ops-view 설치

2.1 모니터링

eks-node-viewer --node-sort=eks-node-viewer/node-cpu-usage=dsc --extra-labels eks-node-viewer/node-age
watch -d kubectl get node,pod -A

2.2 kube-ops-view 설치 (Helm Chart 사용)

helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl get events -w --sort-by '.lastTimestamp' # 출력 이벤트 로그 분석해보자

2.3 노드 및 자원 정보 확인

# 확인
kubectl get nodeclaims
NAME                      TYPE         CAPACITY    ZONE              NODE                  READY   AGE
general-purpose-528mt     c5a.large    on-demand   ap-northeast-2c   i-09cf206aee76f0bee   True    54s

# OS, KERNEL, CRI 확인
kubectl get node -owide
NAME                  STATUS   ROLES    AGE     VERSION               INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                                          KERNEL-VERSION   CONTAINER-RUNTIME
i-09cf206aee76f0bee   Ready    <none>   2m14s   v1.31.4-eks-0f56d01   10.20.44.40    <none>        Bottlerocket (EKS Auto) 2025.3.9 (aws-k8s-1.31)   6.1.129          containerd://1.7.25+bottlerocket

# CNI 노드 확인
kubectl get cninodes.eks.amazonaws.com   
NAME                  AGE
i-09cf206aee76f0bee   3m24s

2.4. 웹 UI 접속을 위한 포트 포워딩

#[신규 터미널] 포트 포워딩
kubectl port-forward deployment/kube-ops-view -n kube-system 8080:8080 &

2.5 웹 UI 접속

# 접속 주소 확인 : 각각 1배, 1.5배, 3배 크기
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080"
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080/#scale=1.5"
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080/#scale=3"

open "http://127.0.0.1:8080/#scale=1.5" # macOS

2.6 AWS 콘솔에서 EC2 확인

  • kube-ops-view로 표시되는 노드는 EC2 인스턴스로 자동 생성된 EKS Auto Mode 노드이며, 콘솔의 EC2 > 인스턴스 목록에서 확인 가능합니다.
  • 일반적으로 노드 이름은 i-로 시작하는 EC2 Instance ID 형식이며, Karpenter가 생성한 NodeClaim과 일치합니다.

3. Karpenter 기반 EKS Auto Mode 노드 자동 생성 동작 확인

Amazon EKS Auto Mode 클러스터에서 Karpenter의 동작 방식인 Workload 기반 자동 노드 프로비저닝 기능을 확인하기 위한 것입니다. Deployment를 통해 리소스를 요청하면, Karpenter는 Auto Mode 노드를 자동으로 생성하여 스케줄링할 수 있도록 처리합니다.

3.1 기존 NodePool 존재 여부 확인

# Step 1: Review existing compute resources (optional)
kubectl get nodepools
general-purpose
  • Auto Mode에서는 최소 하나 이상의 NodePool이 존재해야 Karpenter가 요청에 따라 노드를 생성할 수 있습니다.

3.2 테스트 애플리케이션 배포

# Step 2: Deploy a sample application to the cluster
# eks.amazonaws.com/compute-type: auto selector requires the workload be deployed on an Amazon EKS Auto Mode node.
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

3.3 이벤트 및 노드 생성 확인

# Step 3: Watch Kubernetes Events
kubectl get events -w --sort-by '.lastTimestamp'
kubectl get nodes

3.4 대규모 스케일링 테스트

kubectl scale deployment inflate --replicas 100 && kubectl get events -w --sort-by '.lastTimestamp'

# 
kubectl scale deployment inflate --replicas 200 && kubectl get events -w --sort-by '.lastTimestamp'

#
kubectl scale deployment inflate --replicas 50 && kubectl get events -w --sort-by '.lastTimestamp'

3.5 모니터링 도구 활용

eks-node-viewer --node-sort=eks-node-viewer/node-cpu-usage=dsc --extra-labels eks-node-viewer/node-age
watch -d kubectl get node,pod -A

3.6 관련 이슈: Pod Eviction 및 포트포워딩 주의

만약 kube-ops-view 파드가 함께 실행 중이라면, 자원 부족 시 Eviction 대상이 될 수 있습니다.

포워딩 중이던 포트 연결이 끊기는 경우 다시 실행 필요:

kubectl port-forward deployment/kube-ops-view -n kube-system 8080:8080 &
  • 이러한 현상은 PodDisruptionBudget 또는 priorityClass를 미설정했을 때 발생할 수 있는 일반적인 문제이며, 실제 운영 환경에서는 이를 고려한 구성 설계가 필요합니다.

3.7 리소스 정리

실습 종료 후 Deployment를 삭제하여 노드 정리 이벤트 및 스케일 다운 여부를 확인합니다.

# 실습 확인 후 삭제
kubectl delete deployment inflate && kubectl get events -w --sort-by '.lastTimestamp'

0개의 댓글