쿠버네티스 환경에서 nas를 마운트해서 사용하고 싶었는데 방법이 어떤 것이 있을지 찾아보았다.
NFS
nfs는 네트워크에 파일을 저장하는 방식으로, 사용자가 원격 컴퓨터에 있는 파일 및 디렉토리에 액세스할 수 있게 한다. 주로 NAS에서 사용한다.
Kubernetes에서 NFS 사용하기
pod에 직접 마운트
마운트가 필요한 파드에 직접 값을 넣어주는 방법이 존재한다.
volumes: - name: nas-cli-volume nfs: server: xxx.xxx.xxx.xxx path: <nas-mount-dir>
그러나 추상화 측면에서 좋지 않아 보이고, 모든 pod마다 nfs 정보를 가지고 있는 것이 좋지 않아 보인다.
nfs-pod-provisioner를 통해 pv 생성을 pvc 요청할 때마다 해줌
(kubernetes) - nfs storage사용하기
pvc를 요청 → nfs-pod-provisioner에서 pv를 dynamic하게 생성 → 마운트 완료 의 과정으로 진행된다.
사용하는 입장에서는 pv를 선언할 필요 없이 pvc만 선언하면 provisioner에서 알아서 해주는 다이나믹 프로비저닝 방식이다.
Provisioner
rbac
apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - 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: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-client-provisioner subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
StorageClass
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME' parameters: archiveOnDelete: "false"
Provisoner
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER # do not change value: xxx.xxx.xxx.xxx # Ip of the NFS SERVER - name: NFS_PATH # do not change value: <nfs-path> # path to nfs directory setup volumes: - name: nfs-client-root nfs: server: xxx.xxx.xxx.xxx path: <nfs-path>
실제 사용하기
pvc
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: task-pv-claim spec: storageClassName: nfs-client accessModes: - ReadWriteOnce resources: requests: storage: 20Gi
pod
apiVersion: v1 kind: Pod metadata: name: task-pv-pod spec: volumes: - name: task-pv-storage persistentVolumeClaim: claimName: task-pv-claim containers: - name: task-pv-container image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/usr/share/nginx/html" name: task-pv-storage
동적 프로비저닝 방식이기 때문에 따로 pv를 관리하지 않아도
nfs-client-provisioner
deployment에서 자동으로 pv를 생성해준다.Deployment에서 클러스터 레벨의 pv를 생성할 수 있는 이유는
nfs-client-provisioner
서비스 어카운트에nfs-client-provisioner-runner
클러스터 롤과leader-locking-nfs-client-provisioner
롤이 바인딩되어 kubernetes api를 자유롭게 호출할 수 있기 때문이다. Deployment 내에서 pv를 만들면서 mounting될 path도 host에 자연스럽게 만들어 준다.단점
- NFS가 제한하는 total size보다 더 많은 양을 allocate할 수 있다.
- Storage resize나 expansion를 지원하지 않는다.
'k8s' 카테고리의 다른 글
[TIL] regcred 알아보기 (0) | 2023.04.24 |
---|---|
K8S 컴포넌트 정리 (0) | 2023.03.31 |
Kubernetes 스토리지 구조 (0) | 2023.03.26 |
[TIL] pod에서 서비스 접속하기 (0) | 2022.07.10 |
Minikube, Kubeadm, Kind, K3S (0) | 2022.05.08 |