EKS 노드 그룹 생성

엔스마트·2024년 8월 14일

Amazon EKS

목록 보기
3/4

이 문서는 노드 그룹을 생성하고, ECR에 Nginx 도커 이미지를 업로드한 후 이를 EKS에 배포하는 방법을 설명합니다.

1. IAM 역할 생성

먼저 EKS 노드에 사용되는 역할 정책은 최소한으로 하여 IAM 역할을 생성합니다.

1단계 - 엔터티 유형 및 서비스 설정
엔터티 유형은 AWS 서비스를, 서비스는 EC2를 선택합니다.

2단계 - 권한 정책 설정
필요한 최소한의 권한 정책을 추가합니다.
AmazonEKSWorkerNodePolicy - EKS 워커 노드가 EKS 클러스터에 연결할 수 있도록 허용
AmazonEC2ContainerRegistryReadOnly - ECR 컨테이너 이미지 사용
AmazonEKS_CNI_Policy - VPC CNI 플러그인에 EKS 워커 노드의 IP 주소 구성을 수정할 때 사용

3단계 - 설정 정보 검토
역할의 이름을 입력하고 선택한 엔터티 유형과 권한 정책을 확인한 후 역할을 생성합니다.


2. (옵션) 시작 템플릿 생성

시작 템플릿을 사용하여 노드를 생성하는 경우에는 먼저 EC2 콘솔 > Launch Templates 으로 이동하여 시작 템플릿을 생성합니다.

1단계 - 시작 템플릿 이름 및 설명
시작 템플릿 이름 및 설명을 입력하고 원본 템플릿이 있는 경우 원본 템플릿과 버전을 지정할 수 있습니다.

2단계 - 애플리케이션 및 OS 이미지(AMI)
Amazon EKS 사용자 가이드를 참고하여 Amazon EKS에 최적화된 AMI를 선택합니다.

# Amazon EKS에 최적화된 Amazon Linux AMI ID 검색
aws ssm get-parameter --name /aws/service/eks/optimized-ami/<KUBERNETES_VERSION>/<AMI_TYPE>/recommended/image_id \
    --region <REGION_CODE> --query "Parameter.Value" --output text
KEYVALUE
KUBERNETES_VERSION1.30Amazon EKS 버전
AMI_TYPEamazon-linux-2Amazon Linux 2 x86 기반 인스턴스
amazon-linux-2-arm64Amazon Linux 2 ARM 기반 인스턴스
amazon-linux-2023/x86_64/standardAmazon Linux 2023 x86 기반 인스턴스
(AL2023부터 /etc/eks/bootstrap.sh 대신 nodeadm 사용)
amazon-linux-2023/arm64/standardAmazon Linux 2023 ARM 기반 인스턴스
(AL2023부터 /etc/eks/bootstrap.sh 대신 nodeadm 사용)
REGION_CODEap-northeast-2EKS 지원 AWS 리전 코드


3단계 - (옵션) 인스턴스 유형
원하는 요건에 맞는 인스턴스 유형을 선택합니다.

4단계 - (옵션) 키 페어
인스턴스 연결에 사용할 키 페어를 선택합니다.

5단계 - (옵션) 네트워크 설정
네트워크 인터페이스가 위치한 서브넷과 보안 그룹을 선택합니다.

6단계 - 스토리지(볼륨)
인스턴스에 대한 스토리지 옵션을 설정합니다.

7단계 - (옵션) 리소스 태그
시작 템플릿에 포함할 리소스 태그를 추가합니다.

8단계 - 사용자 데이터 설정
노드가 EKS 클러스터에 정상적으로 연결되고 필요한 설정이 적용되도록 고급 세부 정보의 사용자 데이터를 설정합니다.

Amazon Linux 2인 경우 (/etc/eks/bootstrap.sh)

#!/bin/bash
set -ex
/etc/eks/bootstrap.sh <CLUSTER_NAME> --kubelet-extra-args "--node-labels=alpha.eksctl.io/cluster-name=<CLUSTER_NAME>,alpha.eksctl.io/nodegroup-name=<NODEGROUP_NAME>,eks.amazonaws.com/nodegroup=<NODEGROUP_NAME>,eks.amazonaws.com/nodegroup-image=<CUSTOM_AMI_ID>"

Amazon Linux 2023인 경우 (nodeadm)

 aws eks describe-cluster --name <CLUSTER_NAME> --region <REGION_CODE>

EKS 콘솔에서 클러스터 세부 정보를 확인하거나 AWS CLI 명령어를 사용하여 클러스터 세부 정보를 확인할 수 있습니다.
확인한 정보를 사용하여 사용자 데이터를 구성합니다.

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"
--BOUNDARY
Content-Type: application/node.eks.aws
---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name: <CLUSTER_NAME>
    apiServerEndpoint: <API_SERVER_ENDPOINT>
    certificateAuthority: <CERTIFICATE_AUTHORITY>
    cidr: <K8S_NETWORK_CIDR>
--BOUNDARY--

3. 노드 그룹 생성

EKS 클러스터의 노드 그룹은 시작 템플릿과 사용자 지정 AMI를 사용하여 생성하는 방법과 시작 템플릿을 사용하지 않는 방법이 있습니다.

AWS 콘솔

EKS 클러스터 콘솔 > 컴퓨팅 탭에서 노드 그룹을 추가를 선택합니다.

1단계 - 노드 그룹 구성
이름, 노드 IAM 역할 등을 입력합니다.
시작 템플릿을 사용하는 경우 더욱 다양하게 노드 그룹을 커스텀할 수 있습니다.

2단계 - 컴퓨팅 및 조정 구성 설정
AMI, 용량, 인스턴스 유형 등을 선택하고 노드 수를 지정합니다.

3단계 - 네트워크 지정
관리형 노드를 시작할 서브넷을 선택합니다.

노드에 원격으로 접속하는 경우 액세스 허용을 활성화하고 노드 인스턴스에 접속 시 사용할 키페어와 허용 대상을 선택합니다.
노드에 대한 액세스를 IP로 제한하는 경우, 아래 설정을 참고하여 보안 그룹을 생성하고 생성한 보안 그룹을 적용합니다.

유형 - SSH
프로토콜 - TCP
포트 - 22
소스 - 액세스할 소스

eksctl

노드 그룹 설정 파일을 구성한 후 eksctl을 사용하여 생성하는 방법도 있습니다.

1단계 - 노드 그룹 설정 파일 구성

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: <CLUSTER_NAME>  # 클러스터 이름 (Cluster와 일치해야 함)
  region: <REGION_CODE>    # AWS 리전 (Cluster와 일치해야 함)
vpc:
  id: <VPC_ID>    # 기존 VPC ID / 새로 생성도 가능
  subnets:
    private: # Private 서브넷 환경에 맞게 AZ, 서브넷 ID 변경
      ap-northeast-2a: { id: <SUBNET_ID> }
      ap-northeast-2c: { id: <SUBNET_ID> }
  securityGroup: <SG_ID>
managedNodeGroups:
  - name: <NODEGROUP_NAME> # 클러스터의 노드 그룹명
    instanceType: <INSTANCE_TYPE> # 클러스터 워커 노드의 인스턴스 타입
    instanceName: <NODE_INSTANCE_NAME>
    desiredCapacity: 1       # 원하는 노드 수
    minSize: 1               # 최소 노드 수
    maxSize: 2               # 최대 노드 수
    volumeSize: 20  # 클러스터 워커 노드의 EBS 용량 (단위: GiB)
    privateNetworking: true
    iam:
      withAddonPolicies: # 1. Addon 사용하는 경우
        imageBuilder: true # Amazon ECR에 대한 권한 추가
        albIngress: true  # albIngress에 대한 권한 추가
        cloudWatch: true # cloudWatch에 대한 권한 추가
        autoScaler: true # auto scaling에 대한 권한 추가
      instanceRoleARN: <ROLE_ARN> # 2. 자체 role 사용하는 경우

2단계 - 노드 그룹 생성
설정 파일을 사용하여 노드 그룹을 생성합니다.
생성 과정은 AWS 콘솔의 CloudFormation에서 확인 가능합니다.

eksctl create nodegroup --config-file <FILE_NAME>

4. 네임스페이스 생성

클러스터 내에서 리소스를 그룹화하고 격리하여 쉽게 관리할 수 있도록 네임스페이스를 생성합니다.

kubectl create namespace <NAMESPACE_NAME>

5. ECR 생성

Docker 이미지를 올리기 위해 Amazon ECR(Elastic Container Registry)를 생성합니다.

AWS 콘솔

1단계 - 일반 설정
리포지토리 공개 여부, 이름, 태그 불변성 설정을 합니다.
태그 변경 불가능 설정은 리포지토리의 이미지 태그를 덮어쓸 수 있는지 여부를 결정합니다.

2단계 - 이미지 스캔 설정
리포지토리에 푸시할 때 이미지 자동 스캔 여부를 결정합니다.

3단계 - 암호화 설정
AWS KMS(Key Management Service)를 사용하여 저장된 이미지 암호화 여부를 결정합니다.

AWS CLI

기본 명령어

aws ecr create-repository \
--repository-name <REPO_NAME> \
--region <AWS_REGION>

기본 명령어에 아래 옵션들을 활용하여 ECR을 생성할 수 있습니다.

태그 불변성

--image-tag-mutability IMMUTABLE

이미지 스캔 여부

--image-scanning-configuration scanOnPush=true

암호화 여부

--encryption-configuration encryptionType=KMS

6. Docker 이미지 업로드

nginx 기본 페이지를 띄우기 위해서 ECR에 Nginx 이미지를 업로드합니다.

1. ECR 로그인
ECR에 이미지를 푸시하기 위해 인증 토큰을 가져와 docker login 명령어를 실행합니다.

aws ecr get-login-password --region <REGION_CODE> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.<REGION_CODE>.amazonaws.com

2. Nginx 이미지 다운로드

docker pull nginx:latest

3. 이미지 태그

docker tag nginx:latest <ACCOUNT_ID>.dkr.ecr.<REGION_CODE>.amazonaws.com/<REPOSITORY_NAME>:latest

4. ECR에 이미지 푸시

docker push <ACCOUNT_ID>.dkr.ecr.<REGION_CODE>.amazonaws.com/<REPOSITORY_NAME>:latest

(옵션) '/' 경로가 아닌 다른 경로로 접근하는 경우
Nginx에서 별도 경로(ex. /nginx)로 접근을 처리하려면 'default.conf'파일에 /nginx 경로에 대한 location 블록을 추가해야합니다.


7. AWS Load Balancer Controller 설정

Kubernetes 클러스터의 AWS Load Balancer Controller를 설치하기 위해선 Helm, 매니페스트 등 다양한 방법이 있지만 해당 문서에서는 매니페스트를 사용하여 기능을 설치해보도록 하겠습니다.

1. 태그 설정

서브넷에 로드 밸런서를 배포하려는 경우 태그 설정이 필요합니다.

퍼블릭 서브넷

  • Key - kubernetes.io/role/elb
  • Value - 1


    프라이빗 서브넷
  • Key - kubernetes.io/role/internal-elb
  • Value - 1

이외에도 Kubernetes 버전에 따라 추가로 태그 설정이 필요한 경우가 있습니다.

Kubernetes 클러스터 버전이 1.14 이하인 경우
Amazon EKS에서 지정된 VPC에 다음 태그를 추가해야합니다.

  • Key - kubernetes.io/cluster/<CLUSTER_NAME>
  • Value - owned


    Kubernetes 클러스터 버전이 1.18 이하인 경우
    Amazon EKS에서 지정된 서브넷에 다음 태그를 추가해야합니다.
  • Key - kubernetes.io/cluster/<CLUSTER_NAME>
  • Value - shared

2. IAM 구성

IAM 콘솔에 AmazonEKSLoadBalancerControllerRole이 있는지 확인하고 있는 경우에는 2-3. IAM 역할 생성로 이동합니다.

2-1. IAM 정책 다운로드
사용자 대신 AWS API를 호출할 수 있는 AWS Load Balancer Controller의 IAM 정책을 다운로드합니다.

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.2/docs/install/iam_policy.json

2-2. IAM 정책 생성
다운로드한 정책을 사용하여 IAM 정책을 생성합니다.

aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

2-3. IAM 역할 생성
eksctl을 사용하여 IAM 역할을 생성합니다.

eksctl create iamserviceaccount \
  --cluster=<CLUSTER_NAME> \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::<ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
  --region=<REGION_CODE> \
  --approve

3. cert-manager 설치

인증서 구성을 웹훅에 삽입할 수 있도록 cert-manager를 설치합니다.
cert-manager는 쿠버네티스 클러스터 내에서 TLS인증서를 자동으로 프로비저닝 및 관리하는 오픈 소스입니다.

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.5/cert-manager.yaml

4. AWS Load Balancer Controller 설치

4-1. 설정 파일 다운로드
컨트롤러 사양을 다운로드합니다.

curl -Lo v2_7_2_full.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.7.2/v2_7_2_full.yaml

4-2. 다운로드한 파일 수정
다음 명령을 실행하여 매니페스트에서 ServiceAccount 섹션을 제거합니다.

sed -i.bak -e '612,620d' ./v2_7_2_full.yaml

다른 버전의 파일을 다운받은 경우 해당 내용을 제거합니다.

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/name: aws-load-balancer-controller
  name: aws-load-balancer-controller
  namespace: kube-system
---

Deployment spec 섹션에 있는 my-cluster를 생성한 클러스터 이름으로 변경합니다.

sed -i.bak -e 's|your-cluster-name|<CLUSTER_NAME>|' ./v2_7_2_full.yaml

4-3. AWS Load Balancer Controller 적용

kubectl apply -f v2_7_2_full.yaml

4-4. IngressClass 다운로드
IngressClass 및 IngressClassParams 매니페스트를 클러스터에 다운로드합니다.

curl -Lo v2_7_2_ingclass.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.7.2/v2_7_2_ingclass.yaml

4-5. IngressClass 적용
IngressClass 매니페스트를 클러스터에 적용합니다.

kubectl apply -f v2_7_2_ingclass.yaml

4-6. Controller 설치 확인

kubectl get deployment -n kube-system aws-load-balancer-controller


8. EKS 배포

1. Deployment

1-1. Deployment YAML 파일 구성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <DEPLOYMENT_NAME>
  namespace: <NAMESPACE_NAME>
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: <ECR_URI>
        ports:
        - containerPort: 80

1-2. Deployment 적용

kubectl apply -f deployment.yaml

2. Service

2-1. Service YAML 파일 구성

apiVersion: v1
kind: Service
metadata:
  name: <SERVICE_NAME>
  namespace: <NAMESPACE_NAME>
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

2-2. Service 적용

kubectl apply -f service.yaml

3. Ingress

3-1. Ingress YAML 파일 구성

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: <INGRESS_NAME>
  namespace: <NAMESPACE_NAME>
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/type: instance
    alb.ingress.kubernetes.io/load-balancer-name: <ALB_NAME>
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: <SERVICE_NAME>
                port:
                  number: 80

3-2. Ingress 적용

kubectl apply -f ingress.yaml

3-3. Ingress 확인

kubectl get ingress <INGRESS_NAME> -n <NAMESPACE_NAME>

9. 로드밸런서 확인

Ingress 배포 후 생성된 로드밸런서는 AWS 콘솔 > EC2 > 로드밸런서에서 확인할 수 있습니다.

로드밸런서의 DNS 정보를 활용하여 접속하면 nginx 기본 페이지가 노출됩니다.

Ingress를 배포한 후에도 로드밸런서를 확인할 수 없다면 다음과 같은 명령어를 사용하여 원인을 파악할 수 있습니다.

로드밸런서 컨트롤러 로그

kubectl logs -f -n <NAME_SPACE> -l app.kubernetes.io/name=aws-load-balancer-controller
profile
클라우드 전환, MSA 서비스, DevOps 환경 구축과 기술지원 그리고 엔터프라이즈 시스템을 구축하는 최고 실력과 경험을 가진 Architect Group 입니다.

0개의 댓글