티스토리 뷰
[Kubernetes-Storage] CentOS 8에 Dynamic NFS Client Provisioner 구성하기
ccambo 2021. 1. 5. 19:03[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로 마운트해서 사용하고 있는 것을 확인할 수 있다.
'개발 > Kubernetes 이해' 카테고리의 다른 글
- Total
- Today
- Yesterday
- dynamic nfs client provisioner
- Kubernetes
- Kudo
- terrminating
- Replica
- Galera Cluster
- k8s
- CentOS 8
- zookeeper
- operator
- SolrCloud
- operator framework
- 쿠버네티스
- leader
- ssh
- Cluster
- Node
- collection
- opencensus
- galera
- NFS
- custom resource
- macos
- Packages
- GIT
- provisioner
- docker
- CentOS
- KUBECTL
- kudo-cli
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |