✅ 이번 주 실습에서는 다수의 파드를 사용하므로 t3.medium에서 c5d.large로 사용하였습니다.
✅ 인스턴스 스토어 볼륨이 있는 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
- 인스턴스 스토어는 스토리지 정보에 출력되지 않습니다.
클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출합니다.
Web Proxy와 같이 L7 레이어에서 경로를 할당하여 파드와 통신할 수 있는 기능을 제공합니다.
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 ```
✅ 파드는 모두 상태가 없는(Stateless) 애플리케이션입니다.
- 파드 내부의 데이터는 파드가 정지되면 모두 삭제됩니다.
- 데이터베이스(파드)처럼 데이터 보존이 필요한 경우 상태가 있는(Stateful) 애플리케이션에 마운트하여 사용합니다.
동적 프로비저닝(Dynamic Provisioning)
은 파드가 생성될 때 자동으로 볼륨을 마운트하여 파드에 연결하는 기능입니다.
- 퍼시스턴트 볼륨의 사용이 끝났을 때 해당 볼륨은 어떻게 초기화할 것인지 별도로 설정할 수 있습니다.
쿠버네티스는 이를Reclaim Policy
라고 부릅니다.
Reclaim Policy
에는 크게 Retain(보존), Delete(삭제, 즉 EBS 볼륨도 삭제됨),Recycle방식이 있습니다.
쿠버네티스는 여러 유형의 볼륨을 지원합니다
emptyDir
파드가 노드에 할당될 때 처음 생성되며, 해당 노드에서 파드가 실행되는 동안에만 존재합니다.
처음 생성시에는 비어있습니다.
파드 내의 모든 컨테이너는 emptyDir
볼륨에서 동일한 파일을 읽고 쓸수 있습니다.
어떤 이유에서든 파드가 제거되면 데이터가 영구적으로 삭제 됩니다.
단, 컨테이너가 크래시되는것은 노드가 파드를 제거하지 않습니다. → emptyDir
은 컨테이너 크래시로 부터는 안전합니다.
hostPath
HostPath 볼륨에는 많은 보안 위험이 있으며, 가능하면 HostPath를 사용하지 않는 것이 좋습니다.
HostPath를 사용해야 하는경우, 필요한 파일 또는 디렉토리만 범위를 지정하고 ReadOnly로 마운트하여 사용합니다.
hostPath
볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 마운트 한다. 이것은 대부분의 파드들이 필요한 것은 아니지만, 일부 어플리케이션의 요구사항을 위해 사용할 수 있습니다.
PV/PVC
PV는 관리자가 프로비저닝하거나 스토리지 클래스를 사용하여 동적으로 프로비저닝한 “클러스터”의 스토리지 입니다. 노드가 클러스터의 리소스인것 처럼 PV는 클러스터의 리소스 입니다.
PV는 Volumes와 같은 볼륨 플러그인이지만, PV를 사용하는 개별 파드와는 별개의 라이프 사이클을 가지게 됩니다.
PVC는 사용자의 스토리지에 대한 요청입니다. 마치 파드와 비슷합니다.
파드는 노드 리소스를 사용하고, PVC는 PV의 리소스를 사용합니다.
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 입니다
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**
Volumesnapshots 사용하여 EBS 볼륨의 스냅샷을 생성합니다.
cluster에 대한 스펙을 업데이트 하는것 만으로 간단하게 기능을 추가할 수 있습니다.
# kOps 클러스터 편집
kops edit cluster
-----
spec:
**snapshotController:
enabled: true**
-----
****# 업데이트 적용
**kops update cluster --yes && sleep 3 && kops rolling-update cluster**
네트워크와 스토리지에 대해서 스터디하였습니다.
인그레스 및 ALB를 이용하여 파드의 IP로 바로 전달되는 과정도 직접 수행해 보며 잘 이해하지 못했었던 인그레스에 대해서 알게 된 좋은 경험을 한 것 같습니다.
또한, 스토리지 클래스에 대해서 이해하고, 원격으로 스토리지 용량을 늘려보며 이 또한 하나하나 수동으로 용량을 늘렸었던 이때까지의 과정에 비해 쿠버네티스 환경에서 쉽게 변경함을 확인할 수 있었습니다.