링크: https://www.youtube.com/watch?v=E49Q3y9wsUo
Pod를 중심으로 많은 Object가 모여있음
여기서부터는 L7 (애플리케이션 계층)
annotaions 방식을 사용하면 aws에서 참조해서 사용
aws load balancer addon을 설치하면 얘가 인스턴스모드, ip 모드 선택 가능.
기본 인프라는 CloudNet@에서 AWS CloudFromation 템플릿으로 준비해주셨다.
# CloudFormataion 템플릿 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/myeks-1week.yaml
템플릿을 사용해 CloudFormation에서 리소스를 생성한다.
KeyName: KeyPair (없으면 생성한다)
SgIngressSshCidr: 본인 집의 IP로 (작업용 EC2 접근을 집에서만 할 수 있게)
내용을 확인하고 배포한다.
사용하면 가상 네트워크 VPC, PublicSubent1, PublicSubent2, 작업용 EC2를 배포하게 된다 (사진에 있는 아키텍처 그대로)
생성이 완료되면 CREATE_COMPLETE가 된다.
kubectl version --client=true -o yaml
eksctl version
aws --version
docker info
실습을 하기 위해 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
그 이후에는 EKS 배포할 VPC 정보와 서브넷 ID를 환경변수에 저장합니다.
# 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
# Subnet
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
echo 결과가 잘 나오면 성공한 것이다.
이미 eksctl가 서버에 깔려있기 때문에 바로 사용하면 된다. --dry-run을 사용하면 실제 배포 없이 내용 확인이 가능하다.
사용 전 연습
# eks 클러스터 생성 + 노드그룹 없이
eksctl create cluster --name myeks --region=ap-northeast-2 --without-nodegroup --dry-run | yh
기본 값으로 나오는 것들을 argument로 줄 수 있다.
# 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
이제 실제로 배포해본다. 터미널을 새로 띄운 뒤 아래 명령어를 사용한다.
# 옵션 [터미널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
루프를 돌며 EC2 정보를 계속 보여주는 것을 볼 수 있다. 이제 실제로 eks를 생성해본다.
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.31 --ssh-access --external-dns-access --verbose 4
dry-run을 했을 때와는 다르게 로그가 찍히는 것을 확인할 수 있다.
eksctl로 CloudFormatin Stack을 생성하여 리소스를 생성하기 때문에 CloudFormation콘솔에서 생성되는 과정을 확인할 수 있다.
생성이 완료되면 CREATE_COMPLETE 상태가 된다.
또한 노드 모니터링용 인스턴스에도 Node Group이 생기는 것을 확인할 수 있다.
# 클러스터 정보 확인
eksctl get cluster
# 노드 그룹 정보 확인
eksctl get nodegroup --cluster $CLUSTER_NAME --name $CLUSTER_NAME-nodegroup
aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-nodegroup | jq
# 노드의 capacityType 확인
kubectl get node --label-columns=eks.amazonaws.com/capacityType
# 파드 정보 확인
kubectl get pod -n kube-system
kubectl get pod -n kube-system -o wide
kubectl get pod -A
kubectl top node
kubectl top pod -A
터미널 2개를 띄우고 하나는 모니터링을, 하나는 Deployment를 배포한다.
# 터미널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
<- 명령어 / 모니터링 ->
파드가 모두 삭제되었지만, 곧바로 새로운 3개의 파드가 뜨는 것을 확인할 수 있다.
kubectl get deploy -o yaml | kubectl neat | yh
replica: 3으로 구성이 되어있기 때문에 파드가 삭제해도 일관성을 보장하기 위해 다시 파드를 띄우기 때문이다.
실습 완료 후에는 Deployment를 삭제한다.
kubectl delete deploy my-webs
EKS API 서버는 AWS 관리 VPC에 위치
API 서버 <> 워커 노드 연결 시 EKS Owned ENI를 사용
kubectl -> API 서버의 endpoint -> API 서버 -> EKS owned ENI -> kubelet
kubelet, kube-proxy -> EKS owned ENI -> API 서버
현재는 pulic 하게 열려있기 때문에 보안 강화를 목적으로 외부에서 접근이 가능했던 API Server의 End Point를 AWS VPC내에서만 접근이 가능하도록 변경해본다.
이후에 kubectl cluster-info 명령어를 입력하면 결과가 제대로 나오지 않는 것을 확인할 수 있다.
또한 콘솔에서 확인해도 API server endpoint access가 public에서 public and private로 변경되었다.
이제 설정을 허용해주기 위해 보안 그룹 설정을 해준다.
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
echo "export NGSGID=$NGSGID" >> /etc/profile
그 뒤에는 노드 보안그룹에 eksctl-host 에서 노드(파드)에 접속 가능하게 rule을 설정한다.
# 노드 보안그룹에 eksctl-host 에서 노드(파드)에 접속 가능하게 룰(Rule) 추가 설정
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
보안 그룹 수정 후에 ping 테스트가 성공하는 것을 확인할 수 있다.
ping -c 2 $N1
ping -c 2 $N2
아까는 실행이 되지 않던 cluster-info도 잘 나오는 것을 확인할 수 있다.
kubectl cluster-info
- eksctl delete cluster --name $CLUSTER_NAME
- aws cloudformation delete-stack --stack-name myeks