ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Udemy] AKS Storage - Azure Disks
    kubernetes/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

     

    [참고 문서]

    https://github.com/stacksimplify/azure-aks-kubernetes-masterclass/tree/master/05-Azure-Disks-for-AKS-Storage

Designed by Tistory.