基于NFS文件系统创建持久化存储

Provisioning: PV的预制创建有两种模式:静态和动态供给模式:
静态供给模式: 需要先手动创建PV, 然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision)。
动态供给模式: 只需要创建PVC,系统根据PVC创建PV, 如果没有满足 PVC 条件的 PV,会动态创建 PV。相比静态供给,动态供给(Dynamical Provision)有明显的优势:不需要提前创建 PV,减少了管理员的工作量,效率高.
动态供给是通过 StorageClass 实现的,StorageClass 定义了如何创建 PV。

部署NFS 服务( 10.68.56.11 主机上 )

#   创建 NFS 存储目录
mkdir -p /home/cicd
#   安装nfs服务
yum -y install nfs-utils rpcbind
#   修改配置文件
echo "/home/cicd *(rw,sync,no_root_squash,no_subtree_check)" >> /etc/exports
#   启动服务
systemctl start nfs && systemctl start rpcbind
#   设置开机启动
systemctl enable nfs-server && systemctl enable rpcbind

下面就分别实践这两种模式的创建跟使用:

NFS作为静态供给模式持久化存储卷
1
手动创建PV—>手动创建PVC—>POD挂载使用

  1. 创建PV
cat >> nfs-test-pv.yaml << EOF
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-test-pv
  namespace: default
  labels:
    app: nfs-test-pv
spec:
  capacity:
    storage: 5Gi   # 指定PV容量为5G
  accessModes:
    - ReadWriteOnce #  指定访问模式为 ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle # 指定当 PV 的回收策略为 Recycle
  storageClassName: nfs   # 定 PV 的 class 为 nfs。相当于为 PV 设置了一个分类,PVC 可以指定 class 申请相应 class 的 PV。
  nfs:
    path: /nfs_data # 指定 PV 在 NFS 服务器上对应的目录
    server: 10.68.56.11 # NFS Server地址
EOF

create_pv
STATUS 为 Available,表示 nfs-test-pv 就绪,可以被 PVC 申请。
接下来创建 PVC nfs-test-pv-claim:

  1. 创建PVC
cat >> nfs-test-pv-claim.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-test-pv-claim
  namespace: default
spec:
  accessModes: # 存储访问模式,此能力依赖存储厂商能力
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi # 请求获得的pvc存储大小
  storageClassName: nfs 
EOF

create_pvc

从 kubectl get pvc 和 kubectl get pv 的输出可以看到 nfs-test-pv-claim 已经 Bound 到 nfs-test-pv,申请成功。
接下来就可以在 Pod 中使用存储了:

  1. 创建Pod
cat >> nfs-test-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  name:  nfs-test-pod
spec:
  containers:
  - name:  nfs-test-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 30000
    volumeMounts:
    - mountPath: "/nfs-data"
      name: nfs-data
  volumes:
    - name: nfs-data
      persistentVolumeClaim:
        claimName:  nfs-test-pv-claim
EOF

与使用普通 Volume 的格式类似,在 volumes 中通过 persistentVolumeClaim 指定使用 nfs-test-pv-claim 申请的 Volume。

create_pod
验证 PV 是否可用:
1

kubectl exec nfs-test-pod touch /nfs-data/SUCCESS

create_result
可见,在 Pod 中创建的文件 /nfs-data/SUCCESS 确实已经保存到了 NFS 服务器目录 /nfs_data/中。
如果不再需要使用 PV,可用删除 PVC 回收 PV:

  1. 回收PVC
    持久化卷声明的保护
    PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失。
    注意:当 pod 状态为 Pending 并且 pod 已经分配给节点或 pod 为 Running 状态时,PVC 处于活动状态。
    当启用PVC保护功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用。
    您可以看到,当我直接删除上面POD正在使用的PVC时命令直接hang住了,此时虽然为 Teminatiing,但PVC 受到保护,Finalizers 列表中包含 kubernetes.io/pvc-protection:

1

kubectl delete pvc nfs-test-pv-claim

pvc_delete_status

等待 pod 状态变为 Terminated(删除 pod 或者等到它结束),然后检查,确认 PVC 被移除。
反之,如果一个PVC没有被pod使用则可以直接删除。
用户用完 volume 后,可以从允许回收资源的 API 中删除 PVC 对象。PersistentVolume 的回收策略告诉集群在存储卷声明释放后应如何处理该卷。目前,volume 的处理策略有:

Retain,不清理, 保留 Volume(需要手动清理)
Recycle,删除数据,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
Delete,删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
OK 以上是NFS创建静态模式创建PVC,以及PVC跟POD生命周期的一些实践,

NFS作为动态持久化存储卷
利用NFS client provisioner动态提供Kubernetes后端存储卷
想要动态生成PV,需要运行一个NFS-Provisioner服务,将已配置好的NFS系统相关参数录入,并向用户提供创建PV的服务。官方推荐使用Deployment运行一个replica来实现,当然也可以使用Daemonset等其他方式,这些都在官方文档中提供了。

前提条件是有已经安装好的NFS服务器,并且NFS服务器与Kubernetes的Slave节点都能网络连通。 所有下文用到的文件来自于git clone https://github.com/kubernetes-incubator/external-storage.git 的nfs-client目录

nfs-client-provisioner 是一个Kubernetes的简易NFS的外部provisioner,本身不提供NFS,需要现有的NFS服务器提供存储

PV以 n a m e s p a c e − {namespace}- namespace{pvcName}- p v N a m e 的命名格式提供(在 N F S 服务器上) P V 回收的时候以 a r c h i e v e d − {pvName}的命名格式提供(在NFS服务器上) PV回收的时候以 archieved- pvName的命名格式提供(在NFS服务器上)PV回收的时候以archieved{namespace}- p v c N a m e − {pvcName}- pvcName{pvName} 的命名格式(在NFS服务器上)

  1. 获取nfs-client-provisioner配置文件
    1
git clone https://github.com/kubernetes-incubator/external-storage.git
  1. 安装部署:
  2. 修改deployment文件并部署 deploy/deployment.yaml
    需要修改的地方只有NFS服务器所在的IP地址(10.68.56.11),以及NFS服务器共享的路径(/nfs_data_2),两处都需要修改为你实际的NFS服务器和共享目录
cat deploy/deployment.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 10.68.56.11 
            - name: NFS_PATH
              value: /nfs_data_2
      volumes:
        - name: nfs-client-root
          nfs:
            server: 10.68.56.11
            path: /nfs_data_2
$ kubectl apply -f deploy/deployment.yaml # 执行部署
serviceaccount/nfs-client-provisioner created
deployment.extensions/nfs-client-provisioner created
  1. 修改StorageClass文件并部署 deploy/class.yaml
    此处可以不修改,或者修改provisioner的名字,需要与上面的deployment的PROVISIONER_NAME名字一致。
cat deploy/class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"
# 执行部署 
kubectl apply -f deploy/class.yaml
storageclass.storage.k8s.io/managed-nfs-storage created
# 查看StorageClass
kubectl get sc
NAME                  PROVISIONER      AGE
managed-nfs-storage   fuseim.pri/ifs   16m

# 设置这个managed-nfs-storage名字的SC为Kubernetes的默认存储后端
kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
$ kubectl get sc
NAME                            PROVISIONER      AGE
managed-nfs-storage (default)   fuseim.pri/ifs   19m
  1. 授权
    如果您的集群启用了RBAC,或者您正在运行OpenShift,则必须授权provisioner。 如果你在非默认的“default”名称空间/项目之外部署,可以编辑deploy/rbac.yaml或编辑`oadm policy“指令。

如果启用了RBAC
需要执行如下的命令来授权。

cat deploy/rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    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
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
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

kubectl create -f deploy/rbac.yaml
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
  1. 执行部署:
    测试创建PVC
cat deploy/test-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

$ kubectl create -f deploy/test-claim.yaml
persistentvolumeclaim/test-claim created

$ kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                STORAGECLASS          REASON    AGE
persistentvolume/pvc-dsfasdf-0048-11e11-af7a-sadfadswerer   1Mi        RWX            Delete           Bound     default/test-claim   managed-nfs-storage             9m

NAME                               STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
persistentvolumeclaim/test-claim   Bound     pvc-dsfasdf-0048-11e11-af7a-sadfadswerer   1Mi        RWX            managed-nfs-storage   9m

以上可以看到我们的pvc已经申请成功,等待POD挂载使用

测试创建POD
POD文件如下,作用就是在test-claim的PV里touch一个SUCCESS文件。

cat deploy/test-pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: gcr.io/google_containers/busybox:1.24
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && exit 0 || exit 1"
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: test-claim
        
kubectl create -f deploy/test-pod.yaml
pod/test-pod created
# 启动POD,一会儿POD就是completed状态,说明执行完毕。
kubectl get pod | grep test-pod
NAME                                      READY     STATUS      RESTARTS   AGE
test-pod                                  0/1       Completed   0          18s
在NFS服务器上的共享目录下的卷子目录中检查创建的NFS PV卷下是否有”SUCCESS” 文件。
以上,说明我们部署正常,并且可以通过动态分配NFS的持久共享卷

参考文档:
https://kubernetes.io/docs/concepts/storage/storage-classes/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值