1、kubernetes中的存储卷
1、为什么需要存储卷
在部署pod的时候,启动时需要配置文件
还有产生的临时的数据,需要多个容器共享
还有数据库的持久化数据
还有一个最重要的一点就是默认情况下,容器的文件在磁盘上是临时存放的,如果这个容器需要删除的话,这些数据也就会消失,之前的配置就没有了,所以需要存储卷来存储之前的配置
2、emptyDir(临时存储卷)
- 顾名思义,就是一个临时存储数据的,可以实现pod中的容器之间共享目录数据,但是没有持久化的数据,存储卷会随着pod的结束而结束
# 这个字段
kubectl explain pod.spec.volumes.emptyDir
medium # 指定emptydir卷的存储位置,Default和Memory
sizeLimit # 用于指定存储卷的大小
1、emptydir实现
[root@master mnt]# cat n1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: n1
name: n1
spec:
nodeName: node1
containers:
- image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
name: n1
resources: {}
volumeMounts:
- name: empty
mountPath: /var/empty
volumes:
- name: empty
emptyDir: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@master pods]# kubectl get pod n1 -o jsonpath='{.metadata.uid}'
1c580bb2-23ab-4116-9996-065fa87a03dd
# 进入到/var/lib/kubelet/pods/这个目录,就可以看到临时存储挂载的目录了
3、hostPath(节点存储卷)
就是将node节点上面的目录以文件挂载到pod容器指定目录上面去
但是有一个缺点,如果这个pod调度在别的节点上面的话,那么就不能实现跨node节点的pod共享资源了,但是可以指定这个pod一直调度在这个节点上面去即可
能在单独的一个节点上面持久化存储数据
1、hostPath字段
[root@master mnt]# kubectl explain pod.spec.volumes.hostPath
type # 字段的取值为DirectoryOCreate 如果给定的路径上面什么都不存在的话,那么就需要创建空目录,默认是这个
# Directory 就是路径上面必须存在目录
2、hostPath实现
[root@master mnt]# cat n1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: n1
name: n1
spec:
nodeName: master
containers:
- image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
name: n1
resources: {}
volumeMounts:
- name: hostpath
mountPath: /var/hostpath
volumes:
- name: hostpath
hostPath:
path: /var/hostpath
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
4、nfs(网络共享)
- 就是搭建一个NFS,然后利用共享目录提供出去,这样的话,不需要关心pod调度在哪一个节点上面去了,都可以获取到之前的配置了
[root@master mnt]# cat /etc/exports
/mnt/nfs *(rw)
[root@master mnt]# cat n1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: n1
name: n1
spec:
nodeName: master
containers:
- image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
name: n1
resources: {}
volumeMounts:
- name: nfs
mountPath: /var/nfs
volumes:
- name: nfs
nfs:
server: 10.104.43.227 # nfs的ip地址
path: /mnt/nfs # nfs提供的挂载的目录
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
2、kubernetes中的数据卷pv和pvc
1、基本介绍pv和pvc
pv是一个从存储设备空间中逻辑划分创建出来的可持久化的存储对象,也就是磁盘中分出来一部分用于做成pv,就是一些硬盘等
持久卷声明PVC,对pv存储资源的请求和和绑定,相当于是格式化吧,pod使用的一种存储卷的类型
1、pv的状态
生命周期 | 描述 |
---|---|
Available(可用) | pv的创建,直接创建pv的静态方式,还没有被pvc绑定 |
binding | pv和pvc绑定后即可 |
Released(已释放) | 表示PVC被删除了,但是PV还没被回收 |
failed(失败) | 表示pv自动回收失败 |
2、accessModes字段
访问模式 | 描述 |
---|---|
ReadWriteOnce(rwo) | 读写的权限,但是只能被单个的node挂载 |
ReadOnMany(rox) | 只读的,允许被多个node挂载 |
ReadWriteMany(rwx) | 读写的权限,允许被多个node挂载 |
3、回收策略
就是pv的一些策略
Retain的话就是PVC删除的时候,pv会被保留在集群中,不会被删除,也不会自动的清理里面的数据,但是pvc被删除后,pv仍然存在,需要手动删除pv或者清理里面的数据,就可以再次使用
Recycle 当PVC被删除时,pv中的所有文件会被清除掉,这个策略只有NFS和HostPath的PV支持,就是清理存储中的文件,然后就能使用了
Delete 当删除pvc的时候,pv会被自动删除,相关的数据也会被删除掉
2、创建的pvc的思路
- 首先需要搭建一个MFS服务器,提供一个对外的共享文件夹,然后创建pv,以这个文件夹为例,这样PV就创建出来了,然后创建一个PVC,绑定即可,就能使用了PVC了
[root@master mnt]# cat pv-pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
nfs:
path: /mnt/nfs
server: 10.104.43.227
accessModes:
- ReadWriteMany
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes: # pvc的访问模式,需要与上面保持的一致即可
- ReadWriteMany
resources: # pvc需要的大小
requests:
storage: 2Gi
[root@master mnt]# cat n1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: n1
name: n1
spec:
nodeName: master
containers:
- image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
name: n1
resources: {}
volumeMounts:
- name: pvc1
mountPath: /usr/share/nginx/html
volumes:
- name: pvc1
persistentVolumeClaim: # 使用pvc挂载
claimName: pvc1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
3、动态的创建PV
- 上面的静态有一个缺点,就是如果需要大量的pv,就需要创建很多的pv,因此的话,就会有一个动态的创建pv的出来,创建出来
1、自动创建的思路
# 因为安装这个自动创建pv的插件,也就是供应商,所以的话就需要sa和权限
首先创建一个nfs服务器
然后创建sa和账户
然后创建供应商,绑定sa和nfs服务器,这样的话自动创建pvc,这个供应商就会自动的创建pv出来,与pvc进行绑定,然而,这个pv就是从这个nfs服务器提供的目录里面进行划分的
这样的话就实现了自动创建pv的操作
2、动态创建的实现
1、创建一个nfs服务器和账户和绑定权限
# 创建一个nfs服务器
[root@master mnt]# cat /etc/exports
/mnt/nfs *(rw)
# 这样的话,这个账户就创建出来了,并且赋予了权限
[root@master pvc]# cat s1.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: s1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: s1-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: ""
kind: ServiceAccount
name: s1
namespace: default
2、创建一个供应商
[root@master pvc]# cat nfs-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nfs-provisioner
name: nfs-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs-provisioner
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nfs-provisioner
spec:
serviceAccountName: s1
containers:
- image: uhub.service.ucloud.cn/k8s-q7/nfs-subdir-external-provisioner:v4.0.0 # 供应商镜像
name: nfs-client-provisioner
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME # 配置provisioner的name,这个名字需要与后面创建动态类一样名字
value: nfs-storage
- name: NFS_SERVER # 配置绑定NFS的服务器
value: 10.104.43.227
- name: NFS_PATH # NFS服务器目录
value: /mnt/nfs
volumes:
- name: nfs-client-root
nfs:
server: 10.104.43.227
path: /mnt/nfs
3、创建一个存储类(storage class)
[root@master pvc]# cat storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: storage1
provisioner: nfs-storage # 名字与provisioner的一致
[root@master pvc]# kubectl get storageclasses.storage.k8s.io
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storage1 nfs-storage Delete Immediate false 9m52s
4、创建一个pvc的pod
[root@master pvc]# cat pvc1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: storage1
[root@master pvc]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pvc-e4280b84-cc41-45b8-bf33-8773b18a3e9d 2Gi RWX storage1 9m8s
[root@master pvc]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-e4280b84-cc41-45b8-bf33-8773b18a3e9d 2Gi RWX Delete Bound default/pvc1 storage1 9m10s
# 这个nfs目录也会创建一个目录来使用
[root@master nfs]# pwd
/mnt/nfs
[root@master nfs]# ls
default-pvc1-pvc-e4280b84-cc41-45b8-bf33-8773b18a3e9d
3、总结
动态的创建pv,就是先创建一个底座,也就是提供存储的NFS,然后创建一个供应商,连接这个NFS,创建一个动态的存储类连接这个供应商,这样的话,就能创建pvc的时候,自动的创建pv了
查看pod的uid
[root@master nfs]# kubectl get pod n1 -o jsonpath='{.metadata.uid}'