1. eksctl를 활용한 EKS 배포
참조 사이트: https://malwareanalysis.tistory.com/594
1.1 원클릭 배포 템플릿
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "<<<<< EKSCTL MY EC2 >>>>>"
Parameters:
- ClusterBaseName
- KeyName
- SgIngressSshCidr
- MyInstanceType
- LatestAmiId
- Label:
default: "<<<<< Region AZ >>>>>"
Parameters:
- TargetRegion
- AvailabilityZone1
- AvailabilityZone2
- Label:
default: "<<<<< VPC Subnet >>>>>"
Parameters:
- VpcBlock
- PublicSubnet1Block
- PublicSubnet2Block
- PrivateSubnet1Block
- PrivateSubnet2Block
Parameters:
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
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.
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
TargetRegion:
Type: String
Default: ap-northeast-2
AvailabilityZone1:
Type: String
Default: ap-northeast-2a
AvailabilityZone2:
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
PrivateSubnet1Block:
Type: String
Default: 192.168.3.0/24
PrivateSubnet2Block:
Type: String
Default: 192.168.4.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
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
# 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
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
# 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'
CidrIp: !Ref SgIngressSshCidr
EKSEC2:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref MyInstanceType
ImageId: !Ref LatestAmiId
KeyName: !Ref KeyName
Tags:
- Key: Name
Value: !Sub ${ClusterBaseName}-host
- 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}-host"
# 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.28.5/2024-01-04/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)' >> /etc/profile
echo 'alias k=kubectl' >> /etc/profile
echo 'complete -F __start_kubectl k' >> /etc/profile
git clone https://github.com/jonmosco/kube-ps1.git /root/kube-ps1
cat <<"EOT" >> /root/.bash_profile
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
# CLUSTER_NAME
export CLUSTER_NAME=${ClusterBaseName}
echo "export CLUSTER_NAME=$CLUSTER_NAME" >> /etc/profile
# Create SSH Keypair
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
Outputs:
eksctlhost:
Value: !GetAtt EKSEC2.PublicIp
1.2 eksctl이란?
- AWS에서 공식으로 지원하는 eks 관리 CLI
- AWS EKS만 관리하고 다른 리소스 관리 불가
1.2.1 eksctl 설치
# eksctl 설치
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
# 어디서든 명령어 사용가능하도록 설정
sudo mv /tmp/eksctl /usr/local/bin
# 설치 버전 확인
eksctl version
> 0.203.0
1.2.2 EKS 설정 파일 생성
cat << EOF > cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: Study-cluster # eks 이름
region: ap-northeast-2
version: "1.31" # 쿠버네티스 버전
vpc:
cidr: "10.0.0.0/16" # eks클러스터에서 사용할 VPC의 CIDR
managedNodeGroups:
- name: node-group-a
instanceType: t3.medium
desiredCapacity: 2
volumeSize: 20
privateNetworking: true
tags:
off: exception
addons:
- name: vpc-cni
version: latest
attachPolicyARNs:
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
configurationValues: |-
enableNetworkPolicy: "true"
- name: kube-proxy
version: latest
- name: coredns
version: latest
EOF
설정파일은 EKS메타정보, 네트워크(VPC), 워커노드(Auto Scaling group)으로 구성됩니다.
- metadata: 쿠버네티스 버전, 리전 등을 설정
- VPC: AWS VPC 설정. VPC설정에 AWS Subnet이 설정 그리고 클러스터 네트워크 정보 설정
- managedNodeGroups: 워커노드 설정합니다. EKS는 EC2 인스턴스와 Fargate 사용 가능. managedNodeGroups 은 Auto scaling group으로 워커노드 관리됨. tag 달았음.
- addons: 추가 기능 설치. VPC CNI, kube-proxy, coredns 설치함
# 배포 yaml 생성
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
# 배포 실행
eksctl create cluster -f cluster.yaml
eksctl 명령어를 사용하여 yaml 템플릿 내용을 만들고 필요한 설정만 수정해서 배포하는 것이 편리하다.
EKS Addons
EKS가 설치되면 쿠버네티스 네트워킹을 위한 pod가 자동으로 생성됩니다.
관련된 내용은 EKS애드온 공식문서를 참조하시길 바랍니다.
EKS애드온 문서: https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/eks-add-ons.html
'세미나 & 교육 & Tech' 카테고리의 다른 글
[Amazon EKS STUDY] #1주차 (이론) Amazon EKS의 개념 및 구성 요소 (0) | 2025.02.04 |
---|---|
[Amazon EKS STUDY] #0주차 EKS 원클릭 배포 가이드 (0) | 2025.01.30 |
Google Cloud Summit 2024 후기 (1) | 2024.07.06 |
[교육] DevOps Engineering on AWS 3일차 (1) | 2024.06.24 |
[교육] DevOps Engineering on AWS 2일차 (0) | 2024.06.24 |