NFS卷
NFS:主流的文件共享服务器
NFS卷:提供对NFS挂载支持,可以自动将NFS共享路径挂载到Pod中
############# 每个Node上都要安装nfs-utils包 ################
# 安装NFS工具包
yum install nfs-utils -y
# 配置NFS共享路径
vi /etc/exports
/nfs/kubernetes *(rw,no_root_squash)
# 创建好共享文件夹(上面配置的)
mkdir -p /nfs/kubernetes
# 启动,并设置开机自启
systemctl start nfs && systemctl enable nfs
# 挂载文件夹
mkdir -p /nfs/kubernetes && mount -t nfs 172.26.209.141:/nfs/kubernetes /nfs/kubernetes
# 卸载 已挂载的文件夹
umount /nfs/kubernetes
使用Pod挂载NFS数据卷
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: zheng
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
volumeMounts: # 挂载存储卷
- name: zheng # 挂载存储卷的名字
mountPath: /usr/share/nginx/html # 挂载到容器中的哪个目录下
volumes: # 使用网络数据卷:NFS
- name: zheng
nfs: # 这里是NFS的地址
server: 192.168.189.172 # NFS的服务器地址
path: /nfs/kubernetes/pv-0 # 在这里随便创建一个html文件,访问nginx
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-nfs-svc # service的标签
name: nginx-nfs-svc # service的名字
namespace: zheng
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80 # 这里是容器中的访问入口
selector:
app: nginx # 这里是选择Deployment中暴露的容器名
type: NodePort # service的端口暴露方式
PV-PVC
PV
- 对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
手动创建的共享存储,数据卷定义
# PV 是事先 运维创建好的,后期直接通过PVC调用
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv # PV的名字
namespace: zheng
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /nfs/kubernetes/pv-1 # 创建PV的时候指定存储路径
server: 192.168.189.172 # NFS服务器地址
访问模式
AccessModes:用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限
- RWO(ReadWriteOnce):读写权限,但是只能被单个节点挂载
- ROX(ReadOnlyMany):只读权限,可以被多个节点挂载
- RWX(ReadWriteMany):读写权限,可以被多个节点挂载
回收策略
删除PV之后,进行的操作
- Retain(保留): 保留数据,需要管理员手工清理数据
- Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/*
- Delete(删除):与 PV 相连的后端存储同时删除
当前状态
STATUS:一个 PV 的生命周期中,可能会处于4中不同的阶段
- Available(可用):表示可用状态,还未被任何 PVC 绑定
- Bound(已绑定):表示 PV 已经被 PVC 绑定
- Released(已释放):PVC 被删除,但是资源还未被集群重新声明
- Failed(失败): 表示该 PV 的自动回收失败
PVC
卷需求模板
- 让用户不需要关心具体的Volume实现细节
- Pod申请PVC作为卷来使用,K8S
通过PVC查找绑定的PV
,并挂载给Pod- 容量大小
- 读写模式
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc # PVC的名字
namespace: zheng
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi # 通过容量大小,实现自动查找和绑定
使用
- 挂载的时候,指明使用PVC卷
- 指定PVC的名字
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: zheng
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
volumeMounts: # 挂载存储卷
- name: zheng # 挂载存储卷的名字
mountPath: /usr/share/nginx/html # 挂载到容器中的哪个目录下
volumes: # 使用PVC卷,PVC会根据存储大小,自动查找PV
- name: zheng
persistentVolumeClaim: # 使用PVC存储
claimName: nginx-pvc # 指定的是PVC的名字
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-pvc-svc # service的标签
name: nginx-pvc-svc # service的名字
namespace: zheng
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80 # 这里是容器中的访问入口
selector:
app: nginx # 这里是选择Deployment中暴露的容器名
type: NodePort # service的端口暴露方式
上面这种静态供给的方式,需要不断的创建PV,维护成本太高
K8S开始支持
动态供给:StorageClass
SC-PVC
SC 区分名称空间
K8s默认不支持NFS动态供给,需要单独部署社区开发的插件
项目地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
部署插件
RABC
授权访问ApiServer
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# 替换为部署了PV的命名空间
namespace: default
---
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: [ "create", "update", "patch" ]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# 替换为部署了PV的命名空间
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# 替换为部署了PV的命名空间
namespace: default
rules:
- apiGroups: [ "" ]
resources: [ "endpoints" ]
verbs: [ "get", "list", "watch", "create", "update", "patch" ]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# 替换为部署了PV的命名空间
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# 替换为部署了PV的命名空间
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
Deployment
# 部署插件,需要修改NFS服务器地址和共享目录
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# 替换为部署了PV的命名空间
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: lizhenliang/nfs-subdir-external-provisioner:v4.0.1
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.189.172 # 修改这里的NFS地址
- name: NFS_PATH
value: /nfs/kubernetes # 修改这里的NFS路径
volumes:
- name: nfs-client-root
nfs:
server: 192.168.189.172 # 修改这里的NFS地址
path: /nfs/kubernetes # 修改这里的NFS路径
使用SC的PVC
SC
创建存储类-StorageClass
动态供给,在插件中(Deployment)中指定了nfs的地址之后,SC会自动创建PV
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mysql
namespace: zheng # StorageClass区分命名空间
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # 这里与部署的插件中保持一致
parameters:
archiveOnDelete: "false" # 删除SC之后,PV是否保留
PVC
持久数据卷
支持动态供给-storageClass的PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: zheng
spec:
storageClassName: "mysql" # 告诉PVC,这里使用storageClass,使用的是mysql这个存储类
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi # storageClass会自动创建一个这么大的存储卷
使用
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: zheng
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
volumeMounts: # 挂载存储卷
- name: zheng # 挂载存储卷的名字
mountPath: /usr/share/nginx/html # 挂载到容器中的哪个目录下
volumes: # 使用网络数据卷:NFS
- name: zheng
persistentVolumeClaim: # 这里同样使用PVC,不过是动态供给的PVC(自动创建PV)
claimName: mysql-pvc-sc # PVC的名字
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-pvc-svc # service的标签
name: nginx-pvc-svc # service的名字
namespace: zheng
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80 # 这里是容器中的访问入口
selector:
app: nginx # 这里是选择Deployment中暴露的容器名
type: NodePort # service的端口暴露方式
评论区