세미나 & 교육 & Tech

[Amazon EKS STUDY] #0주차 EKS 원클릭 배포 가이드

jih0ssang 2025. 1. 30. 14:18

참고: https://base-on.tistory.com/category/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C/AWS#google_vignette

 

가시다 님의 스터디에 참여한 수강생의 블로그를 참조하며, Amazon EKS STUDY 를 진행하고자 한다.

 

1. 실습 환경 아키텍처

bastion-ec2를 활용하여 EKS Cluster 와 통신하고자 한다

  • VPC 1 ea, Subnet (Public 3ea, Private 3ea)
  • EKS 클러스터(Control Plane)
  • 관리형 노드 그룹(EC2 3대)
  • Add-on 기능

 

2. CloudFormation을 활용한 실습 환경 배포

2.0 사전 수행 작업

  • 관리자 권한을 가진 IAM User 
  • 관리자 권한을 가진 IAM Role
  • IAM User의 AccessKey 및 SecretKey
용도
IAM User - Root 계정은 보안적으로 사용 지양하므로 IAM User를 사용
IAM Role
- CloudFormation이 리소스 생성을 위해 사용하는 Role
AccessKey 및 SecretKey
- 관리자 수준의 권한을 가진 IAM User의 액세스 키ID 입력

KeyPair - 작업용 bastion ec2에 SSH 접속을 위한 SSH 키페어 선택

 

위의 준비물은 미리 생성해둬야 한다.

CloudFormation 스택 배포 시 위의 정보를 사용해야하기 때문이다.

 

 

2.1 스택 생성

브라우저를 통해 아래의 링크를 접속하면 CloudFormation 스택 YAML을 다운받을 수 있다.

https://ap-northeast-2.console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/create?stackName=myeks&templateURL=https:%2F%2Fs3.ap-northeast-2.amazonaws.com%2Fcloudformation.cloudneta.net%2FK8S%2Feks-oneclick.yaml

 

 

CloudFormation yaml 내용

앞서 다운받은 CloudFormation 스택 YAML의 내용이다.

EKS Cluster Version 1.31 로 변경하고, SCP 정책에 의해 EC2 tag를 추가하여 Custom하였다. 

AWSTemplateFormatVersion: '2010-09-09'

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "<<<<< Deploy EC2 >>>>>"
        Parameters:
          - KeyName
          - MyIamUserAccessKeyID
          - MyIamUserSecretAccessKey
          - SgIngressSshCidr
          - MyInstanceType
          - LatestAmiId

      - Label:
          default: "<<<<< EKS Config >>>>>"
        Parameters:
          - ClusterBaseName
          - KubernetesVersion
          - WorkerNodeInstanceType
          - WorkerNodeCount
          - WorkerNodeVolumesize

      - Label:
          default: "<<<<< Region AZ >>>>>"
        Parameters:
          - TargetRegion
          - AvailabilityZone1
          - AvailabilityZone2
          - AvailabilityZone3

      - Label:
          default: "<<<<< VPC Subnet >>>>>"
        Parameters:
          - VpcBlock
          - PublicSubnet1Block
          - PublicSubnet2Block
          - PublicSubnet3Block
          - PrivateSubnet1Block
          - PrivateSubnet2Block
          - PrivateSubnet3Block

Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances. Linked to AWS Parameter
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  MyIamUserAccessKeyID:
    Description: IAM User - AWS Access Key ID (won't be echoed)
    Type: String
    NoEcho: true
  MyIamUserSecretAccessKey:
    Description: IAM User - AWS Secret Access Key (won't be echoed)
    Type: String
    NoEcho: true
  SgIngressSshCidr:
    Description: The IP address range that can be used to communicate to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  MyInstanceType:
    Description: Enter t2.micro, t2.small, t2.medium, t3.micro, t3.small, t3.medium. Default is t2.micro.
    Type: String
    Default: t3.medium
    AllowedValues: 
      - t2.micro
      - t2.small
      - t2.medium
      - t3.micro
      - t3.small
      - t3.medium
  LatestAmiId:
    Description: (DO NOT CHANGE)
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
    AllowedValues:
      - /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  ClusterBaseName:
    Type: String
    Default: myeks
    AllowedPattern: "[a-zA-Z][-a-zA-Z0-9]*"
    Description: must be a valid Allowed Pattern '[a-zA-Z][-a-zA-Z0-9]*'
    ConstraintDescription: ClusterBaseName - must be a valid Allowed Pattern
  KubernetesVersion:
    Description: Enter Kubernetes Version, 1.29~1.32
    Type: String
    Default: 1.31
  WorkerNodeInstanceType:
    Description: Enter EC2 Instance Type. Default is t3.medium.
    Type: String
    Default: t3.medium
  WorkerNodeCount:
    Description: Worker Node Counts
    Type: String
    Default: 3
  WorkerNodeVolumesize:
    Description: Worker Node Volumes size
    Type: String
    Default: 30

  TargetRegion:
    Type: String
    Default: ap-northeast-2
  AvailabilityZone1:
    Type: String
    Default: ap-northeast-2a
  AvailabilityZone2:
    Type: String
    Default: ap-northeast-2b
  AvailabilityZone3:
    Type: String
    Default: ap-northeast-2c

  VpcBlock:
    Type: String
    Default: 192.168.0.0/16
  PublicSubnet1Block:
    Type: String
    Default: 192.168.1.0/24
  PublicSubnet2Block:
    Type: String
    Default: 192.168.2.0/24
  PublicSubnet3Block:
    Type: String
    Default: 192.168.3.0/24
  PrivateSubnet1Block:
    Type: String
    Default: 192.168.11.0/24
  PrivateSubnet2Block:
    Type: String
    Default: 192.168.12.0/24
  PrivateSubnet3Block:
    Type: String
    Default: 192.168.13.0/24

Resources:
# VPC
  EksVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcBlock
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-VPC

# PublicSubnets
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone1
      CidrBlock: !Ref PublicSubnet1Block
      VpcId: !Ref EksVPC
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PublicSubnet1
        - Key: kubernetes.io/role/elb
          Value: 1
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone2
      CidrBlock: !Ref PublicSubnet2Block
      VpcId: !Ref EksVPC
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PublicSubnet2
        - Key: kubernetes.io/role/elb
          Value: 1
  PublicSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone3
      CidrBlock: !Ref PublicSubnet3Block
      VpcId: !Ref EksVPC
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PublicSubnet3
        - Key: kubernetes.io/role/elb
          Value: 1

  InternetGateway:
    Type: AWS::EC2::InternetGateway
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref EksVPC

  PublicSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref EksVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PublicSubnetRouteTable
  PublicSubnetRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicSubnetRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicSubnetRouteTable
  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicSubnetRouteTable
  PublicSubnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet3
      RouteTableId: !Ref PublicSubnetRouteTable

# PrivateSubnets
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone1
      CidrBlock: !Ref PrivateSubnet1Block
      VpcId: !Ref EksVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PrivateSubnet1
        - Key: kubernetes.io/role/internal-elb
          Value: 1
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone2
      CidrBlock: !Ref PrivateSubnet2Block
      VpcId: !Ref EksVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PrivateSubnet2
        - Key: kubernetes.io/role/internal-elb
          Value: 1
  PrivateSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone3
      CidrBlock: !Ref PrivateSubnet3Block
      VpcId: !Ref EksVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PrivateSubnet3
        - Key: kubernetes.io/role/internal-elb
          Value: 1

  PrivateSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref EksVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-PrivateSubnetRouteTable

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateSubnetRouteTable
  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateSubnetRouteTable
  PrivateSubnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet3
      RouteTableId: !Ref PrivateSubnetRouteTable

# EKSCTL-Host
  EKSEC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: eksctl-host Security Group
      VpcId: !Ref EksVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-HOST-SG
      SecurityGroupIngress:
      - IpProtocol: '-1'
        #FromPort: '22'
        #ToPort: '22'
        CidrIp: !Ref SgIngressSshCidr

  EKSEC2:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref MyInstanceType
      ImageId: !Ref LatestAmiId
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-bastion-EC2
        - Key: 'off'
          Value: exception
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PublicSubnet1
          GroupSet:
          - !Ref EKSEC2SG
          AssociatePublicIpAddress: true
          PrivateIpAddress: 192.168.1.100
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeType: gp3
            VolumeSize: 30
            DeleteOnTermination: true
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            hostnamectl --static set-hostname "${ClusterBaseName}-bastion-EC2"

            # Config Root account
            echo 'root:qwe123' | chpasswd
            sed -i "s/^#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
            sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
            rm -rf /root/.ssh/authorized_keys
            systemctl restart sshd

            # Config convenience
            echo 'alias vi=vim' >> /etc/profile
            echo "sudo su -" >> /home/ec2-user/.bashrc
            sed -i "s/UTC/Asia\/Seoul/g" /etc/sysconfig/clock
            ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

            # Install Packages
            yum -y install tree jq git htop

            # Install kubectl & helm
            cd /root
            curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.31.3/2024-12-12/bin/linux/amd64/kubectl
            install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
            curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

            # Install eksctl
            curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz" | tar xz -C /tmp
            mv /tmp/eksctl /usr/local/bin

            # Install aws cli v2
            curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
            unzip awscliv2.zip >/dev/null 2>&1
            ./aws/install
            complete -C '/usr/local/bin/aws_completer' aws
            echo 'export AWS_PAGER=""' >>/etc/profile
            export AWS_DEFAULT_REGION=${AWS::Region}
            echo "export AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /etc/profile

            # Install YAML Highlighter
            wget https://github.com/andreazorzetto/yh/releases/download/v0.4.0/yh-linux-amd64.zip
            unzip yh-linux-amd64.zip
            mv yh /usr/local/bin/

            # Install krew
            curl -L https://github.com/kubernetes-sigs/krew/releases/download/v0.4.4/krew-linux_amd64.tar.gz -o /root/krew-linux_amd64.tar.gz
            tar zxvf krew-linux_amd64.tar.gz
            ./krew-linux_amd64 install krew
            export PATH="$PATH:/root/.krew/bin"
            echo 'export PATH="$PATH:/root/.krew/bin"' >> /etc/profile

            # Install kube-ps1
            echo 'source <(kubectl completion bash)' >> /root/.bashrc
            echo 'alias k=kubectl' >> /root/.bashrc
            echo 'complete -F __start_kubectl k' >> /root/.bashrc
            
            git clone https://github.com/jonmosco/kube-ps1.git /root/kube-ps1
            cat <<"EOT" >> /root/.bashrc
            source /root/kube-ps1/kube-ps1.sh
            KUBE_PS1_SYMBOL_ENABLE=false
            function get_cluster_short() {
              echo "$1" | cut -d . -f1
            }
            KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
            KUBE_PS1_SUFFIX=') '
            PS1='$(kube_ps1)'$PS1
            EOT

            # Install krew plugin
            kubectl krew install ctx ns get-all neat # ktop df-pv mtail tree

            # Install Docker
            amazon-linux-extras install docker -y
            systemctl start docker && systemctl enable docker

            # Create SSH Keypair
            ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa

            # IAM User Credentials
            export AWS_ACCESS_KEY_ID=${MyIamUserAccessKeyID}
            export AWS_SECRET_ACCESS_KEY=${MyIamUserSecretAccessKey}
            export AWS_DEFAULT_REGION=${AWS::Region}
            export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
            echo "export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> /etc/profile
            echo "export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> /etc/profile
            echo "export AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /etc/profile
            echo "export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)" >> /etc/profile

            # CLUSTER_NAME
            export CLUSTER_NAME=${ClusterBaseName}
            echo "export CLUSTER_NAME=$CLUSTER_NAME" >> /etc/profile

            # K8S Version
            export KUBERNETES_VERSION=${KubernetesVersion}
            echo "export KUBERNETES_VERSION=$KUBERNETES_VERSION" >> /etc/profile

            # VPC & Subnet
            export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq -r .Vpcs[].VpcId)
            echo "export VPCID=$VPCID" >> /etc/profile
            export PubSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text)
            export PubSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet2" --query "Subnets[0].[SubnetId]" --output text)
            export PubSubnet3=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet3" --query "Subnets[0].[SubnetId]" --output text)
            echo "export PubSubnet1=$PubSubnet1" >> /etc/profile
            echo "export PubSubnet2=$PubSubnet2" >> /etc/profile
            echo "export PubSubnet3=$PubSubnet3" >> /etc/profile
            export PrivateSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PrivateSubnet1" --query "Subnets[0].[SubnetId]" --output text)
            export PrivateSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PrivateSubnet2" --query "Subnets[0].[SubnetId]" --output text)
            export PrivateSubnet3=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PrivateSubnet3" --query "Subnets[0].[SubnetId]" --output text)
            echo "export PrivateSubnet1=$PrivateSubnet1" >> /etc/profile
            echo "export PrivateSubnet2=$PrivateSubnet2" >> /etc/profile
            echo "export PrivateSubnet3=$PrivateSubnet3" >> /etc/profile

            # Create EKS Cluster & Nodegroup
            eksctl create cluster --name $CLUSTER_NAME --region=$AWS_DEFAULT_REGION --nodegroup-name=ng1 --node-type=${WorkerNodeInstanceType} --nodes ${WorkerNodeCount} --node-volume-size=${WorkerNodeVolumesize} --vpc-public-subnets "$PubSubnet1","$PubSubnet2","$PubSubnet3" --version ${KubernetesVersion} --ssh-access --ssh-public-key /root/.ssh/id_rsa.pub --with-oidc --external-dns-access --full-ecr-access --dry-run > myeks.yaml
            sed -i 's/certManager: false/certManager: true/g' myeks.yaml
            sed -i 's/ebs: false/ebs: true/g' myeks.yaml
            sed -i '/tags:/a \ \ \ \ off: exception' myeks.yaml


            cat <<EOT >> myeks.yaml
            addons:
              - name: vpc-cni # no version is specified so it deploys the default version
                version: latest # auto discovers the latest available
                attachPolicyARNs:
                  - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
                configurationValues: |-
                  enableNetworkPolicy: "true"
              - name: kube-proxy
                version: latest
              - name: coredns
                version: latest
            EOT
            cat <<EOT > precmd.yaml
              preBootstrapCommands:
                - "yum install nvme-cli links tree tcpdump sysstat -y"
            EOT
            sed -i -n -e '/instanceType/r precmd.yaml' -e '1,$p' myeks.yaml
            nohup eksctl create cluster -f myeks.yaml --verbose 4 --kubeconfig "/root/.kube/config" 1> /root/create-eks.log 2>&1 &
            echo 'cloudinit End!'

Outputs:
  eksctlhost:
    Value: !GetAtt EKSEC2.PublicIp

 

 

 

2.2 스택 세부정보 지정

위의 CloudFormation 스택을 생성하면 아래의 파라미터 정보를 입력 받는다.

 

앞서 사전 작업으로 생성해둔 KeyPair, AccessKey 및 Secret Key 정보를 기입한다.

SgIngressSshCidr는 접속하고자 하는 사용자의 Public IP(ex_ A.B.C.D/32)를 기입하면 된다. 

 

사용자 PC의 공인 IP 확인 방법
사용자 PC의 cmd 창에서 curl ipconfig.me 명령어를 통해 사용자 PC의 공인 IP를 확인한다.

 

 

2.2.1 EKS Config 변경사항

EKS Version
- 평균 4개월에 한 번씩 새로운 Kubernetes 마이너 버전(예: 1.30 )을 릴리스
- v1.28는 2024년 12월 EOL 되었고, v1.29는 2025년 3월 만료 예정

 

KuberenetesVersion의 기본값은 1.28이다. 버전이 만료되었으므로 v1.31으로 변경해서 실습 진행할 예정이다.

 

 

2.2.2 CloudFormation이 배포할 때 사용할 IAM Role 생성 

  • AdministratorAccess

테스트 용도니... Admin 권한을 줘버렸다..

 

 

2.3 스택 옵션 구성

앞서 생성한 IAM Role은 CloudFormation 스택 옵션 구성에서 권한 부분에 지정하면 된다.

 

2.4 배포 확인

총 스택은 4개의 스택이 배포된다.

이어서 각 스택별 용도를 설명하겠다.

 

2.4.1 myeks 스택 배포 확인

CloudFormation에서 배포되는 스택은 myeks 스택이다.

VPC, Subnet, Route Table, EC2(Bastion-ec2) 생성 정의가 되어있다.

 

Output 값으로 bastion-ec2 Public IP를 확인할 수 있다.

 

2.4.2 eksctl-myeks-cluster 스택 배포 확인

앞서 CloudFormation에 정의된 EC2 Userdata를 통해 배포된 eksctl-myeks-cluster 스택이다.

서버 내에서 eksctl 명령어를 실행하면 내부적으로는 CloudFormation 스택이 생성되어 배포된다.

eksctl을 통해 생성된 스택은 이름에 'eksctl-{cluster이름}- ~~'이 붙는다.

EKS Cluster, SG, IAM Role 생성 정의가 되어있다.

 

 

2.4.3 eksctl-myeks-addon-vpc-cni 스택 배포 확인

앞서 CloudFormation에 정의된 EC2 Userdata를 통해 배포된 eksctl-myeks-addon-vpc-cni 스택이다.

addon-vpc-cni 관련 IAM Role 생성 정의가 되어있다.

 

 

 

2.5 EC2와 EKS 권한 연결

IAM Role을 추가적으로 생성한다.

이는 EKS Cluster 생성 완료 후 바로 수행하기 바랍니다.

NodeGroup 생성하기 전에 수행해야 에러가 뜨지 않습니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "ec2.amazonaws.com",
                    "eks.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

주체는 ec2와 eks가 사용할 Role이다.

AdministratorAccess 권한을 주어버렸다.

 

 

 

EC2에 IAM Role 연결

생성한 IAM Role로 변경해줍니다.

 

 

EKS Cluster에 IAM Role 연결

 

 

액세스 > 액세스 항목 생성

생성한 IAM Role을 지정한다.

 

  • AmazonEKSAdminPolicy
  • AmazonEKSClusterAdminPolicy

 

정책을 추가합니다.

 

 

2.5.2 eksctl-myeks-nodegroup-ng1 스택 배포 확인

앞서 CloudFormation에 정의된 EC2 Userdata를 통해 배포된 eksctl-myeks-nodegroup-ng1 스택이다.

Nodegroup, LaunchTemplate, IAM Role, Policy, SG 생성 정의가 되어있다.

 

 

 

 

3. 배포 정상 확인

앞서 배포한 CloudFormation에서 초기화한 로그인 정보를 통해 접속한다.

ssh root@<bastion의 public-ip>
# id: root, pw: qwe123

 

MobaXterm을 통해 bastion-ec2에 접속했다. 개인별 편리한 ssh 접속 Tool을 사용하여 접속하면 되겠다.

UserData에 정의된 Kubectl, AWS CLI, Docker 설치 되었는지 확인하였다.

 

이후 아래의 추가 작업 진행 필요합니다.



3.1 EC2의 EKS cluster config 설정

 

 aws eks --region ap-northeast-2 update-kubeconfig --name <Cluster명>

 

config 설정 후, kubectl get all -A 하면 모든 오브젝트 확인이 가능하다.