7주차 테라폼으로 AWS EKS 배포

1. 배경지식

1.1 EKS

  • AWS 환경에서 K8S 클러스터 패턴을 제공해줍니다.

  • Managed Service로 제공하는 서비스이며, Control Node에 대한 운영은 생각할 필요가 없습니다.

  • 다른 AWS 서비스들과 빠른 호환성을 제공하며, AWS 환경 내의 K8S 운영을 도와줍니다.

    • 컨테이너 이미지 저장소 ECR

    • 로드 분산 ELB

    • 인증 IAM

    • 격리 VPC

1.2 Fargate

  • Fargate는 서버리스 컴퓨팅 엔진으로 서버나 클러스터를 직접 관리할 필요 없습니다.

  • 다음과 같이 EKS + Fargate 를 사용하게되면 완전한 서버리스로 운용하고 서버 관리에 대한 복잡성을 줄일 수 있습니다.

  • autoscaling에 대한 부담도 자동확장이 되서 처리할 필요가 없어집니다.

1.3 Karpenter

  • ASG를 거치거나 Cluster Autoscaler를 거치지 않고 바로 EC2를 생성해주는 AWS 솔루션입니다.

  • 23년 10월에 베타가 완료됨

2. AWS EKS Blueprints for Terraform

2.1 Karpenter EKS On Fargate Terraform으로 배포하기

  • AWS EKS Blueprints for terraform은 필요한 요구사항에 따른 terraform 예제 코드가 제공되어있어서 각각 알맞게 적용할 수 있습니다. (링크)

  • 모듈로 구성되어 있진 않아서, 알맞게 모듈로 구성해서 사용하면 됩니다.

  • 또한, blueprint addon들을 제공해줘서 helm 차트 기반으로 빠르게 요구사항을 충족시킬 수 있습니다.

2.2 주요 준비 사항

aws --version
terraform --version
kubectl version --client=true
helm -h
// 해당 툴들에 대한 준비를 해줍니다.

git clone https://github.com/aws-ia/terraform-aws-eks-blueprints
cd terraform-aws-eks-blueprints/patterns/karpenter

// repository를 받아옵니다.

terraform init

2.3 배포된 리소스들 확인

  1. VPC 배포

// VPC 코드에는 다음과 같이 CIDR 이 있는데 해당 FUNCTION은 간편한 TERRAFORM FUNCTION이다.

```
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
```
// 현재 VPC 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
Vpcs: []

terraform apply -target="module.vpc" -auto-approve
Apply complete! Resources: 23 added, 0 changed, 0 destroyed.
  • 다음과 같이 vpc는 잘 구성이 되었다

  1. eks 배포

terraform apply -target="module.eks" -auto-approve
// Apply complete! Resources: 24 added, 0 changed, 0 destroyed.
terraform state list  // 정상적으로 배포된 것을 확인 할 수 있습니다.
// data.aws_availability_zones.available
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
module.eks.data.tls_certificate.this[0]
module.eks.aws_cloudwatch_log_group.this[0]
module.eks.aws_ec2_tag.cluster_primary_security_group["Blueprint"]
module.eks.aws_ec2_tag.cluster_primary_security_group["GithubRepo"]
module.eks.aws_ec2_tag.cluster_primary_security_group["karpenter.sh/discovery"]
module.eks.aws_eks_access_entry.this["cluster_creator"]
module.eks.aws_eks_access_policy_association.this["cluster_creator_admin"]
module.eks.aws_eks_cluster.this[0]
module.eks.aws_iam_openid_connect_provider.oidc_provider[0]
module.eks.aws_iam_policy.cluster_encryption[0]
module.eks.aws_iam_role.this[0]
module.eks.aws_iam_role_policy_attachment.cluster_encryption[0]
module.eks.aws_iam_role_policy_attachment.this["AmazonEKSClusterPolicy"]
module.eks.aws_iam_role_policy_attachment.this["AmazonEKSVPCResourceController"]
module.eks.time_sleep.this[0]
module.vpc.aws_default_network_acl.this[0]
module.vpc.aws_default_route_table.default[0]
module.vpc.aws_default_security_group.this[0]
module.vpc.aws_eip.nat[0]
module.vpc.aws_internet_gateway.this[0]
module.vpc.aws_nat_gateway.this[0]
module.vpc.aws_route.private_nat_gateway[0]
module.vpc.aws_route.public_internet_gateway[0]
module.vpc.aws_route_table.private[0]
module.vpc.aws_route_table.public[0]
module.vpc.aws_route_table_association.private[0]
module.vpc.aws_route_table_association.private[1]
module.vpc.aws_route_table_association.private[2]
module.vpc.aws_route_table_association.public[0]
module.vpc.aws_route_table_association.public[1]
module.vpc.aws_route_table_association.public[2]
module.vpc.aws_subnet.private[0]
module.vpc.aws_subnet.private[1]
module.vpc.aws_subnet.private[2]
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
module.vpc.aws_subnet.public[2]
module.vpc.aws_vpc.this[0]
module.eks.module.fargate_profile["karpenter"].data.aws_caller_identity.current
module.eks.module.fargate_profile["karpenter"].data.aws_iam_policy_document.assume_role_policy[0]
module.eks.module.fargate_profile["karpenter"].data.aws_partition.current
module.eks.module.fargate_profile["karpenter"].data.aws_region.current
module.eks.module.fargate_profile["karpenter"].aws_eks_fargate_profile.this[0]
module.eks.module.fargate_profile["karpenter"].aws_iam_role.this[0]
module.eks.module.fargate_profile["karpenter"].aws_iam_role_policy_attachment.this["AmazonEKSFargatePodExecutionRolePolicy"]
module.eks.module.fargate_profile["karpenter"].aws_iam_role_policy_attachment.this["AmazonEKS_CNI_Policy"]
module.eks.module.fargate_profile["kube_system"].data.aws_caller_identity.current
module.eks.module.fargate_profile["kube_system"].data.aws_iam_policy_document.assume_role_policy[0]
module.eks.module.fargate_profile["kube_system"].data.aws_partition.current
module.eks.module.fargate_profile["kube_system"].data.aws_region.current
module.eks.module.fargate_profile["kube_system"].aws_eks_fargate_profile.this[0]
module.eks.module.fargate_profile["kube_system"].aws_iam_role.this[0]
module.eks.module.fargate_profile["kube_system"].aws_iam_role_policy_attachment.this["AmazonEKSFargatePodExecutionRolePolicy"]
module.eks.module.fargate_profile["kube_system"].aws_iam_role_policy_attachment.this["AmazonEKS_CNI_Policy"]
module.eks.module.kms.data.aws_caller_identity.current[0]
module.eks.module.kms.data.aws_iam_policy_document.this[0]
module.eks.module.kms.data.aws_partition.current[0]
module.eks.module.kms.aws_kms_alias.this["cluster"]
module.eks.module.kms.aws_kms_key.this[0]
# k8s 노드, 파드 정보 확인
kubectl cluster-info
kubectl get node
kubectl get pod -A
  • kube-ops-view 설치 : 노드의 파드 상태 정보를 웹 페이지에서 실시간으로 출력해 줍니다.

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/#scale=3"
  • 다음과 같이 local에서 바로 확인할 수 있습니다.

// karpenter 설치
helm install karpenter oci://public.ecr.aws/karpenter/karpenter --namespace "default"

// karpenter terraform 실행을 해주면 
kubectl apply -f karpenter.yaml

// deployment 생성하고 3개로 스케일합니다.

kubectl apply -f example.yaml
kubectl scale deployment inflate --replicas=3
  • 이렇게 provisioning이 되는 것을 확인할 수 있다.

terraform destroy -auto-approve
// 으로 vpc, eks, addon 등, 모두 삭제해주면 된다.
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
// kubeconfig 삭제 확인
rm -rf ~/.kube/config 

3. EKS Workshop

3.1 EKS 배포

git clone https://github.com/aws-samples/eks-workshop-v2
terraform init
tree .terraform
cat .terraform/modules/modules.json | jq
tree .terraform/providers/registry.terraform.io/hashicorp -L 2

terraform apply -auto-approve
// 리소스 생성

terraform show
// 상세 정보 확인
# EKS 자격증명
## aws eks --region <REGION> update-kubeconfig --name <CLUSTER_NAME> --alias <CLUSTER_NAME>
aws eks --region ap-northeast-2 update-kubeconfig --name eks-workshop
cat ~/.kube/config

# 각자 자신의 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
 
# (참고) 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"


  • 위와 같이 kube-ops-view를 설치해서 프로비져닝에 대한 모니터링이 바로 가능하다.

helm uninstall kube-ops-view -n kube-system

terraform destroy -auto-approve

# VPC 삭제 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml

# kubeconfig 삭제
rm -rf ~/.kube/config

  • Terraform을 이용한 aws eks 배포를 배웠고, 해당 워크숍에서 terraform으로 빠르고 쉽게 배포할 수 있습니다.

Last updated