前情回顾
存储卷:
emptyDir 容器内部,随着pod销毁,emptyDir也会消失 不能做数据持久化
hostPath:持久化存储数据 可以和节点上目录做挂载。pod被销毁了数据还在
NFS:一台机器,提供pod内容器所有的挂载点
pv和pvc:
pvc就是pod发起的挂载请求
pv:持久化存储目录
静态pv和pvc: 运维负责:创建好持久化存储卷,声明好读写和挂载类型 以及可以提供的存储空间
pvc开发做,要和开发沟通好,你期望的读写和挂载类型,以及存储空间。
当我发布pvc之后可以自动生成pv,还可以在共享服务器上直接生成挂载目录。
pvc直接绑定和使用pv
动态pv
1.卷插件,k8s本身不支持的动态pv创建不包括nfs,需要声明和安装一个外部插件
Provisioner:存储分配器。动态创建pv,然后根据pvc的请求自动绑定和使用。
StorageClass:来定义pv的属性,存储类型,大小,回收策略。
用nfs来实现动态PV,NFS支持的方式NFS-client,Provisioner
实验模拟
步骤一:在stor01节点上安装nfs,并配置nfs服务
1、在stor01节点上安装nfs,并配置nfs服务
node02
cd /opt
mkdir k8s
chmod 777 k8s
vim /etc/exports
/opt/k8s 20.0.0.0/24(rw,no_root_squash,sync)
wq
systemctl restart rpcbind
systemctl restart nfs
showmount -e
master01
showmount -e 20.0.0.63
查看
接下来在matser01上配置
步骤二:创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限和动态规则
vim nfs-client-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
#定义权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-clusterrole
rules:
- apiGroups: [""]
#apigroup定义了规则使用了哪个api的组,空字符“”,直接使用api的核心组的资源
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
#表示权限的动作。
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
#获取pv属性
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
#获取api活动的时间信息
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
#集群角色绑定
apiVersion: rbac.authorization.k8s.io
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-clusterrole
apiGroup: rbac.authorization.k8s.io
wq
步骤三:使用 Deployment 来创建 NFS Provisioner
vim /etc/kubernetes/manifests/kube-apiserver.yaml
...
spec:
containers:
- command:
- --feature-gares=RemoveSelfLink=false
- --advertise-address=20.0.0.61
feature-gates:在不破坏现有规则以及功能基础上引入新功能或者修改现有功能的机制。
禁用不影响之前的规则
wq
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl get pods -n kube-system | grep apiserver
部署nfs-provisioners插件:
nfs的provisioner的客户端以pod的方式运行在集群当中,监听k8s集群当中的pv的请求。动态的创建于NFS服务器相关的pv。
容器里使用配置,在provisioner当中定义好环境变量,穿给容器。storageclass的名称,nfs服务器的地址,nfs的目录
vim nfs-client-provisioner.yaml
#创建 NFS Provisioner
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs1
spec:
serviceAccountName: nfs-client-provisioner
#指定Service Account账户来调用
containers:
- name: nfs1
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs1
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-storage
#配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致
- name: NFS_SERVER
value: stor01
#配置绑定的nfs服务器
- name: NFS_PATH
value: /opt/k8s
#配置绑定的nfs服务器目录
volumes:
#申明nfs数据卷
- name: nfs-client-root
nfs:
server:20.0.0.63
path: /opt/k8s
kubectl apply -f nfs-client-provisioner.yaml
步骤四:创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-storageclass
provisioner: nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:
archiveOnDelete: "false"
#false表示在删除PVC时不会对数据目录进行打包存档,即删除数据;为ture时就会自动对数据目录进行打包存档,存档文件以archived开头
reclaimPolicy: Retain
#定义pv的回收策略,retain,另一个是delete,不支持回收
allowVolumeExpansion: true
#pv的存储空间可以动态的扩缩容
kubectl apply -f nfs-client-storageclass.yaml
步骤五: 创建 PVC 和 Pod 测试
先创建pvc
vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass #关联StorageClass对象
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx1
spec:
replicas:1
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: nginx1
mountPath: /usr/share/nginx/html
volumes:
- name: nginx1
persistentVolumeClaim:
claimName: nfs-pvc
#与PVC名称保持一致
kubectl apply -f test-pvc-pod.yaml
nfs主机中:
下面进行读写测试
总结
动态pv的两个组件:
provisioner插件:支持nfs。创建pv目录
strogeclass:定义pv的属性。
动态pv的默认策略是删除
动态pv删除pvc的状态。最好设置为releassed
1.给卷插件创建账号,确保集群可以在集群内部通信,获取资源,监听事件。创建和删除以及更新pv
2.创建卷插件的pod。由卷插件的pod创建pv
3。定义storageclass给pv赋予属性。属性包括:pvc被删除之后pv的状态,以及回收策略。
4.创建pvc
5.实验完成