PKOS (Production Kubernetes Online Study) 1주차!

 

본 실습은 <24단계 실습으로 정복하는 쿠버네티스>를 기반으로 진행합니다.

이 책입니다. ㅎㅎ

 

운이 좋게, 가시다님의 쿠버네티스 실습 스터디에 참여하게 되었다.

본 스터디는 kOps(Kubernetes Operations)를 이용해서 쿠버네티스 실습을 한다.

처음 들어보는데...

kOps는 클라우드 플랫폼에서 쉽게 k8s를 설치할 수 있도록 도와주는 도구다.

이번 시간에는 kops-ec2라는 일종의 인터페이스 역할을 하는 ec2에서 커맨드를 이용해 k8s 클러스터를 배포하는 실습을 진행할 예정이다.

 

감사하게도, 가시다님이 이미 cloudformation으로 클릭 한번으로 서비스가 배포되도록 만들어주셨다.

 

이미 kops가 배포된 ec2에 설치되어있다.
administrator access 권한을 가진 iam user를 ec2에 연결해줬다.
그리고 k8s 설정 파일이 저장될 버킷을 생성했다.

aws s3 mb s3://버킷 --region ap-northeast-2

 

 

계속 똑같은 변수를 입력할 필요가 없게, 환경 설정을 해주자.

 

export AWS_PAGER="" export REGION=ap-northeast-2
export KOPS_CLUSTER_NAME=kops.hojaelee.com
export KOPS_STATE_STORE=s3://본인의s3버킷주소
echo 'export AWS_PAGER=""' >>~/.bashrc echo '
export REGION=ap-northeast-2' >>~/.bashrc echo '
export KOPS_CLUSTER_NAME=kops.hojaelee.com' >>~/.bashrc echo '
export KOPS_STATE_STORE=s3://본인의s3버킷주소' >>~/.bashrc

 

이제 k8s 클러스터를 배포할건데, ec2가 제대로 만들어지는지 확인해보자.

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 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

 

잠깐!

route53에서 도메인을 구매했으면 상관 없겠지만,

가비아같은 다른 사이트에서 도메인을 구입했다면, 가비아에 들어가서 해당 도메인의 네임서버를 AWS route53의 네임서버로 변경해줘야 한다.

https://www.opsnow.com/godaddy%EC%97%90%EC%84%9C-route-53%EC%9C%BC%EB%A1%9C-%EB%84%A4%EC%9E%84-%EC%84%9C%EB%B2%84-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0/

 

GoDaddy에서 Route 53으로 네임 서버 변경하기 - OpsNow

저희는 고객의 성공적인 클라우드 도입과 관리를 위한 소프트웨어와 고객의 니즈에 맞는 다양한 클라우드 SaaS 솔루션을 제공하고 있습니다. 클라우드에 대한 모든 것 OpsNow에 문의하세요.

www.opsnow.com

설명이 잘 되어있는 게시글을 찾았다.

인스턴스가 생성된다.

 

클러스터가 healthy가 될 때까지, 시간이 좀 걸리는 것으로 보인다.

kops validate cluster --wait 10m

validation이 되는지 확인하고 진행하자.

 

# 자신의 도메인 변수 지정 : 소유하고 있는 자신의 도메인을 입력하시면 됩니다
MyDomain=<자신의 도메인>
MyDomain=hojaelee.com

# 자신의 Route 53 도메인 ID 조회 및 변수 지정
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Name"
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text
MyDnzHostedZoneId=`aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text`
echo $MyDnzHostedZoneId

# A 레코드 타입 조회
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" --output text

# A 레코드 값 반복 조회
while true; do aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq ; date ; echo ; sleep 1; done

제대로 연결이 됐는지 확인하기 위해서, 노드의 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

좀 신기한 부분인데, 이제 마스터 노드에 접근해서 조작을 할 수 있다.

 

# [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

당연히 워커 노드에도 접근이 가능하다.

다 가려놔서 보이지는 않지만,

ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP

이런 방식으로 워커 노드에 접근을 했고, 접속이 잘 된 것을 확인할 수 있다.

 

그럼 이번에는 워커 노드에 마리오를 설치해보자.. ㅎㅎ

watch -d 'kubectl get pod'

# 수퍼마리오 디플로이먼트 배포
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 }'

짜잔, 실행됐다.

저번에도 느낀거지만 진짜 만든 사람 천재인듯...ㅎ

 

이번에는 ExternalDNS Addon을 설치해보자.

# 모니터링
watch -d kubectl get pod -A

# 정책 생성 -> 마스터/워커노드에 정책 연결
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 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-66969c4497-wbs5p   1/1     Running   0          8m53s

요렇게 하게 되면,

ExternalDNS Addon이 설치된다.

 

# 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"

 

그리고 위 명령어를 입력하면...!

실제로 연결이 된다!

 

이제 다음 주차를 따라갈 환경 구성은 완료되었고, 이 부분이 좀 중요한 것 같다.

 

노드 최대 파드 배포

워커 노드의 인스턴스 타입 별 파드 생성 갯수에 제한이 있다고 한다.

최대 파드 생성 갯수 : (Number of network interfaces for the instance type × (the number of IP addressess per network interface - 1)) + 2

그럼 인스턴스 타입 별 IPv4의 갯수와 MaxENI의 갯수에 대해 알아보자.

aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* \
 --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
 --output table

위 공식에 의거하면, t3.medium의 경우 3* (6-1) +2 = 17

그런데 aws-node와 kube-proxy 2개를 제외하면 15개라고 한다.

 

가시다님이 주신 질문)

이 상황에서 해당 노드에 좀 더 많은 파드를 배치하려면 어떻게 해야할까?

음...... ?_? 고민좀 해보자.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기