[pkos] 쿠버네티스 스터디 - 3주차

xgro·2023년 1월 30일
0

PKOS

목록 보기
3/11

📌 Summary

  • Ingress를 실습해보고 동작 원리를 이해합니다.
  • NodePort로 전달하지 않고, 파드의 IP에 직접 전달하는것을 확인할 수 있습니다.
  • 운영 중인 EBS 볼륨을 확장할 수 있습니다.

✅ 이번 주 실습에서는 다수의 파드를 사용하므로 t3.medium에서 c5d.large로 사용하였습니다.


📌 Prequisite

인스턴스 스토어 볼륨이 있는 c5 타입의 스토리지를 확인해 봅니다.

# 인스턴스 스토어 볼륨이 있는 c5 모든 타입의 스토리지 크기
aws ec2 describe-instance-types \
 --filters "Name=instance-type,Values=c5*" "Name=instance-storage-supported,Values=true" \
 --query "InstanceTypes[].[InstanceType, InstanceStorageInfo.TotalSizeInGB]" \
 --output table
--------------------------
|  DescribeInstanceTypes |
+---------------+--------+
|  c5d.large    |  50  |
|  c5d.12xlarge |  1800  |
...
# 워커 노드의 Public IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value}" --filters Name=instance-state-name,Values=running --output table

# 워커 노드 Public IP 변수 지정
W1PIP=3.39.224.199
echo "export W1PIP=$W1PIP" >> /etc/profile   

# 워커 노드 스토리지 확인 : NVMe SSD 인스턴스 스토어 볼륨 확인
ssh -i ~/.ssh/id_rsa ubuntu@**$W1PIP lsblk -e 7 -d
ssh -i ~/.ssh/id_rsa ubuntu@**$W1PIP df -hT -t ext4
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP lspci | grep Non-Volatile

# 파일시스템 생성 및 /data 마운트
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP sudo mkfs -t xfs /dev/nvme1n1
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP sudo mkdir /data
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP sudo mount /dev/nvme1n1 /data
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP df -hT -t ext4 -t xfs

  • 인스턴스 스토어는 스토리지 정보에 출력되지 않습니다.

📌 Study Notes.

👉 Step 01. Ingress

✅ Ingress란?

클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출합니다.

Web Proxy와 같이 L7 레이어에서 경로를 할당하여 파드와 통신할 수 있는 기능을 제공합니다.

AWS Load Balancer Controller + Ingress (ALB) IP 모드

EC2 instance profiles 설정 및 AWS LoadBalancer 배포 & ExternalDNS 설치 및 배포

# EC2 instance profiles 에 IAM Policy 추가(attach)
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name nodes.$KOPS_CLUSTER_NAME

# 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 edit cluster
-----
spec:
  certManager:
    enabled: true
  awsLoadBalancerController:
    enabled: true
  externalDns:
    provider: external-dns
-----

# 업데이트 적용
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster

서비스/파드 배포 테스트 with Ingress(ALB)

 # 게임 파드와 Service, Ingress 배포
 cat ~/pkos/3/ingress1.yaml | yh
 kubectl apply -f ~/pkos/3/ingress1.yaml

 # 생성 확인
 kubectl get-all -n game-2048
 kubectl get ingress,svc,ep,pod -n game-2048
 kubectl get targetgroupbindings -n game-2048
 NAME                               SERVICE-NAME   SERVICE-PORT   TARGET-TYPE   AGE
 k8s-game2048-service2-e48050abac   service-2048   80             ip            87s

 # Ingress 확인
 kubectl describe ingress -n game-2048 ingress-2048

 # 게임 접속 : ALB 주소로 웹 접속
 kubectl get ingress -n game-2048 ingress-2048 -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Game URL = http://"$1 }'

 # 파드 IP 확인
 kubectl get pod -n game-2048 -owide
 NAME                               READY   STATUS    RESTARTS   AGE     IP              NODE                  NOMINATED NODE   READINESS GATES
 deployment-2048-6bc9fd6bf5-42v9n   1/1     Running   0          6m36s   172.30.88.130   i-07fac859b8896addd   <none>           <none>
 deployment-2048-6bc9fd6bf5-8p7pq   1/1     Running   0          6m36s   172.30.47.18    i-05f82825145ee0009   <none>           <none>
 ```

📌 AWS Load Balancer Controller + Ingress (ALB) IP 모드에서 파드의 IP로 바로 타겟되는 것을 확인 할 수 있습니다.

파드 3개로 증가해보기

# 터미널1
watch kubectl get pod -n game-2048

# 터미널2 : 파드 3개로 증가
kubectl scale deployment -n game-2048 deployment-2048 --replicas 3

마찬가지로 NodePort로 전달하지 않고, 파드의 IP에 직접 전달하는것을 확인할 수 있습니다.

Ingress with ExternalDNS

```bash
# 변수 지정 - 자신의 full 도메인
WEBDOMAIN=<각자편한웹서버도메인>
WEBDOMAIN=albweb.gasida.link

# 게임 파드와 Service, Ingress 배포
cat ~/pkos/3/ingress2.yaml | yh
WEBDOMAIN=$WEBDOMAIN envsubst < ~/pkos/3/ingress2.yaml | kubectl apply -f -

# 확인
kubectl get ingress,svc,ep,pod -n game-2048

# AWS R53 적용 확인
dig +short $WEBDOMAIN
dig +short $WEBDOMAIN @8.8.8.8

# 외부단말(집PC 등)에서 접속 확인 : curl or 웹브라우저

# 로그 확인
kubectl logs -n kube-system -f $(kubectl get po -n kube-system | egrep -o 'external-dns[A-Za-z0-9-]+')

# 삭제
kubectl delete ingress ingress-2048 -n game-2048
kubectl delete svc service-2048 -n game-2048 && kubectl delete deploy deployment-2048 -n game-2048 && kubectl delete ns game-2048
```

👉 Step 02. 쿠버네티스 스토리지

파드는 모두 상태가 없는(Stateless) 애플리케이션입니다.

  • 파드 내부의 데이터는 파드가 정지되면 모두 삭제됩니다.
  • 데이터베이스(파드)처럼 데이터 보존이 필요한 경우 상태가 있는(Stateful) 애플리케이션에 마운트하여 사용합니다.
  • 동적 프로비저닝(Dynamic Provisioning)은 파드가 생성될 때 자동으로 볼륨을 마운트하여 파드에 연결하는 기능입니다.
  • 퍼시스턴트 볼륨의 사용이 끝났을 때 해당 볼륨은 어떻게 초기화할 것인지 별도로 설정할 수 있습니다.
    쿠버네티스는 이를 Reclaim Policy 라고 부릅니다.
  • Reclaim Policy 에는 크게 Retain(보존), Delete(삭제, 즉 EBS 볼륨도 삭제됨), Recycle 방식이 있습니다.

스토리지 유형

쿠버네티스는 여러 유형의 볼륨을 지원합니다

  1. emptyDir
    파드가 노드에 할당될 때 처음 생성되며, 해당 노드에서 파드가 실행되는 동안에만 존재합니다.
    처음 생성시에는 비어있습니다.
    파드 내의 모든 컨테이너는 emptyDir 볼륨에서 동일한 파일을 읽고 쓸수 있습니다.
    어떤 이유에서든 파드가 제거되면 데이터가 영구적으로 삭제 됩니다.
    단, 컨테이너가 크래시되는것은 노드가 파드를 제거하지 않습니다. → emptyDir 은 컨테이너 크래시로 부터는 안전합니다.

  2. hostPath
    HostPath 볼륨에는 많은 보안 위험이 있으며, 가능하면 HostPath를 사용하지 않는 것이 좋습니다.
    HostPath를 사용해야 하는경우, 필요한 파일 또는 디렉토리만 범위를 지정하고 ReadOnly로 마운트하여 사용합니다.
    hostPath 볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 마운트 한다. 이것은 대부분의 파드들이 필요한 것은 아니지만, 일부 어플리케이션의 요구사항을 위해 사용할 수 있습니다.

  3. PV/PVC
    PV는 관리자가 프로비저닝하거나 스토리지 클래스를 사용하여 동적으로 프로비저닝한 “클러스터”의 스토리지 입니다. 노드가 클러스터의 리소스인것 처럼 PV는 클러스터의 리소스 입니다.
    PV는 Volumes와 같은 볼륨 플러그인이지만, PV를 사용하는 개별 파드와는 별개의 라이프 사이클을 가지게 됩니다.
    PVC는 사용자의 스토리지에 대한 요청입니다. 마치 파드와 비슷합니다.
    파드는 노드 리소스를 사용하고, PVC는 PV의 리소스를 사용합니다.

✅ CSI란?

Kubernetes source code 내부에 존재하는 AWS EBS provisioner는 당연히 Kubernetes release lifecycle을 따라서 배포되므로, provisioner 신규 기능을 사용하기 위해서는 Kubernetes version을 업그레이드해야 하는 제약 사항이 있습니다.

따라서, Kubernetes 개발자는 Kubernetes 내부에 내장된 provisioner (in-tree)를 모두 삭제하고, 별도의 controller Pod을 통해 동적 provisioning을 사용할 수 있도록 만들었습니다. 이것이 바로 CSI (Container Storage Interface) driver 입니다

  • CSI 를 사용하면, K8S 의 공통화된 CSI 인터페이스를 통해 다양한 프로바이더를 사용할 수 있습니다.

👉 Step 03. AWS EBS Controller

Volume (ebs-csi-controller) : EBS CSI driver 동작과정

볼륨 생성 및 파드에 볼륨을 연결하는 기능을 담당합니다.

# kOps 설치 시 기본 배포됨
**kubectl get pod -n kube-system -l app.kubernetes.io/instance=aws-ebs-csi-driver**
ebs-csi-controller-57c97ddd8-7j89l                5/5     Running             0             57m
ebs-csi-node-5tq2n                                3/3     Running             0             57m
...

# 스토리지 클래스 확인
**kubectl get sc kops-csi-1-21 kops-ssd-1-17**
NAME                      PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
kops-csi-1-21 (default)   ebs.csi.aws.com         Delete          WaitForFirstConsumer   true                   112m
kops-ssd-1-17             kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   true                   112m

**kubectl describe sc kops-csi-1-21 | grep Parameters**
Parameters:            encrypted=true,type=**gp3**
**kubectl describe sc kops-ssd-1-17 | grep Parameters**
Parameters:            encrypted=true,type=**gp2**

# 워커노드의 EBS 볼륨 확인 : tag(키/값) 필터링 - [링크](https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-usage-filter.html)
**aws ec2 describe-volumes --filters Name=tag:k8s.io/role/node,Values=1 --output table**

👉 Step 04. AWS Volume SnapShots Controller

Volumesnapshots 사용하여 EBS 볼륨의 스냅샷을 생성합니다.

cluster에 대한 스펙을 업데이트 하는것 만으로 간단하게 기능을 추가할 수 있습니다.

# kOps 클러스터 편집
kops edit cluster
-----
spec:
  **snapshotController:
    enabled: true**
-----

****# 업데이트 적용
**kops update cluster --yes && sleep 3 && kops rolling-update cluster**

📌 Comments

네트워크와 스토리지에 대해서 스터디하였습니다.
인그레스 및 ALB를 이용하여 파드의 IP로 바로 전달되는 과정도 직접 수행해 보며 잘 이해하지 못했었던 인그레스에 대해서 알게 된 좋은 경험을 한 것 같습니다.
또한, 스토리지 클래스에 대해서 이해하고, 원격으로 스토리지 용량을 늘려보며 이 또한 하나하나 수동으로 용량을 늘렸었던 이때까지의 과정에 비해 쿠버네티스 환경에서 쉽게 변경함을 확인할 수 있었습니다.


📌 Reference

profile
안녕하세요! DevOps 엔지니어 이재찬입니다. 블로그에 대한 피드백은 언제나 환영합니다! 기술, 개발, 운영에 관한 다양한 주제로 함께 나누며, 더 나은 협업과 효율적인 개발 환경을 만드는 과정에 대해 인사이트를 나누고 싶습니다. 함께 여행하는 기분으로, 즐겁게 읽어주시면 감사하겠습니다! 🚀

0개의 댓글