Post

[AWS] 0206 EKS

로컬 상에서 aws cli를 연결 후, eks를 배포하는 과정이다.

아래와 같이 yml 파일을 만든 후 eksctl create cluster -f cluster.yaml 로 배포한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# eksctl 설정 파일 버전 정의
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

# 클러스터 기본 정보 설정
metadata:
  name: lee # 생성할 EKS 클러스터 이름 (태그와 일치해야 함)
  region: ap-south-1 # 클러스터가 생성될 리전 (도쿄)
  version: "1.31" # 쿠버네티스 제어 평면 버전(1.29 ~ 1.35 지원, 1.31 권장)

# 기존 VPC 및 서브넷 활용 설정
vpc:
  id: "vpc-00561de4a3e1d1392" # 사용자가 UI로 생성한 기존 VPC ID
  subnets:
    # 외부 로드밸런서가 위치할 퍼블릭 서브넷 (elb 태그 필요)
    public:
      ap-south-1a: { id: "subnet-0d518f598179a2d22" }
      ap-south-1b: { id: "subnet-0bc227ff840ad2463" }
      ap-south-1c: { id: "subnet-0a81640136d8b8813" }
    # 실제 워커 노드가 위치할 프라이빗 서브넷 (internal-elb 태그 필요)
    private:
      ap-south-1a: { id: "subnet-0f8a3782bc6771f2c" }
      ap-south-1b: { id: "subnet-079205a67b662960c" }
      ap-south-1c: { id: "subnet-00ded7e402f69ed65" }
  clusterEndpoints:
    publicAccess: true
    privateAccess: true
    # publicAccessCIDRs:
    #   - "210.xxx.xxx.xxx/32"
    #   - "1.2.3.4/32"

# 관리형 노드 그룹(Managed Node Group) 설정
managedNodeGroups:
  - name: lee-cluster-ng # 노드 그룹의 이름
    instanceType: t3.medium # 사용할 EC2 인스턴스 타입 (사양)
    minSize: 1 # 최소 1대 유지
    maxSize: 3 # 최대 3대까지 확장 가능
    # desiredCapacity: 2         # 초기 생성할 노드 개수
    desiredCapacity: 3
    volumeSize: 20 # 각 노드의 EBS(디스크) 크기 (GB)
    privateNetworking: true # 노드들을 외부 인터넷에 노출되지 않는 프라이빗 서브넷에 배치
    securityGroups:
      attachIDs: ["sg-0aba5e8b80e5e5b3b"] #  보안 그룹 ID
    iam:
      # 노드에 기본적으로 필요한 AWS 정책 권한 추가
      withAddonPolicies:
        imageBuilder: true # ECR 이미지 접근 권한
        autoScaler: true # Cluster Autoscaler 사용을 위한 권한
        albIngress: true # 로드밸런서 관련 기본 권한을 노드에 자동으로 부여
        cloudWatch: true # 로그 전송을 위한 CloudWatch 권한
        ebs: true # EBS 볼륨 사용을 위한 권한
        certManager: true # SSL/TLS 인증서 관리를 위한 권한
        externalDNS: true # 외부 DNS (Route53) 관리를 위한 권한

# IAM OIDC 프로바이더 설정
iam:
  withOIDC: true # 쿠버네티스 서비스 계정에 IAM 역할을 부여하기 위한 설정 (필수)

이후 ec2 안에 파드 생성 후 내부 컨테이너를 Nginx와 FastAPI 각각 생성한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# ---------------------------------------------------------
# 1. Service: 외부에서 접속 가능한 로드밸런서(대문) 정의
# ---------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
  name: web-project-svc # 서비스의 이름
  annotations: # [핵심] AWS Load Balancer Controller에 전달할 세부 옵션
    # AWS에서 최신형 NLB(Network Load Balancer)를 생성하도록 지정
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    # 로드밸런서가 파드 인스턴스로 직접 통신하도록 설정
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
    # 인터넷망을 통해 누구나 접속할 수 있도록 설정 (퍼블릭 서브넷 활용)
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
    # 사용할 보안 그룹 ID 지정 (쉼표로 여러 개 지정 가능, 쉼표 사이에 공백 없이)
    service.beta.kubernetes.io/aws-load-balancer-security-groups: "sg-0aba5e8b80e5e5b3b"
spec:
  type: LoadBalancer # AWS의 로드밸런서 서비스와 연동하겠다는 타입 선언
  selector:
    app: web-project # 위에서 만든 nginx 라벨을 가진 파드들로 트래픽을 전달
  ports:
    - name: http # [리스너 1] 이름 지정 (포트가 여러 개일 땐 필수)
      protocol: TCP
      port: 80 # 로드밸런서가 외부에서 받는 포트
      targetPort: 80 # 실제 파드로 전달되는 포트
    - name: custom-port # [리스너 2] 추가된 리스너
      protocol: TCP
      port: 8000 # 외부에서 8080으로 접속하면
      targetPort: 8000 # 파드의 80번으로 전달 (포트 포워딩 역할)
---
# ---------------------------------------------------------
# 2. Deployment: 애플리케이션(Nginx) 컨테이너 실행 정의
# ---------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cluster-deployment # 이 배포의 이름
spec:
  replicas: 2 # [요청 개수] 처음에 띄울 파드의 개수 (요청하신 2개)
  selector:
    matchLabels:
      app: web-project # 이 라벨이 붙은 파드들을 관리하겠다는 선언
  template:
    metadata:
      labels:
        app: web-project # 생성될 파드에 부여할 라벨 (위의 selector와 일치해야 함)
    spec:
      containers:
        # 1번 컨테이너: Nginx (웹서버 역할)
        - name: nginx
          image: 036333380579.dkr.ecr.ap-south-1.amazonaws.com/lee/nginx:latest
          ports:
            - containerPort: 80 # 컨테이너 안에서 Nginx가 사용하는 포트
          resources: # [중요] HPA가 CPU 사용량을 계산하기 위한 기준 설정
            requests:
              cpu: "100m" # [예약] "최소한 이만큼은 보장해줘" (스케줄링 기준)
              memory: "128Mi"
            limits:
              cpu: "250m" # [한계] "아무리 바빠도 0.5코어 이상은 쓰지마" (강제 제한)
              memory: "256Mi"

        # 2번 컨테이너: FastAPI (Application 역할)
        - name: fastapi
          image: 036333380579.dkr.ecr.ap-south-1.amazonaws.com/lee/fastapi:latest
          ports:
            - containerPort: 8000 # FastAPI가 사용하는 포트
          resources:
            requests:
              cpu: "100m" # [예약] "최소한 이만큼은 보장해줘" (스케줄링 기준)
              memory: "128Mi"
            limits:
              cpu: "500m" # [한계] "아무리 바빠도 0.5코어 이상은 쓰지마" (강제 제한)
              memory: "256Mi"

이후 로드밸런서 생성을 해줘야 하는데 아래 순서로 따라가면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 로브밸런서 생성
eksctl create iamserviceaccount \
--cluster=lee \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::aws:policy/AmazonEC2FullAccess \
--approve

# 역할자를 생성하기 위한 AWS EKS 차트 리포지토리 추가
helm repo add eks https://aws.github.io/eks-charts

# 최신 정보로 업데이트
helm repo update

# AWS Load Balancer Controller 설치
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=lee \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=ap-south-1 \
--set vpcid=vpc-00561de4a3e1d1392\n

# 설치 확인
kubectl get deployment -n kube-system aws-load-balancer-controller
This post is licensed under CC BY 4.0 by the author.