-
[Udemy] AKS Storage - Azure Diskskubernetes/udemy 2025. 2. 14. 10:50
AKS Storage
Persistent Volume (PV)
- 클러스터 내에서 사용할 수 있는 스토리지
Persistent Volume Claim (PVC)
- 정의: PVC는 사용자가 필요한 스토리지의 요구 사항을 정의하는 객체입니다. 사용자는 PVC를 통해 필요한 스토리지의 크기와 접근 모드를 요청합니다.
- 용도: PVC는 SC를 통해 프로비저닝된 PV(Persistent Volume)를 요청하는 데 사용됩니다. 사용자는 PVC를 통해 스토리지를 요청하고, Kubernetes는 이를 충족하는 PV를 찾아 연결합니다.
- 특징
사용자가 직접 스토리지의 세부 사항을 지정할 수 있습니다.
PVC는 특정 SC에 의해 생성된 PV와 연결됩니다
Storage Class (SC)
- 정의: Storage Class는 Kubernetes에서 스토리지의 유형과 특성을 정의하는 객체입니다. 사용자가 요청한 스토리지의 속성을 설정할 수 있습니다.
- 용도: 다양한 스토리지 제공자에 대한 설정을 포함하여, 동적 프로비저닝을 가능하게 합니다. 예를 들어, 특정 스토리지 유형(SSD, HDD 등)을 지정할 수 있습니다.
- 특징
스토리지의 성능, 접근 모드, 재사용 정책 등을 정의합니다.
여러 스토리지 제공자와의 통합을 지원합니다.
차이점
- SC는 스토리지의 유형과 특성을 정의하는 반면, PVC는 사용자가 요청하는 스토리지의 요구 사항을 정의합니다.
- SC는 스토리지의 프로비저닝을 관리하고, PVC는 사용자가 필요한 스토리지를 요청하는 방법입니다.
사용 예시
1. PV 생성: 클러스터 관리자가 PV를 정의하여 스토리지를 프로비저닝합니다.
2. PVC 생성: 사용자가 PVC를 생성하여 필요한 스토리지를 요청합니다.
3. 바인딩: Kubernetes는 PVC의 요구 사항을 충족하는 PV를 찾아 바인딩합니다.
4. Pod에서 사용: 바인딩된 PVC를 Pod에서 사용하여 데이터를 저장하거나 읽을 수 있습니다.Storage Class(SC) 생성
# Storage Class 확인
kubectl get sc --- NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE azurefile file.csi.azure.com Delete Immediate true 44h azurefile-csi file.csi.azure.com Delete Immediate true 44h azurefile-csi-premium file.csi.azure.com Delete Immediate true 44h azurefile-premium file.csi.azure.com Delete Immediate true 44h default (default) disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-csi disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-csi-premium disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-premium disk.csi.azure.com Delete WaitForFirstConsumer true 44h
이는 AKS 클러스터 생성 시, 자동으로 생성된 storage class이다.
# Storage-class.yml 파일 작성
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-premium-retain-sc provisioner: kubernetes.io/azure-disk reclaimPolicy: Retain # Default is Delete, recommended is retain volumeBindingMode: WaitForFirstConsumer # Default is Immediate, recommended is WaitForFirstConsumer allowVolumeExpansion: true parameters: storageaccounttype: Premium_LRS # or we can use Standard_LRS kind: managed # Default is shared (Other two are managed and dedicated)
# Storage Class 생성
kubectl apply -f 01-storage-class.yml --- storageclass.storage.k8s.io/managed-premium-retain-sc created
# 확인
kubectl get sc --- NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE azurefile file.csi.azure.com Delete Immediate true 44h azurefile-csi file.csi.azure.com Delete Immediate true 44h azurefile-csi-premium file.csi.azure.com Delete Immediate true 44h azurefile-premium file.csi.azure.com Delete Immediate true 44h default (default) disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-csi disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-csi-premium disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-premium disk.csi.azure.com Delete WaitForFirstConsumer true 44h managed-premium-retain-sc kubernetes.io/azure-disk Retain WaitForFirstConsumer true 3m19s
PVC(Persistent Volume Claim) 생성
# Persistent-volume-claim.yml 파일 작성
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: azure-managed-disk-pvc spec: accessModes: - ReadWriteOnce storageClassName: managed-premium-retain-sc resources: requests: storage: 5Gi
# PVC 생성
kubectl apply -f 02-persistent-volume-claim.yml
# 확인
kubectl get pvc --- NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE azure-managed-disk-pvc Pending managed-premium-retain-sc <unset> 54s
현재 managed-premium-retain-sc가 WaitforFirstConsumer 상태이므로
azure-managed-disk-pvc도 pending 상태
ConfigMap 생성
ConfigMap
- 미리 ConfigMap에 구성정보를 정의해놓았다가, 컨테이너마다 해당 구성정보가 필요할 경우 사용
# UserManagement-ConfigMap.yml 파일 작성
apiVersion: v1 kind: ConfigMap metadata: name: usermanagement-dbcreation-script data: mysql_usermgmt.sql: |- DROP DATABASE IF EXISTS webappdb; CREATE DATABASE webappdb;
사용자 관리 DB 스크립트에 관한 ConfigMap이다.
# ConfigMap 생성
kubectl apply -f 03-UserManagement-ConfigMap.yml
Deployment 생성
# mysql-deployment.yml 생성
apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: replicas: 1 selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.6 env: - name: MYSQL_ROOT_PASSWORD value: dbpassword11 ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql - name: usermanagement-dbcreation-script mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: azure-managed-disk-pvc - name: usermanagement-dbcreation-script configMap: name: usermanagement-dbcreation-script
Mysql:5.6 이미지의 Mysql 컨테이너를 생성한다.
해당 컨테이너에는 mysql-persistent-storage와 usermanagement-dbcreation-script라는 Volume이 Mount 된다.
# Deployment 생성
kubectl apply -f 04-mysql-deployment.yml
ClusterIP 생성
# mysql-clusterip-service.yml 파일 생성
apiVersion: v1 kind: Service metadata: name: mysql spec: selector: app: mysql ports: - port: 3306 clusterIP: None # This means we are going to use Pod IP
# ClusterIP 생성
kubectl apply -f 05-mysql-clusterip-service.yml
중간 확인
# pvc 확인
kubectl get pvc --- NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE azure-managed-disk-pvc Bound pvc-92e8ebe7-6a51-47a6-b469-2b761d61e123 5Gi RWO managed-premium-retain-sc <unset> 175m
pvc가 pending에서 bound 상태가 되었다.
현재 pod가 생성되었고, 그에 따라 volume이 mount 되었기 때문이다.
# pv 확인
kubectl get pv --- NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-92e8ebe7-6a51-47a6-b469-2b761d61e123 5Gi RWO Retain Bound default/azure-managed-disk-pvc managed-premium-retain-sc <unset> 8m54s
pv도 정상적으로 생성되었다.
해당 pv는 Azure Portal 내 Disk에서도 조회 가능하다. (하기 후술)
# pod 확인
kubectl get pods --- NAME READY STATUS RESTARTS AGE mysql-6868c58fbd-h9tk7 1/1 Running 0 4m3s
kubectl describe pod mysql-6868c58fbd-h9tk7 --- Name: mysql-6868c58fbd-h9tk7 Namespace: default Priority: 0 Service Account: default Node: aks-agentpool-29221675-vmss000004/10.224.0.199 Start Time: Fri, 14 Feb 2025 13:39:02 +0900 Labels: app=mysql pod-template-hash=6868c58fbd Annotations: <none> Status: Running IP: 10.224.0.20 IPs: IP: 10.224.0.20 Controlled By: ReplicaSet/mysql-6868c58fbd Containers: mysql: Container ID: containerd://aa0cd771c1fda8b5b1849778026c50a060366bbe15bd5dfb0b44d42c94267c5f Image: mysql:5.6 Image ID: docker.io/library/mysql@sha256:20575ecebe6216036d25dab5903808211f1e9ba63dc7825ac20cb975e34cfcae Port: 3306/TCP Host Port: 0/TCP State: Running Started: Fri, 14 Feb 2025 13:39:28 +0900 Ready: True Restart Count: 0 Environment: MYSQL_ROOT_PASSWORD: dbpassword11 Mounts: /docker-entrypoint-initdb.d from usermanagement-dbcreation-script (rw) /var/lib/mysql from mysql-persistent-storage (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8clwd (ro) Conditions: Type Status PodReadyToStartContainers True Initialized True Ready True ContainersReady True PodScheduled True Volumes: mysql-persistent-storage: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: azure-managed-disk-pvc ReadOnly: false usermanagement-dbcreation-script: Type: ConfigMap (a volume populated by a ConfigMap) Name: usermanagement-dbcreation-script Optional: false kube-api-access-8clwd: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 4m18s default-scheduler Successfully assigned default/mysql-6868c58fbd-h9tk7 to aks-agentpool-29221675-vmss000004 Normal SuccessfulAttachVolume 4m6s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-92e8ebe7-6a51-47a6-b469-2b761d61e123" Normal Pulling 4m3s kubelet Pulling image "mysql:5.6" Normal Pulled 3m52s kubelet Successfully pulled image "mysql:5.6" in 11.373s (11.374s including waiting). Image size: 102984033 bytes. Normal Created 3m52s kubelet Created container mysql Normal Started 3m52s kubelet Started container mysql
mysql 컨테이너가 생성되었고,
mysql-persistent-storage와 usermanagement-dbcreation-script 두 개의 Volume이 Mount 되었다.
# Portal 내 Disk 확인
Portal에서도 Disk가 정상적으로 조회되는 것을 확인 가능하다.
MySQL Database에 연결
# MySQL DB에 연결
# Connect to MYSQL Database kubectl run mysql-client --image=mysql:5.6 -it --rm --restart=Never -- mysql -h [MySQL 서버 호스트] -p[비밀번호] kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -pdbpassword11
이 명령어는 MySQL 클라이언트를 실행하여 지정된 MySQL 서버에 연결할 수 있도록 합니다.
삭제
# 삭제
kubectl delete -f kube-manifests/ --- storageclass.storage.k8s.io "managed-premium-retain-sc" deleted persistentvolumeclaim "azure-managed-disk-pvc" deleted configmap "usermanagement-dbcreation-script" deleted deployment.apps "mysql" deleted service "mysql" deleted
# pvc 및 pv 확인
kubectl get pvc --- No resources found in default namespace.
pvc는 삭제되었다.
kubectl get pv --- NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-92e8ebe7-6a51-47a6-b469-2b761d61e123 5Gi RWO Retain Released default/azure-managed-disk-pvc managed-premium-retain-sc <unset> 23m
pv는 그대로 남아있다.
Portal > Disk에서도 그대로 남아있는 것을 확인 가능하다.
즉, PV 및 Disk는 그대로 사용가능하다.
# pv 삭제
kubectl delete pv pvc-92e8ebe7-6a51-47a6-b469-2b761d61e123 --- persistentvolume "pvc-92e8ebe7-6a51-47a6-b469-2b761d61e123" delete
pv는 이렇게 수동으로 지워줘야 삭제된다.
kubectl get pv --- No resources found
그러나 Portal 내 Disk는 여전히 존재한다.
실수로 Pod를 삭제해도 Disk는 그대로 남아있고 상태만 Unattached가 될 뿐이다.
이게 PV(Persistent Volume)의 장점이다.
원하면 다시 붙여써도 되고, 필요 없으면 삭제하자
[참고 영상]
Udemy - Azure Kubernetes Service with Azure DevOps and Terraform
섹션 6 : AKS Storage - Azure Disks
44. Step-01: Azure Disks for AKS Storage Introduction
45. Step-02: Create Storage class Kubernetes Manifest
46. Step-03: Create Persistent Volume Claim Manifest, Deploy SC, PVC and Test
47. Step-04: Create ConfigMap Kubernetes Manifest
48. Step-05: Create MySQL Kubernetes Deployment Manifest
49. Step-06: Create MySQL Kubernetes Cluster IP Service, Deploy, Test and CleanUp
[참고 문서]
'kubernetes > udemy' 카테고리의 다른 글
[Udemy] Secrets (0) 2025.02.18 [Udemy] AKS Storage - Azure Disks (2) (0) 2025.02.14 [Udemy] Services Demo with Cluster IP and Load Balancer Services (Declarative) (0) 2025.02.14 [Udemy] Services Demo with Cluster IP and Load Balancer Services (Imperative) (0) 2025.02.13 [Udemy] Deployments (0) 2025.02.13