[Kubernetes-Storage] CentOS 8에 Dynamic NFS Client Provisioner 구성하기 화요일, 1월 05, 2021 [Kubernetes - Storage] How to configure a dynamic storage provisioner for Kubernetes using a network file system on CentOS 8 참고 이 문서는 Network File System을 CentOS 8에 설치하여 NFS Server로 운영하면서 Kubernetes의 PVC (Perssistent Volume Claim) - StorageClass - NFS 로 연동되는 PV (Persistent Volume)를 자동으로 구성하는 방법을 정리한 것입니다. CentOS 8에 설치되는 NFS를 Kubernetes의 Dynamic Storage Provisioning 으로 활용해서 PV (Persistent Volume)를 구성해 본다. Network file system 구성 NFS 서버를 구성하는 부분은 CentOS 8에 NFS 설정 및 테스트 글을 참고해서 진행하도록 한다. NFS 서버는 물리적인 머신으로 네트워크 상에 존재하면 되며, Network을 통해서 Kubernetes Cluster에서 NFS 서버로 접근할 수 있어야 한다. 위에서 구성한 NFS 서버를 사용할 수 있도록 처리하는 NFS Provisioner Pod가 Kubernetes Cluster에 PV를 배포할 수 있도록 하기 위해서는 필요한 권한 설정이 필요하다. 따라서 PV를 배포할 수 있도록 ClusterRole, ClusterRoleBinding, Role, RoleBinding 설정을 가지는 Service Account를 생성해 줘야 한다. Service Account 생성 서비스 계정을 생성한다. (serviceaccount.yaml) apiVersion: v1 kind: ServiceAccount metadata: name: nfs-provisioner 아래의 명령을 사용해서 Kubernetes에 적용한다. $ kubectl apply -f serviceaccount.yaml ClusterRole 생성 Cluster를 위한 역할을 생성한다. (clusterrole.yaml) kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-provisioner-runner rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["watch", "create", "update", "patch"] - apiGroups: [""] resources: ["services", "endpoints"] verbs: ["get"] - apiGroups: ["extensions"] resources: ["podsecuritypolicies"] resourceNames: ["nfs-provisioner"] verbs: ["use"] 아래의 명령을 사용해서 Kubernetes에 적용한다. $ kubectl apply -f clusterrole.yaml ClusterRoleBinding 생성 Cluster를 위한 역할 바인딩을 생성한다. (clusterbinding.yaml) kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-provisioner subjects: - kind: ServiceAccount name: nfs-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-provisioner-runner apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: nfs-provisioner-otherRoles rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: nfs-provisioner-otherRoles subjects: - kind: ServiceAccount name: nfs-provisioner namespace: default # provisioner가 배포될 네임스페이스 roleRef: kind: Role name: nfs-provisioner-otherRoles apiGroup: rbac.authorization.k8s.io 아래의 명령을 사용해서 Kubernetes에 적용한다. $ kubectl apply -f clusterbinding.yaml NFS Client Provisioner 생성 Provisioner는 PVC와 StorageClass를 통해서 자동으로 PV를 구성해 주는 역할을 담당한다. NFS 서버를 Dynamic Storage Provisioning으로 사용할 수 있도록 NFS Client Dynmaic Provisioner Pod를 배포하도록 구성한다. (deployment-nfs.yaml) kind: Deployment apiVersion: apps/v1 metadata: name: nfs-client-provisioner spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccount: nfs-provisioner containers: - name: nfs-client-provisioner image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: fuseim.pri/ifs - name: NFS_SERVER value: 10.0.1.20 - name: NFS_PATH value: /data/NFS volumes: - name: nfs-client-root nfs: server: 10.0.1.20 path: /data/NFS 아래의 명령을 사용해서 Kubernetes에 적용한다. $ kubectl apply -f deployment-nfs.yaml StorageClass 생성 NFS 연계를 위한 StorageClass를 생성한다. (storageclass-nfs.yaml) apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: managed-nfs-storage provisioner: fuseim.pri/ifs 아래의 명령을 사용해서 Kubernetes에 적용한다. $ kubectl apply -f storageclass-nfs.yaml Statefulset 생성 및 PV 검증 NFS 연계를 검증하기 위한 Statefulset을 생성하고 PV의 생성여부를 검증한다. (statefulset-nfs.yaml) apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx1" replicas: 1 selector: matchLabels: app: nginx1 volumeClaimTemplates: - metadata: name: test annotations: volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 2Gi template: metadata: labels: app: nginx1 spec: serviceAccount: nfs-provisioner containers: - name: nginx1 image: nginx:1.7.9 volumeMounts: - mountPath: "/mnt" name: test 아래의 명령을 사용해서 Kubernetes에 적용한다. $ kubectl apply -f statefulset-nfs.yaml Dynamic Provisioner Pod 실행 상태 확인 $ kubectl get all NAME READY STATUS RESTARTS AGE pod/nfs-pod-provisioner-5f8686f8dd-bfkgz 1/1 Running 0 8m51s 주의 만일 어느 정도의 시간이 지나도 STATUS가 ContainerCreating 또는 Pending 이라고 나오는 경우는 NFS 설정에 따라서 오류가 발생했을 수 있다.kubectl describe <pod name>으로 확인해 보면 오류 상황을 알 수 있다. connection timeout: NFS 서버의 IP에 접근이 안되는 경우이므로 실제 접근 가능한 IP인지 확인해야 한다. IP가 맞다면 NFS 서버에서 /etc/exports 설정을 다시 확인해 보고 sudo exportfs -ra를 수행하고 다시 처리한다. access denied by server: NFS 서버에는 접근을 했지만 권한이 없는 경우이므로 NFS 서버에서 sudo chmod 666 <nfs directory>를 수행하고 다시 처리한다. wrong fs type, bad option...: NFS 관련 패키지가 설치되지 않았을 경우이므로 클러스터의 각 노드에 sudo dnf install -y nfs-utils를 수행하고 다시 처리한다. 그 이외의 오류가 발생했다면 관련된 메시지를 통해서 원인을 파악하고 해결해야 한다. PVC (Persistent Volume Claim)를 통한 PV 생성 검증 StorageClass를 이용해서 간단한 테스트를 위한 PVC를 구성한다. (fns-pvc.yaml) apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc-test spec: storageClassName: managed-nfs-storage # StorageClass 명 accessModes: - ReadWriteMany # 생성될 PV에 적용할 사용 모드 resources: requests: storage: 10Mi # 생성될 PV 크기 참고 사용할 수 있는 AccessMode는 다음과 같다. ReadWriteOnce (RWO): 하나의 Pod에만 마운트되고 하나의 Pod에서만 읽고 쓰기 가능 ReadWriteMany (RWX): 여러 개의 Pod에 마운트 가능하고 여러 개의 Pod에서 읽고 쓰기 가능 ReadOnlyMany (ROX): 여러 개의 Pod에 마운트 가능하고 여러 개의 Pod에서 읽기는 가능하지만 쓰기는 불가능 테스트이므로 작은 크기로 설정하고 Kubernete에 적용하고 확인한다. $ kubectl apply -f nfs-pvc.yaml persistentvolumeclaim/nfs-pvc-test created $ kubectl get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-2dca7757-d8c1-4e80-8a21-f1d661d69b19 10Mi RWX Delete Bound default/nfs-pvc-test managed-nfs-storage 7s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/nfs-pvc-test Bound pvc-2dca7757-d8c1-4e80-8a21-f1d661d69b19 10Mi RWX managed-nfs-storage 7s NFS 서버에서 실제 생성된 정보 확인 PVC를 통해서 생성된 PV를 확인했으므로 실제 NFS 서버에도 생성이 되었는지 확인해 보면 된다. # NFS 서버에서 공유 디렉터리 확인 $ sudo ls /data/NFS default-nfs-pvc-test-pvc-2dca7757-d8c1-4e80-8a21-f1d661d69b19 실제 PVC와 PV 관련된 이름으로 유추할 수 있는 디렉터리가 생성된 것을 확인할 수 있다. Deploy된 Pod의 Volume Mount 확인 실제 사용할 애플리케이션 Pod에서도 정상적으로 동작하는지를 확인하기 위해서 간단한 샘플을 구성해 보도록 한다. (nfs-test-app.yaml) apiVersion: apps/v1 kind: Deployment metadata: name: ccambo-nfs-test labels: app: nginxnfs spec: replicas: 2 selector: matchLabels: app: nginxnfs template: metadata: labels: app: nginxnfs spec: containers: - name: nginxnfs image: nginx:latest ports: - containerPort: 80 volumeMounts: - mountPath: /nfs name: nfsvolume volumes: - name: nfsvolume persistentVolumeClaim: claimName: nfs-pvc-test 위의 YAML을 Kubernetes에 적용하고 확인한다. $ kubectl apply -f nfs-test-app.yaml deployment.apps/ccambo-nfs-test created # Deployment 확인 $ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE ccambo-nfs-test 0/1 1 0 15s nfs-client-provisioner 1/1 1 1 75m # Pod 확인 $ kubectl get pods NAME READY STATUS RESTARTS AGE ccambo-nfs-test-9d7fc4c6c-25xr4 1/1 Running 0 39s ccambo-nfs-test-9d7fc4c6c-js5pl 1/1 Running 0 39s nfs-client-provisioner-775496b5bb-vpglp 1/1 Running 0 82m 생성된 두 개의 Pod 중에 하나의 Pod에 접속해서 마운트된 경로에서 테스트용 파일을 생성한다. $ kubectl exec -it ccambo-nfs-test-9d7fc4c6c-25xr4 -- /bin/bash # 연결된 Pod에서 마운트된 /nfs 디렉터리로 이동해서 테스트용 파일을 하나 생성한다. > cd /nfs > echo "This is NFS test" > /nfs/test.log > cat /nfs/test.log This is NFS test 다른 Pod에 연결해서 마운트된 /nfs 디렉터리에 파일이 존재하는지 확인한다. $ kubectl exec -it ccambo-nfs-test-9d7fc4c6c-js5pl -- /bin/bash # 연결된 Pod에서 마운트된 /nfs 디렉터리로 이동해서 테스트용 파일을 확인한다. > ls /nfs test.log > cat /nfs/test.log This is NFS test 위의 테스트와 같이 생성된 POD가 동일한 NFS를 PV로 마운트해서 사용하고 있는 것을 확인할 수 있다. 공유 공유 링크 만들기 Facebook Twitter Pinterest 이메일 기타 앱 태그 centos CentOS 8 dynamic nfs client provisioner Kubernetes nfs provisioner storage storage class 공유 공유 링크 만들기 Facebook Twitter Pinterest 이메일 기타 앱 댓글
댓글
댓글 쓰기