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
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
네트워크를 생성하고, 서브넷안에 작업용 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
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
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
질문?
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
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
수업 내용을 간단하게라도 블로깅해주세요
노션에는 하지 마지마시고 블로그에 꼭 해주세요. 노션은 공유 해지하면 볼수가 없어요.
본인이 정리하는 목적입니다.
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 > 로드 밸런서 삭제
콘솔에서 로드밸런서는 반드시 별도로 삭제해주세요~~
Amazon EKS 아키텍처 이해?
명령서버 1대 만들고, eksctl로 Amazon EKS 생성 ?
Amazon EKS에 게임 서비스 하나 올리기 ?
https://brunch.co.kr/@topasvga/3214
전체 보기
https://brunch.co.kr/@topasvga/3217
감사합니다.