参考教程: https://medium.com/@myte/kubernetes-nfs-and-dynamic-nfs-provisioning-97e2afb8b4a9
k8s nfs 客户端仓库: https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client

步骤1: 在nfs服务器上配置新的导出目录

导出目录是用于与nfs客户端共享的目录,这个目录可以是linux上的任意目录。这里我们使用一个创建的新目录。

sudo mkdir -p /srv/nfs/mydata2
#后边两步非常关键,如果没有这两步,可能导致其它客户端连接后出现访问禁止的错误
sudo chown nobody:nogroup /srv/nfs/mydata2
sudo chmod 777 /srv/nfs/mydata2

配置nfs-server

sudo vi /etc/exports
	-->添加对目录的路径 可以参考之前的配置
sudo exportfs -a
sudo systemctl restart nfs-kernel-server

步骤2:创建服务账户

https://gist.github.com/Ccaplat/99f316f4435b1ec5fe3d1af01dfefd56/raw/c5ce0cf39318c4abc49fe342f5141f29643400f0/rbac.yaml

kind: ServiceAccount
apiVersion: v1
metadata:
  name: nfs-pod-provisioner-sa
---
kind: ClusterRole # Role of kubernetes
apiVersion: rbac.authorization.k8s.io/v1 # auth API
metadata:
  name: nfs-provisioner-clusterRole
rules:
  - apiGroups: [""] # rules on persistentvolumes
    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: nfs-provisioner-rolebinding
subjects:
  - kind: ServiceAccount
    name: nfs-pod-provisioner-sa # defined on top of file
    namespace: default
roleRef: # binding cluster role to service account
  kind: ClusterRole
  name: nfs-provisioner-clusterRole # name defined in clusterRole
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-pod-provisioner-otherRoles
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-pod-provisioner-otherRoles
subjects:
  - kind: ServiceAccount
    name: nfs-pod-provisioner-sa # same as top of the file
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: nfs-pod-provisioner-otherRoles
  apiGroup: rbac.authorization.k8s.io

Deploying the service account:

$ kubectl apply -f rbac.yaml
serviceaccount/nfs-pod-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-provisioner-clusterRole created
clusterrolebinding.rbac.authorization.k8s.io/nfs-provisioner-rolebinding created
role.rbac.authorization.k8s.io/nfs-pod-provisioner-otherRoles created
rolebinding.rbac.authorization.k8s.io/nfs-pod-provisioner-otherRoles created$ kubectl get clusterrole,role 

步骤3:创建一个storage classs

https://gist.github.com/Ccaplat/1578c81282339fdccc749458f95e7c9c/raw/96c8bc962eb79e110b490fcbc38b7a6e4ecc2534/nfs_class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storageclass # IMPORTANT pvc needs to mention this name
provisioner: nfs-test # name can be anything
parameters:
  archiveOnDelete: "false"
$ kubectl create -f nfs_class.yaml
$ bubectl get storageclass
NAME                 PROVISIONER                AGE
nfs-storageclass     nfs-pod

步骤4:以pod方式部署NFS client provisioner

NFS client provisioner github

yaml文件:https://gist.github.com/Ccaplat/fc69461b7f47eb6791e050da2f151f26/raw/81bbd0c99beb0255ca32a24ed77f101605a9d786/nfs_pod_provision.yaml

注意 这个配置文件中有些选项需要根据实际情况进行修改

链接中的yaml文件缺少spec.selector字段

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-pod-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-pod-provisioner
  template:
    metadata:
      labels:
        app: nfs-pod-provisioner
    spec:
      serviceAccountName: nfs-pod-provisioner-sa # name of service account created in rbac.yaml
      containers:
        - name: nfs-pod-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-provisioner-v
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME # do not change
              value: nfs-test # SAME AS PROVISONER NAME VALUE IN STORAGECLASS
            - name: NFS_SERVER # do not change
              value: 192.168.1.7 # Ip of the NFS SERVER
            - name: NFS_PATH # do not change
              value: /srv/nfs/mydata2 # path to nfs directory setup
      volumes:
       - name: nfs-provisioner-v # same as volumemouts name
         nfs:
           server: 192.168.1.7
           path: /srv/nfs/mydata2

Deploying the NFS client pod:

$ kubectl apply -f nfs_pod_provision.yaml
pod/nfs-pod-provisioner-66ffbbbbf-sg4kh   1/1     Running   0          7s
$ kubectl describe po nfs-pod-provisioner-66ffbbbbf-sg4kh
 nfs-provisioner-v:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.1.7
    Path:      /srv/nfs/mydata2
     Mounts:
      /persistentvolumes from nfs-provisioner-v (rw)

The NFS client has been attached to the NFS server and mounted to the persistence volume with Read and Write permission.

步骤5:测试

请求并部署一个pvc:

https://gist.github.com/Ccaplat/7fbce589a37c8083816b1b7f7266d3ac/raw/69b98ccaccaacde51d6207cdf11f06119d2940d9/nfs_pvc_dynamic.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc-test
spec:
  storageClassName: nfs-storageclass # SAME NAME AS THE STORAGECLASS
  accessModes:
    - ReadWriteMany #  must be the same as PersistentVolume
  resources:
    requests:
      storage: 50Mi
$ kubectl get pv,pvc
$ kubectl apply -f  nfs_pvc_dynamic.yaml
nfs-pvc-test   Bound    pvc-620ff5b1-b2df-11e9-a66a-080027db98ca   50Mi       RWX            nfs-storageclass   7s
$ ls /srv/nfs/mydata2/
default-nfs-pvc-test-pvc-620ff5b1-b2df-11e9-a66a-080027db98ca

可以看到在 mydata2/文件夹中创建了一个default-nfs-pvc-test… 文件夹

这个pvc所创建的文件都会在这个文件夹下。

部署一个nginx来进行测试:

https://gist.github.com/Ccaplat/d6bca372a794215b1d526812ff6e5cff/raw/16d878a86f0546d772df862bb5c1f1ea77bcb5a0/nginx_nfs.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nfs-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
      - name: nfs-test #
        persistentVolumeClaim:
          claimName: nfs-pvc-test  # same name of pvc that was created
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: nfs-test # name of volume should match claimName volume
          mountPath: mydata2 # mount inside of contianer
$ kubectl get po 
nfs-nginx-76c48f6466-fnkh9             1/1     Running   0

在pod中创建一个txt文件,并且验证它存在于nfs对应的文件夹中:

$ kubectl exec -it po nfs-nginx-76c48f6466-fnkh9 bash
$ cd mydata2/
$ root@nfs-nginx-76c48f6466-fnkh9:/mydata2# touch testfile.txt
$ exit$ ls /srv/nfs/mydata2/default-nfs-pvc-test-pvc-620ff5b1-b2df-11e9-a66a-080027db98ca/
testfile.txt

可以看到文件已经被同步,nfs客户端运行正常!

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐