들어가며
지난 PKOS(Production Kubernetes Online Study)에 이어 새로운 워크숍 스터디인 AEWS(AWS EKS Workshop Study)에 참여하게 되었다.
PKOS에서는 kOps를 이용하여 클러스터 환경을 구축했었는데, 이번에는 업계에서 가장 많이 사용하고 있는 EKS(Amazon Elastic Kubernetes Service)를 기반으로 클러스터 환경을 구축한다. 자체 Kubernetes 컨트롤 플레인을 운영하고 유지 관리해야 했던 kOps와는 달리 EKS에서는 관리형 서비스 형태로 컨트롤 플레인을 사용할 수 있도록 해준다. 운영을 위해 숙지해야할 클러스터 환경에 대한 내용과 네트워크, 스토리지, 보안 개념 등을 배우게 된다.
이번 주차에는 Amazon EKS를 설치하고 기본적인 사용 방법에 대해 학습했다.
Amazon EKS 란?
Amazon EKS는 Kubernetes를 쉽게 실행할 수 있는 관리형 서비스로써, AWS 환경에서 Kubernetes 컨트롤 플레인 노드를 직접 설치, 운영 및 유지할 필요가 없다.
EKS는 그림과 같이 여러 가용 영역에서 컨트롤 플레인을 분산하여 실행하기 때문에 고가용성이 보장된다. 또한 비정상 컨트롤 플레인 인스턴스를 자동으로 감지하고 교체하여 자동화된 버전 업그레이드 및 패치를 제공한다. EKS는 오픈 소스 Kubernetes 소프트웨어 최신 버전을 실행하기 때문에 Kubernetes 커뮤니티에서 사용하는 플러그인과 툴을 모두 사용할 수 있다. 다음의 링크를 통해 EKS가 지원하는 여러 가지 버전을 확인할 수 있다. 링크
EKS 컨트롤 플레인 구성
EKS 컨트롤 플레인은 다음과 같은 구성을 하고 있다.
컨트롤 플레인의 구성요소인 API 서버, 컨트롤러, 스케줄러, etcd가 AWS Managed VPC에서 여러 AZ(Availability Zone)에 배치되어있다. 그림의 구성에 나오는 Network Load Balancer는 Elastic Load Balancing이 지원하는 Load Balancer 중 하나로 단일 접점에서 트래픽을 수신하여 여러 인스턴스로 분산하는 역할을 한다.
API 서버는 클러스터와 통신하는 중앙 인터페이스로, 사용자와 시스템 요청을 처리한다. 컨트롤러는 클러스터의 상태를 관리하고, 목표 상태를 유지하기 위해 자동으로 조정한다. 스케줄러는 적절한 노드에 파드를 할당하며, etcd는 분산 데이터 저장소로 클러스터 구성 정보를 저장하는 컨트롤 플레인의 요소다.
EKS 데이터 플레인(Follow Node) 구성
Kubernetes에는 기본적으로 세가지의 구성요소가 있다.
- 컨테이너 런타임: 컨테이너 실행을 담당
- Kubelet: 컨테이너가 관련 Pod 내에서 정상적으로 실행 중인지 확인
- Kube-proxy: Pod과 통신을 허용하는 네트워크 규칙을 관리
kubelet은 각 노드에서 실행되며, 해당 노드에 할당된 파드의 생명 주기를 관리한다. kube-apiserver는 클러스터의 중앙 인터페이스로, kubelet과 통신하며 파드 상태를 업데이트하고 명령을 전달한다. 이들의 통신을 통해 노드와 클러스터 전체의 동작 상태가 관리된다.
위의 그림을 보면 VPC가 두가지로 나뉜다.
AWS Managed VPC는 AWS에서 자동으로 생성되고 관리되는 가상 사설 네트워크로, 사용자의 작업 부하를 위한 격리된 네트워크 환경을 제공한다. 이전의 그림에서 살펴보았듯이 컨트롤 플레인 요소들은 모두 여기에 배치되어 있다.
Customer VPC는 사용자가 직접 생성하고 관리하는 VPC로 관리형 노드 그룹(EC2)이 배치된다. VPC가 분리되어 있기 때문에 통신을 위해 EKS owned ENI(Elastic Network Interface)를 사용한다. EKS owned ENI는 클러스터 생성 시 자동으로 생성되며, VPC의 서브넷에 할당되어 각 노드의 kubelet과 통신할 수 있도록 한다.
EKS Cluster의 Endpoint에 접근하는 방법에 대한 내용 역시 설명을 들었는데, AWS Managed VPC와 Customer VPC를 Public환경과 Private 환경으로 구축하여 API 서버와 Kubelet과의 통신, 그리고 Kube-proxy의 외부 통신, 개발자의 클러스터 접근하는 방법을 제한할 수 있는 다양한 방법이 있었다.
결과적으로 Kube-apiserver를 포함한 모든 Kubernetes 리소스가 외부로 노출되지 않도록 Private 환경에서 모든것을 구축하고, Private Hosted Zone을 통해 접근하도록 환경을 구축하는 것이 실무적으로 가장 보안성이 좋다고 느껴졌다.
Private Hosted Zone은 Amazon Route 53에서 제공하는 DNS 서비스로, 특정 Amazon VPC 내에서만 DNS 이름을 사용할 수 있는 도메인 네임스페이스를 생성한다. 이를 통해 사용자는 VPC 내의 리소스에 대해 사설 DNS 이름을 지정하고 관리할 수 있다. Private Hosted Zone은 VPC 외부에서는 액세스 할 수 없으므로, 보안 및 네트워크 트래픽의 격리를 효과적으로 제공한다.
EKS 환경 구성 실습
EKS 환경을 구축하기 위해서 다양한 방법을 활용할 수 있다고 한다. Terraform을 이용하는 방법도 있고, awscli에서 커맨드 형태로 하나하나 구축하는 방법, CloudFormation을 이용하는 방법 등을 사용할 수 있다.
우선은 실습에서 활용한 AWS CloudFormation Template을 이용해서 작업용 Bastion 인스턴스를 생성하고, EKS 클러스터를 구축했다. 링크
Customer VPC에 Bastion을 설치하고, EKS Control Plane과 데이터 플레인을 생성하는 형태로 EKS 클러스터를 구축한다.
가시다 님께서 작성하신 CloudFomation yaml 파일을 통해 환경을 설치하면 VPC와 Subnet 4개(PrivateSubnet 2개, PublicSubnet 2개), EC2 1대, 그리고 보안그룹이 생성된다.
Bastion 서버에서 eksctl create cluster를 이용하여 EKS 클러스터를 구축하는 방법은 아래와 같다.
# Bastion 설치시 Yaml파일에 선언된 내용
## 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/
echo $AWS_DEFAULT_REGION # ap-northeast-2, 배포용 YAML 파일에 명시되어 있음
echo $CLUSTER_NAME # myeks 배포용 YAML 파일에 명시되어 있음
# 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
## EKS 배포할 VPC에 속한 Subnet 정보 확인 (YAML highlighter를 사용하여 시각적으로 확인이 가능하다.)
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 $VPCID
echo $PubSubnet1,$PubSubnet2
## 터미널에서 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
## eks 클러스터를 생성하고, 관리형 노드그룹을 생성함(이름과 인스턴스 타입, EBS 볼륨 사이즈, SSH 접속 허용등을 설정)
## 가용영역은(ap-northeast-2 -> 2a, 2c)로 설정하고, VPC 대역을 지정함
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
실습 환경을 통해 쿠버네티스를 구축하면 Kubernetes 1.24버전이 설치되고, t3.medium 2대로 구성된 데이터 플레인이 생성되었다. 이때 API 서버 엔드포인트는 Public으로 구성되어서 아래와 같이 외부에서 접근가능해진다.
실무 환경에서 클러스터를 운영할때는 Private Hosted Zone을 활용한 Private 환경을 구축하여 이러한 상황이 발생하지 않도록 주의해야 할 것이다.
생성된 Instance들을 확인하고, Bastion Server에서 생성된 데이터 플레인 노드(Pod)들에 접속 가능하게 보안그룹에 Rule을 추가한다.
세팅을 끝내고 hostname을 조회해보면 Bastion에서 각 데이터 플레인 노드에 접속 가능해진다.
마지막으로 지난 스터디에서 처럼 생성된 클러스터에 정상적으로 Pod가 배포되는지 Bastion 서버에서 테스트해보았다.
# 터미널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 }'
생성된 CLB 주소로 접속하면 Mario 게임 Pod가 정상적으로 배포되었음을 확인할 수 있다.
마치며
이번 글에서는 Amazon EKS 워크숍 스터디 1주 차에 진행한 내용을 정리해 보았다.
오랜만에 key pair를 새로 생성하여 활용하니 보안 관련 문제가 발생해서 당황했지만, pem 파일을 ~/.ssh 디렉터리로 옮긴 후 chmod 600으로 권한을 변경해서 해결했다. 이론적으로는 kOps 환경에서 클러스터를 구축하던 것보다 안정성이 훨씬 좋아 보였다. 또한 최신버전의 Kubernetes version을 자동으로 관리할 수 있다는 점도 프로덕션 환경에서 많은 부담을 줄일 수 있을 것으로 보였다.
실제로 서비스를 배포하면서 스터디 장이신 가시다님께서 말씀하신 대로 마리오게임의 CLB가 엄청 빨리 배포되는 것을 보면서 공식적으로 제공되는 Kubernetes 서비스가 좋긴 좋구나 하는 생각도 들었다.
스터디를 진행할수록 AWS 관련 배경지식이 늘어 이해를 할 수 있는 부분이 이전보다 많아졌지만, 아직 곱씹어보고 내용을 정확히 이해해야 할 부분이 많은 것을 느꼈다. 더 열심히 해야겠군요..
'클라우드 컴퓨팅 & NoSQL > [AEWS] Amazon EKS 워크숍 스터디' 카테고리의 다른 글
[6주차] AEWS Amazon EKS 워크숍 스터디 (23.05.28) (3) | 2023.06.02 |
---|---|
[5주차] AEWS Amazon EKS 워크숍 스터디 (23.05.21) (0) | 2023.05.27 |
[4주차] AEWS Amazon EKS 워크숍 스터디 (23.05.14) (0) | 2023.05.20 |
[3주차] AEWS Amazon EKS 워크숍 스터디 (23.05.07) (2) | 2023.05.14 |
[2주차] AEWS Amazon EKS 워크숍 스터디 (23.04.30) (0) | 2023.05.07 |