[DevOps/Terraform/T101] 테라폼으로 AWS EKS 생성하고 Kubernetes 리소스 관리하기
이번에는 terraform으로 EKS 클러스터를 생성해 보고 (튜토리얼대로만)
terraform으로 kubernetes 리소스 관리까지 해 볼 것이다!
Provision an EKS Cluster (AWS)
참고 링크 ) Provision an EKS Cluster (AWS) - Terraform - HashiCorp Developer
hashicorp 사에서 제공하는 튜토리얼을 따라 EKS 클러스터를 구축해 보았다.
튜토리얼대로 따라하면 막힘없이 잘 구축할 수 있는데 필요에 따라 tf 파일을 수정해 주면 된다.
$ git clone https://github.com/hashicorp/learn-terraform-provision-eks-cluster
$ cd learn-terraform-provision-eks-cluster
$ ls -al
total 61
drwxr-xr-x 1 rkdls 197609 0 Dec 7 20:39 ./
drwxr-xr-x 1 rkdls 197609 0 Dec 7 20:39 ../
drwxr-xr-x 1 rkdls 197609 0 Dec 7 20:39 .git/
-rw-r--r-- 1 rkdls 197609 674 Dec 7 20:39 .gitignore
-rw-r--r-- 1 rkdls 197609 5772 Dec 7 20:39 .terraform.lock.hcl
-rw-r--r-- 1 rkdls 197609 17136 Dec 7 20:39 LICENSE
-rw-r--r-- 1 rkdls 197609 269 Dec 7 20:39 README.md
-rw-r--r-- 1 rkdls 197609 1160 Dec 7 20:39 eks-cluster.tf
-rw-r--r-- 1 rkdls 197609 1095 Dec 7 20:39 main.tf
-rw-r--r-- 1 rkdls 197609 592 Dec 7 20:39 outputs.tf
-rw-r--r-- 1 rkdls 197609 518 Dec 7 20:39 security-groups.tf
-rw-r--r-- 1 rkdls 197609 527 Dec 7 20:39 terraform.tf
-rw-r--r-- 1 rkdls 197609 107 Dec 7 20:39 variables.tf
-rw-r--r-- 1 rkdls 197609 739 Dec 7 20:39 vpc.tf
eks-cluster.tf
은 클러스터를 생성하고 노드 그룹을 구성할 수 있다.
main.tf
에 지정해 둔 클러스터 이름을 사용하고 vpc.tf
와 security-groups.tf
로 생성한 환경으로 사용한다
노드 그룹마다 인스턴스 타입을 지정할 수 있고 디폴트로 온디맨드 인스턴스가 생성된다.
min/max/desired size로 각 노드 그룹마다 원하는 노드 수를 지정할 수 있다
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "18.26.6"
cluster_name = local.cluster_name # main.tf
cluster_version = "1.22"
vpc_id = module.vpc.vpc_id # vpc.tf
subnet_ids = module.vpc.private_subnets # vpc.tf
eks_managed_node_group_defaults = {
ami_type = "AL2_x86_64"
attach_cluster_primary_security_group = true
# Disabling and using externally provided security groups
create_security_group = false
}
eks_managed_node_groups = {
one = {
name = "node-group-1"
instance_types = ["t3.small"]
min_size = 1
max_size = 3
desired_size = 2
pre_bootstrap_user_data = <<-EOT
echo 'foo bar'
EOT
vpc_security_group_ids = [
aws_security_group.node_group_one.id # security-groups.tf
]
}
two = {
name = "node-group-2"
instance_types = ["t3.medium"]
min_size = 1
max_size = 2
desired_size = 1
pre_bootstrap_user_data = <<-EOT
echo 'foo bar'
EOT
vpc_security_group_ids = [
aws_security_group.node_group_two.id # security-groups.tf
]
}
}
}
마지막으로 variables.tf
에서 region만 서울 리전으로 수정해 줬다.
이제 terraform 명령어를 실행해 주면 EKS 구축 성공이다!
$ terraform init
$ terraform apply -auto-approve
마지막으로 클러스터에 접속하기 위해 aws configure에 등록된 IAM 유저에 대해서 토큰을 발급하여 사용하도록 하는 kubeconfig를 생성하면 된당
$ aws eks --region $(terraform output -raw region) update-kubeconfig \
--name $(terraform output -raw cluster_name)
Added new context arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos to /home/gain/.kube/config
$ cat /home/gain/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: [token]
server: https://[control-plane].gr7.ap-northeast-2.eks.amazonaws.com
name: arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos
contexts:
- context:
cluster: arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos
user: arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos
name: arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos
current-context: arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos
kind: Config
preferences: {}
users:
- name: arn:aws:eks:ap-northeast-2:[account-id]:cluster/education-eks-woK1xAos
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- ap-northeast-2
- eks
- get-token
- --cluster-name
- education-eks-woK1xAos
command: aws
이제 생성된 클러스터 정보와 node를 확인할 수 있다!
$ kubectl cluster-info
Kubernetes control plane is running at https://[control-plane].gr7.ap-northeast-2.eks.amazonaws.com
CoreDNS is running at https://[control-plane].gr7.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-2-41.ap-northeast-2.compute.internal Ready <none> 158m v1.22.15-eks-fb459a0
ip-10-0-2-7.ap-northeast-2.compute.internal Ready <none> 158m v1.22.15-eks-fb459a0
ip-10-0-3-12.ap-northeast-2.compute.internal Ready <none> 158m v1.22.15-eks-fb459a0
AWS EKS 생성 후,
EKS를 생성하고 나서 설치해야 하는 필수 리소스는 아래와 같은데 나는 deployment 하나만 생성하였다.
왜냐하면 EKS 생성하고 나서 어떻게 terraform으로 리소스 관리를 하는지가 이번 포스팅의 목적이기 때문에 나머지는 생략하였다! (쿠버네티스 사용이 아니라 테라폼 사용이 주 목적!!!!)
- cluster-autoscaler
cluster autoscaler는 pod 상태가 fail이거나 다른 노드로 rescheduled되는 경우에 클러스터의 노드 수를 autoscaling해 준다. 일반적으로 클러스터에 배포된다. - aws-node-termination-handler (NTH) (스팟 인스턴스 사용 시 필수인듯함)
AWS에서는 미사용 EC2 용량을 활용하면서 비용 절감을 하기 위해 EC2 스팟 인스턴스를 사용하기도 한다는데, 스팟 인스턴스 종료 알람이 발생하고 나면 인스턴스는 2분 후에 회수된다. aws-node-termination-handler가 인터럽션을 체크하다가 node에 있는 pod를 drain하고, node가 회수되면 최대한 안전하게 다른 node에 pod를 binding하는 역할을 한다. - metrics-server
클러스터 전체의 리소스 사용 데이터를 모니터링하는데, 노드나 컨테이너의 cpu 및 memory 같은 리소스 사용량 메트릭을 수집할 수 있다. - ingress controller
외부 트래픽에 대한 규칙을 정의해 둔 ingress 리소스에 따라 L7 로드밸런서를 구성하는 컨트롤러이다.
참고 링크 ) k8s 필수 애플리케이션, 테라폼으로 한번에 설치하기
★ Manage Kubernetes Resources via Terraform
아래 링크를 참조하여 실습을 진행해 보았고 정말 간단하지만 내 GitHub Repo에 올려두었다ㅎㅎ
참고 링크 ) Manage Kubernetes Resources via Terraform - Terraform - HashiCorp Developer
1. Provider Kubernetes 설정
kubernetes.tf
파일에서 우선 provider를 지정해 준다.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.20.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.0.1"
}
}
}
그리고 “learn-terraform-provision-eks-cluster”로 배포한 EKS 클러스터 정보는 tfstate 파일에 저장되어 있는 점을 활용하여 EKS 클러스터에 접근할 것이다.
data "terraform_remote_state" "eks" {
backend = "local"
config = {
path = "../learn-terraform-provision-eks-cluster/terraform.tfstate"
}
}
# Retrieve EKS cluster information
provider "aws" {
region = data.terraform_remote_state.eks.outputs.region
}
data "aws_eks_cluster" "cluster" {
name = data.terraform_remote_state.eks.outputs.cluster_id
}
그리고 kubernetes를 provider로 구성하려면 여러 가지 방법이 있지만 아래와 같이 하는 것이 좋다.
provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
exec {
api_version = "client.authentication.k8s.io/v1alpha1"
command = "aws"
args = [
"eks",
"get-token",
"--cluster-name",
data.aws_eks_cluster.cluster.name
]
}
}
왜냐하면 AWS EKS에서는 15분 후에 인증 토큰이 만료되기 때문에, EKS에서 제공하는 인증 플러그인(eks get-token
)을 사용하여 토큰이 항상 최신인지 확인하는 것이 좋다!
다른 방법은 oauth2 token 사용, TLS 인증서 자격 증명 사용, HTTP 기본 인증 등이 있다고 한다.
궁금하다면 Terraform Registry에서 찾아 보자~
2. Deployment 리소스 생성
terraform으로 쿠버네티스 리소스를 생성할 때도 yaml 파일로 구성하는 것과 별반 다르지 않았다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
spec:
selector:
matchLabels:
app: ScalableNginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: ScalableNginx
spec:
containers:
- name: nginx
image: nginx:1.7.8
ports:
- containerPort: 80
resources:
requests:
memory: "50Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "0.5"
기존 쿠버네티스에서 사용하는 yaml 구성파일인데 tf 파일로 아래와 같이 바꿀 수 있다.
resource "kubernetes_deployment" "nginx" {
metadata {
name = "deployment-nginx"
labels = {
App = "ScalableNginx"
}
}
spec {
replicas = 2
selector {
match_labels = {
App = "ScalableNginx"
}
}
template {
metadata {
labels = {
App = "ScalableNginx"
}
}
spec {
container {
image = "nginx:1.7.8"
name = "nginx"
port {
container_port = 80
}
resources {
limits = {
cpu = "0.5"
memory = "512Mi"
}
requests = {
cpu = "250m"
memory = "50Mi"
}
}
}
}
}
}
}
아래와 같이 terraform apply를 해 주면 리소스 생성 완료다!
$ terraform apply -auto-approve
data.terraform_remote_state.eks: Reading...
data.terraform_remote_state.eks: Read complete after 0s
data.aws_eks_cluster.cluster: Reading...
data.aws_eks_cluster.cluster: Read complete after 0s [id=education-eks-woK1xAos]
...(중략)...
Plan: 1 to add, 0 to change, 0 to destroy.
kubernetes_deployment.nginx: Creating...
kubernetes_deployment.nginx: Creation complete after 5s [id=default/ingress-nginx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
헉 완전 신기…..
진짜 deployment-nginx가 생겼다!!!
삭제도 멀-끔한 Terraform 사용!
$ terraform destroy -auto-approve
이 명령어만 쳐주면 쿠버네티스 리소스도, EKS 클러스터도, 멀-끔하게 삭제 가능하다! 👏
Leave a comment