kOps를 활용하여 AWS 배포하기
by softPine스터디를 하면서 kOps를 활용하여 AWS에 t3.medium 인스턴스 3대로 k8s를 구성하기로 했다.
전체적인 설치를 진행해본다.
kOps, kubectl 설치하기
먼저 kOps로 배포를 하기 위해 kOps를 설치한다. 전부 Amazon Linux 2 환경에서 root 계정으로 진행을 한다.
kOps 설치
curl -Lo kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64
chmod +x ./kops
sudo mv ./kops /usr/local/bin/
kubectl 설치
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo "alias k='/usr/local/bin/kubectl'" >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
source .bashrc
AWS 환경 셋팅하기
먼저 kOps로 k8s를 AWS에 배포하기 위해서 권한을 먼저 셋팅을 해야한다. 먼저 AWS CLI를 이용해서 제대로 설치를 하고 설정을 진행을 했다면 인증까지 문제없이 진행이 될 것이다.
AWS IAM 유저 생성하기
AWS 내에서 클러스터를 구축하기 위해 kOps용 IAM 유저를 생성한다. 이 유저는 kOps를 옳바르게 사용하려면 AWS API에 대한 권한이 필요하다.
kOps 유저에 필요한 권한은 다음과 같다.
AmazonEC2FullAccess
AmazonRoute53FullAccess
AmazonS3FullAccess
IAMFullAccess
AmazonVPCFullAccess
위에서 이야기한 AWS CLI를 활용하여 kOps 유저에 대한 권한 설정을 진행한다.
aws iam create-group --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess --group-name kops
aws iam create-user --user-name kops
aws iam add-user-to-group --user-name kops --group-name kops
aws iam create-access-key --user-name kops
마지막 명령을 실행하게 되면 kOps 계정에 대한 액세스키와 시크릿키에 대한 json output을 반환 받는다. 이 반환 받은 키 값들을 사용하여 다음의 명령어를 실행한다.
# 새로 만든 kOps 유저의 키들을 사용하여 cli 환경 설정을 진행한다.
aws configure # 신규 키를 삽입한다.
aws iam list-users # 정상적으로 호출이 되는지 확인하고 iam 유저들의 리스트를 확인한다.
# aws configure 에서는 kOps에서 사용할 변수를 반환해주지 않기 때문에 지금 export 한다.
export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id)
export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key)
DNS 설정하기
kOps로 k8s 클러스터를 구축하려면 DNS 레코드를 설정할 수 있는 DNS 서버가 있어야 한다. 아래 3가지 중 AWS의 상황에 가장 근접한 상황을 선택한다.
- AWS를 통해 도메인 구매 및 호스팅
- Route53에 구매를 한 도메인에 대해 host zone이 있다면 더 이상 작업이 필요없다.
- 구매한 도메인의 sub 도메인 사용
- 이번에는 softpine.dev 도메인을 그대로 사용하고서브도메인으로 k8s.softpine.dev를 사용해 볼 것이다. 이때 kubernetes에 대한 레코드는 etcd-us-east-1c.internal.clustername.k8s.softpine.dev 처럼 보일 것이다.
- sub 도메인을 사용 시 Route53에서 sub 도메인에 대한 host zone 영역을 새로 생성하여 경로 위임 설정을 진행해야 한다. 이는 Route53의 부모 도메인으로 sub 도메인의 NS 서버를 복사하는 것이다.
- 다음의 작업 절차를 거친다.
- sub 도메인을 만들고 이 도메인에 대하여 기록해 놓는다(이미 작업이 완료된 경우 값을 가져올 수 있다).
# Note: 미리 jq 를 설치해 놓는다. ID=$(uuidgen) && aws route53 create-hosted-zone --name k8s.softpine.dev --caller-reference $ID | \ jq .DelegationSet.NameServers --- [ "ns-####.awsdns-##.co.uk", "ns-####.awsdns-##.org", "ns-####.awsdns-##.net", "ns-####.awsdns-##.com" ]
- 상위 도메인의 host zone id 를 기록해 놓는다(/hostedzone/ 뒷 부분만 기록해 놓으면 된다).
aws route53 list-hosted-zones | jq '.HostedZones[] | select(.Name=="softpine.dev.") | .Id' --- "/hostedzone/ABCDEFGQWERTY123456789"
- 위 값들을 활용하여 새로운 sub 도메인에 대한 subdomain.json 파일을 생성한다.
{ "Comment": "Create a subdomain NS record in the parent domain", "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "k8s.softpine.dev", "Type": "NS", "TTL": 300, "ResourceRecords": [ { "Value": "ns-####.awsdns-##.co.uk" }, { "Value": "ns-####.awsdns-##.org" }, { "Value": "ns-####.awsdns-##.com" }, { "Value": "ns-####.awsdns-##.net" } ] } } ] }
- sub 도메인의 NS 레코드를 상위 도메인의 host zone에 적용한다.
이제 *.k8s.softpine.dev 로 가는 트래픽은 route53을 통하여 sub 도메인 host zone으로 라우팅이 된다. 실제로 상위 도메인의 host zone을 보면 sub 도메인에 대한 NS가 적용되어 있다.aws route53 change-resource-record-sets \ > --hosted-zone-id ABCDEFGQWERTY123456789 \ > --change-batch file://subdomain.json --- { "ChangeInfo": { "Status": "PENDING", "Comment": "Create a subdomain NS record in the parent domain", "SubmittedAt": "2021-06-13T09:19:00.574Z", "Id": "/change/C0548358Z0TRUB6F1QOO" } }
- sub 도메인을 만들고 이 도메인에 대하여 기록해 놓는다(이미 작업이 완료된 경우 값을 가져올 수 있다).
- AWS에서 구매한 도메인이 아닌 타사에서 구매를 한 경우.
- 타사에서 도메인을 구매했지만, route53 을 사용하려는 경우.
- route53 으로 구매한 도메인을 위임하는 방법으로 사용하면 된다. 이때도 다른 설정이 필요없다.
- 타사에서 도메인 구매를 하고 상위 도메인은 다른 DNS 서버를 두고 sub 도메인을 routet53 으로 사용을 하려는 경우
- AWS에서 sub 도메인으로 사용을 하려는 경우와 마찬가지로 sub 도메인은 route53에 host zone을 만들어 놓고 타사의 DNS 서버에 sub 도메인의 NS 정보를 똑같이 업데이트를 해준다.
- 타사에서 도메인을 구매했지만, route53 을 사용하려는 경우.
Public/Private DNS 사용(kOps 1.5+)
기본적으로 NS 레코드는 Public으로 사용할 수 있다는 가정이 있다. Private DNS 레코드가 필요한 경우 이번 포스트 뒷 부분에서 실행하는 명령을 수정하여 실행한다.
kops create cluster --dns private $NAME
퍼블릭 영역과 프라이빗 영역이 혼합되어있는 경우 배포하려는 호스팅 영역 ID와 함께 --dns-zone 플래그도 포함해야한다.
kops create cluster --dns private --dns-zone ZABCDEFG $NAME
DNS 테스트하기
dig 명령어를 사용하여 k8s.softpine.dev 도메인에 대한 NS를 질의를 해본다. 정상적으로 이전에 입력한 NS에 대해 반환이 된다면 정상적으로 DNS가 셋팅이 된 것이다.
dig ns k8s.softpine.dev
---
;; ANSWER SECTION:
k8s.softpine.dev. 300 IN NS ns-####.awsdns-##.com.
k8s.softpine.dev. 300 IN NS ns-####.awsdns-##.net.
k8s.softpine.dev. 300 IN NS ns-####.awsdns-##.org.
k8s.softpine.dev. 300 IN NS ns-####.awsdns-##.co.uk.
Cluster State Storage
클러스터의 상태를 저장하려면 kOps에서 사용할 전용 S3 버킷을 생성해야 한다. 이 버킷은 클러스터의 실제 구성 원본이 된다. 이번 가이드에서는 이름을 k8s-softpine-dev-state-store로 만들어서 사용한다. 버킷명은 고유해야 한다.
aws s3api create-bucket \
--bucket k8s-softpine-dev-state-store \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
{
"Location": "http://k8s-softpine-dev-state-store.s3.amazonaws.com/"
}
필히 위에서 만든 버킷은 버저닝을 통하여 관리를 하는 것을 권고한다.
aws s3api put-bucket-versioning --bucket k8s-softpine-dev-state-store \
--versioning-configuration Status=Enabled
kops cli를 사용할 때 클러스터 상태 저장소 위치에 대한 정보를 설정해야 한다. 추가적인 정보는 해당 Link를 확인한다.
S3 기본 버킷 암호화 사용
kOps는 기본 버킷 암호화를 지원하여 S3 버킷의 상태를 암호화한다. 이렇게하면 버킷에 설정된 기본 서버 측 암호화가 kOps 상태에도 사용된다. 예를 들어, 기본적으로 작성된 모든 객체를 쉽게 암호화하거나 규정 준수 이유로 특정 암호화 키(KMS, CMK)를 사용해야하는 경우 쉽게 AWS 기능을 사용할 수 있다.
S3 버킷에 기본 암호화 설정이 있는 경우 kOps가 이를 사용한다.
aws s3api put-bucket-encryption --bucket k8s-softpine-dev-state-store --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'
기본 암호화를 설정하지 않았거나 확인할 수 없는 경우 kOps는 Amazon S3-Managed 암호화 키(SSE-S3)와 함께 서버측 AES256 버킷 암호화를 사용한다.
K8S 클러스터 생성
로컬 환경 변수 설정
클러스터 구축을 편하기 위해 로컬 환경변수를 설정한다.
export NAME=cluster.k8s.softpine.dev
export KOPS_STATE_STORE=s3://k8s-softpine-dev-state-store
해당 환경변수를 설정하지 않고도 추후에 -name 및 -state 플래그를 사용하여 설정할 수 있다.
클러스터 설정 생성
kops create cluster \
--zones=ap-northeast-2a \
--networking calico \
${NAME}
해당 명령어를 실행하면 기본적으로 kOps가 명령어가 실행된다. kops가 생성 한 모든 인스턴스는 ASG (Auto Scaling Groups) 내에 구축된다. 즉, 장애가 발생하면 AWS에서 각 인스턴스를 자동으로 모니터링하고 재구축한다.]
클러스터 구성 변경
kops edit cluster ${NAME}
위 명령을 사용하여 클러스터의 구성에 대한 환경을 볼 수 있다. yaml 파일 내부의 설정을 변경하여 클러스터의 구성을 업데이트 할 수 있다.
클러스터의 수 변경
클러스터의 수를 변경하려면 kops edit cluster 명령어로는 안된다. 다음의 명령어로 진행을 해서 클러스터의 수를 변경한다.
kops get ig
---
Using cluster from kubectl context: cluster.k8s.softpine.dev
NAME ROLE MACHINETYPE MIN MAX ZONES
master-ap-northeast-2a Master t3.medium 1 1 ap-northeast-2a
nodes-ap-northeast-2a Node t3.medium 1 1 ap-northeast-2a
---
kops edit ig nodes-ap-northeast-2a
---
spec:
image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415
machineType: t3.medium -> 추후에 스펙을 변경 시 필요
maxSize: 1 -> 이 부분을 2로
minSize: 1 -> 이 부분을 2로
nodeLabels:
kops.k8s.io/instancegroup: nodes-ap-northeast-2a
role: Node
subnets:
- ap-northeast-2a
클러스터 빌드
위에서 변경된 구성을 새로 빌드를 진행해야 클러스터에 구성이 변경이 된다.
kops update cluster ${NAME} --yes
위 명령어로 변경된 클러스터 구성을 변경할 수 있다.
K8S 클러스터 접근하기
먼저 k8s의 클러스터에 접근을 하기 위해서는 kubecfg를 설정을 진행해야 한다. kOps로 K8S 클러스터를 구축이 끝난다면 편하게 kubecfg를 구성할 수 있다.
kops export kubecfg --admin
위 명령어를 실행하면 자동으로 kubecfg 파일을 구성을 해준다.
K8S 클러스터 상태 확인하기
k get no 명령어를 사용하여 기존에 3대로 증설된 k8s 클러스터를 확인할 수 있다.
k get no
---
NAME STATUS ROLES AGE VERSION
ip-172-20-34-82.ap-northeast-2.compute.internal Ready node 8m11s v1.20.7
ip-172-20-51-247.ap-northeast-2.compute.internal Ready node 22m v1.20.7
ip-172-20-59-174.ap-northeast-2.compute.internal Ready control-plane,master 23m v1.20.7
K8S 클러스터 삭제하기
k8s 클러스터를 삭제하려면 하위의 명령어를 사용하면 된다.
kops delete cluster --name ${NAME} --yes
이상 kOps를 사용한 k8s 클러스터 배포를 간단하게 완료한다.
블로그의 정보
나의 삽질저장소
softPine