문제 상황#

EKS 1.34 클러스터 구축 중 발생한 두 가지 주요 이슈와 해결 과정 정리.


1. Node Group 생성 실패 - kubelet 라벨 문제#

증상#

  • Node Group 상태: CREATE_FAILED
  • 에러 메시지: NodeCreationFailure - Unhealthy nodes in the kubernetes cluster
  • EC2 인스턴스는 실행 중이지만 클러스터에 조인 안 됨

원인 분석#

SSM으로 노드에 접속하여 kubelet 로그 확인:

sudo journalctl -u kubelet -n 50

kubelet 에러:

unknown 'kubernetes.io' or 'k8s.io' labels specified with --node-labels

근본 원인#

Terraform EKS 모듈에서 노드그룹 라벨에 node-role.kubernetes.io/infra 사용:

labels = {
  "node-role.kubernetes.io/infra" = "true"  # <- 이게 문제!
  "role" = "infra"
}

왜 문제인가?

  • kubelet은 kubernetes.io 또는 k8s.io 네임스페이스의 라벨을 노드 등록 시 사용하는 것을 금지함
  • 이는 보안상의 이유로, 해당 네임스페이스는 쿠버네티스 시스템이 관리하는 예약된 네임스페이스
  • 노드가 스스로 이 네임스페이스의 라벨을 설정하면 권한 상승 등의 보안 문제 발생 가능

해결#

node-role.kubernetes.io/* 라벨 제거:

# 수정된 코드
labels = {
  "arch"          = "amd64"
  "role"          = "infra"      # 일반 라벨 사용
  "capacity-type" = "on-demand"
  "workload"      = "infra"
  "owner"         = var.owner_name
}

영향받은 파일#

  • modules/eks/main.tf - monitoring, infra, apps 노드그룹 라벨
  • staging/charts/karpenter/templates/nodepool.yaml - Karpenter NodePool 라벨

2. Node NotReady - vpc-cni addon 누락#

증상#

  • 모든 노드가 NotReady 상태
  • kubectl describe node 에서:
    NetworkNotReady: network is not ready: container runtime network not ready
    NetworkPluginNotReady: cni plugin not initialized
    

원인 분석#

kube-system pods 확인:

kubectl get pods -n kube-system

aws-node (vpc-cni) pods가 없음!

addon 목록 확인:

aws eks list-addons --cluster-name goormgb-staging-eks --profile wonny

결과:

{
    "addons": ["aws-ebs-csi-driver"]  // vpc-cni, kube-proxy, coredns 없음!
}

근본 원인#

Terraform apply 과정에서 cluster_addons 블록의 addon들이 생성되지 않음.

cluster_addons = {
  vpc-cni = { most_recent = true }
  kube-proxy = { most_recent = true }
  coredns = { most_recent = true }
}

terraform state 확인 시:

terraform state list | grep addon
  • data.aws_eks_addon_version.this["vpc-cni"] - 버전 데이터만 존재
  • aws_eks_addon.this["vpc-cni"] - 실제 리소스 없음

해결#

EKS destroy 후 다시 apply:

terraform destroy -target=module.eks
terraform apply -target=module.eks

필수 EKS Addons#

Addon역할
vpc-cniPod 네트워킹 (ENI 할당) - 없으면 노드 NotReady
kube-proxyService 네트워킹 (iptables/ipvs)
corednsDNS 서비스
ebs-csi-driverEBS 볼륨 프로비저닝

추가 설정 - Addon Tolerations#

taint가 있는 노드에서 addon이 실행되려면 toleration 필요:

cluster_addons = {
  vpc-cni = {
    most_recent = true
    configuration_values = jsonencode({
      tolerations = [{
        key      = "role"
        operator = "Exists"
        effect   = "NoSchedule"
      }]
    })
  }
  coredns = {
    most_recent = true
    configuration_values = jsonencode({
      tolerations = [{
        key      = "role"
        operator = "Equal"
        value    = "infra"
        effect   = "NoSchedule"
      }]
      nodeSelector = {
        role = "infra"
      }
    })
  }
}

교훈#

  1. kubernetes.io 네임스페이스 라벨 금지: kubelet이 거부함. 일반 라벨(role, workload 등) 사용할 것.

  2. EKS Addon 확인 필수: aws eks list-addons로 필수 addon 존재 여부 확인.

  3. SSM 디버깅 활용: 노드 문제 시 SSM으로 접속하여 journalctl -u kubelet 확인.

  4. terraform state 확인: plan에서 보이는 것과 실제 생성된 것이 다를 수 있음.


참고 명령어#

# 노드 상태 확인
kubectl get nodes -w
kubectl describe node <node-name>

# Addon 확인
aws eks list-addons --cluster-name <cluster> --profile <profile>
aws eks describe-addon --cluster-name <cluster> --addon-name vpc-cni

# SSM 접속
aws ssm start-session --target <instance-id> --profile <profile>

# kubelet 로그
sudo journalctl -u kubelet -n 100

# EC2 콘솔 출력 (부팅 로그)
aws ec2 get-console-output --instance-id <id> --latest --output text

EKS Addons 완전 가이드#

Addon이란?#

EKS Addon은 쿠버네티스 클러스터의 핵심 운영 기능을 제공하는 소프트웨어 컴포넌트다. AWS가 관리하며, 버전 호환성 검증과 보안 패치가 자동으로 적용된다.

Addon 사용 장점:

  • AWS 관리형: 버전 업데이트, 보안 패치 자동화
  • EKS 버전 호환성 보장
  • IAM Role for Service Account (IRSA) 통합
  • 구성 값 커스터마이징 가능

필수 Addons (클러스터 동작에 반드시 필요)#

1. Amazon VPC CNI (vpc-cni)#

역할: Pod 네트워킹 담당. 각 Pod에 VPC의 실제 IP 주소를 할당.

동작 방식:

  • ENI(Elastic Network Interface)를 노드에 연결
  • ENI의 Secondary IP를 Pod에 할당
  • Pod가 VPC 내 다른 리소스와 직접 통신 가능

없으면?

  • 노드가 NotReady 상태 유지
  • Pod가 IP를 받지 못해 스케줄링 불가
  • 컨테이너 네트워크 초기화 실패

DaemonSet으로 배포: 모든 노드에서 aws-node Pod 실행

# 주요 설정
configuration_values:
  env:
    ENABLE_PREFIX_DELEGATION: "true"  # Pod 밀도 증가
    WARM_IP_TARGET: "5"               # 예약 IP 수
  tolerations:
    - operator: Exists                # 모든 노드에서 실행

2. CoreDNS (coredns)#

역할: 클러스터 내 DNS 서비스. Service 이름을 IP로 해석.

동작 방식:

  • kube-dns 서비스로 노출 (기본 ClusterIP: 10.100.0.10)
  • Pod의 /etc/resolv.conf가 이 DNS 서버 참조
  • Service 이름 → ClusterIP 해석
  • External 도메인은 upstream DNS로 포워딩

없으면?

  • curl http://my-service 같은 서비스 디스커버리 불가
  • Pod 간 통신 시 IP 직접 사용해야 함
  • 외부 도메인 해석도 불가 (설정에 따라)

Deployment로 배포: 보통 2개 replica (HA)

# 주요 설정
configuration_values:
  replicaCount: 2
  tolerations:
    - key: "role"
      value: "infra"
      effect: "NoSchedule"
  nodeSelector:
    role: infra

3. kube-proxy (kube-proxy)#

역할: Service 네트워킹 담당. Service ClusterIP → Pod IP 라우팅.

동작 방식:

  • 각 노드에서 iptables/ipvs 규칙 관리
  • Service의 ClusterIP로 들어온 트래픽을 backend Pod로 분산
  • NodePort, LoadBalancer 타입 Service도 처리

없으면?

  • ClusterIP Service 접근 불가
  • Service → Pod 로드밸런싱 안 됨
  • 네트워크 정책 일부 동작 안 함

DaemonSet으로 배포: 모든 노드에서 실행

# 주요 설정
configuration_values:
  mode: "iptables"  # 또는 "ipvs"
  tolerations:
    - operator: Exists

권장 Addons (운영에 필요)#

4. Amazon EBS CSI Driver (aws-ebs-csi-driver)#

역할: EBS 볼륨의 동적 프로비저닝. PersistentVolumeClaim → EBS 볼륨 자동 생성.

동작 방식:

  • CSI (Container Storage Interface) 표준 구현
  • StorageClass 기반 볼륨 프로비저닝
  • gp3, io1, io2 등 EBS 타입 지원
  • 스냅샷, 리사이즈 지원

없으면?

  • PVC 생성 시 볼륨 프로비저닝 안 됨 (Pending 상태)
  • StatefulSet 사용 불가
  • 데이터 영속성 확보 불가

구성:

  • Controller: Deployment (2 replica)
  • Node: DaemonSet (각 노드)
# 주요 설정
configuration_values:
  controller:
    tolerations:
      - key: "role"
        value: "infra"
        effect: "NoSchedule"
    nodeSelector:
      role: infra
  node:
    tolerations:
      - operator: Exists  # 모든 노드에서 실행

5. Amazon EFS CSI Driver (aws-efs-csi-driver)#

역할: EFS 파일시스템 마운트. 여러 Pod에서 동시에 읽기/쓰기 가능.

사용 사례:

  • 공유 파일 스토리지 (ReadWriteMany)
  • 컨테이너 간 파일 공유
  • 정적 콘텐츠 서빙

없으면?

  • EFS 마운트 불가
  • ReadWriteMany 볼륨 사용 불가

6. AWS Load Balancer Controller (별도 설치)#

역할: ALB/NLB 자동 프로비저닝. Ingress, Service(type: LoadBalancer) 처리.

주의: EKS Addon이 아닌 Helm Chart로 별도 설치 필요!

# Helm으로 설치
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=<cluster-name>

선택적 Addons#

7. Amazon CloudWatch Observability (amazon-cloudwatch-observability)#

역할: 컨테이너 메트릭, 로그를 CloudWatch로 전송.

구성 요소:

  • CloudWatch Agent: 메트릭 수집
  • Fluent Bit: 로그 수집
  • ADOT Collector: 트레이싱 (선택)

8. Amazon GuardDuty Agent (aws-guardduty-agent)#

역할: 런타임 위협 탐지. 컨테이너 이상 행동 모니터링.


9. AWS Distro for OpenTelemetry (adot)#

역할: 분산 트레이싱, 메트릭 수집. X-Ray, CloudWatch, Prometheus 등으로 전송.


10. Karpenter (별도 설치)#

역할: 노드 오토스케일링. Pending Pod 감지 → 최적 인스턴스 프로비저닝.

EKS Addon 아님! Helm으로 별도 설치:

helm install karpenter oci://public.ecr.aws/karpenter/karpenter \
  --namespace karpenter

Addon 관리 명령어#

# 사용 가능한 addon 목록
aws eks describe-addon-versions --kubernetes-version 1.34 \
  --query 'addons[].{name:addonName,versions:addonVersions[0].addonVersion}' \
  --output table

# 클러스터에 설치된 addon 목록
aws eks list-addons --cluster-name <cluster>

# addon 상세 정보
aws eks describe-addon --cluster-name <cluster> --addon-name vpc-cni

# addon 설치
aws eks create-addon --cluster-name <cluster> --addon-name vpc-cni

# addon 업데이트
aws eks update-addon --cluster-name <cluster> --addon-name vpc-cni \
  --addon-version v1.21.1-eksbuild.5

# addon 삭제
aws eks delete-addon --cluster-name <cluster> --addon-name vpc-cni

Terraform에서 Addon 설정#

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.0"

  cluster_addons = {
    # 필수
    vpc-cni = {
      most_recent = true
      configuration_values = jsonencode({
        tolerations = [{ operator = "Exists" }]
      })
    }
    kube-proxy = {
      most_recent = true
    }
    coredns = {
      most_recent = true
      configuration_values = jsonencode({
        tolerations = [{
          key    = "role"
          value  = "infra"
          effect = "NoSchedule"
        }]
      })
    }

    # 권장
    aws-ebs-csi-driver = {
      most_recent              = true
      service_account_role_arn = module.ebs_csi_irsa.iam_role_arn
    }
  }
}

Addon 버전 호환성 확인#

# 특정 K8s 버전에서 지원되는 addon 버전
aws eks describe-addon-versions \
  --addon-name vpc-cni \
  --kubernetes-version 1.34 \
  --query 'addons[].addonVersions[].addonVersion'

주의사항:

  • EKS 버전 업그레이드 전 addon 호환성 확인
  • most_recent = true 사용 시 자동으로 최신 호환 버전 선택
  • 프로덕션에서는 버전 고정 권장

Addon 문제 해결#

Addon이 Degraded 상태일 때:

# 상태 확인
aws eks describe-addon --cluster-name <cluster> --addon-name vpc-cni \
  --query 'addon.health'

# Pod 상태 확인
kubectl get pods -n kube-system -l k8s-app=aws-node
kubectl describe pod -n kube-system <aws-node-pod>

# 이벤트 확인
kubectl get events -n kube-system --sort-by='.lastTimestamp'

흔한 문제:

  1. IRSA 역할 권한 부족 → IAM 정책 확인
  2. toleration 없음 → 모든 노드에 taint가 있으면 실행 불가
  3. 리소스 부족 → requests/limits 조정
  4. 이미지 pull 실패 → ECR 권한 또는 네트워크 확인