brunch

EKS 8탄-1.Amazon EKS 설치-1/17

EKS 8탄 - 1주차

by Master Seo

1

본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863

개인적으로 작성한 내용이 포함되어 있어, 내용이 틀릴수 있습니다.



2

진행

이론

실습 진행합니다.



전체 내용

슬라이드2.JPG



----------------------------------------------------------------------------


목표

Amazon EKS 아키텍처 이해하기

명령서버 1대 만들고, eksctl로 Amazon EKS 생성하기

Amazon EKS에 게임 서비스 하나 올리기



<1> Amazon EKS 아키텍처

<2> CF로 명령서버 1대만들고, eksctl로 Amazon EKS 생성

<3> Amazon EKS에 게임서비스 하나 올리기

<4> EKS Cluster Endpoint 이해하기

<5> 워커 노드 증설하기

<6> 숙제

<7> 삭제

<8> 확인



<1> Amazon EKS 아키텍처


1

Master와 Worker Node로 구성되어 있다.

Master(컨트롤 플래인)은 컨트롤 역할을 한다.

Work Node는 Pod와 컨테이너가 생성되어 서버로 동작을 한다.





2

Amazon EKS가 기존 쿠버네티스와 크게 다른점은 ?

Master를 CSP인 Amazon 에서 관리해준다.

일반 쿠버네티스는 사용자가 Master도 관리하야 한다.



3

버전 ?

1.24.2

Major.Minor.Patch

Major(Breaking Changes) . Minor(New Features) . Patch(Bug fixes Security)


1.24이 버전이다.

1.24.2의 마지막 2는 패치이다.



4

현재 사용가능한 Amazon EKS Kubernetes versions 확인은 ?

영문 사이트가 정확하다.

한글은 업데이트하는데 시간이 좀 필요하다.

영문 사이트에서 확인

https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html



5

Amazon EKS nodes의 특징을 알아보자.

일반적으로 EKS managed node groups 을 사용한다.

https://docs.aws.amazon.com/eks/latest/userguide/eks-compute.html





<2> CF로 명령서버 1대만들고, eksctl로 Amazon EKS 생성


CloudFormation으로 네트워크를 생성하고, 서브넷안에 작업용 EC2 1대를 만들자.

CloudFormation으로 만든 EC2에는 기본 툴이 이미 설치되어 있다.




1

실습 환경

퍼블릭 서브넷 2개

프라이빗 서브넷 2개


eks-work-vpc 192.168.0.0/16

Public Subnet1 192.168.1.0/24

Public Subnet2 192.168.2.0/24

0 arch.png



2

AWS 콘솔 로그인 하자~

https://console.aws.amazon.com/


서울 리전 사용

웹브라우저에서 새 탭에서 보기 사용하자 = AWS console이 닫히는 경우가 있다.



3

명령서버 1대와 명령툴 설치 클라우드 포메이션~



myeks


EC2 Keypairs 입력



Public Subnet 2개 , Private Subnet 2개 자동 생성됨.

작업용 EC2 1대가 Public Subnet에 1대 생성됨. ip는 100번.

이후 작업용 EC2에 로그온해서 EKS설치를 한다.



4

명령서버 1대와 명령툴 설치 클라우드 포메이션~


AWS 콘솔로그인

https://console.aws.amazon.com/console/home



명령서버 1대와 명령툴 설치 클라우드 포메이션~

링크 클릭해서 cloudformation 사용


내용


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.

:


// 원하는 IP블럭을 입력하여 설치할수 있다.


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

:

# 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}-host

NetworkInterfaces:

- DeviceIndex: 0

SubnetId: !Ref PublicSubnet1

GroupSet:

- !Ref EKSEC2SG

AssociatePublicIpAddress: true

PrivateIpAddress: 192.168.1.100

BlockDeviceMappings:

- DeviceName: /dev/xvda

Ebs:

VolumeType: gp3

VolumeSize: 20

DeleteOnTermination: true

UserData:

Fn::Base64:

!Sub |

#!/bin/bash

hostnamectl --static set-hostname "${ClusterBaseName}-host"


# Config convenience

echo 'alias vi=vim' >> /etc/profile

echo "sudo su -" >> /home/ec2-user/.bashrc


# Change Timezone

sed -i "s/UTC/Asia\/Seoul/g" /etc/sysconfig/clock

ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime


# Install Packages

cd /root

yum -y install tree jq git htop lynx


# Install kubectl & helm

#curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.26.2/2023-03-17/bin/linux/amd64/kubectl

curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.25.7/2023-03-17/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 --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_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

sudo ./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 -LO https://github.com/kubernetes-sigs/krew/releases/download/v0.4.3/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 # 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



5

PublicIp로 EC2 접속하여 eksctl 명령어로 EKS 클러스터를 생성하자.


eksctl ?

Amazon EKS에서 Kubernetes 클러스터를 생성 및 관리하기 위한 간단한 명령 도구이다.


https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/eksctl.html




6

원격에서 명령을 내리려면 권한이 있어야 하다.

컨트롤 플래인과 worker node를 만들수 있는 권한이 필요하다.


access-key 와 secret-key가 필요하다.

콘솔 IAM에서 만든다.


명령 EC2에 권한 적용은 aws configure로 권한 설정을 한다.

ap-northeast-2



7

권한 확인


aws s3 ls

aws ec2 describe-instances



8

변수 설정

VPC ID와 서브넷을 변수로 지정한다.

EKS를 해당 서브넷에 설치하기 위함이다.


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)


echo "export PubSubnet1=$PubSubnet1" >> /etc/profile


echo "export PubSubnet2=$PubSubnet2" >> /etc/profile


echo $PubSubnet1,$PubSubnet2




9

변수 확인

echo $AWS_DEFAULT_REGION

echo $CLUSTER_NAME

echo $VPCID

echo $PubSubnet1,$PubSubnet2




10

클러스터 만들수 있는지 체크해보자.

실제 클러스터가 만들어지는건 아니고, 테스트만 하는 것이다. --dry-run 옵션.


최신버전인 1.31 버전으로 설치해보자


eksctl create cluster --name $CLUSTER_NAME --region=$AWS_DEFAULT_REGION --nodegroup-name=$CLUSTER_NAME-nodegroup --node-type=t3.medium --node-volume-size=30 --vpc-public-subnets "$PubSubnet1,$PubSubnet2" --version 1.31 --ssh-access --external-dns-access --dry-run | yh


--dry-run 에서 이상이 없다면 실제 EKS 클러스터 만들어보자.




11

쿠버네티스 클러스터 생성해보자


eksctl create cluster --name $CLUSTER_NAME --region=$AWS_DEFAULT_REGION --nodegroup-name=$CLUSTER_NAME-nodegroup --node-type=t3.medium --node-volume-size=30 --vpc-public-subnets "$PubSubnet1,$PubSubnet2" --version 1.31 --ssh-access --external-dns-access --verbose 4


// -verbose 4 디버깅 옵션



12

while로 node 서버 생성 확인법 ?


while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done




# 노드 서버 생성 1분후 노드로 kubectl 명령어로 조회가 가능하다.

while true ; do kubectl get nodes ;echo "-----------";date; sleep 2 ;done




15분 걸림

https://vclock.kr/timer/#countdown=00:10:00&enabled=0&seconds=0&sound=xylophone&loop=1




13

k get nodes


NAME STATUS ROLES AGE VERSION

ip-192-168-1-102.ap-northeast-2.compute.internal Ready <none> 93s v1.28.3-eks-e71965b

ip-192-168-2-87.ap-northeast-2.compute.internal Ready <none> 95s v1.28.3-eks-e71965b




14

EC2 IP정보 확인


aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table






15

콘솔 > ec2 인스턴스 가보면 서버가 나온다.


인스턴스를 종료하더라도 auto scaling 걸려있어 다시 ec2가 생성된다.





16

AWS 콘솔 > EKS 가서 정보 확인하자.


질문?




17

# kube-ops-view 설치


1)

# 방법 1 - git 다운로드 설치


파드와 노드증가를 시각화 하여 확인하는 Kubeops view 설치


1

git clone https://codeberg.org/hjacobs/kube-ops-view.git

cd kube-ops-view/

kubectl apply -k deploy


2

외부에서 kube-ops-view를 접속하기 위해서 Service Type을 LoadBalancer 로 변경한다.


kubectl edit svc kube-ops-view



apiVersion: v1

kind: Service

metadata:

annotations:

name: kube-ops-view

spec:

....

sessionAffinity: None

type: LoadBalancer

status:



(3분 걸림)


# kube ops view 접속 URL

kubectl get svc kube-ops-view | tail -n 1 | awk '{ print "Kube-ops-view URL = http://"$4 }'




2)

벙법2


helm repo add geek-cookbook https://geek-cookbook.github.io/charts/


helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system


kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'


k get svc -n kube-system

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP 14m

kube-ops-view LoadBalancer 10.100.62.65 a256ec82aa


2

8080으로 접속 하기




k ns kube-system






<3> Amazon EKS에 게임서비스 하나 올리기



1

AWS 콘솔은 새탭으로 보기 하자~

다른것 클릭하면 콘솔 화면이 닫힌다.



2

EC2 다른 터미널에서 모니터링 하자.

watch -d kubectl get deploy,rs,pod,svc



3

# Super Mario 디플로이먼트 배포

curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/1/mario.yaml

kubectl apply -f mario.yaml


(6분 걸립니다.)




apiVersion: apps/v1

kind: Deployment

metadata:

name: mario

labels:

app: mario

spec:

replicas: 1

selector:

matchLabels:

app: mario

template:

metadata:

labels:

app: mario

spec:

containers:

- name: mario

image: pengbai/docker-supermario

---

apiVersion: v1

kind: Service

metadata:

name: mario

spec:

selector:

app: mario

ports:

- port: 80

protocol: TCP

targetPort: 8080

type: LoadBalancer



cat mario.yaml | yh




4

# 배포 확인 : CLB 배포 확인

kubectl get deploy,svc,ep mario



5

# 마리오 게임 접속 : CLB 주소로 웹 접속

kubectl get svc mario -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Maria URL = http://"$1 }'


100 mario.png


6

생성된 로드 밸런서등 리소스는 콘솔에서 확인 가능하다.



7

삭제

kubectl delete -f mario.yaml



8

생성

디플로이먼트, 레플리카세스, Pod, 컨테이너 , 서비스(로드밸런서)

슬라이드3.JPG



사용자 인터넷 - 서비스

10 LB.jpg

9

질문?






<4> EKS Cluster Endpoint 이해하기


EKS 클러스터를 어느 서브넷에 구축하느냐에 따라 동작이 달라진다.

EKS Cluster Endpoint - Public 경우 동작은 ?

EKS Cluster Endpoint - Public과 Private 인 경우 동작은 ?

EKS Cluster Endpoint - Private인 경우 동작은 ?



1

EKS Cluster Endpoint - Public 경우 동작은 ?


10 통신1.png


1) 사용자 kubectl → (퍼블릭 도메인) 제어부

// 사용자가 컨트롤 플레인에 입력할때 Public도메인이라 Public으로 찌른다.


2) 제어부(컨트롤 플래인) → (EKS owned ENI) 워커노드 kubelet

// 제어부에서 워커노드에 명령을 내릴때 고객 VPC의 ENI를 통해 Kubelet을 통해 수행한다.


3) 워커노드 → (퍼블릭 도메인) 제어부

// 워커노드에서 컨트롤 플래인 통신은 인터넷 게이트웨이를 통해 통신한다. Public 도메인이라.




2

EKS Cluster Endpoint - Public과 Private 인 경우 동작은 ?


20 통신2.png



1) 사용자 kubectl → (퍼블릭 도메인) 제어부

// 사용자가 컨트롤 플레인에 입력할때 Public도메인이라 Public으로 찌른다.


2) 제어부(컨트롤 플래인) → (EKS owned ENI) 워커노드 kubelet

// 동일하게 ENI로 통신


3) 워커노드 → (프라이빗 도메인, EKS owned ENI) 제어부

// ENI에 매칭된 Private Host도메인으로 통신한다.




3

EKS Cluster Endpoint - Private인 경우 동작은 ?


30 pri.png


1) Private 설치는 외부에서 API 서버 노출이 안된다.

// Public , Private 설치의 의미는 API 서버와 통신을 Public으로 하느냐, Private로 하느냐를 정하는 것이다.

EKS owned ENI) 제어부

// 내부 통신한다.


2) 제어부(컨트롤 플래인) → (EKS owned ENI) 워커노드 kubelet,

// 내부 통신한다.


3) 워커노드,사용자 kubectl → (프라이빗 도메인,

// 내부 통신한다.







4

API server Endpoint 확인은 ?





dig A539F75FBE332DF52BEEC920327282B4.gr7.ap-northeast-2.eks.amazonaws.com

------------------------------------------------------------

;; ANSWER SECTION:

A539F75FBE332DF52BEEC920327282B4.gr7.ap-northeast-2.eks.amazonaws.com. 46 IN A 3.39.118.140


A539F75FBE332DF52BEEC920327282B4.gr7.ap-northeast-2.eks.amazonaws.com. 46 IN A 3.36.29.133



NLB 고정 IP 2개 이다.

50 nlb.png



https://docs.aws.amazon.com/eks/latest/userguide/clusters.html



5

CLI로 확인 가능하다.


kubectl cluster-info

------------------------------------------------------------

Kubernetes control plane is running at https://A539F75FBE332DF52BEEC920327282B4.gr7.ap-northeast-2.eks.amazonaws.com

CoreDNS is running at https://A539F75FBE332DF52BEEC920327282B4.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy





<5> 워커 노드 증설하기



1

# 옵션 [터미널1]

EC2 생성 모니터링


aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table


while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done

------------------------------

myeks-myeks-nodegroup-Node 192.168.2.48 54.180.105.93 running

myeks-host 192.168.1.100 15.165.76.115 running

myeks-myeks-nodegroup-Node 192.168.1.186 15.165.17.199 running

------------------------------


또는

watch -d kubectl get nodes



2

# eks 노드 그룹 정보 확인

eksctl get nodegroup --cluster $CLUSTER_NAME --name $CLUSTER_NAME-nodegroup

CLUSTER NODEGROUP STATUS CREATED MIN SIZE MAX SIZE DESIRED CAPACITY INSTANCE TYPE IMAGE ID ASG NAME TYPE

myeks myeks-nodegroup ACTIVE 2023-04-24T07:34:09Z 2 2 2 t3.medium AL2_x86_64 eks-myeks-nodegroup-8ac3d917-921b-868a-98d1-7f379386079d managed



3

# 노드 2개 → 3개 증가


eksctl scale nodegroup --cluster $CLUSTER_NAME --name $CLUSTER_NAME-nodegroup --nodes 3 --nodes-min 3 --nodes-max 6




모니터링

myeks-myeks-nodegroup-Node 192.168.2.48 54.180.105.93 running

myeks-host 192.168.1.100 15.165.76.115 running

myeks-myeks-nodegroup-Node 192.168.1.186 15.165.17.199 running

------------------------------

myeks-myeks-nodegroup-Node 192.168.2.48 54.180.105.93 running

myeks-myeks-nodegroup-Node 192.168.2.93 3.35.3.28 running

myeks-host 192.168.1.100 15.165.76.115 running

myeks-myeks-nodegroup-Node 192.168.1.186 15.165.17.199 running

------------------------------



4

# 노드 확인

kubectl get nodes -o wide


kubectl get nodes -l eks.amazonaws.com/nodegroup=$CLUSTER_NAME-nodegroup



5

# 노드 3개 → 2개 감소 : 적용까지 시간이 소요됨

aws eks update-nodegroup-config --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-nodegroup --scaling-config minSize=2,maxSize=2,desiredSize=2





<6> 숙제


수업 내용을 간단하게라도 블로깅해주세요

노션에는 하지 마지마시고 블로그에 꼭 해주세요. 노션은 공유 해지하면 볼수가 없어요.

본인이 정리하는 목적입니다.




<7> 삭제


1

CLI로 삭제하기 ?


EKS 클러스터 삭제

eksctl delete cluster --name $CLUSTER_NAME


AWS CloudFormation 스택 삭제 = EC2 삭제임

aws cloudformation delete-stack --stack-name myeks



2

콘솔에서 로드밸런서는 반드시 별도로 삭제해주세요~~




or


1

Cloudformation에서 Stack 삭제 = 명령서버 EC2 삭제 확인


2

콘솔에서 수동 삭제시는 EC2 > AutoSacling Group을 먼저 삭제해야 한다.

그래야, 서버가 다시 생성되지 않는다.

주의) AutoSacling Group삭제하지 않고 그냥 EC2를 삭제하면,AutoSacling Group에 의해 서버가 다시 재 생성 된다.


3

EC2 > 로드 밸런서 삭제

콘솔에서 로드밸런서는 반드시 별도로 삭제해주세요~~




<8> 확인


Amazon EKS 아키텍처 이해?

명령서버 1대 만들고, eksctl로 Amazon EKS 생성 ?

Amazon EKS에 게임 서비스 하나 올리기 ?



전체 보기

https://brunch.co.kr/@topasvga/3217






다음은 EKS 네트워크를 알아보자.


https://brunch.co.kr/@topasvga/3214



keyword
매거진의 이전글EKS 7탄-5. EKS 네트워크 정책 적용-5/5