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

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

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

 

 

 

Overview

2023년 1월 8일, [교육, 커뮤니티 후기] 카테고리로 작성된 이번 포스팅은

CloudNet@ AEWS(AWS EKS Workshop Study) 스터디의 첫 번째 주차 학습 기록이다.

 


이전 PKOS 스터디 이후 이직을 경험한 후,

다시금 쿠버네티스와 AWS EKS에 대한 실무적인 이해를 높이고자 스터디에 참여하였으며,

 

 

본 글에서는 EKS의 개념부터 실제 배포 실습, 네트워크 구성 확인, 노드 그룹 확장/축소,

퍼블릭 ECR 활용, 간단한 애플리케이션 배포까지 전 과정을 상세하게 정리하였다.

 

 

출처 : 스터디원 이현수님

 

 

 

 

 


 

 

 

 

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주차 후기

이번 1주차 스터디를 통해 AWS EKS 클러스터의 전체 구조와 구성 요소, 그리고 관리형 노드 그룹의 개념 및 실습 흐름을 체계적으로 익힐 수 있었다. 특히, 단순히 EKS 클러스터를 만드는 데서 끝나는 것이 아니라, CloudFormation을 통한 인프라 생성부터 시작해 EC2 기반 작업환경 설정, eksctl과 kubectl을 활용한 클러스터 배포 및 리소스 확인까지 실무 중심의 전 과정을 단계별로 따라가며 배울 수 있었다는 점이 인상 깊었다.

 

또한, EKS의 핵심인 Control Plane(제어 영역)과 Data Plane(데이터 영역)의 개념, 그리고 모든 Kubernetes 클러스터의 중심이라 할 수 있는 etcd의 역할과 중요성에 대해 구체적으로 학습할 수 있었다. 이를 통해 클라우드 기반 쿠버네티스 운영의 신뢰성과 확장성이 어떻게 구현되는지를 실제 예제와 명령어 실습을 통해 감각적으로 익히게 되었다.

 

무엇보다도, CloudNet 스터디의 자료 구성과 실습 흐름은 자율적인 탐구와 반복 학습이 가능하도록 설계되어 있어, 중간에 막히더라도 충분히 따라가며 습득할 수 있도록 도와주었다.

 

 

배운 핵심 요약

  • EKS Control Plane은 AWS에서 관리하며, 고가용성과 안정성을 자동으로 보장해준다.
  • etcd는 클러스터의 모든 상태 정보를 저장하는 핵심 DB이며, 유실 시 복구가 매우 어려움.
  • eksctl 명령어의 --dry-run 기능을 통해 실제 리소스 생성 전 계획을 검토할 수 있는 점이 Terraform과 유사해 실무에서도 유용하게 활용 가능.
  • 퍼블릭 ECR 및 마리오 게임 배포를 통한 CLB 생성 확인 등 실습이 직관적이어서 학습 흥미를 높였다.

 

 

다음 주차에는 본격적으로 EKS의 네트워크 구조, Pod 간 통신, 서비스 디스커버리에 대해 더 깊이 다룰 예정이라고 하니, 실제 서비스 운영 관점에서 꼭 알아야 할 부분들이라 더욱 기대가 된다.


 

 

 

 


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
반응형