교육, 커뮤니티 후기/AEWS 스터디

AEWS 스터디 1주차 - AWS EKS 설치 및 기본 사용

Somaz 2023. 4. 30. 00:06
728x90
반응형

출처 : 스터디원 이현수님

 

Overview

2023.01.08 - [교육, 커뮤니티 후기] - PKOS 쿠버네티스 스터디 1주차 - kOps 클러스터 배포

 

PKOS 쿠버네티스 스터디 1주차 - kOps 클러스터 배포

Overview 가시다님이 진행하시는 쿠버네티스 실무 실습 스터디에 참여하게 되었다. 일정은 아래와 같다. 스터디 일정과 커리큘럼 : 1월 8일 ~ 2월 26일 (총 7주 진행) , 매주 일요일 (저녁 8시~10시) 사

somaz.tistory.com

지난번에 참여했던 PKOS 스터디 이후로 이직을 하게 되었다.
 
이번에는 가시다님이 CloudNet@ AEWS(AWS EKS Workshop Study)를 하신다는 얘기를 듣게되었다. 
 
해당 스터디를 통해 EKS에 대해서 열심히 공부해 볼 예정이다.


AWS EKS란?

 

AWS EKS 소개

AWS EKS(Elastic Kubernetese Service)는 자체 Kubernetes 컨트롤 플레인 또는 노드를 설치, 운영 및 유지 관리할 필요 없이 Kubernetes 실행에 사용할 수 있는 관리형 서비스이다.
 
여러 가용 영역에 걸쳐 Kubernetes 컨트롤 플레인을 실행하고 크기를 조정하여 높은 가용성을 보장한다.
그리고 Amazon ECR(컨테이너 이미지 저장소) , ELB(로드벨런서), IAM(인증) , VPC(격리를 위한 네트워크)와 같이 다양한 AWS 서비스와 통합된다.

출처 : https://catalog.us-east-1.prod.workshops.aws/workshops/9c0aa9ab-90a9-44a6-abe1-8dff360ae428/ko-KR/10-intro/200-eks

 


EKS 아키텍처

쿠버네티스를 배포하면 클러스터를 얻는다. 그리고 이 클러스터는 노드들의 집합이다.
노드들은 크게 두 가지 유형으로 나눠지는데, 각각이 컨트롤 플레인과 데이터 플레인이다.
 

 
Control Plane이란?
 

EKS 컨트롤 플레인 (Control Plane)워커 노드와 클러스터 내 파드를 관리하고 제어한다.
Kubernetes API 서버 노드, etcd 클러스터로 구성된다.

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

 
 
Data Plane이란?

 
데이터 플레인(Data Plane)은 워커 노드들로 구성되어 있으며 컨테이너화된 애플리케이션의 구성 요소인 파드를 호스트한다.

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

 

ETCD란 무엇일까?
 

Kubernetes는 기반 스토리지(backing storage)로 etcd를 사용하고 있고, 모든 데이터가 etcd에 보관된다.
예를 들어, 클러스터에 어떤 노드가 몇 개나 있고 어떤 파드가 어떤 노드에서 동작하고 있는지가 etcd에 기록된다.
만약 동작 중인 클러스터의 etcd 데이터베이스가 유실된다면 컨테이너뿐만 아니라 클러스터가 사용하는 모든 리소스가 미아가 되어버린다.

출처 : https://aws.github.io/aws-eks-best-practices/reliability/docs/controlplane/


EKS 실습

EKS 배포를 하는 실습을 진행해보려고 한다. 사용하는 버전은 EKS 1.24 버전이다.

  • Amazon EKS now supports Kubernetes version 1.24 - 링크

 

기본 인프라 배포

  • 링크 ← AWS CloudFormation 페이지로 연결되며, 파라미터 입력 후 스택 실행

위의 있는 링크를 사용해 CloudFormation을 사용해 배포할수도 있다. 

파라미터 : 아래 **빨간색** 부분은 **설정**해주는어야 할 것, **그외** 부분은 **기본값** 사용을 권장

1. <<<<< **EKSCTL MY EC2** >>>>>
    1. ClusterBaseName: EKS 클러스터의 기본 이름 (생성되는 리소스들의 주석에 접두어로 활용), EKS 클러스터 이름에 **'_(밑줄)'** 사용 불가!
    2. **KeyName**: EC2 접속에 사용하는 SSH 키페어 지정
    3. **SgIngressSshCidr**: eksctl 작업을 수행할 EC2 인스턴스를 접속할 수 있는 IP 주소 입력 (**집 공인IP**/32 입력)
    4. MyInstanceType: eksctl 작업을 수행할 EC2 인스턴스의 타입 (기본 t3.medium)
2. <<<<< **Region AZ** >>>>> : 리전과 가용영역을 지정
3. <<<<< **VPC Subnet** >>>>> : VPC, 서브넷 정보 지정

출처 : 가시다님 스터디

 
하지만 나는 해당 방법으로 배포하지 않고 AWS CLI를 사용해 배포하려고 한다.
배포 전 사전 준비는 아래와 같다.

  • aws cli 설치
    • Admin권한이 있는 User 생성 후 Key 다운로드 하여 Accesskey와 Secretkey로 aws configure 구성
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************7SXG shared-credentials-file
secret_key     ****************6qVc shared-credentials-file
    region           ap-northeast-2      config-file    ~/.aws/config
  • ssh 접속을 위한 키 생성

 
이제 cloudformation을 사용해 생성해본다.

# yaml 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/myeks-1week.yaml

# 배포
# aws cloudformation deploy --template-file ~/Downloads/myeks-1week.yaml --stack-name mykops --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 --region <리전>
예시) $ aws cloudformation deploy --template-file ~/Downloads/myeks-1week.yaml \
> --stack-name myeks --parameter-overrides KeyName=somaz-key SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

 

console에서도 확인가능한다.

 
작업용 EC2 생성 후 접속완료 하였다.

# CloudFormation 스택 배포 완료 후 EC2 IP 출력
aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[*].OutputValue' --output text
예시) 3.35.137.31

# ec2 에 SSH 접속
예시) ssh -i <My SSH Keyfile> ec2-user@3.35.137.31
ssh -i ~/.ssh/somaz-key.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)

# 접속성공!
Warning: Permanently added '3.35.229.93' (ED25519) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[root@myeks-host ~]#

 


 
기본 정보 확인

# 사용자 확인
sudo su -
whoami

# 기본 툴 및 SSH 키 설치 등 확인
kubectl version --client=true -o yaml | yh
...
kustomizeVersion: v4.5.7

eksctl version
0.139.0

aws --version
aws-cli/2.11.16 Python/3.11.3 Linux/4.14.311-233.529.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off

# 도커 엔진 설치 확인
docker info

 


 

IAM User 자격 증명 설정 및 VPC 확인 및 변수 지정

생성한 작업용 EC2를 사용하여 EKS를 배포할 것이다. 따라서 해당 EC2에서 aws configure을 한번 더 구성해준다.

# 자격 구성 설정 없이 확인
aws ec2 describe-instances

# IAM User 자격 구성 : 실습 편리를 위해 administrator 권한을 가진 IAM User 의 자격 증명 입력
aws configure
AWS Access Key ID [None]: AKIA5...
AWS Secret Access Key [None]: CVNa2...
Default region name [None]: ap-northeast-2
Default output format [None]: json

# 다시 한번 자격 구성 적용 확인 : 노드 IP 확인
aws ec2 describe-instances
...
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-0f4e16a6f2ceab9ef",
                    "InstanceId": "i-0b4e24c036c303d7e",
                    "InstanceType": "t3.medium",
                    "KeyName": "somaz-key",
 ...
 
# EKS 배포할 VPC 정보 확인
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq Vpcs[]
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq Vpcs[].VpcId
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq -r .Vpcs[].VpcId

# 중요! 배포할 VPCID를 변수에 넣는작업 
export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq -r .Vpcs[].VpcId)
echo "export VPCID=$VPCID" >> /etc/profile

echo $VPCID
vpc-0eb1f80d7fbfa9fc3

# EKS 배포할 VPC에 속한 Subnet 정보 확인
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --output json | jq
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --output yaml | yh

## 퍼블릭 서브넷 ID 확인
aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" | jq
aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text

## 중요 ! 배포할 SubnetID를 변수에 넣는작업
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
subnet-084532f4d3268f433

echo $PubSubnet2
subnet-0b7fd282355622193

 

VPC ID

 

Subnet ID

 


 
eksctl 사용 연습

  • 실제 배포는 하지 않음 - 링크
# eksctl help
eksctl
eksctl create
eksctl create cluster --help
eksctl create nodegroup --help

# 현재 지원 버전 정보 확인
eksctl create cluster -h | grep version
      --version string        Kubernetes version (valid options: 1.22, 1.23, 1.24, 1.25, 1.26) (default "1.25")
      

# eks 클러스터 생성 + 노드그룹없이 / --dry-run이라는 명령어를 사용하면 확인할 수 있다.
# terraform plan과 유사해보인다?
eksctl create cluster --name myeks --region=ap-northeast-2 --without-nodegroup --dry-run | yh


# eks 클러스터 생성 + 노드그룹없이 & 사용 가용영역(2a,2c)
eksctl create cluster --name myeks --region=ap-northeast-2 --without-nodegroup --zones=ap-northeast-2a,ap-northeast-2c --dry-run | yh

# eks 클러스터 생성 + 관리형노드그룹생성(이름, 인스턴스 타입, EBS볼륨사이즈) & 사용 가용영역(2a,2c) + VPC 대역 지정
eksctl create cluster --name myeks --region=ap-northeast-2 --nodegroup-name=mynodegroup --node-type=t3.medium --node-volume-size=30 \
--zones=ap-northeast-2a,ap-northeast-2c --vpc-cidr=172.20.0.0/16 --dry-run | yh

# eks 클러스터 생성 + 관리형노드그룹생성(이름, 인스턴스 타입, EBS볼륨사이즈, SSH접속허용) & 사용 가용영역(2a,2c) + VPC 대역 지정
eksctl create cluster --name myeks --region=ap-northeast-2 --nodegroup-name=mynodegroup --node-type=t3.medium --node-volume-size=30 \
--zones=ap-northeast-2a,ap-northeast-2c --vpc-cidr=172.20.0.0/16 --ssh-access --dry-run | yh
...
managedNodeGroups:
...
  ssh:
    allow: true
    publicKeyPath: ~/.ssh/id_rsa.pub

 


 
Amazon EKS 배포 실습

# 변수확인
echo $AWS_DEFAULT_REGION
ap-northeast-2

echo $CLUSTER_NAME
myeks

echo $VPCID
vpc-0eb1f80d7fbfa9fc3

echo $PubSubnet1,$PubSubnet2
subnet-084532f4d3268f433,subnet-0b7fd282355622193

# 옵션 [터미널1] EC2 생성 모니터링
#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
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
-------------------------------------------------------------
|                     DescribeInstances                     |
+--------------+-----------------+---------------+----------+
| InstanceName |  PrivateIPAdd   |  PublicIPAdd  | Status   |
+--------------+-----------------+---------------+----------+
|  myeks-host  |  192.168.1.100  |  3.35.229.93  |  running |
+--------------+-----------------+---------------+----------+

# eks 클러스터 & 관리형노드그룹 배포: 총 16분(13분+3분) 소요 
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.24 --ssh-access --external-dns-access --verbose 4
...

 
 

while 명령어를 사용해 모니터링

 
 

EKS 생성완료 확인

 
AWS CloudFormation 확인해보기 → AWS EKS 확인해보기 → AWS EC2 확인해보기 → AWS EC2 ASG 확인해보기

CloudFormation 스택에서도 생성완료 확인
EKS 확인
EC2 인스턴스 확인
EC2 AutoScaling 그룹 확인

 


eks 정보 확인

# krew 플러그인 확인
kubectl krew list
kubectl ctx
kubectl ns
kubectl ns default
kubectl get-all    # 모든 네임스페이스에서 모든 리소스 확인

# eks 클러스터 정보 확인
kubectl cluster-info
Kubernetes control plane is running at https://0E7F7608B22E24988BE1E99640C74388.yl4.ap-northeast-2.eks.amazonaws.com
CoreDNS is running at https://0E7F7608B22E24988BE1E99640C74388.yl4.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

eksctl get cluster
aws eks describe-cluster --name $CLUSTER_NAME | jq
aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint
https://0E7F7608B22E24988BE1E99640C74388.yl4.ap-northeast-2.eks.amazonaws.com

## dig 조회 : 해당 IP 소유 리소스는 어떤것일까요?
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS
52.79.69.11
43.201.245.136

# eks API 접속 시도
curl -k -s $(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint)
curl -k -s $(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint)/version | jq
{
  "major": "1",
  "minor": "24+",
  "gitVersion": "v1.24.12-eks-ec5523e",
  "gitCommit": "3939bb9475d7f05c8b7b058eadbe679e6c9b5e2e",
  "gitTreeState": "clean",
  "buildDate": "2023-03-20T21:30:46Z",
  "goVersion": "go1.19.7",
  "compiler": "gc",
  "platform": "linux/amd64"
}

# 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-29T14:09:56Z    2               2               2                       t3.medium       AL2_x86_64     eks-myeks-nodegroup-d0c3e6ac-a252-f294-a3c0-8bb0dd718062 managed

aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-nodegroup | jq


# 노드 정보 확인 : OS와 컨테이너런타임 확인
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
kubectl get node --label-columns=node.kubernetes.io/instance-type
kubectl get node
kubectl get node -owide
kubectl get node -v=6
I0429 23:21:42.220398    7538 loader.go:374] Config loaded from file:  /root/.kube/config
I0429 23:21:43.133548    7538 round_trippers.go:553] GET https://0E7F7608B22E24988BE1E99640C74388.yl4.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500 200 OK in 905 milliseconds
NAME                                               STATUS   ROLES    AGE   VERSION
ip-192-168-1-253.ap-northeast-2.compute.internal   Ready    <none>   10m   v1.24.11-eks-a59e1f0
ip-192-168-2-63.ap-northeast-2.compute.internal    Ready    <none>   10m   v1.24.11-eks-a59e1f0

# 노드의 capacityType 확인
kubectl get node --label-columns=eks.amazonaws.com/capacityType
NAME                                               STATUS   ROLES    AGE   VERSION                CAPACITYTYPE
ip-192-168-1-253.ap-northeast-2.compute.internal   Ready    <none>   11m   v1.24.11-eks-a59e1f0   ON_DEMAND
ip-192-168-2-63.ap-northeast-2.compute.internal    Ready    <none>   11m   v1.24.11-eks-a59e1f0   ON_DEMAND

# 인증 정보 확인 : 자세한 정보는 6주차(보안)에서 다룸
cat /root/.kube/config | yh
aws eks get-token --cluster-name $CLUSTER_NAME --region $AWS_DEFAULT_REGION

# 파드 정보 확인 : 온프레미스 쿠버네티스의 파드 배치와 다른점은? , 파드의 IP의 특징이 어떤가요? 자세한 네트워크는 2주차에서 다룸
kubectl get pod -n kube-system
kubectl get pod -n kube-system -o wide

kubectl get pod -A
NAMESPACE     NAME                      READY   STATUS    RESTARTS   AGE
kube-system   aws-node-8bxzn            1/1     Running   0          11m
kube-system   aws-node-jng8k            1/1     Running   0          11m
kube-system   coredns-dc4979556-969bp   1/1     Running   0          17m
kube-system   coredns-dc4979556-dxc5k   1/1     Running   0          17m
kube-system   kube-proxy-bjl9w          1/1     Running   0          11m
kube-system   kube-proxy-m8wb8          1/1     Running   0          11m

# kube-system 네임스페이스에 모든 리소스 확인
kubectl get-all -n kube-system

# 모든 네임스페이스에서 모든 리소스 확인
kubectl get-all

# 모든 파드의 컨테이너 이미지 정보 확인
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon-k8s-cni:v1.11.4-eksbuild.1
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.8.7-eksbuild.3
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.24.7-minimal-eksbuild.2

# AWS ECR에서 컨테이너 이미지 가져오기 시도
docker pull 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.8.7-eksbuild.3
Error response from daemon: Head "https://602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/v2/eks/coredns/manifests/v1.8.7-eksbuild.3": no basic auth credentials

 


 

노드 정보 상세 확인

 
노드에 SSH로 접속

# 노드 IP 확인 및 PrivateIP 변수 지정
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
----------------------------------------------------------------------------
|                             DescribeInstances                            |
+-----------------------------+----------------+---------------+-----------+
|        InstanceName         | PrivateIPAdd   |  PublicIPAdd  |  Status   |
+-----------------------------+----------------+---------------+-----------+
|  myeks-myeks-nodegroup-Node |  192.168.2.63  |  13.125.112.8 |  running  |
|  myeks-host                 |  192.168.1.100 |  3.35.229.93  |  running  |
|  myeks-myeks-nodegroup-Node |  192.168.1.253 |  3.39.0.83    |  running  |
+-----------------------------+----------------+---------------+-----------+

kubectl get node --label-columns=topology.kubernetes.io/zone
NAME                                               STATUS   ROLES    AGE   VERSION                ZONE
ip-192-168-1-253.ap-northeast-2.compute.internal   Ready    <none>   16m   v1.24.11-eks-a59e1f0   ap-northeast-2a
ip-192-168-2-63.ap-northeast-2.compute.internal    Ready    <none>   16m   v1.24.11-eks-a59e1f0   ap-northeast-2c

kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a
kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo $N1, $N2
192.168.1.253, 192.168.2.63

# eksctl-host 에서 노드의IP나 coredns 파드IP로 ping 테스트 / ping이 되지 않는다?
ping <IP>
ping -c 2 $N1
ping -c 2 $N2

# 노드 보안그룹 ID 확인
aws ec2 describe-security-groups --filters Name=group-name,Values=*nodegroup* --query "SecurityGroups[*].[GroupId]" --output text
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*nodegroup* --query "SecurityGroups[*].[GroupId]" --output text)
echo $NGSGID
sg-00b7f1cb430feb455

# 노드 보안그룹에 eksctl-host 에서 노드(파드)에 접속 가능하게 룰(Rule) 추가 설정
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32

# eksctl-host 에서 노드의IP나 coredns 파드IP로 ping 테스트
ping -c 2 $N1
PING 192.168.1.253 (192.168.1.253) 56(84) bytes of data.
64 bytes from 192.168.1.253: icmp_seq=1 ttl=255 time=0.376 ms
64 bytes from 192.168.1.253: icmp_seq=2 ttl=255 time=0.364 ms

--- 192.168.1.253 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1022ms
rtt min/avg/max/mdev = 0.364/0.370/0.376/0.006 ms

ping -c 2 $N2
PING 192.168.2.63 (192.168.2.63) 56(84) bytes of data.
64 bytes from 192.168.2.63: icmp_seq=1 ttl=255 time=1.02 ms
64 bytes from 192.168.2.63: icmp_seq=2 ttl=255 time=1.09 ms

--- 192.168.2.63 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.021/1.057/1.094/0.048 ms


# 워커 노드 SSH 접속
ssh -i ~/.ssh/id_rsa ec2-user@$N1 hostname
ssh -i ~/.ssh/id_rsa ec2-user@$N2 hostname

ssh -i ~/.ssh/id_rsa ec2-user@$N1
Last login: Tue Apr 11 23:23:29 2023 from 205.251.233.109

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
No packages needed for security; 7 packages available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-192-168-1-253 ~]$
[ec2-user@ip-192-168-1-253 ~]$ exit


ssh -i ~/.ssh/id_rsa ec2-user@$N2
Last login: Tue Apr 11 23:23:29 2023 from 205.251.233.109

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
No packages needed for security; 7 packages available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-192-168-2-63 ~]$ exit
logout
Connection to 192.168.2.63 closed.

 

EKS owned ENI 확인

출처 : 가시다님 스터디

# kubelet, kube-proxy 통신 Peer Address는 어딘인가요?
ssh -i ~/.ssh/id_rsa ec2-user@$N1 sudo ss -tnp
ssh -i ~/.ssh/id_rsa ec2-user@$N2 sudo ss -tnp

# [터미널] aws-node 데몬셋 파드 1곳에 bash 실행해두기 
kubectl exec daemonsets/aws-node -it -n kube-system -c aws-node -- bash

# exec 실행으로 추가된 연결 정보의 Peer Address는 어딘인가요? >> AWS 네트워크 인터페이스 ENI에서 해당 IP 정보 확인
ssh -i ~/.ssh/id_rsa ec2-user@$N1 sudo ss -tnp
ssh -i ~/.ssh/id_rsa ec2-user@$N2 sudo ss -tnp

 
 
관리형 노드 그룹의 워커 노드는 내 소유지만, 연결된 ENI(NIC)의 인스턴스(관리형 노드)는 AWS 소유이다.

 


 

EKS 기본사용

관리 편의성을 위해 kubectl 자동 완성 기능과 alias 사용한다.

# 자동 완성 및 alias 축약 설정
source <(kubectl completion bash)
alias k=kubectl
complete -F __start_kubectl k'

 


 

서비스/파드(mario 게임) 배포 테스트 with CLB

# 터미널1 (모니터링)
watch -d 'kubectl get pod,svc'

# 수퍼마리오 디플로이먼트 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/1/mario.yaml
kubectl apply -f mario.yaml
cat mario.yaml | yh

# 배포 확인 : CLB 배포 확인
kubectl get deploy,svc,ep mario
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mario   0/1     1            0           8s

NAME            TYPE           CLUSTER-IP       EXTERNAL-IP
   PORT(S)        AGE
service/mario   LoadBalancer   10.100.213.197   af975eb31587b4bcc9943363dba72f35-1832582100.ap-northeast-2.elb.amazonaws.com   80:32515/TCP   8s

NAME              ENDPOINTS   AGE
endpoints/mario   <none>      8s

# 마리오 게임 접속 : CLB 주소로 웹 접속
kubectl get svc mario -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Maria URL = http://"$1 }'
Maria URL = http://af975eb31587b4bcc9943363dba72f35-1832582100.ap-northeast-2.elb.amazonaws.com

 
 

로드벨런서 확인

 
 

슈퍼마리오 확인

확인 후 리소스 삭제한다.

k delete -f mario.yaml
deployment.apps "mario" deleted
service "mario" deleted

 


 
 

ECR 퍼블릭 Repository 사용

  • 퍼블릭 Repo 는 설정 시 us-east-1 를 사용 - 링크
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
cat /root/.docker/config.json | jq

# 퍼블릭 Repo 기본 정보 확인
aws ecr-public describe-registries --region us-east-1 | jq

# 퍼블릭 Repo 생성
NICKNAME=<각자자신의닉네임>
NICKNAME=somaz
aws ecr-public create-repository --repository-name $NICKNAME/nginx --region us-east-1

# 생성된 퍼블릭 Repo 확인
aws ecr-public describe-repositories --region us-east-1 | jq
REPOURI=$(aws ecr-public describe-repositories --region us-east-1 | jq -r .repositories[].repositoryUri)
echo $REPOURI
public.ecr.aws/y5u7s1e1/somaz/nginx

# 이미지 태그
docker pull nginx:alpine
docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        alpine    8e75cbc5b25c   4 weeks ago   41MB

docker tag nginx:alpine $REPOURI:latest
docker images
REPOSITORY                            TAG       IMAGE ID       CREATED       SIZE
nginx                                 alpine    8e75cbc5b25c   4 weeks ago   41MB
public.ecr.aws/y5u7s1e1/somaz/nginx   latest    8e75cbc5b25c   4 weeks ago   41MB

# 이미지 업로드
docker push $REPOURI:latest

ECR 이미지 업로드 확인

# 파드 실행
kubectl run mynginx --image $REPOURI
kubectl get pod
kubectl delete pod mynginx

# 퍼블릭 이미지 삭제
aws ecr-public batch-delete-image \
      --repository-name $NICKNAME/nginx \
      --image-ids imageTag=latest \
      --region us-east-1

# 퍼블릭 Repo 삭제
aws ecr-public delete-repository --repository-name $NICKNAME/nginx --force --region us-east-1

ECR 삭제 확인

 


 
 

관리형노드에 노드 추가 및 삭제 Scale

# 옵션 [터미널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

# 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-29T14:09:56Z    2               2               2                       t3.medium       AL2_x86_64      eks-myeks-nodegroup-d0c3e6ac-a252-f294-a3c0-8bb0dd718062        managed

# 노드 2개 → 3개 증가
eksctl scale nodegroup --cluster $CLUSTER_NAME --name $CLUSTER_NAME-nodegroup --nodes 3 --nodes-min 3 --nodes-max 6

# 노드 확인
kubectl get nodes -o wide
NAME                                               STATUS     ROLES    AGE   VERSION                INTERNAL-IP     EXTERNAL-IP     OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-192-168-1-253.ap-northeast-2.compute.internal   Ready      <none>   45m   v1.24.11-eks-a59e1f0   192.168.1.253   3.39.0.83       Amazon Linux 2   5.10.176-157.645.amzn2.x86_64   containerd://1.6.19
ip-192-168-1-8.ap-northeast-2.compute.internal     NotReady   <none>   12s   v1.24.11-eks-a59e1f0   192.168.1.8     43.201.61.209   Amazon Linux 2   5.10.176-157.645.amzn2.x86_64   containerd://1.6.19
ip-192-168-2-63.ap-northeast-2.compute.internal    Ready      <none>   45m   v1.24.11-eks-a59e1f0   192.168.2.63    13.125.112.8    Amazon Linux 2   5.10.176-157.645.amzn2.x86_64   containerd://1.6.19

kubectl get nodes -l eks.amazonaws.com/nodegroup=$CLUSTER_NAME-nodegroup
NAME                                               STATUS   ROLES    AGE   VERSION
ip-192-168-1-253.ap-northeast-2.compute.internal   Ready    <none>   45m   v1.24.11-eks-a59e1f0
ip-192-168-1-8.ap-northeast-2.compute.internal     Ready    <none>   25s   v1.24.11-eks-a59e1f0
ip-192-168-2-63.ap-northeast-2.compute.internal    Ready    <none>   45m   v1.24.11-eks-a59e1f0

# 노드 3개 → 2개 감소 : 적용까지 시간이 소요됨
aws eks update-nodegroup-config --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-nodegroup --scaling-config minSize=2,maxSize=2,desiredSize=2

 


(실습 완료 후) 자원삭제

  • Amazon EKS 클러스터 삭제(10분 정도 소요)
eksctl delete cluster --name $CLUSTER_NAME

 

  • (클러스터 삭제 완료 확인 후) AWS CloudFormation 스택 삭제
aws cloudformation delete-stack --stack-name myeks

 


 
 

스터디 1주차 후기

EKS 설치와 기본사용 방법에 대해 배울 수 있는 시간이었던 것 같다.
개념적인 부분에서 도움이 많이 되었다.
다음시간도 기대가 많이 됩니다!
 


Reference

https://catalog.us-east-1.prod.workshops.aws/workshops/9c0aa9ab-90a9-44a6-abe1-8dff360ae428/ko-KR/10-intro/200-eks
 
https://docs.aws.amazon.com/eks/latest/userguide/clusters.html
 
https://docs.aws.amazon.com/eks/latest/userguide/eks-compute.html
 
https://aws.github.io/aws-eks-best-practices/reliability/docs/controlplane/
 
KaKao Tech etcd에 대한 이해

728x90
반응형