쿠버네티스를 운영하면서 사용하는 kubectl 버전은 운영하는 Kubernetes 클러스터 버전과 호환되어야 한다. 이 내용은 Kubernetes 공식 문서 내 버전 차이 정책(Version Skew Policy)에서 확인할 수 있으며, Amazon EKS 문서에도 명시적으로 언급되어 있다.
kubectl은kube-apiserver의 한 단계 마이너 버전(이전 또는 최신) 내에서 지원한다.
예:
kube-apiserver은1.32이다.
kubectl은1.33,1.32및1.31을 지원한다.
참고:
HA 클러스터의kube-apiserver인스턴스 간에 버전 차이가 있으면 지원되는kubectl버전의 범위도 줄어든다.
예:
kube-apiserver인스턴스는1.32및1.31이다.
kubectl은1.32및1.31에서 지원한다(다른 버전은kube-apiserver인스턴스 중에 한 단계 이상의 마이너 버전 차이가 난다).
Go 개발 환경: 아래 과정을 사용하면 원하는 kubectl 버전에 맞추어 go를 직접 다운로드하여 바이너리를 빌드하는 과정을 거친다. 해당 Go가 잘 실행될 수 있도록 https://go.dev/wiki/MinimumRequirements 홈페이지에서 언급하는 go 최소 요구 사항을 확인하여 Go 개발 환경을 갖추도록 한다.
Git: 이미 git 명령어가 실행되는 환경이라면 추가로 고려하지 않아도 된다. 그렇지 않다면 https://git-scm.com/ 등을 참고하여 git를 설치하도록 한다.
$ git clone https://github.com/kubernetes/kubernetes $ cd kubernetes
2.기존 버전 태그 확인
아래 명령어를 사용하여 최신 릴리스된 Kubernetes 버전부터 이전 버전까지 목록을 확인할 수 있다. 명령어가 종료되지 않고 : 마크가 앞에 나오는 것을 볼 수 있는데, 스페이스바를 누르면 계속 목록을 볼 수 있으며, q 문자를 누르면 빠져나온다.
$ git tag --sort=-taggerdate
3. 버전 선택 및 체크아웃
빌드하고자 하는 버전 태그를 로컬 환경 변수에 저장하고, 해당 버전에 대한 소스로 변경하기 위해 "git checkout" 커맨드를 사용한다. 여기서는 TAG라는 이름으로 환경 변수를 사용하여 값을 저장한 다음 $TAG 형태로 해당 값을 사용하여 해당 버전에 대한 소스를 체크아웃하였다.
$ TAG=v1.31.2 # 반드시 git tag 목록에 있는 버전을 사용 $ git checkout $TAG
4. 커스텀 태그 설정
Kubernetes 에서 제공하는 빌드 방식은 소스에 대한 Git 저장소에 기존 태그가 이미 저장되어 있어 해당 태그 이름을 우선적으로 활용하여 빌드하도록 구성이 되어 있다. 여기서는 해당 방식을 변경하기보다는, 기존 태그 목록을 제거한 후, 현재 체크아웃한 소스에 대해 커스텀 태그를 설정하는 방식을 적용해보자. 이 때, 임의의 문자열을 사용할 수는 없으며 "v{SEMVER}-{CUSTOM}" 형태를 사용한다. SEMVER는 https://semver.org/lang/ko/ 에서 설명하는 버전 번호에 해당하며, {CUSTOM} 부분에 위에서 설명한 목적에 따라 간단한 문자열을 추가해보는 식으로 설정한다.
이와 같이 빌드한 kubectl은 원하는 버전 커스팀 문자열을 가질 수 있으며, 해당 문자열을 활용한다면 CI/CD에서 kubectl 버전을 확인하여 클러스터 관리에 도움을 주는 방향으로 활용하는 것도 가능하겠다.실제 운영 환경에서는 공식 배포판을 사용하는 것이 안전하며,커스텀 빌드는 테스트나 개발 환경에서 사용하는 것을 권장한다.
Windows 운영체제를 오래 사용하던 사람이라면 아마도 제어판에서 프로그램을 추가 및 삭제하는 방법이 어느정도 익숙하지 않을까 싶다. "프로그램 추가/제거"라는 이전 이름이 어느 순간 "프로그램 및 기능"으로 변경되었고, 이를 통해 설치된 버전이 무엇인지 살펴보고 변경 및 제거를 할 수가 있다.
Windows 11 환경에서 "프로그램 및 기능" 메뉴에서 "AWS" 키워드로 검색한 결과
Windows 11 환경에서 "프로그램 및 기능" 메뉴에서 "AWS" 키워드로 검색한 결과, 현재 설치된 AWS CLI 버전은 2.15.9.0임을 확인할 수 있었다. AWS CLI는 AWS 서비스를 명령어를 통해 관리하도록 해주는 CLI 도구로, `aws configure`를 실행하여 Access Key ID, Secret Access Key, 리전 이름 정도만 설정하면 AWS 서비스를 손쉽게 제어할 수가 있다. 설치할 당시에는 공식 홈페이지 (https://aws.amazon.com/ko/cli/)에서 다운로드를 하여 직접 설치를 진행하였는데, 시간이 지나면서 설치된 버전이 최신인지 확인하고, 최신 버전으로 업그레이드하는 과정이 필자에게는 다소 번거롭게 느껴졌다.
Ubuntu에서 사용하던 "sudo apt update && sudo apt upgrade"와 같이 손쉽게 할 수 있다면 얼마나 좋을까?
문득 갑자기 이런 궁금증이 들었고, winget이라는 도구가 있다는 잊고 있던 생각이 갑자기 났다. 이를 통해 AWS CLI 버전을 최신으로 업그레이드를 진행한 경험을 블로그를 통해 적고자 한다.
winget을 사용하는 기본적인 방법은 apt와 많이 유사하다. 필자는 여전히 "sudo apt update && sudo apt upgrade" 명령어가 익숙한데, winget에서는 update와 upgrade 명령어가 동일하다는 점을 참고하자 (정확히는 update가 upgrade에 대한 alias로 구성되어 있다). 자세한 도움말은 https://aka.ms/winget-command-help 를 통해 확인할 수 있으며, 또는 국내 Microsoft 권순만 MVP께서 정리하신 블로그 글 (URL: https://blog.naver.com/hakunamata2/223366445380 )을 참고해도 좋겠다.
또 다른 방법으로는 Ubuntu에서 "apt list | grep AWS"와 같이 실행하는 것과 같이 PowerShell에서는 다음과 같은 명령어를 통해 확인할 수도 있겠다. 이 방법은 현재 설치된 버전이 2.15.9.0이며, 최신 설치 가능한 버전이 2.16.4라는 정보까지를 같이 알 수가 있다는 장점이 있다.
> winget list | Select-String -Pattern AWS
Freedom Scientific JAWS 2024 FreedomScientific.JAWS.2024 2024.2310.70.400 2024.240??winget
Freedom Scientific JAWS Training Table??{AE1E7553-752E-4D04-9695-EE1FB83C54AE} 25.0.2005.0
AWS Command Line Interface v2 Amazon.AWSCLI 2.15.9.0 2.16.4 winget
이렇게 특정 패키지를 winget 명령어를 통해 설치, 업그레이드, 제거까지 손쉽게 하는 방법에 대해 알아보았다.
5. winget 명령어로 여러 패키지 업그레이드하기
사실 원래는 AWS CLI 툴 자체를 업그레이드하는 목적보다는 이전에 https://github.com/ianychoi/aws-ecs-fargate-dotnet-module3-supplementary 와 같은 내용을 준비하면서 "Build Tools for Visual Studio 2019"가 설치되었던 것 같은데, 해당 패키지를 포함해 AWS CLI 등 여러 버전들을 각각 다운로드받아 최신 버전으로 설치하기가 번거롭다보니 winget을 사용하면 어떨까하는 생각이 들었고 "winget upgrade" 명령어를 통해 손쉽게 최신 버전으로 업데이트를 진행할 수 있었다. "winget upgrade" 를 실행하면 업그레이드 가능한 모든 프로그램들이 나온다. 필자의 경우 이전에 영상 자막을 직접 관리하고자 사용했던 Vrew 프로그램이 오래 되었고, Bandizip, GIMP 등도 업그레이드하지 않던 상황을 손쉽게 확인할 수 있었다. 모든 것을 업그레이드하려면 "winget upgrade --all" 명령어를 사용하면 되겠지만, 꼭 모든 소프트웨어를 업그이드할 필요는 없겠다. 필자의 경우 GIMP를 굳이 최신으로 꼭 업그레이드가 필요한가 싶어 다음과 같이 3개 소프트웨어만 업데이트를 진행하였다.
"winget upgrade"를 실행한 결과 (일부)3개 패키지에 대해 명시적으로 업그레이드하기
이와 같이 winget을 사용해 AWS CLI를 설치, 업그레이드, 제거하는 방법을 살펴보았다. 설치된 소프트웨어를 최신 버전으로 유지함으로써 최신 기능을 활용할 뿐만 아니라 보안 취약점을 방지할 수 있으므로, 정기적으로 업그레이드를 확인하는 것이 좋은데 winget을 통해 AWS CLI 뿐만 아니라 설치된 여러 소프트웨어의 설치된 버전 및 최신 버전을 손쉽게 확인하고 명령어를 통해 쉽게 업그레이드가 가능한 장점을 잘 활용해보았으면 한다.
그리고 Visual Studio Code (줄여서 VSCode) 를 사용하는데, 이 때 본인은 WSL 환경에서 실습을 하고 있으므로, VSCode가 WSL 환경을 인지해야 한다. 이 부분은 WSL이라는 확장팩 설치 및 왼쪽 하단을 클릭하여 "Connect to WSL"을 실행하여 연결이 되어야 한다는 점을 참고하자.
# 초기화
terraform init
ls -al
tree .terraform
# plan 확인
terraform plan
# apply 실행
terraform apply
Enter a value: yes 입력
# ec2 생성 확인 : aws 웹 관리 콘솔에서도 확인 - 서울 리전 선택
export AWS_PAGER=""
aws ec2 describe-instances --output table
# 테라폼 정보 확인
terraform state list
terraform show
terraform show aws_instance.example
이번에는 태그 정보를 수정하고 적용해보자.
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$AL2ID"
instance_type = "t2.micro"
tags = {
Name = "aews-study"
}
}
EOT
# plan 실행 시 아래와 같은 정보가 출력
terraform plan
# aws_instance.example will be updated in-place
~ resource "aws_instance" "example" {
id = "i-0fe5acad038030055"
~ tags = {
+ "Name" = "aews-study"
}
~ tags_all = {
+ "Name" = "aews-study"
}
# (38 unchanged attributes hidden)
# (8 unchanged blocks hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
# apply 실행
terraform apply
Enter a value: yes 입력
# 모니터링 : [터미널1]에 Name 확인
실습을 완료하였으면 리소스를 삭제하자.
# 리소스 삭제
terraform destroy
Enter a value: yes 입력
혹은
terraform destroy -auto-approve
# 배포
terraform plan && terraform apply -auto-approve
terraform state list
aws_internet_gateway.myigw
aws_subnet.mysubnet1
aws_subnet.mysubnet2
aws_vpc.myvpc
그 다음에는 vpc.tf 코드를 수정하여 IGW 인터넷 게이트웨이로 전달하는 디폴트 라우팅 정보를 추가하자.
# 배포
ls *.tf
terraform plan && terraform apply -auto-approve
terraform state list
aws_security_group.mysg
aws_security_group_rule.mysginbound
aws_security_group_rule.mysgoutbound
...
terraform state show aws_security_group.mysg
terraform state show aws_security_group_rule.mysginbound
# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot
- ec2.tf 파일 내용:
data "aws_ami" "my_amazonlinux2" {
most_recent = true
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
}
owners = ["amazon"]
}
resource "aws_instance" "myec2" {
depends_on = [
aws_internet_gateway.myigw
]
ami = data.aws_ami.my_amazonlinux2.id
associate_public_ip_address = true
instance_type = "t2.micro"
vpc_security_group_ids = ["${aws_security_group.mysg.id}"]
subnet_id = aws_subnet.mysubnet1.id
user_data = <<-EOF
#!/bin/bash
wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64
mv busybox-x86_64 busybox
chmod +x busybox
echo "Web Server</h1>" > index.html
nohup ./busybox httpd -f -p 80 &
EOF
user_data_replace_on_change = true
tags = {
Name = "aews-myec2"
}
}
output "myec2_public_ip" {
value = aws_instance.myec2.public_ip
description = "The public IP of the Instance"
}
#
ls *.tf
terraform plan && terraform apply -auto-approve
terraform state list
data.aws_ami.my_amazonlinux2
aws_instance.myec2
...
terraform state show data.aws_ami.my_amazonlinux2
terraform state show aws_instance.myec2
# 데이터소스 값 확인
terraform console
>
data.aws_ami.my_amazonlinux2.id
"ami-0972fbae82d8513f6"
data.aws_ami.my_amazonlinux2.image_id
data.aws_ami.my_amazonlinux2.name
data.aws_ami.my_amazonlinux2.owners
data.aws_ami.my_amazonlinux2.platform_details
data.aws_ami.my_amazonlinux2.hypervisor
data.aws_ami.my_amazonlinux2.architecture
exit
# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot
# 출력된 EC2 퍼블릭IP로 cul 접속 확인
terraform output -raw myec2_public_ip
43.203.247.218
MYIP=$(terraform output -raw myec2_public_ip)
while true; do curl --connect-timeout 1 http://$MYIP/ ; echo "------------------------------"; date; sleep 1; done
AWS 리소스에 대한 의존성은 다음과 같다.
이와 같이 AWS EC2 리소스와 Security Group, 그리고 관련한 네트워크 리소스에 대한 전반적인 의존성을 확보하면서 Terraform으로 생성해보는 실습을 진행하였다. 실습을 다 진행한 후에는 리소스 삭제를 꼭 하자.
terraform destroy -auto-approve
1.4. 프로바이더 활용하기 - Tier
Terraform는 프로바이더에 대한 Tier (Official, Partner, Community) 가 있다. https://registry.terraform.io/browse/providers 에서는 Official은 Hashicorp에서 직접 유지보수를 하는 Tier, Partner는 기술 파트너를 통해 유지보수가 이루어지는 Tier, Community는 Hashicorp 커뮤니티 생태계를 통해 퍼블리싱 및 유지보수가 이루어진다고 한다.
# variable.tf
variable "isDB" {
type = bool
default = false
description = "패스워드 대상의 DB 여부"
}
# output.tf
output "id" {
value = random_pet.name.id
}
output "pw" {
value = nonsensitive(random_password.password.result)
}
#
cd 06-module-traning/modules/terraform-random-pwgen
#
ls *.tf
terraform init && terraform plan
# 테스트를 위해 apply 시 변수 지정
terraform apply -auto-approve -var=isDB=true
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
id = "knowing-aardvark"
pw = "Y5eeP0i2KLLE9gBa"
# 확인
terraform state list
terraform state show random_pet.name
terraform state show random_password.password
# graph 확인
terraform graph > graph.dot
자식 모듈 호출을 실습해본다. 다수 리소스를 같은 목적으로 여러 번 반복해서 사용하려면 리소스 수만큼 반복해 구성 파일을 정의해야 하고 이름도 고유하게 설정해줘야 하는 부담이 있지만, 모듈을 활용하면 반복되는 리소스 묶음을 최소화할 수 있다.
# 코드 가져오기
git clone https://github.com/gasida/aews-cicd.git
cd aews-cicd/4
# terraform 환경 변수 저장
export TF_VAR_KeyName=[각자 ssh keypair]
export TF_VAR_KeyName='kp-ian'
echo $TF_VAR_KeyName
#
terraform init
terraform plan
# 10분 후 배포 완료
terraform apply -auto-approve
약 10분이 지나 배포가 완료되면 배포 정보를 확인한다. kubectl 명령어를 실행 가능하도록 인증 정보를 가져오는 단계가 필요하다.
#
kubectl get node -v=6
# EKS 클러스터 인증 정보 업데이트
CLUSTER_NAME=myeks
aws eks update-kubeconfig --region ap-northeast-2 --name $CLUSTER_NAME
kubectl config rename-context "arn:aws:eks:ap-northeast-2:$(aws sts get-caller-identity --query 'Account' --output text):cluster/$CLUSTER_NAME" "Aews-Labs"
#
kubectl cluster-info
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
kubectl get pod -A
그 다음 코드를 재사용하여 두 번째 클러스터를 배포해보자. 다른 클러스터에 접근하므로 서로 다른 kubeconfig 가 필요하다. myeks 클러스터에 접근할 때는 디폴트 config를, myeks2 클러스터에 접근할 때는 myeks2config 파일을 참조하는 것으로 확인을 하였다.
#
cd ..
mkdir 5
cd 5
cp ../4/*.tf .
ls
#
terraform init
terraform apply -auto-approve -var=ClusterBaseName=myeks2 -var=KubernetesVersion="1.28"
# EKS 클러스터 인증 정보 가져오기
CLUSTER_NAME2=myeks2
aws eks update-kubeconfig --region ap-northeast-2 --name $CLUSTER_NAME2 --kubeconfig ./myeks2config
# EKS 클러스터 정보 확인
kubectl --kubeconfig ./myeks2config get node
kubectl --kubeconfig ./myeks2config get pod -A
실습을 다 하였다면 첫 번째 클러스터 및 두 번째 클러스터를 아래를 참고하여 완전히 삭제하도록 하자. 첫 번째 클러스터를 삭제하고