1. Amazon EKS Blueprints for Terraform - Karpenter on EKS Fargate
Amazon EKS Blueprints for Terraform는 Terraform을 사용하여 다양한 Amazon EKS 클러스터 패턴 템플릿을 제공합니다. 테라폼이 복잡하게 권장하는 구성 지침보다는 사용자가 EKS 클러스터를 최대한 빠르고 쉽게 구성할 수 있도록 하는데에 초점을 두고 있습니다.
아래와 같이 다양한 기타 프로젝트를 지원합니다.
- Gitops
- Data on EKS
- Observability Accelerator
- Karpenter Blueprints
- karpenter-blueprints
Fargate는 컨트롤 플레인 + Fargate(데이터 플레인)의 완전한 서버리스형 쿠버네티스 컴퓨팅 엔진입니다.
이번 실습에서는 제공하는 다양한 패턴들 중에서, Karpenter on EKS Fargate를 실습해 보도록 하겠습니다.
사전준비
aws-eks-blueprints 코드를 준비합니다.
git clone https://github.com/aws-ia/terraform-aws-eks-blueprints
cd terraform-aws-eks-blueprints/patterns/karpenter
tree
main.tf 파일의 local 블록을 수정하여, 이름과 리전 등을 환경에 맞게 수정합니다.
locals {
name = "t101-${basename(path.cwd)}"
region = "ap-northeast-2"
vpc_cidr = "10.10.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Blueprint = local.name
GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints"
}
}
module.vpc 배포
쉬운 이해를 위해서 모듈을 순차적으로 배포해보도록 하고, 첫 번째로 VPC를 먼저로 배포합니다. -target 옵션을 사용하여 특정 모듈을 선택하여 배포할 수 있습니다.
# VPC 배포 - 3분 소요
terraform apply -target="module.vpc" -auto-approve
# 배포 확인
data.aws_availability_zones.available
module.vpc.aws_default_network_acl.this[0]
module.vpc.aws_default_route_table.default[0]
module.vpc.aws_default_security_group.this[0]
...
# VPC 정보 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
aws 콘솔 확인
module.eks 배포
vpc 모듈 배포가 완료되면, eks 모듈을 배포합니다.
# EKS 배포 - 13분소요
terraform apply -target="module.eks" -auto-approve
# 배포 확인
terraform state list
module.eks.data.aws_caller_identity.current
module.eks.data.aws_iam_policy_document.assume_role_policy[0]
module.eks.data.aws_iam_session_context.current
module.eks.data.aws_partition.current
...
배포가 완료되면 EKS 자격 증명을 등록하고 쿠버네티스 동작을 확인 해봅니다. output을 통해 자격증명 명령어를 확인할 수 있습니다.
# 자격증명 확인
terraform output
configure_kubectl = "aws eks --region ap-northeast-2 update-kubeconfig --name t101-karpenter"
# 자격증명 등록
## aws eks --region <REGION> update-kubeconfig --name <CLUSTER_NAME> --alias <CLUSTER_NAME>
aws eks --region ap-northeast-2 update-kubeconfig --name t101-karpenter
cat ~/.kube/config
# context name 변경(kube-ps1 플러그인 등 사용 시, context명이 길 경우)
kubectl config rename-context "arn:aws:eks:ap-northeast-2:$(aws sts get-caller-identity --query 'Account' --output text):cluster/t101-karpenter" "T101-Lab"
# k8s 노드, 파드 정보 확인
kubectl cluster-info
kubectl get node
kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-5b9dfbf96-24cns 0/1 Pending 0 21m
kube-system coredns-5b9dfbf96-952st 0/1 Pending 0 21m
addon 배포 & karpenter helm 배포
eks는 클러스터는 배포되었지만, cni,kube-proxy와 같은 필수 addon등이 설치되지 않았기 때문에, 아직 파드의 상태가 pending 상태인 것을 확인할 수 있습니다. 따라서, 마지막으로 남은 eks_blueprints_addons 모듈을 배포하고 addon과 karpenter(helm)을 확인합니다.
배포할 모듈이 1개 남았기 때문에, 이번에는 타깃을 지정하지 않고 배포합니다. 이번에는 쿠버네티스 노드와 파드가 정상적으로 동작하며, Karpenter는 Helm 통해 배포됨을 확인할 수 있습니다.
# 배포 - 2분소요
terraform apply -auto-approve
# 확인
terraform state list
data.aws_ecrpublic_authorization_token.token
aws_eks_access_entry.karpenter_node_access_entry
module.eks_blueprints_addons.data.aws_caller_identity.current
module.eks_blueprints_addons.data.aws_eks_addon_version.this["coredns"]
module.eks_blueprints_addons.data.aws_eks_addon_version.this["kube-proxy"]
module.eks_blueprints_addons.data.aws_eks_addon_version.this["vpc-cni"]
...
# k8s 클러스터, 노드, 파드 정보 확인
kubectl cluster-info
k get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
fargate-ip-10-10-16-170.ap-northeast-2.compute.internal Ready <none> 9m40s v1.30.0-eks-404b9c6 10.10.16.170 <none> Amazon Linux 2 5.10.220-209.867.amzn2.x86_64 containerd://1.7.11
fargate-ip-10-10-19-50.ap-northeast-2.compute.internal Ready <none> 9m39s v1.30.0-eks-404b9c6 10.10.19.50 <none> Amazon Linux 2 5.10.220-209.867.amzn2.x86_64 containerd://1.7.11
fargate-ip-10-10-25-71.ap-northeast-2.compute.internal Ready <none> 9m43s v1.30.0-eks-404b9c6 10.10.25.71 <none> Amazon Linux 2 5.10.220-209.867.amzn2.x86_64 containerd://1.7.11
fargate-ip-10-10-5-200.ap-northeast-2.compute.internal Ready <none> 9m38s v1.30.0-eks-404b9c6 10.10.5.200 <none> Amazon Linux 2 5.10.220-209.867.amzn2.x86_64 containerd://1.7.11
(⎈|T101-Lab:N/A) JSX⚡️ ~/terraform/eks/terraform-aws-eks-blueprints/patterns/karpenter main ±
kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
karpenter karpenter-6fbc6788cb-ppmtl 1/1 Running 0 2m42s
karpenter karpenter-6fbc6788cb-pv8kk 1/1 Running 0 2m42s
kube-system coredns-86dcddd859-bbhs2 1/1 Running 0 2m44s
kube-system coredns-86dcddd859-dm99x 1/1 Running 0 2m44s
helm list -n karpenter
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
karpenter karpenter 1 2024-07-27 15:21:28.195209 +0900 KST deployed karpenter-0.35.0 0.35.0
Amazon SQS(simple queue)
배포한 karpenter 헬름차트 value를 확인해보면 큐와 관련된 설정을 볼 수 있는데, 이는 Amazon SQS를 활용하여 좀 더 안정성있는 배포를 제공합니다.
KMS(Key Management Service)
AWS의 키관리서비스(KMS)를 활용해서 쿠버네티스의 시크릿 리소스나 ETCD 등을 암호화합니다. 아래 시크릿의 상세 데이터를 보면 Base64로 인코딩 된 값이 아닌 암호화된 값을 확인할 수 있습니다.
아래 키를 통하여 데이터를 암/복호화(대칭키 암호화 방식) 합니다.
Karpenter 실습
실습도구 설치
Karpenter는 노드를 동적으로 오토스케일링 해주는 도구로, 효과적인 실습을 위해서 시각화를 도와주는 도구를 사전에 준비합니다.
kube-ops-view
kube-ops-view는 노드의 파드 상태 정보를 웹 페이지에서 실시간으로 출력해주는 도구입니다.
kube-ops-view를 설치합니다.
# helm 배포
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 port-forward deployment/kube-ops-view -n kube-system 8080:8080 &
# 접속 주소 확인 : 각각 1배, 1.5배, 3배 크기
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080"
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080/#scale=1.5"
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080/#scale=3"
eks-node-viewer
eks-node-viewer는 클러스터 내에서 동적 노드 사용량을 시각화하는 도구입니다.
eks-node-viewer를 설치합니다.
# macOS
brew tap aws/tap
brew install eks-node-viewer
# Windows/Linux Manual
## go 설치
go version
## EKS Node Viewer 설치 : 약 2분 이상 소요
go install github.com/awslabs/eks-node-viewer/cmd/eks-node-viewer@latest
# 실행
eks-node-viewer --resources cpu,memory
Karpenter 리소스 배포
Karpenter.yaml 수정
위에서 모듈을 배포할 때 locals 블록을 수정하여, 아래 사진과 같이 태그 정보 등이 변경되었을 경우에는 Karpenter.yaml의 태그 정보를 동일하게 수정해 줍니다.
카펜터 리소스를 배포하고 확인합니다.
# 배포
kubectl apply -f karpenter.yaml
# 확인
kubectl get ec2nodeclass,nodepool
NAME AGE
ec2nodeclass.karpenter.k8s.aws/default 31s
NAME NODECLASS
nodepool.karpenter.sh/default default
CPU 크기가 1인 샘플 디플로이먼트를 배포하고 레플리카 수를 증가시켜서, 노드의 과부하를 유도합니다. 그리고 노드가 스케일링되는지 확인합니다.
# example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 0
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 1
kubectl apply -f example.yaml
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
inflate 0/0 0 0 42s
# replicas : 0 -> 3
kubectl scale deployment inflate --replicas=3 && kubectl get pod -w
실습 확인
2. EKS Workshop - Terraform
Amazon EKS Workshop은 AWS가 EKS를 배우고 활용하는 방법을 안내하는 교육 프로그램입니다. Kubernetes를 사용하여 애플리케이션을 배포하고 관리하는 방법들과 다양한 EKS 운영에 대한 모범 사례에 대한 실습 랩 가이드를 제공합니다.
EKS Workshop에서 제공하는 테라폼을 통해 EKS를 배포하는 실습을 진행합니다.
사전 준비
코드를 준비합니다.
#
git clone https://github.com/aws-samples/eks-workshop-v2
cd eks-workshop-v2/cluster/terraform
# 각각 .tf 파일 확인해보기
tree
.
├── eks.tf
├── main.tf
├── providers.tf
├── terraform.tfstate
├── variables.tf
└── vpc.tf
실습 확인을 위해 tag를 추가합니다.
locals {
tags = {
created-by = "eks-workshop-v2"
study = "t101"
env = var.cluster_name
}
}
EKS 배포
EKS 배포합니다.
# EKS 배포 : 11분 소요
terraform init
terraform apply -auto-approve
# 배포 확인
terraform state list
module.eks.data.aws_caller_identity.current
module.eks.data.aws_eks_addon_version.this["vpc-cni"]
module.eks.data.aws_iam_policy_document.assume_role_policy[0
...
EKS 배포 확인
AWS 콘솔을 통해서도 EKS가 잘 배포됨을 확인할 수 있습니다.
EKS 자격 증명
이전 blueprint를 이용한 EKS 배포에서는 EKS에 자격 증명에 대한 작업들이 자동화되어 있지만, EKS Workshop 테라폼 코드에는 존재하지 않기 때문에 수동으로 Access Entry를 생성해 주고 정책을 부여해야 합니다.
kubeconfig를 등록하고 kubectl 명령어를 입력해 보면, 아래와 같이 에러가 발생함을 확인할 수 있습니다.
EKS Access Entry 생성
IAM User를 통해 access entry를 생성하고 AamazonEKSClusterAdminPolicy를 연동합니다.
# 각자 자신의 IAM User 의 access entry 생성
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
MYIAMUSER=<각자 자신의 IAM User>
MYIAMUSER=admin
echo $ACCOUNT_ID $MYIAMUSER
aws eks create-access-entry --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER}
aws eks list-access-entries --cluster-name eks-workshop
# 각자 자신의 IAM User에 AmazonEKSClusterAdminPolicy 연동
aws eks associate-access-policy --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster
aws eks list-associated-access-policies --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} | jq
aws eks describe-access-entry --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} | jq
# EKS 자격증명
aws eks --region ap-northeast-2 update-kubeconfig --name eks-workshop
cat ~/.kube/config
# (참고) context name 변경
kubectl config rename-context "arn:aws:eks:ap-northeast-2:$(aws sts get-caller-identity --query 'Account' --output text):cluster/eks-workshop" "T101-Lab"
EKS 자격증명이 정상적으로 되었음을 확인할 수 있습니다.
기타
그 외에도 테라폼을 통해서 다양한 아키텍처의 EKS를 배포하는 방법들을 제공합니다.
'Automation > Terraform' 카테고리의 다른 글
Terraform OpenTofu - T101 9주차 (0) | 2024.08.03 |
---|---|
Terraform Module & Runner - T101 5주차 (2) | 2024.07.14 |
Terraform Provider & State - T101 4주차 (0) | 2024.07.06 |
Terraform 기본사용 3 - T101 3주차 (0) | 2024.06.29 |
Terraform 기본사용 2 - T101 2주차 (0) | 2024.06.23 |