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 서비스와 통합된다.
EKS 아키텍처
쿠버네티스를 배포하면 클러스터를 얻는다. 그리고 이 클러스터는 노드들의 집합이다.
노드들은 크게 두 가지 유형으로 나눠지는데, 각각이 컨트롤 플레인과 데이터 플레인이다.
Control Plane이란?
EKS 컨트롤 플레인 (Control Plane)은 워커 노드와 클러스터 내 파드를 관리하고 제어한다.
Kubernetes API 서버 노드, etcd 클러스터로 구성된다.
Data Plane이란?
데이터 플레인(Data Plane)은 워커 노드들로 구성되어 있으며 컨테이너화된 애플리케이션의 구성 요소인 파드를 호스트한다.
ETCD란 무엇일까?
Kubernetes는 기반 스토리지(backing storage)로 etcd를 사용하고 있고, 모든 데이터가 etcd에 보관된다.
예를 들어, 클러스터에 어떤 노드가 몇 개나 있고 어떤 파드가 어떤 노드에서 동작하고 있는지가 etcd에 기록된다.
만약 동작 중인 클러스터의 etcd 데이터베이스가 유실된다면 컨테이너뿐만 아니라 클러스터가 사용하는 모든 리소스가 미아가 되어버린다.
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
작업용 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
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
...
AWS CloudFormation 확인해보기 → AWS EKS 확인해보기 → AWS EC2 확인해보기 → AWS EC2 ASG 확인해보기
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
# 파드 실행
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
관리형노드에 노드 추가 및 삭제 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에 대한 이해
'교육, 커뮤니티 후기 > AEWS 스터디' 카테고리의 다른 글
AEWS 스터디 6주차 - EKS Security (4) | 2023.06.03 |
---|---|
AEWS 스터디 5주차 - EKS Autoscaling (0) | 2023.05.27 |
AEWS 스터디 4주차 - EKS Observability (0) | 2023.05.17 |
AEWS 스터디 3주차 - EKS Storage & Node 관리 (1) | 2023.05.11 |
AEWS 스터디 2주차 - EKS Networking (0) | 2023.05.01 |