hostPath
hostPath卷能将主机节点文件系统上的文件或目录挂载到Pod中 Pod与宿主机文件实现互通
mountPath表示pod里的路径
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: hostpath-pod
image: nginx
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: hostpathvolume
mountPath: /testpath
volumes:
- name: hostpathvolume
hostPath:
path: /usr/local/testpath
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
可以复杂一点,通过标签更细致的匹配
存储类 Storage Class
自动创建PV的机制,比PVC还抽象一层
在一个大规模的k8s集群里可能有成千上万的PVC,运维人员就需要手动创建多个PV
Storage Class调用provisoner创建pv
Storage Class对象会定义下面两部分内容:
- PV的属性,存储类型,Volume的大小等
- 创建这种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}对应