hostPath

hostPath卷能将主机节点文件系统上的文件或目录挂载到Pod中 Pod与宿主机文件实现互通
mountPath表示pod里的路径

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: hostpath-pod
  5. spec:
  6. containers:
  7. - name: hostpath-pod
  8. image: nginx
  9. resources:
  10. limits:
  11. cpu: 200m
  12. memory: 500Mi
  13. requests:
  14. cpu: 100m
  15. memory: 200Mi
  16. volumeMounts:
  17. - name: hostpathvolume
  18. mountPath: /testpath
  19. volumes:
  20. - name: hostpathvolume
  21. hostPath:
  22. path: /usr/local/testpath
  23. type: DirectoryOrCreate

type: DirectoryOrCreate表示文件夹不存在就创建
先查看一下挂载到那个节点

 kubectl describe pod hostpath-pod

然后就可以发现对应节点与容器里实现互通

NFS卷

hostPath只能存储在某一Node节点主机上,不灵活
nfs是一种网络上存储的方式,也可以使用其他的工具,比如minio,ceph

安装nfs

yum install -y nfs-utils

修改配置
vim /etc/exports

/nfsdata    *(rw,sync,no_root_squash)

开机自启动

systemctl enable rpcbind
systemctl enable nfs

创建Pod

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
  - name: test-container
    image: nginx
    volumeMounts:
    - name: test-volume
      mountPath: /usr/share/nginx/html
  volumes:
    - name: test-volume
      nfs:
        server: 192.168.12.111
        path: /nfsdata

持久化卷 PersistentVolume

为用户和管理员提供了一组API,将存储如何供应的细节抽象出来
持久卷是集群资源,就像其他节点也是集群资源一样,独立于任何使用PV的Pod的生命周期,此API对对象中记述了存储的实现细节,对外提供可以调用的地方

事例

一次只有一个node进行读写,用2G存储,回收策略为可回收,使用nfs来存储,也可以换成hostPath

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-demo
spec:
  capacity:
    storage: 2Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /nfsdata
    server: 192.168.12.111

与ReadWriteOnce对应的是 ReadWriteMany

持久化卷 PersistentVolumeClaim

和PV结合使用,单独使用没有意义
PV:持久化存储,对存储的资源进行抽象,对外提供可以调用的地方【生产者】
PVC:用于调用,不需要关心内部实现细节【消费者】
PV和Node是资源的提供者,根据集群的基础设施变化而变 化,由K8s集群管理员配置;而PVC和Pod是资源的使用者,根据业务服务的需求变化而变化,由K8s集 群的使用者即服务的管理员来配置。

事例

提出1G申请,不用关心底层pv在哪,只关心要什么样的pv

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

创建好之后,可以看到pvc-demo绑定了pv-demo
image.png
可以复杂一点,通过标签更细致的匹配
image.png

存储类 Storage Class

自动创建PV的机制,比PVC还抽象一层
在一个大规模的k8s集群里可能有成千上万的PVC,运维人员就需要手动创建多个PV
Storage Class调用provisoner创建pv

Storage Class对象会定义下面两部分内容:

  1. PV的属性,存储类型,Volume的大小等
  2. 创建这种PV需要用到的存储插件

自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中 而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上。

使用PVC和StorageClass挂载nfs

首先配置 Deployment,将里面的对应的参数替换成我们自己的 nfs 配置(nfs-client.yaml)

配置Deployment

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner #默认执行default
      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: yudi-nfs-storage
            - name: NFS_SERVER
              value: 192.168.12.111
            - name: NFS_PATH
              value: /nfsdata
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.12.111
            path: /nfsdata

给serviceAccount绑定权限

上面的deployment指定了nfs-client-provisioner 的serviceAccountName,现在要创建
我们这里新建的一个名为 nfs-client-provisioner 的ServiceAccount,然后绑定了一个名为 nfs-client-provisioner-runner 的ClusterRole,而该ClusterRole声明了一些权限,其中就包括对persistentvolumes的增、删、改、查等权限,所以我们可以利用该ServiceAccount来自动创建 PV。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: default #根据实际环境设定namespace
---
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: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]

---
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

创建StorageClass对象

StorageClass调用对应的provisioner创建对应的pv

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: my-nfs-storage
provisioner: yudi-nfs-storage # 与deployment环境变量PROVISIONER_NAME一致

创建PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-claim
spec:
  storageClassName: my-nfs-storage
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 100Mi

用一个Pod测试一下

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: "nginx"
    volumeMounts:
    - name: nfs-pvc
      mountPath: /mnt
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: my-claim

挂载会生成对应名称的文件夹,名称与${namespace}-${pvcName}-${pvName}对应
image.png