实验环境

安装好k8s集群
存储卷回顾
一、存储卷介绍
pod有生命周期,生命周期结束后pod里的数据会消失(如配置文件,业务数据等)。
解决:我们需要将数据与pod分离,将数据放在专门的存储卷上
pod在k8s集群的节点中是可以调度的,如果pod挂了被调度到另一个节点,那么数据和pod的联系会中断。
解决:所以我们需要与集群节点分离的存储系统才能实现数据持久化
简单来说:volume提供了在容器上挂载外部存储的能力
二、存储卷的分类
存储卷分类:
(1)本地存储卷(Volume)
emptyDir 宿主机目录映射(临时存储),pod删除,数据也会被清除
hostPath 宿主机目录映射(持久存储),pod删除,数据不会被清除
(2)网络存储卷
NAS类(Network Attached Storage):NFS
SAN类(Storage Area Network):iSCSI、FC
分布式存储: GlusterFS、CephFS、RBD、Cinder
云存储:AWS、Azure、Google Cloud
三、PV(持久存储卷)与PVC(持久存储卷声明)
1、认识PV与PVC
PersistentVolume (PV)是配置好的一段存储(可以是任意类型的存储卷),也就是说将网络存储共享出来,配置定义成PV。
PersistentVolumeClaim (PVC)是用户pod使用PV的申请请求。用户不需要关心具体的volume实现细节,只需要关心使用需求。
2、PV与PVC之间的关系
pv提供存储资源(生产者)
pvc使用存储资源(消费者)
使用pvc绑定pv

静态供给:创建pv,创建pvc,创建pod关联pvc
四、存储的动态供给
1、什么是动态供给
每次使用存储要提前先创建pv, 再创建pvc,比较麻烦,我们可以实现使用存储的动态供给特性。
- 静态存储需要用户申请PVC时保证容量和读写类型与预置PV的容量及读写类型完全匹配,而动态存储则无需如此。
- 管理员无需预先创建大量的PV作为存储资源
Kubernetes从1.4版起引入了一个新的资源对象StorageClass(存储类),可用于将存储资源定义为具有显著特性的类(Class即模板)而不是具体的PV。
用户通过PVC直接向意向的类别发出申请,匹配由管理员事先创建的PV,或者由其按需为用户动态创建PV,这样就免去了需要先创建PV的过程。
2、使用NFS文件系统创建存储动态供给
PV对存储系统的支持可通过其插件来实现,目前官方插件是不支持NFS动态供给的,但是我们可以用第三方的插件来实现。
补充:安装配置nfs服务
所有节点都安装nfs-utils工具包服务
yum -y install nfs-utils
这里将192.168.10.14作为nfs服务器(192.168.10.14)
mkdir -p /data/nfs
vim /etc/exports

添加:
/data/nfs *(rw,sync,no_root_squash)

systemctl start nfs-server
systemctl enable nfs-server
showmount -e

worker1:
showmount -e 192.168.10.14

worker2:
showmount -e 192.168.10.14

(1)下载或上传storageclass-nfs.yml文件并创建storageclass(master1)

mv class.yaml storageclass-nfs.yml

vim storageclass-nfs.yml

字段解析:
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner:
指定用于动态创建 PV 的 Provisioner。
这里的 k8s-sigs.io/nfs-subdir-external-provisioner 是一个常用的 NFS Provisioner,它会根据 PVC 的请求动态创建 PV,并在 NFS 共享目录下创建子目录。
该值必须与部署的 Provisioner 的 PROVISIONER_NAME 环境变量一致。
archiveOnDelete: "false":
指定删除 PVC 时是否将 NFS 子目录归档(重命名而不是删除)。
"true":归档(重命名为 archived-<目录名>)。
"false":直接删除子目录。
创建资源
kubectl apply -f storageclass-nfs.yml

查看当前 Kubernetes 集群中定义的 StorageClass 的详细信息
kubectl get storageclass

返回字段解析:
NAME:StorageClass 的名称,这里是 nfs-client。在创建 PVC 时,可以通过 storageClassName: nfs-client 引用该 StorageClass。
PROVISIONER:指定用于动态创建 PV 的 Provisioner。这里是 k8s-sigs.io/nfs-subdir-external-provisioner,表示使用 NFS 子目录外部 Provisioner。
RECLAIMPOLICY:定义 PV 的回收策略,即当 PVC 被删除时,PV 的处理方式。
Delete:删除 PVC 时,自动删除对应的 PV 和底层存储资源。
其他选项包括 Retain(保留 PV 和底层存储资源)和 Recycle(已弃用)。
VOLUMEBINDINGMODE:定义 PV 和 PVC 的绑定时机。
Immediate:在 PVC 创建时立即绑定 PV。
其他选项包括 WaitForFirstConsumer(延迟绑定,直到 Pod 使用 PVC 时再绑定 PV)。
ALLOWVOLUMEEXPANSION:是否允许动态扩展 PVC 的存储容量。
false:不允许扩展。
如果设置为 true,则可以动态调整 PVC 的存储大小。
AGE:StorageClass 的创建时间,这里是 46s,表示该 StorageClass 已经创建了 46 秒。
(2)下载或上传rbac.yaml文件配置清单文件,创建rbac(创建账号,并授权)(master1)
因为storage自动创建pv需要经过kube-apiserver,所以需要授权。
RBAC(Role-Based Access Control):基于角色的访问控制
定义:
RBAC(Role-Based Access Control,基于角色的访问控制)是一种访问控制模型,它通过将用户分配到不同的角色,并为每个角色定义权限,从而实现对资源的访问控制。用户通过其所属的角色获得相应的权限,而无需直接为每个用户分配权限。
核心组件:
用户(User):需要访问系统资源的主体,如员工、客户等。
角色(Role):一组权限的集合,代表用户在系统中的职责或身份。例如,"管理员"、"普通用户"等。
权限(Permission):允许用户对资源进行的操作,如"读取"、"写入"、"删除"等。
资源(Resource):系统中需要保护的对象,如文件、数据库、网络设备等。

mv rbac.yaml storageclass-nfs-rbac.yaml

vim storageclass-nfs-rbac.yaml



创建资源
kubectl apply -f storageclass-nfs-rbac.yaml

(3)创建动态供给的deployment(master1)
需要一个deployment来专门实现pv与pvc的自动创建
vim deploy-nfs-client-provisioner.yml

添加:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.10.14
- name: NFS_PATH
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.10.14
path: /data/nfs


创建资源
kubectl apply -f deploy-nfs-client-provisioner.yml

kubectl get pod | grep nfs-client-provisioner

(4)测试存储动态供给是否可用(master1)
vim nginx-sc.yaml

添加:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
imagePullSecrets:
- name: huoban-harbor
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "nfs-client"
resources:
requests:
storage: 1Gi
创建资源
kubectl apply -f nginx-sc.yaml

kubectl get pod

192.168.10.14:
ls /data/nfs/

master1:
kubectl delete -f nginx-sc.yaml

192.168.10.14:
ls /data/nfs/
