새소식

반응형
k8s/CloudNet@

[CloudNet@] AWS EKS Workshop Study - 1주차.

  • -
728x90
반응형

 

 

안녕하세요 늑대양입니다 😍

 

 

늑대양 오리지널 버전!!

 

 

 

 

이번에 CloudNet@에서 진행하는 AWS EKS Workshop Study(AEWS)에 참여하여 관련 내용을 공유드리고자 합니다.

 

 

AEWS Study #1주차

 

 

오늘은 AEWS 스터디 1주차 학습 내용을 안내해드리록하겠습니다.

 

 

 

CloudNet@ 팀 블로그 메인 커버

 

 

 

 

CloudNet@ 팀 블로그 Main URL:

https://www.notion.so/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863

 

CloudNet@ Blog

CloudNet@ 팀에서 Cloud Infra & Network 기술에 대한 정보를 공유하는 블로그 입니다.

www.notion.so

 

 

 

 

AWS EKS Workshop Study - 1주차

1주차 학습 주제: Amazon EKS 설치 및 기본 사용

Index.

  • Amazon EKS 소개
  • 직접 처음부터 EKS 배포해보기
  • 관리 편리성
  • 기본 사용
  • AWS EKS Workshop: Fundamentals
  • (실습 완료 후) 자원 삭제

 

 

 

 

Amazon EKS 소개

Amazon Elastic Kubernetes Service는 자체 Kubernetes 컨트롤 플레인 또는 노드를 설치, 운영 및 유지 관리할 필요 없이 Kubernetes 실행에 사용할 수 있는 관리형 서비스

 

Amazon EKS Architecture - Image Source: https://static.us-east-1.prod.workshops.aws/public/e7ab9b91-502d-4ada-84e2-5c8b92d8f791/static/images/10-intro/eks_architecture.svg

 

  • 오픈 소스 Kubernetes 소프트웨어의 최신 버전을 실행하므로 Kubernetes 커뮤니티에서 모든 기존 플러그 인과 도구를 사용할 수 있습니다.
  • 필요한 코드를 수정하지 않고 표준 Kubernetes 애플리케이션을 Amazon EKS로 쉽게 마이그레이션할 수 있습니다.

 

 

EKS Control Plane - Image Source: https://awskoreamarketingasset.s3.amazonaws.com/2022%20Summit/pdf/T14S4_Amazon%20EKS%20%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98%20%EC%9A%94%EC%A0%90%20%EC%A0%95%EB%A6%AC.pdf

 

 

  • Control plane: AWS Managed VPC에 배포된 EKS 리소스를 위한 관리 영역 (Not mine!!) (a.k.a Master node)
  • Control plane의 주요 구성 요소: API Server, etcd, Scheduler, Controller manager
  • 여러 AWS 가용 영역에 걸쳐 Kubernetes 컨트롤 플레인을 실행하고 크기를 조정하여 높은 가용성을 보장합니다.
  • 컨트롤 플레인은 제어 영역 인스턴스의 크기를 자동으로 조정하고, 비정상 제어 영역 인스턴스를 감지하고 교체하며, 자동화된 버전 업데이트 및 패치를 제공합니다.

 

 

 

EKS Data Plane - Image Source: https://awskoreamarketingasset.s3.amazonaws.com/2022%20Summit/pdf/T14S4_Amazon%20EKS%20%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98%20%EC%9A%94%EC%A0%90%20%EC%A0%95%EB%A6%AC.pdf

 

 

 

  • Data plane: EKS 클러스터의 실제 작업이 수행되는 영역 (Mine!!!) (a.k.a Worker node)
  • k8s 클러스터의 pod에서 실행되는 컨테이너의 네트워크 및 스토리지를 관리합니다.
  • 이를 위해 Kubernetes의 CNI(Container Network Interface)를 사용하여 Pod 간의 네트워크 연결을 설정하고, StorageClass 및 PersistentVolumeClaim을 사용하여 데이터를 관리합니다.

 

 

etcd 는 어떤 역할을 할까?!🥸

 

  • Kubernetes는 분산 시스템으로 구성되어 있으며, 이를 가능하게 하는 핵심 요소 중 하나가 etcd입니다. 
  • etcd는 Kubernetes의 모든 리소스의 상태를 저장하고 관리하는 분산형 키-값 저장소입니다. 
  • etcd는 Kubernetes API Server와 함께 작동하여 클러스터 상태를 유지 관리합니다. (Control Plane의 짝꿍처럼 이해하자)
  • Kubernetes API Server는 etcd에 데이터를 저장하고, etcd는 이러한 데이터를 안전하게 보관하고 필요한 경우 Kubernetes API Server에 반환합니다. 
  • 이러한 방식으로 etcd는 모든 Kubernetes 리소스의 논리적인 중앙 데이터 저장소 역할을 합니다. 
  • etcd는 안정적이고 일관된 분산 저장소이며, 여러 노드에서 복제됩니다. 
  • 이는 고가용성과 내결함성을 제공하여 Kubernetes 클러스터 전체가 신뢰성 있게 작동할 수 있도록 보장합니다. 
  • 따라서 etcd에 대한 적절한 백업 및 복구 계획이 있어야 하며, 데이터의 안전성을 유지하기 위해 보안 관리도 중요합니다.

 

 

 

AWS 환경에서 EKS를 활용하는 방법은 세 가지!!

  1. Managed node groups
  2. Self-managed nodes
  3. AWS Fargate (Serverless)

 

 

 

직접 처음부터 EKS 배포해보기

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=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

# 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/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)

 

 

기본 정보 확인 작업

Bastion에서 확인 작업 진행!

 

 

 

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

# 자격 구성 설정 없이 확인
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

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

# 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
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
echo $PubSubnet2

 

 

 

EKS 배포를 위한 기본적인 VPC 리소스 확인 진행, 변수에 담아 eksctl create 명령어 실행 시, 사용!!

 

 

# 배포 진행
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

 

 

CloudFormation을 통한 EKS 배포 완료

 

 

EKS Networking 탭에서 배포된 환경 확인 가능 - API Server의 endpoint가 public인 부분 확인!!

 

 

 

노드 정보 상세 확인

# 노드 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
kubectl get node --label-columns=topology.kubernetes.io/zone
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

# eksctl-host 에서 노드의IP나 coredns 파드IP로 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

# 노드 보안그룹에 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 -c 2 $N2

# 워커 노드 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 
exit
ssh -i ~/.ssh/id_rsa ec2-user@$N2
exit

 

 

 

노드 IP 확인 작업 진행

 

 

 

Ping 테스트를 위해, 보안 그룹에 특정 규칙을 aws cli를 통해 추가!!

 

 

 

추가된 보안 그룹 규칙!!

 

 

 

노드 네트워크 정보 확인

# AWS VPC CNI 사용 확인
kubectl -n kube-system get ds aws-node
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

# 파드 IP 확인
kubectl get pod -n kube-system -o wide
kubectl get pod -n kube-system -l k8s-app=kube-dns -owide

ssh -i ~/.ssh/id_rsa ec2-user@$N1 sudo ip -c addr
ssh -i ~/.ssh/id_rsa ec2-user@$N2 sudo ip -c addr
ssh -i ~/.ssh/id_rsa ec2-user@$N1 sudo ip -c route
ssh -i ~/.ssh/id_rsa ec2-user@$N2 sudo ip -c route
ssh -i ~/.ssh/id_rsa ec2-user@$N1 sudo iptables -t nat -S
ssh -i ~/.ssh/id_rsa ec2-user@$N2 sudo iptables -t nat -S

 

 

 

관리 편리성

CLI를 활용한 관리 편리성을 위한 설정 (kubectl to k, krew) 

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


## krew 설치
# 설치
curl -fsSLO 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
tree -L 3 /root/.krew/bin

# PATH 추가
export PATH="${PATH}:/root/.krew/bin"
echo 'export PATH="${PATH}:/root/.krew/bin"' >>~/.bashrc

# krew 확인
kubectl krew
kubectl krew update
kubectl krew search
kubectl krew list
kubectl krew


## kube-ctx, kubbe-ns 설치 및 사용
### kube-ctx
# 설치
kubectl krew install ctx

# 컨텍스트 확인
kubectl ctx

# 컨텍스트 사용 
kubectl ctx <각자 자신의 컨텍스트 이름>



### kube-ns
# 설치
kubectl krew install ns

# 네임스페이스 확인
kubectl ns

# 터미널1
watch kubectl get pod

# kube-system 네임스페이스 선택 사용
kubectl ns kube-system

# default 네임스페이스 선택 사용
kubectl ns -
혹은
kubectl ns default

 

 

 

기본 사용

멱등성 실습!!

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

# 터미널2
# Deployment 배포(Pod 3개)
kubectl create deployment my-webs --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --replicas=3
kubectl get pod -w

# 파드 증가 및 감소
kubectl scale deployment my-webs --replicas=6 && kubectl get pod -w
kubectl scale deployment my-webs --replicas=3
kubectl get pod

# 강제로 파드 삭제 : 바라는상태 + 선언형에 대한 대략적인 확인! ⇒ 어떤 일이 벌어지는가? 
kubectl delete pod --all && kubectl get pod -w
kubectl get pod

# 실습 완료 후 Deployment 삭제
kubectl delete deploy my-webs

 

 

 

서비스/파드(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

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

 

 

 

Mario 게임 배포를 위한 yaml 파일 다운로드 및 apply 진행!!

 

 

 

CLB를 통해, 배포된 마리오 게임

 

 

Mario 배포 정보 확인 및 svc URL(CLB DNS name) 확인

 

 

 

CLB DNS Name을 통해, 배포된 마리오 플레이 가능!!

 

 

 

(내 IT 실력도 버섯 먹은 것처럼 성장할 수 있기를...🫠)

 

 

 

AWS EKS Workshop: Fundamentals

Pod Affinity and Anti-Affinity:

https://www.eksworkshop.com/docs/fundamentals/managed-node-groups/affinity/

 

Pod Affinity and Anti-Affinity | EKS Workshop

Pods can be constrained to run on specific nodes or under specific circumstances. This can include cases where you want only one application pod running per node or want pods to be paired together on a node. Additionally, when using node affinity pods can

www.eksworkshop.com

 

 

Taints:

https://www.eksworkshop.com/docs/fundamentals/managed-node-groups/taints/

 

Taints | EKS Workshop

Taints are a property of a node to repel certain pods. Tolerations are applied to pods to allow their scheduling onto nodes with matching taints. Taints and tolerations work together to ensure that pods are not scheduled on unsuitable nodes. While tolerati

www.eksworkshop.com

 

  • Taint는 노드의 속성으로 특정 파드에 대해, 배포되지 않도록 설정 가능
    (Taint 가 걸린 노드에는 pod가 배포되지 않지만 이를 상쇄시킬 수 있는 toleration이 있으며, 추가 설정 필요)
  • Toleration는 파드에 적용되어 일치하는 taint를 가진 노드에 스케줄링이 가능하도록 설정 
  • Taint와 toleration은 함께 작동하여 파드가 적합하지 않은 노드에 스케줄링되지 않도록 보장!! 
  • Toleration은 일치하는 Taint가있는 노드에 파드를 스케줄링 할 수 있게하지만 이것은 완벽하게 보장되는 것이 아니므로 node affinity 또는 node selector와 같은 다른 k8s 요소를 사용해야 적절히 배포 가능!!
  • Tainted 노드의 구성은 특정 파드가 특정 하드웨어 (예 : GPU 필요)를 갖는 노드 그룹에서만 스케줄링되도록 보장하거나, 특정 k8s 사용자 집합에 전체 노드 그룹을 할당하려는 경우에 사용 가능

 

Taint 설정 옵션:

  • NoSchedule: 해당 노드에 Pod 배포 X, Toleration에 따라 타협(?) 가능
  • PreferNoSchedule: Toleration 없으면 Pod 스케줄링 X (이지만 꼭 그렇지는 않음, 클러스터 내에 자원이 없다면 배포가 되기도..👻)
  • NoExecute: Toleration 없으면 Pod 스케줄링 X

 

 

 

 

(실습 완료 후) 자원 삭제

# Amazon EKS 클러스터 삭제
eksctl delete cluster --name $CLUSTER_NAME

# EKS 클러스터 삭제 확인 후, CloudFormation 스택 삭제
aws cloudformation delete-stack --stack-name myeks

 

 

 

 

 

긴 글 읽어주셔서 감사합니다 

 

 

 

728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.