본 시리즈는 가시다님의 PKOS(Production Kubernetes Online Study) 2기 진행 내용입니다.
스터디에 사용된 서적은 이정훈님의 24단계 실습으로 정복하는 쿠버네티스 입니다.
도서 링크 : http://www.yes24.com/Product/Goods/115187666
kOps란?
프로덕션 수준의 쿠버네티스 클러스터를 구축하고 운영하기 위한 툴이라고 설명되어 있다.
그 전에 이미 많이들 알고있는 kubeadm, kubespray와는 어떤 부분이 다른지, 얼마나 편리하고 Cloud환경에 유효하게 배포되는지 살펴본다.
사전 준비
- AWS 실습 계정
- AWS의 도메인 서비스인 Route53로 도메인 구매
- 혹은 도메인 구매 후 NameServer를 Route53에 위임
실습 구성도
- Cloudformation을 통해 kops-ec2 vm 배포와 kops 실행에 필요한 기본적인 프로비저닝 진행
- kops로 k8s 클러스터 생성 시 S3에 k8s 설정 파일 저장
- Master Node와 Worker Node는 EC2 Auto Scaling Group(ASG)로 구성됨
- 퍼블릭 도메인(Route53) 사용
1주차에서 진행할 2가지
1. kOps를 AWS 환경에서 배포 (kOps on AWS)
2. ExternalDNS를 활용하여 애플리케이션 배포
kOps on AWS 진행 순서
- CloudFormation으로 kops-ec2 배포
- awscli configuration
- S3 배포
- kops cluster 배포
- kops 배포 확인
kOps on AWS
1. CloudFormation으로 kops-ec2 배포
[AWS Console] 에서 CloudFormation으로 kops-ec2 배포
https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?stackName=mykops&templateURL=https:%2F%2Fs3.ap-northeast-2.amazonaws.com%2Fcloudformation.cloudneta.net%2FK8S%2Fkops-new-ec2.yaml
[코드]로 CloudFormation kops-ec2 배포
# yaml 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-new-ec2.yaml
# 배포
# aws cloudformation deploy --template-file ~/Downloads/kops-new-ec2.yaml --stack-name netcloudyops --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 --region <리전>
예시) aws cloudformation deploy --template-file ~/Downloads/kops-new-ec2.yaml --stack-name netcloudyops --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 EC2 IP 출력
aws cloudformation describe-stacks --stack-name netcloudyops --query 'Stacks[*].Outputs[*].OutputValue' --output text
2. awscli configuration
- 사전에 IAM 유저 생성해두면 편리함(별도 IAM 사용자를 만들어야 하는 이유는 보안 강화의 목적)
- 편의를 위해 AdministratorAccess 권한 부여
다시 kops-ec2로 돌아와서
aws configure
AWS Access Key ID [None]: <액세스 키>
AWS Secret Access Key [None]: <비밀 액세스 키>
Default region name [None]: ap-northeast-2
Default output format [None]: json
3. S3 배포
S3를 생성하지 않은 경우에만 진행
kops-ec2에서 진행
REGION=ap-northeast-2
# netcloudy-s3 부분은 전세계적으로 고유한 문자여야 함
aws s3 mb s3://netcloudy-s3 --region $REGION
# S3 배포 확인
aws s3 ls
# KOPS_CLUSTER_NAME = Route53으로 구매한 도메인
# KOPS_STATE_STORE = 고유한 자신의 S3 주소
export KOPS_CLUSTER_NAME=netcloudy.im
export KOPS_STATE_STORE=s3://netcloudy-s3
export AWS_PAGER=""
export REGION=ap-northeast-2
echo 'export AWS_PAGER=""' >>~/.bashrc
echo 'export REGION=ap-northeast-2' >>~/.bashrc
echo 'export KOPS_CLUSTER_NAME=netcloudy.im' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://netcloudy-s3' >>~/.bashrc
4. kops cluster 배포
# 쿠버네티스 클러스터용 Master Node, Worker Node VM 배포 상태 확인 (모니터링 탭)
while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done
# kops 설정 파일 생성(s3) 및 k8s 클러스터 배포 : 6분 정도 소요
## CNI는 aws vpc cni 사용, 마스터 노드 1대(t3.medium), 워커 노드 2대(t3.medium), 파드 사용 네트워크 대역 지정(172.30.0.0/16)
kops create cluster --zones="$REGION"a,"$REGION"c --networking amazonvpc --cloud aws \
--master-size t3.medium --node-size t3.medium --node-count=2 --network-cidr 172.30.0.0/16 \
--ssh-public-key ~/.ssh/id_rsa.pub --name=$KOPS_CLUSTER_NAME --kubernetes-version "1.24.10" -y
# validate
kops validate cluster --wait 10m
대략 6분이 지난 후 완료가 되면 아래 진행
5. kops 배포 확인
# 노드 IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table
# 파드 IP 확인
kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase
# kops 클러스터 정보 확인
kops get cluster
# kubectl 명령 자동 완성 및 alias 축약 설정
source <(kubectl completion bash)
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
exit
exit
kops-ec2에서 Master Node 에 명령하는 방법은?
# [master node] iptable rule 확인
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME sudo iptables -t nat -S
# [master node] 컨테이너 정보 확인
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ps axf |grep /usr/bin/containerd
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ps afxuwww
ExternalDNS
- test 앱 배포
- 자동생성 도메인으로 접속
- ExternalDNS 설정
- 구매한 도메인과 연동하여 접속
ExternalDNS 설명
K8S 서비스/인그레스 생성 시 도메인을 설정하면, AWS(Route 53), Azure(DNS), GCP(Cloud DNS) 에 A 레코드(TXT 레코드)로 자동 생성/삭제
1. test 앱 배포
# 수퍼마리오 디플로이먼트 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/1/mario.yaml
kubectl apply -f mario.yaml
cat mario.yaml | yh
# 배포 확인 : CLB 배포 확인 >> 5분 이상 소요
kubectl get deploy,svc,ep mario
watch kubectl get svc mario
# 마리오 게임 접속 : CLB 주소로 웹 접속
kubectl get svc mario -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Maria URL = http://"$1 }'
2. 자동생성 도메인으로 접속
3. ExternalDNS 설정
아직 우리 Master Node와 Worker Node는 ExternalDNSUpdate 할 권한을 가지고 있지 않다.
따라서, ExternalDNSUpdate할 수 있는 정책을 추가하고 할당해주어야 한다.
# 정책 생성 -> 마스터/워커노드에 정책 연결
curl -s -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/AKOS/externaldns/externaldns-aws-r53-policy.json
aws iam create-policy --policy-name AllowExternalDNSUpdates --policy-document file://externaldns-aws-r53-policy.json
# ACCOUNT_ID 변수 지정
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
# EC2 instance profiles 에 IAM Policy 추가(attach)
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name nodes.$KOPS_CLUSTER_NAME
이후 kops 클러스터 설정 역시 변경해준다.
# kops 클러스터 설정 변경
kops edit cluster
--------------------------
spec:
certManager:
enabled: true
externalDns:
provider: external-dns
--------------------------
# 업데이트 적용
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster
# externalDns 컨트롤러 파드 확인
kubectl get pod -n kube-system -l k8s-app=external-dns
NAME READY STATUS RESTARTS AGE
external-dns-*********-****** 1/1 Running 0 8m53s
4. 구매한 도메인과 연동하여 접속
이제 Master Node와 Worker Node에게 권한도 주었고, kops 클러스터 설정도 변경했으니 구매한 도메인과 앱의 service를 연동해보자.
# CLB에 ExternanDNS 로 도메인 연결
kubectl annotate service mario "external-dns.alpha.kubernetes.io/hostname=mario.$KOPS_CLUSTER_NAME"
# 확인
dig +short mario.$KOPS_CLUSTER_NAME
kubectl logs -n kube-system -l k8s-app=external-dns
# 웹 접속 주소 확인 및 접속
echo -e "Maria Game URL = http://mario.$KOPS_CLUSTER_NAME"
# 도메인 체크
echo -e "My Domain Checker = https://www.whatsmydns.net/#A/mario.$KOPS_CLUSTER_NAME"
test 앱 삭제
kubectl delete deploy,svc mario
service annotate 혹은 service delete 후 external-dns의 로그를 살펴보면 정상적으로 동작하는지 확인할 수 있다.
추가
위 test 앱과 같은 방식으로 Wordpress와 같은 블로그도 배포하고 연동할 수 있다.도메인이 안나오게 캡쳐해서 아쉽지만...
예시)
마치며
블로그에 아직 익숙치 않지만, 이번 스터디를 계기로 꾸준히 관리해보자.
물론 이 글도 단순 과제를 넘어 지식 저장고가 되기를.
'Tech > Kubernetes' 카테고리의 다른 글
[AEWS_1기] 1주차 - Amazon EKS 설치 및 기본 사용 (1/2) (0) | 2023.04.25 |
---|---|
[PKOS_2기] 5주차 보안 (0) | 2023.04.07 |
[PKOS_2기] 4주차 쿠버네티스 모니터링 (2) | 2023.04.01 |
[PKOS_2기] 3주차 GitOps (0) | 2023.03.25 |
[PKOS_2기] 2주차 (네트워크) (0) | 2023.03.17 |
댓글