작년에 이어 Kubernetes 스터디에 참여하게 되었다. 스터디의 교재는 “24단계 실습으로 정복하는 쿠버네티스”를 사용한다. 이 책의 저자가 서문에 말씀 주셨 듯이 실습으로 이해의 폭을 넓히는 과정은 정말 중요한 것 같다. 이 도서는 쿠버네티스의 실습 위주로 정말 깔끔 구성되어 있다.
이 글은 스터디를 참여하면서 학습한 내용을 중심으로 Kubernetes를 정리하는 연재 글이다.
스터디 진도에 맞춰 4~5개의 글을 작성 할 예정이다.
이 글에서는 쿠버네티스의 개념과 설치, 기본 관리 방법을 알아본다.
1. kOps로 Cluster 설치하기
kOps란?
kOps 공식 웹페이지에서는 Kubernetes 환경에서 Kubectl을 사용한다면, Cluster를 설치하고 관리할 때는 kops를 사용해달라고 소개되어 있다.
We like to think of it as kubectl for clusters.
클러스터용 kubectl로 생각하고 싶습니다.
kops는 프로덕션 레벨의 고가용성 Kubernetes Cluster를 생성, 파괴, 업그레이드 및 유지 관리하는 데 사용할 수 있다. 현재 AWS(Amazon Web Services) 및 Google Cloud는 현재 공식적으로 지원되며 DigitalOcean, Hetzner 및 OpenStack은 베타 지원으로, Azure는 알파로 지원된다고 한다.
1.1. AWS kOps 아키텍처
실습에서의 클러스터는 아래와 같은 아키텍처를 가진다.
AWS Free Tier 계정, AdministratorAccess 정책이 부여된 IAM User, AWS Route53 도메인을 사전 준비해 준다. 나는 ygpark.net이라는 도메인을 구입해뒀다.
1.2. 기본 인프라 배포
스터디에서 제공하는 cloudformation을 통해서 기본 인프라 EC2 3대 (t3.medium) 생성한다.
# yaml 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-new-ec2.yaml
# 배포: 작업용 EC2 인스턴스를 생성한다.
# aws cloudformation deploy --template-file ~/Downloads/kops-new-ec2.yaml --stack-name mykops --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 mykops --parameter-overrides KeyName=ygpark SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 EC2 IP 출력
aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[*].OutputValue' --output text
예시) 13.124.42.108
# kOps-ec2 에 SSH 접속
예시) ssh -i <My SSH Keyfile> ec2-user@3.35.137.31
ssh -i /mnt/c/vswork/_pkos2/secret/ygpark.pem ec2-user@$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)
AWS 콘솔에서 확인 할 수 있다. (설치 진행 중인 화면)
EC2에는 kops, aws CLI, SSH 키 등이 설치되어 있다.
1.3. kOps 클러스터 배포
위에서 생성한 ec2에 잘 접속이 된다면 kOps로 클러스터를 배포해본다.
우선 미리 생성 해둔 administrator 권한을 가진 IAM User 의 자격 증명 입력을 해주고, 버킷을 만들어 준다. 버킷에 k8s 설정 파일이 저장 될 것이다.
# 자격증명 입력
aws configure
AWS Access Key ID [None]: AKIA5...
AWS Secret Access Key [None]: CVNa2...
Default region name [None]: ap-northeast-2
Default output format [None]: json
# 버킷 생성
REGION=ap-northeast-2 # 서울 리전 사용
# aws s3 mb s3://버킷<유일한 이름> --region <S3 배포될 AWS 리전>
aws s3 mb s3://ygpark --region $REGION
# 배포 시 참고할 정보를 환경 변수에 저장
## export NAME=<자신의 퍼블릭 호스팅 메인 주소>
## export KOPS_STATE_STORE=s3://(위에서 생성한 자신의 버킷 이름)
export KOPS_CLUSTER_NAME=ygpark.net
export KOPS_STATE_STORE=s3://ygpark
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=ygpark.net' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://ygpark' >>~/.bashrc
# kops Cluster 생성
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
Cluster가 구성은 CNI는 aws vpc cni 사용, 마스터 노드 1대(t3.medium), 워커 노드 2대(t3.medium), 파드 사용 네트워크 대역 지정(172.30.0.0/16)이다.
클러스터가 모두 배포되면 콘솔에서도 인스턴스를 확인 할 수 있다.
# 클러스터 확인
kops get cluster
NAME CLOUD ZONES
ygpark.net aws ap-northeast-2a,ap-northeast-2c
2. kubectl CLI 환경 최적화
관리 편리성을 위해 kubectl completion, alias를 등록해 준다. 그리고 플러그인으로 kubectl을 확장해 줄 수 있다.
2.1. kubectl 자동 완성 기능, alias
source <(kubectl completion bash)
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
2.2. 플러그인으로 kubectl 확장
추천하는 플러그인은 컨택스트 사용하는 kube-ctx, 네임스페이스 선택, 확인에 kube-ns 이외에 df-pv get-all ktop neat oomd view-secret kube-ps1 등이 있다. kubectl krew list로 플러그인과 버전을 확인 할 수 있다.
# 설치
curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/download/v0.4.3/krew-linux_amd64.tar.gz
tar zxvf krew-linux_amd64.tar.gz
./krew-linux_amd64 install krew
tree -L 3 /root/.krew/bin
/root/.krew/bin
└── kubectl-krew -> /root/.krew/store/krew/v0.4.3/krew
# PATH 추가
export PATH="${PATH}:/root/.krew/bin"
echo 'export PATH="${PATH}:/root/.krew/bin"' >>~/.bashrc
# krew 확인
kubectl krew
kubectl krew update
Updated the local copy of plugin index.
kubectl krew search
kubectl krew list
PLUGIN VERSION
krew v0.4.3
kubectl krew
3. ExternalDNS
ExternalDNS Addon 설치를 하면 Kubernetes의 Service 또는 Ingress 생성 시에 Public Cloud의 DNS 서비스들 - AWS(Route 53), Azure(DNS), GCP(Cloud DNS)에 자동으로 A 레코드를 등록 / 삭제 해준다. 한마디로 대박 기능, 귀찮음이 완전 줄어든다.
3.1 ExternalDNS Addon 설치
# 정책 생성 -> 마스터/워커노드에 정책 연결
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
Unknown output type: ygpark
# 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
# 설치
# 아래 spec 부분을 수정해서 Addon 추가
kops edit cluster
--------------------------
spec:
certManager:
enabled: true
externalDns:
provider: external-dns
--------------------------
apiVersion: kops.k8s.io/v1alpha2
kind: Cluster
metadata:
creationTimestamp: "2023-03-05T11:43:10Z"
name: ygpark.net
spec:
certManager:
enabled: true
externalDns:
provider: external-dns
api:
dns: {}
authorization:
rbac: {}
channel: stable
cloudProvider: aws
configBase: s3://ygpark/ygpark.net
etcdClusters:
...
# 업데이트 적용
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-66969c4497-wbs5p 1/1 Running 0 8m53s
3.2 mario 서비스에 도메인 연결 실습
구입한 도메인으로 잘 연결이 되는지 도메인 연결을 해본다.
# CLB에 ExternanDNS 로 도메인 연결
kubectl annotate service mario "external-dns.alpha.kubernetes.io/hostname=mario.$KOPS_CLUSTER_NAME"
service/mario annotated
# 확인
dig +short mario.$KOPS_CLUSTER_NAME
3.38.78.138
kubectl logs -n kube-system -l k8s-app=external-dns
time="2023-03-05T12:51:54Z" level=info msg="Desired change: CREATE a-kops-controller.internal.ygpark.net TXT [Id: /hostedzone/Z02152902Y86CY31OLIX5]"
time="2023-03-05T12:51:54Z" level=info msg="3 record(s) in zone ygpark.net. [Id: /hostedzone/Z02152902Y86CY31OLIX5] were successfully updated"
time="2023-03-05T12:51:54Z" level=info msg="All missing records are created"
time="2023-03-05T12:51:54Z" level=info msg="Applying provider record filter for domains: [ygpark.net. .ygpark.net.]"
time="2023-03-05T12:51:54Z" level=info msg="All records are already up to date"
time="2023-03-05T12:52:52Z" level=info msg="Applying provider record filter for domains: [ygpark.net. .ygpark.net.]"
time="2023-03-05T12:52:52Z" level=info msg="Desired change: CREATE cname-mario.ygpark.net TXT [Id: /hostedzone/Z02152902Y86CY31OLIX5]"
time="2023-03-05T12:52:52Z" level=info msg="Desired change: CREATE mario.ygpark.net A [Id: /hostedzone/Z02152902Y86CY31OLIX5]"
time="2023-03-05T12:52:52Z" level=info msg="Desired change: CREATE mario.ygpark.net TXT [Id: /hostedzone/Z02152902Y86CY31OLIX5]"
time="2023-03-05T12:52:52Z" level=info msg="3 record(s) in zone ygpark.net. [Id: /hostedzone/Z02152902Y86CY31OLIX5] were successfully updated"
# 웹 접속 주소 확인 및 접속
echo -e "Maria Game URL = http://mario.$KOPS_CLUSTER_NAME"
Maria Game URL = http://mario.ygpark.net
짜잔!
# mario 삭제
kubectl delete deploy,svc mario
4. 리소스 삭제
# kOps 클러스터 삭제
kops delete cluster --yes
#(클러스터 삭제 완료 확인 후) AWS CloudFormation 스택 삭제
aws cloudformation delete-stack --stack-name mykops
5. Kubernetes 트러블슈팅
IaaS 환경의 Instance Managed Service 를 트러블 슈팅 하게 되면 보통 Managed Service의 작업 순서를 따라 가면서 트러블슈팅을 한다. 마찬가지로 Kubernetes 작업의 순서에 따라 Kubernetes 트러블슈팅을 하면 된다.
Kubernetes 작업의 순서
Apply → Get → Describe → Logs → Get Event
에러 상황 발생 시 기본 조치 프로세스:
get 확인 → describe 확인 → 애플리케이션 로그(log) 확인 → 클러스터 에러 이벤트(event) 확인
learnk8s의 Kubernetes 배포 문제 해결에 대한 시각적 가이드 글에서는 Kubernetes의 문제해결의 어려움에 대한 해결책을 제시해 준다.
Kubernetes의 문제 해결은 어디서부터 시작해야 할지 모르는 경우 어려운 작업이 될 수 있습니다. 항상 상향식으로 문제에 접근해야 한다는 점을 기억해야 합니다. 포드에서 시작하여 서비스 및 인그레스로 스택을 위로 이동하세요.
트러블슈팅은 상향식으로, 파드에서 부터 서비스/인그레스 방향으로 확인하자!
6. 마치며
작년 Kubernetes 학습 할 때 개념 이해를 열심히 했다면, 올해는 실제 운영 환경에서 사용할 만한 것들을 명령어를 사용해보려고 한다. 아직 실습해 보지 못한 kOps 기능들이 아쉽다. 스터디 기간에 하나씩 실습해볼 예정이다.
참고
- “24단계 실습으로 정복하는 쿠버네티스”: https://ebook-product.kyobobook.co.kr/dig/epd/ebook/E000005050811
- PKOS - CloudNet@ 팀 스터디 내용
- Kubernetes 배포 문제 해결에 대한 시각적 가이드: https://learnk8s.io/troubleshooting-deployments
- kOps 공식 웹페이지: https://kops.sigs.k8s.io/
'스터디 > Kubernetes' 카테고리의 다른 글
[PKOS] Kubernetes 보안 - kubescape, polaris, RBAC (2/2) (0) | 2023.04.10 |
---|---|
[PKOS] Kubernetes 보안 - kubescape, polaris, RBAC (1/2) (0) | 2023.04.09 |
[PKOS] Kubernetes 모니터링과 로깅 - Prometheus, Grafana, Loki (0) | 2023.04.02 |
[PKOS] Kubernetes GitOps 시스템 - Harbor, GitLab, ArgoCD (0) | 2023.03.26 |
[PKOS] AWS Kubernetes 네트워크, 노드의 Max Pod 제한 (2) | 2023.03.18 |