brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Apr 23. 2023

EKS 8탄-1.Amazon EKS 설치

EKS 8탄 - 1주차

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

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

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


1

발표자 소개

클라우드 전문가 카페 운영자 https://cafe.naver.com/dnspro

Naver Cloud 마스터 https://m.blog.naver.com/n_cloudplatform/222463915756

DEVOCEAN 전문가 https://devocean.sk.com/experts/view.do?ID=topasvga&page=

AWS KRUG 강남 모임 강사

Kakao Cloud , 가비아 클라우드 아키텍터


자격증 ?

AWS 아키 프로, Google 프로 아키,NaverCloud Pro,  Azure 어드민 , Cisco CCNP



2

진행

이론 1시간, 실습 1시간으로  진행합니다.



전체 내용



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


목표 

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 생성


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


1

실습 환경

VPC 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



2

AWS 콘솔 로그인 하자~

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


서울 리전 사용

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



3

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



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.28 버전으로 설치해보자


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.28 --ssh-access --external-dns-access --dry-run | yh


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


또는 

기존 1.24 버전으로 



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.28 --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


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 }'



6

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



7

삭제

kubectl delete -f mario.yaml



8

생성 

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



사용자 인터넷 - 서비스 

9

질문?






<4> EKS Cluster Endpoint 이해하기


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

EKS Cluster Endpoint - Public 경우 동작은 ?

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

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



1

EKS Cluster Endpoint - Public 경우 동작은 ?



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

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


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

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


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

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




2

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




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

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


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

// 동일하게 ENI로 통신


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

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




3

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



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개 이다.



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에 게임 서비스 하나 올리기 ?




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

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



전체 보기

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


감사합니다.


                    


                    

매거진의 이전글 EKS 7탄-5. EKS 네트워크 정책 적용 활성화,삭
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari