VMware vSAN

[번역] Read-Write-Many Persistent Volumes with vSAN 7 File Services

출처 : https://cormachogan.com/2020/03/27/read-write-many-persistent-volumes-with-vsan-7-file-services/

powered-by-vSAN.png

몇 주 전에 vSphere 7.0 출시 이벤트 직후에 vSAN 7.0의 네이티브 파일 서비스(Native File Service)에 대한 글를 작성했었다. SMB나 다른 프로토콜이 아닌 이 초기 릴리즈에서 NFS 지원을 결정한 이유를 묻는 몇 가지 질문이 있었다. 그 이유는 상당히 직설적이다. 기존 가상 시스템 워크로드와 최신 컨테이너형 워크로드를 모두 지원하는 플랫폼으로 vSAN을 포지셔닝하고 있다. 우리는 NFS를 선택하여 Kubernetes의 스토리지 요구 사항, 즉 포드 간에 영구 볼륨을 공유하는 방법을 선택했다. 현재까지 vSphere CSI 드라이버는 Read-Write-Once인 블록 기반 영구 볼륨만 프로비저닝되었으며, 이는 한 번에 한 파드만 볼륨을 소비할 수 있음을 의미한다. 새로운 vSphere CSI 드라이버를 통해 VMware는 이제 파일 서비스(File Service) 기능을 활성화한 상태에서 vSAN 7.0에서 파일 공유의 동적 프로비저닝을 지원한다. 그런 다음 이러한 공유는 컨테이너 워크로드에 의해 소비될 수 있다. 이 글에서, 어떻게 작동하는지 보여주고 싶다.

고지 사항: "분명히 말해서, 이 게시물은 vSAN 7 File Services와 새로운 vSphere CSI 드라이버의 사전 GA 버전을 기반으로 한다. 글 쓰는 시간과 제품이 보편적으로 사용 가능해지는 시기 사이에 크게 달라져서는 안 된다는 가정이지만, 독자들이 특징적인 행동과 사용자 인터페이스가 그 이전에도 여전히 변할 수 있다는 것을 인식하기를 바란다."

vSAN 7 파일 서비스의 배포와 구성에 대해 이야기하는데 시간을 할애하지 않을 것이다. 왜냐하면 이것은 이전 게시물에서 이미 다루어졌기 때문이다. 이 게시물에서는 NFS 파일 공유를 수동으로 생성하는 방법을 살펴보았다. 이 게시물에서는, 쿠버네티스 애플리케이션이 vSAN 파일 서비스를 가리키는 StorageClass를 사용하여 Read-Write-Multi(RWX) Persistent Volume을 요청하고, 새로운 CSI 드라이버와 함께 vSphere에 쿠버네티스(K8s) 클러스터를 구축할 때 파일 공유가 동적으로 어떻게 인스턴스화되는지를 확인할 것이다.

ReadWriteOnce (Block) Persistent Volumes Revisited

먼저 vSphere/vSAN에서 동작하는 방식을 살펴볼 수 있도록 Block Persistent Volumes을 사용하는 애플리케이션을 신속하게 배포해 봅시다. 이는 컨테이너를 관리하고 모니터링하기 위해 vSphere UI에서 제공하는 광범위한 기능 중 일부를 보여 줄 뿐만 아니라 두 포드 간에 블록 PV를 공유하려고 할 때의 문제를 보여 줄 것이다.

여기서 하고 있는 것은:

  1. (블록) RAID1 정책을 사용하는 StorageClass를 생성하여 vSAN 데이터스토어에서 영구 볼륨이 블록 VMDK로 인스턴스화됨을 나타낸다.
  2. ReadWriteOnce Persistent Volume Claim(PVC)를 생성하여 Persistent Volume(PV)를 수동으로 생성한다.
  3. PVC를 사용하는 Pod를 생성하면 PVC와 연관된 PV를 얻을 수 있다.
  4. 파드가 동일한 RWO 블록 볼륨을 공유할 수 없음을 증명하는 동일한 PVC를 가진 다른 파드를 실행한다.

여기 이 데모에 사용할 YAML 매니페스트가 있다. 그 kind 필드는 각각의 오브젝트가 무엇인지 설명한다. 이 첫 번째 매니페스트는 StorageClass이며, 간단히 말해서 프로비저닝된 영구 볼륨을 저장할 vSphere 데이터스토어를 선택한다. provisioner 필드는 VMware CSI 드라이버에 대한 참조 사항이다. storagepolicyname 필드는 SPBM 정책이 vSphere임을 가리킨다. 이 경우 해당 정책이 내 vSAN 데이터스토어를 선택하게 된다.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: vsan-block-sc
provisioner: csi.vsphere.vmware.com
parameters:
  storagepolicyname: "RAID1"

이것은 Persistent Volume Claim 매니페스트다. 이는 StorageClassName의 vSphere 스토리지 참조에 2Gi Persistent Volume(VMDK)을 생성하게 된다. 이 StorageClassName은 위의 StorageClass를 참조하므로 이 PV는 내 vSAN 데이터스토어에 생성된다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: block-pvc
spec:
  storageClassName: vsan-block-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

이것은 파드 선언문이다. 위의 PVC인 claimName block-pvc에서 참조하는 볼륨을 탑재하는 간단한 "busybox" 파드를 만들 것이다. 그러면 2G VMDK가 포드의 /mnt/volume1에 연결되고 마운트된다.

apiVersion: v1
kind: Pod
metadata:
  name: block-pod-a
spec:
  containers:
  - name: block-pod-a
    image: "k8s.gcr.io/busybox"
    volumeMounts:
    - name: block-vol
      mountPath: "/mnt/volume1"
    command: [ "sleep", "1000000" ]
  volumes:
    - name: block-vol
      persistentVolumeClaim:
        claimName: block-pvc

이것은 첫번째와 동일한 두 번째 포드다. 또한 동일한 PV를 부착하고 장착하려고 시도할 것이다. 그러나 이것은 RWO의 영구적인 볼륨이며, 이미 첫 번째 팟에 부착되어 있고 탑재되어 있기 때문에, 우리는 이 팟에 대한 PV의 부착 작동이 실패하는 것을 보게 될 것이다.

apiVersion: v1
kind: Pod
metadata:
  name: block-pod-b
spec:
  containers:
  - name: block-pod-b
    image: "k8s.gcr.io/busybox"
    volumeMounts:
    - name: block-vol
      mountPath: "/mnt/volume1"
    command: [ "sleep", "1000000" ]
  volumes:
    - name: block-vol
      persistentVolumeClaim:
        claimName: block-pvc

각 개체를 생성하고 vSphere 클라이언트의 변경/업데이트를 모니터링해 봅시다. 먼저 StorageClass를 생성해 봅시다.

$ ls
block-pod-a.yaml block-pod-b.yaml block-pvc.yaml block-sc.yaml

$ kubectl apply -f block-sc.yaml
storageclass.storage.k8s.io/vsan-block-sc created

$ kubectl get sc
NAME          PROVISIONER             AGE
vsan-block-sc csi.vsphere.vmware.com  4s

다음 단계는 PVC를 생성하고 결과 PV를 쿼리하는 것이다.

$ kubectl apply -f block-pvc.yaml
persistentvolumeclaim/block-pvc created

$ kubectl get pvc
NAME      STATUS VOLUME                                   CAPACITY  ACCESS MODES STORAGECLASS   AGE
block-pvc Bound  pvc-6398f749-f93e-4dfd-8121-cf91926d642e 2Gi       RWO          vsan-block-sc  10s

$ kubectl get pv
NAME                                      CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM              STORAGECLASS   REASON  AGE
pvc-6398f749-f93e-4dfd-8121-cf91926d642e  2Gi       RWO           Delete          Bound   default/block-pvc  vsan-block-sc          13s

그리고 이 볼륨은 이제 CNS 덕분에 vSphere 클라이언트의 Container Volumes 뷰에서 볼 수 있다.

block-container-volume.png

vSAN 데이터스토어에서 RAID-1(Mirror)로 인스턴스화되었음을 알 수 있다. 볼륨 이름을 클릭한 다음 View Placement Details 를 클릭하면 vSAN 호스트와 vSAN 디스크에 걸친 PV의 실제 레이아웃을 볼 수 있으므로 vSphere 관리자가 볼륨을 지원하는 인프라 구성 요소를 정확하게 추적할 수 있다.

volume-placement.png

vSphere 관리자의 또 다른 유용한 기능은 "stranded" 영구 볼륨을 식별하는 것이며, 다시 말해 어떤 PV도 파드에 부착되지 않은 PV를 식별하는 것이다. 아직 파드를 배치하지 않았으니, vSAN > Capacity > Usage breakdown에서 PV가 어떻게 나타나는지 보자. 여기서 사용자 오브젝트를 확장했다. "Block container volumes (not attached to a VM)"을 식별하고 있다는 점에 유의하자.

VM은 쿠버네티스 워커 노드를 의미한다. 이것이 VM 리포트가 아닌 사용자 오브젝트 리포트에 나타나는 이유다. 파드가 볼륨을 탑재하려면 해당 볼륨을 쿠버네티스 노드에 부착해야 하며, 그 노드에서 실행 중인 kubelet이 팟에서 사용할 수 있도록 하는 작업을 담당하게 된다. 이 볼륨을 소비할 파드가 아직 없기 때문에 PV의 용량은 "not attached" 섹션 아래에 나타난다.

container-usage-breakdown.png

차트의 User objects를 클릭하여 자세한 보기를 볼 수 있다.

User-objects-view.png

현재 PV를 하나만 프로비저닝하고 vSAN은 항상 씬 디스크를 프로비저닝하므로 이 숫자는 매우 작다. 그러나 희망컨대 우리가 얻을 수 있는 세부 사항의 수준과 이것이 실제로 쿠버네티스 클러스터를 호스팅하는 vSphere 인프라를 관리하는 vSphere 관리자에게 어떤 도움을 줄 수 있는지 잘 알려 줄 것이다.

자, 이제 첫 번째 파드를 준비하자.

$ kubectl apply -f block-pod-a.yaml
pod/block-pod-a created

$ kubectl get pod
NAME        READY STATUS            RESTARTS AGE
block-pod-a 0/1   ContainerCreating 0        4s

$ kubectl get pod
NAME        READY STATUS  RESTARTS AGE
block-pod-a 1/1   Running 0        16s

파드가 준비되었다. 다음 명령을 사용하여 포드 생성과 관련된 이벤트를 검토할 수 있다.

$ kubectl get event --field-selector involvedObject.name=block-pod-a
LAST SEEN TYPE    REASON                  OBJECT           MESSAGE
1m        Normal  Scheduled               pod/block-pod-a  Successfully assigned default/block-pod-a to k8s-worker7-02
1m        Normal  SuccessfulAttachVolume  pod/block-pod-a  AttachVolume.Attach succeeded for volume "pvc-6398f749-f93e-4dfd-8121-cf91926d642e"
1m        Normal  Pulling                 pod/block-pod-a  Pulling image "k8s.gcr.io/busybox"
1m        Normal  Pulled                  pod/block-pod-a  Successfully pulled image "k8s.gcr.io/busybox"
1m        Normal  Created                 pod/block-pod-a  Created container block-pod-a
1m        Normal  Started                 pod/block-pod-a  Started container block-pod-a

볼륨이 성공적으로 부착된 것 같다. 그것에 접속해서 그것이 성공적으로 볼륨을 탑재했는지 확인해 보자.

$ kubectl exec -it block-pod-a -- /bin/sh

/ # mount | grep /mnt/volume1
/dev/sdb on /mnt/volume1 type ext4 (rw,relatime,data=ordered)

/ # df /mnt/volume1
Filesystem  1K-blocks  Used  Available  Use%  Mounted on
/dev/sdb    1998672    6144  1871288    0%    /mnt/volume1
/ #

이것도 좋아 보인다. 그리고 이제 볼륨이 VM(파드가 예정되어 있던 K8s 워커 노드)에 연결되었으므로, 이제 사용량 분석은 보고 방법을 변경한다. 이제 VM 범주의 블록 컨테이너 볼륨(VM에 연결된 볼륨) 아래에 나타난다. 그래서 더 이상 stranded 않는다. 매우 유용하다.

VM-usage-breakdown.png

이제 이 ReadWriteOnce 블록 볼륨을 연결 및 탑재하려는 다른 팟을 배포하려고 하면 어떻게 되는지 보여드리죠,

$ kubectl apply -f block-pod-b.yaml
pod/block-pod-b created

$ kubectl get pod
NAME         READY  STATUS            RESTARTS  AGE
block-pod-a  1/1    Running           0         15m
block-pod-b  0/1    ContainerCreating 0         7s

$ kubectl get event --field-selector involvedObject.name=block-pod-b
LAST SEEN  TYPE     REASON              OBJECT           MESSAGE
16s        Normal   Scheduled           pod/block-pod-b  Successfully assigned default/block-pod-b to k8s-worker7-01
16s        Warning  FailedAttachVolume  pod/block-pod-b  Multi-Attach error for volume "pvc-6398f749-f93e-4dfd-8121-cf91926d642e" Volume is already used by pod(s) block-pod-a

예상대로 RWO 볼륨을 여러 파드에 동시에 부착할 수 없고, 볼륨은 파드 A에서 이미 사용 중이기 때문에 파드 B에 첨부하지 못했다. 쿠베르네스는 결국 일관된 시스템이기 때문에, 컨테이너를 만들기 위해 이 요청을 계속 시도하고 조정한다. 그러나 이것은 결코 성공하지 못할 것이며, 우리가 중지하라고 말할 때까지 이 ContainerCreating 상태로 남을 것이다.

이제 RWO 블록 볼륨으로 마무리하고 RWX 파일 볼륨을 자세히 살펴봅시다.

ReadWriteMany (File) Persistent Volumes

블록 볼륨에서와 마찬가지로 파일 볼륨에서도 유사한 데모를 할 겁니다. 단계:

  1. (파일 공유) RAID1 정책을 사용하는 StorageClass를 생성하여 vSAN 데이터스토어에서 Persistent Volume이 NFS 파일 공유로 인스턴스화됨을 나타낸다.
  2. ReadWriteOnce Persistent Volume Claim(PVC)를 생성하여 Persistent Volume(PV)를 수동으로 생성한다.
  3. PVC를 사용하는 파드를 생성하면 PVC와 연관된 PV를 얻을 수 있다.
  4. 이러한 파드가 동일한 RWX 볼륨을 공유할 수 있음을 증명할 동일한 PVC를 가진 다른 파드를 실행한다.

여기 매니페스트들이 있다. 그것들은 몇 가지 중요한 차이점이 있는 여러 면에서 블록 매니페스트와 유사하다. 현재 StorageClass 매니페스트에는 파일 시스템 유형, 루트 스쿼시, 사용 권한 및 공유 마운트 허용 네트워크와 같은 몇 가지 NFS 특정 매개 변수가 포함되어 있다. 여기서는 모든 네트워크가 읽기-쓰기 권한으로 공유를 마운트할 수 있도록 허용하고 있다. 또한 활성화된 루트 스쿼시는 없다.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: vsan-file-sc
provisioner: csi.vsphere.vmware.com
parameters:
  storagepolicyname: "RAID1"
  csi.storage.k8s.io/fstype: nfs4
  allowroot: "true"
  permission: "READ_WRITE"
  ips: "*"

PersistentVolumeCaim 매니페스트는 이전 블록 예제와 거의 동일하다. 주요한 차이점은 accessModeReadWriteMany로 설정되어 있는 반면, 이전에는 ReadWriteOnce로 설정되었다는 것이다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: file-pvc
spec:
  storageClassName: vsan-file-sc
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

파드 매니페스트 또한 이전과 매우 유사하다. 여기서의 아이디어는 두 개의 파드가 동시에 동일한 ReadWriteMany 공유 볼륨에 부착, 마운트 및 쓰기를 할 수 있다는 것을 증명하는 것이다.

apiVersion: v1
kind: Pod
metadata:
  name: file-pod-a
spec:
  containers:
  - name: file-pod-a
    image: "k8s.gcr.io/busybox"
    volumeMounts:
    - name: file-vol
      mountPath: "/mnt/volume1"
    command: [ "sleep", "1000000" ]
  volumes:
    - name: file-vol
      persistentVolumeClaim:
        claimName: file-pvc

이것은 첫 번째 파드와 RWX 영구 볼륨을 공유하려는 두 번째 파드다.

apiVersion: v1
kind: Pod
metadata:
  name: file-pod-b
spec:
  containers:
  - name: file-pod-b
    image: "k8s.gcr.io/busybox"
    volumeMounts:
    - name: file-vol
      mountPath: "/mnt/volume1"
    command: [ "sleep", "1000000" ]
  volumes:
    - name: file-vol
      persistentVolumeClaim:
        claimName: file-pvc

블록에 대해 했던 것과 같은 방식으로 시작한다. 먼저 스토리지 클래스를 만든 다음 PVC를 만들자. 그런 다음 vSphere 클라이언트 UI에서 변경된 사항을 확인한다. 이전에 만든 블록 객체를 파일을 위해 생성된 오브젝트와 비교할 수 있도록 제거하지 않겠다.

$ kubectl apply -f file-sc.yaml
storageclass.storage.k8s.io/vsan-file-sc created


$ kubectl get sc
NAME            PROVISIONER              AGE
vsan-block-sc   csi.vsphere.vmware.com   76m
vsan-file-sc    csi.vsphere.vmware.com   5s


$ kubectl apply -f file-pvc.yaml
persistentvolumeclaim/file-pvc created


$ kubectl get pvc
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
block-pvc   Bound    pvc-6398f749-f93e-4dfd-8121-cf91926d642e   2Gi        RWO            vsan-block-sc   74m
file-pvc    Bound    pvc-216e6403-fd0c-48ea-bd05-c245a54d72ac   2Gi        RWX            vsan-file-sc    25s


$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS    REASON   AGE
pvc-216e6403-fd0c-48ea-bd05-c245a54d72ac   2Gi        RWX            Delete           Bound    default/file-pvc    vsan-file-sc             17s
pvc-6398f749-f93e-4dfd-8121-cf91926d642e   2Gi        RWO            Delete           Bound    default/block-pvc   vsan-block-sc            74m

PVC 및 PV의 액세스 모드를 기록해 두자. 새로운 볼륨은 ReadWriteMany를 의미하는 RWX다. 위의 명령을 실행한 후 vSphere Client에서 어떤 변경 사항이 발생했는지 확인한다. Configure > vSAN > File Service Shares로 이동하면 동적으로 생성되는 Container Volume 유형의 새로운 파일 공유가 현재 존재한다는 것을 관찰할 수 있다.

File-Service-Share.png

그리고 볼륨의 이름을 클릭하면 이전에 블록 볼륨에서 볼 수 있었던 것처럼 개체 배치 세부 정보를 볼 수 있는 Monitor > vSAN > Virtual Objects로 다시 한 번 이동하게 된다. 그리고 컨테이너 볼륨도 Container Volumes 보기에 나타난다.

Container-Volume-View.png

이제 첫 번째 포드를 배치하고 무엇을 얻는지 봅자. 두 번째 블록 팟은 여전히 이전부터 'ContainerCreating'이며, 무한정 계속 그렇게 할 것이라는 점에 주목한다.

$ kubectl apply -f file-pod-a.yaml
pod/file-pod-a created


$ kubectl get pod
NAME          READY   STATUS              RESTARTS   AGE
block-pod-a   1/1     Running             0          68m
block-pod-b   0/1     ContainerCreating   0          52m
file-pod-a    1/1     Running             0          22s


$  kubectl get event --field-selector involvedObject.name=file-pod-a
LAST SEEN   TYPE     REASON                   OBJECT           MESSAGE
51s         Normal   Scheduled                pod/file-pod-a   Successfully assigned default/file-pod-a to k8s-worker7-01
51s         Normal   SuccessfulAttachVolume   pod/file-pod-a   AttachVolume.Attach succeeded for volume "pvc-216e6403-fd0c-48ea-bd05-c245a54d72ac"
42s         Normal   Pulled                   pod/file-pod-a   Container image "gcr.io/google_containers/busybox:1.24" already present on machine
42s         Normal   Created                  pod/file-pod-a   Created container file-pod-a
42s         Normal   Started                  pod/file-pod-a   Started container file-pod-a

위의 이벤트와 같이 파드가 생성되어 볼륨이 성공적으로 부착되었다. OK – 우리가 읽고 쓸 수 있다는 것을 보여주기 위해 볼륨에 대해 간단한 것을 해보자.

$ kubectl exec -it file-pod-a -- /bin/sh 

/# mount | grep /mnt/volume1 
10.27.51.31:/52890fc4-b24d-e185-f33c-638eabfa5e25 on /mnt/volume1 type nfs4 \
(rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,\
timeo=600,retrans=2,sec=sys,clientaddr=192.168.232.1,local_lock=none,addr=10.27.51.31) 

/ # df /mnt/volume1 
Filesystem           1K-blocks      Used Available Use% Mounted on 
10.27.51.31:/52890fc4-b24d-e185-f33c-638eabfa5e25                      
                     4554505216         0 4554402816   0% /mnt/volume1

/ # cd /mnt/volume1

/mnt/volume1 # mkdir CreatedByPodA

/mnt/volume1 # cd CreatedByPodA

/mnt/volume1/CreatedByPodA # echo "Pod A was here" >> sharedfile

/mnt/volume1/CreatedByPodA # cat sharedfile
Pod A was here

다음 단계는 우리의 두 번째 파드를 시작하고, 그것이 액세스를 공유하고 같은 볼륨을 탑재할 수 있는지 확인하는 것이다.

$ kubectl get pods
NAME         READY  STATUS            RESTARTS  AGE
block-pod-a  1/1    Running           0         116m
block-pod-b  0/1    ContainerCreating 0         100m
file-pod-a   1/1    Running           0         9m11s


$ kubectl apply -f file-pod-b.yaml
pod/file-pod-b created


$ kubectl get pods
NAME         READY  STATUS            RESTARTS  AGE
block-pod-a  1/1    Running           0         116m
block-pod-b  0/1    ContainerCreating 0         100m
file-pod-a   1/1    Running           0         9m29s
file-pod-b   1/1    Running           0         6s


$ kubectl get event --field-selector involvedObject.name=file-pod-b
LAST SEEN  TYPE    REASON                 OBJECT           MESSAGE
27s        Normal  Scheduled               pod/file-pod-b  Successfully assigned default/file-pod-b to k8s-worker7-02
27s        Normal  SuccessfulAttachVolume  pod/file-pod-b  AttachVolume.Attach succeeded for volume "pvc-216e6403-fd0c-48ea-bd05-c245a54d72ac"
19s        Normal  Pulled                  pod/file-pod-b  Container image "gcr.io/google_containers/busybox:1.24" already present on machine
18s        Normal  Created                 pod/file-pod-b  Created container file-pod-b
17s        Normal  Started                 pod/file-pod-b  Started container file-pod-b

가장 먼저 주목해야 할 것은 사건들이다. 이 모든 것이 보기 좋으며, 두 번째 포드인 파드 B는 이미 파드 A에 부착되어 장착되었을 때에도 RWX Persistent Volume을 성공적으로 탑재할 수 있었던 것으로 보일 것이다. 잘 했어요 마지막 단계는 파드 B에 로그인하여 볼륨에도 읽고 쓸 수 있는지 확인하는 것이다.

$ kubectl exec -it file-pod-b -- /bin/sh

/ # mount | grep /mnt/volume1
10.27.51.31:/52890fc4-b24d-e185-f33c-638eabfa5e25 on /mnt/volume1 type nfs4 \
(rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,\
timeo=600,retrans=2,sec=sys,clientaddr=192.168.213.193,local_lock=none,addr=10.27.51.31)

/ # df | grep /mnt/volume1
4554263552 0 4554161152 0% /mnt/volume1

/ # df /mnt/volume1
Filesystem           1K-blocks      Used  Available   Use%  Mounted on
10.27.51.31:/52890fc4-b24d-e185-f33c-638eabfa5e25
                     4554263552     0     4554161152  0%    /mnt/volume1

/ # cd /mnt/volume1

/mnt/volume1 # ls
CreatedByPodA

/mnt/volume1 # cd CreatedByPodA/

/mnt/volume1 # ls
sharedfile

/mnt/volume1/CreatedByPodA # cat sharedfile
Pod A was here

/mnt/volume1/CreatedByPodA # echo "Pod B was here too" >> sharedfile

그래서 우리는 파드 A로부터 공유에 만들어진 디렉토리와 파일을 볼 수 있다. 우리는 방금 파드 A가 원래 파드 B에서 만든 파일을 간단히 업데이트했다. 이제 파드 A에서 열려 있는 셸 세션으로 돌아가면 sharedfile이 대한 업데이트를 볼 수 있는지 확인한다.

/mnt/volume1/CreatedByPodA # cat sharedfile
Pod A was here
Pod B was here too

두 파드 모두 vSAN File Servies에 의해 동적으로 프로비저닝된 이 RWX 영구 볼륨을 성공적으로 읽고 쓸 수 있는 것처럼 보인다.

 

이를 통해 기존 가상 시스템 워크로드와 새로운 컨테이너형 워크로드 모두에 vSAN File Services를 사용할 수 있는 방법에 대해 좋은 아이디어를 얻기를 바란다.

스토리지 정책을 통해 볼륨의 원하는 가용성과 성능을 반영하는 스토리지 클래스와 함께 vSAN의 파일 공유를 영구 볼륨으로 동적으로 프로비저닝하는 방법을 살펴보았다. 우리는 또한 내가 이 게시물에서 그것들을 모두 보여주지는 않았지만 몇몇의 깔끔한 UI 향상도 보았다.

주요 이점은 개발자가 vSAN에서 프로비저닝된 블록 기반 RWO 볼륨 또는 파일 기반 RWX 볼륨을 사용하더라도 vSphere 관리자는 개발자가 vSphere 스토리지를 어떻게 소비하는지에 대한 모든 가시성을 확보한다는 것이다. 이를 통해 개발자든 K8s 관리자든 vSphere Administrator와 Kubernetes 사용자 간에 좋은 커뮤니케이션을 개발할 수 있다. 어느 쪽이든, 이것은 조직에서 Dev-Ops의 문화가 일어나도록 하고 있다.

vSAN File Service와 파일 공유를 위한 새로운 CSI 드라이버에 대해 자세히 알고 싶다면 내 친한 친구 Myles에서 이 블로그 게시물을 확인하십시오. 이 자료에는 vSAN 파일 서비스가 새로운 CSI 드라이버와 어떻게 작동하고 CNS와 통합되는지에 대한 멋진 데모가 포함되어 있다.

이 데모에 사용된 매니페스트는 이 공개 Github repo에서 사용할 수 있다.

 

[번역] Cloud Native Storage and vSAN File Services Integration

출처 : https://blogs.vmware.com/virtualblocks/2020/03/12/cloud-native-storage-and-vsan-file-services-integration/

개요

vSphere 6.7 U3을 사용하여 vSphere에서 볼륨을 온디맨드 방식으로 프로비저닝해야 하는 컨테이너 기반 워크로드에 맞게 구축된 Cloud Native Storage Control Plane을 vSphere에 도입했다.

초기 릴리즈는 영구 볼륨이 필요한 가장 일반적인 워크로드, 즉 ReadWriteOnce 유형(기본적으로 단일 볼륨을 탑재하는 단일 컨테이너)에 대해 제공되었다. 이것이 가장 일반적인 사용 사례인 반면, 우리가 잘 알고 있는 다른 사용 사례도 있었고 실제로 그들의 스토리지 요구에 부응하기 위해 동기 부여된 경우도 있었다.

많은 애플리케이션이 ReadWriteMany 볼륨(읽기/쓰기 방식으로 단일 볼륨을 다중 컨테이너에서 마운트)을 이용할 수 있다. NginX, Apache, Tomcat, Harbor Registration 등-여러 컨테이너가 하나의 볼륨을 마운트-스토리지 효율성을 실현하거나, 프런트 엔드 업데이트를 더 쉽게 하거나 등.

또한 vSphere 및 vSAN 7.0과 당사가 제공하는 CNS를 함께 사용하면 RWM 모드의 Kubernetes Persistent Volumes를 위한 온디맨드 프로비저닝을 완벽하게 수행할 수 있다.

왜 필요한가?

당신이 물어보길 잘 했네요. 일부 애플리케이션, 특히 웹 서버, 앱 서버 및 컨테이너 등록부는 ReadWriteMany(RWM) 볼륨으로 알려진 Kubernetes 개념을 사용하여 대규모 스토리지 효율성과 확장 용이성을 실현할 수 있다.

이러한 애플리케이션이 어떻게 확장되는지 생각해 보면, 부하에 따라 탄력적으로 작동하는데, 이는 매우 변화하기 쉽다. 그러나 모두 동일한 컨텐츠를 제공한다. 10대의 웹 또는 앱 서버가 모두 다른 컨텐츠를 서비스하고 있다면 무슨 소용이 있겠는가?

그렇다면 이 모든 콘텐츠가 동일한 경우 - 외부로 만들 수 있고 이와 같이 상당한 스토리지 효율성을 실현할 수 있는데 왜 컨테이너 자체에 컨텐츠를 넣는가? 저장한 스토리지의 양은 실제로 이 볼륨을 탑재하는 컨테이너의 수와 정비례한다. 만약 10대의 웹 서버가 실제 웹 사이트 데이터가 저장되어 있는 동일한 볼륨을 탑재하고 있다면, 기본적으로 해당 스토리지에서 10-1 만큼(즉 9)을 절약할 수 있다.

즉, 한 컨테이너를 통해 컨텐츠를 업데이트할 때(웹 사이트 업데이트가 이루어진다고 가정함) 다른 모든 컨테이너에서 즉시 제공되는 콘텐츠가 동일한 볼륨의 지원을 받는다는 사실은 말할 필요도 없다. 그래서 좋은 운영 효율성도 가지고 있다.

무엇처럼 보이나요?

"왜"라는 말을 꺼내고, "무엇"으로 넘어가자. 이 기능은 어떻게 작동하는지 볼 수 있을 때 가장 잘 설명되므로 아래 기능의 짧은 비디오 데모를 확인해 보자.

사용자가 Kubernetes에서 RWM 볼륨을 요청할 때 CNS는 vSAN 파일 서비스에 요청하여 요청된 크기 및 적절한 SPBM 정책의 NFS 기반 파일 공유를 생성하고 볼륨을 요청하는 Pod가 상주하는 Kubernetes 작업자 노드에 마운트하도록 요청하며, 또한 여러 노드가 RWM 볼륨 또는 애플리케이션에 대한 액세스를 요청하는 경우스케일 아웃, CNS는 특정 전개에 대한 RWM 볼륨이 이미 존재하며 기존 볼륨도 이 볼륨에 탑재한다는 점을 주목한다.

cns-fs-scaled.png

위의 참고 사항. vSAN File Service를 통해 단일 볼륨을 마운트하는 여러 개의 포드