nfs
理论上nfs 其实并不是存储设备,它是一种远程共享存储服务。
k8s 存储卷 volume
emptyDir:可以实现pod中的容器之间共享数据, 但是存储卷不能持久化数据,且会随着pod的生命周期一起删除。
hostpash:可以实现持久化数据,使用node节点的目录或文件挂载到容器,但是存储空间会受到node节点单机的限制,一旦node节点故障,数据会丢失,pod会跨node节点,不能共享数据。
nfs:可以实现持久化存储,使用nfs存储设备空间挂载到容器,pod可以跨节点共享数据。
pv和pvc
pv有两种创建方式,分为静态和动态。
静态指运维手动创建pv和pvc。
动态指用storageclass自动创建pv
PV和PVC之间的相互作用遵循这个生命周期:
Provisioning (配置)---> Binding (绑定) ---> Using (使用) ---> Releasing (释放) ---> Recycling (回收)
PV 的状态有以下 4 种:
●Available(可用):表示可用状态,还未被任何 PVC 绑定
●Bound(已绑定):表示 PV 已经绑定到 PVC
●Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收
●Failed(失败):表示该 PV 的自动回收失败
一个PV从创建到销毁的具体流程
1、一个PV创建完后状态会变成Available,等待被PVC绑定。
2、一旦被PVc邦定,Pv的状态会变成Bound,就可以被定义了相应PVC的Pod使用。
3、Pod使用完后会释放PV,PV的状态变成Released
4、变成Released的EV会根据定义的回收筑略做相应的回收工作。(有三种回收策略,Retain、Delete和Becycle。)
Retain策略:就是保留现场,K8S集群什么也不做,等待用户手动去处理里的数据,处理完后,再手动删除EV。
Delete策略:K8S会自动删除该pv及里面的数据。
Recycle策略:K8S会将pV里的数据删除,然后把pv的状态变成Available,又可以被新的PVC绑定使用。
pv访问模式
ReadWriteOnce #(RWO)存储可读可写,但只支持被单个 Pod 挂载
ReadOnlyMany #(ROX)存储可以以只读的方式被多个 Pod 挂载
ReadWriteMany #(RWX)存储可以以读写的方式被多个 Pod 共享
静态Pv的使用
准备存储设备和共享目录
创建pv 资源 配置 存储类型 访问模式 存储能力大小
创建pvc资源 配置请求pv 资源的访问模式和存储大小 绑定PV,PVC和PV是一对一的绑定关系。
PV访问模式必须支持PVc的请求访问模式,请求的存储空间会优先选择相等存储大小的PV资源,如果没有会选择大于请求的存储大小的PV资源。
创建Pod资源,存储类型设置成 persistentvolumeclaims,在容器配置中存储挂载。
动态storage
动态创建PV不同的设备支持的插件不一样 我们是以nfs为例
StorageClass动态创建pv的过程
StorageClass+NES+provisioner
准备NES 共享服务器和共享目录。
创建sa 服务账号 ,进行RBAC 资源操作权限的授权。
创建nfs-client-provisioner存储卷插件 (以pod的形式运行的),配置中要关联sa服务账号使得存储卷插件获得相关资源的操作权限。
创建 StorageClass资源,配置中要关联存储卷插件的名称配置。
----以上过程是一劳永逸, 以后只需要创建pvc 就可以动态生成相关的PV资源。
创建pvc在配置中要关联storageClass资源的名称,此时会在NEs服务器上生成相关的PV的共享目录。
创建pod 资源存储类型设置成persistentVolumeclaims,在容器配置中配置存储挂载。
搭建 StorageClass + NFS,实现 NFS 的动态 PV 创建
1、在stor01节点上安装nfs,并配置nfs服务
mkdir /opt/k8s
chmod 777 /opt/k8s/
vim /etc/exports
/opt/k8s 192.168.11.0/24(rw,no_root_squash,sync)
systemctl restart nfs
2、创建 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: [""]
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: ["endpoints"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
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
kubectl apply -f nfs-client-rbac.yaml
3、使用 Deployment 来创建 NFS Provisioner
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --feature-gates=RemoveSelfLink=false #添加这一行
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 Provisioner
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
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-storage
- name: NFS_SERVER
value: stor01
- name: NFS_PATH
value: /data/volumes
volumes:
- name: nfs-client-root
nfs:
server: stor01
path: /data/volumes
kubectl apply -f nfs-client-provisioner.yaml
kubectl get pod
4、创建 StorageClass
vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-storageclass
provisioner: nfs-storage
parameters:
archiveOnDelete: "false"
kubectl apply -f nfs-client-storageclass.yaml
5、创建 PVC 和 Pod 测试
vim test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 1Gi
vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-storageclass-pod
spec:
containers:
- name: nginx
image: nginx:1.14
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-nfs-pvc
kubectl apply -f test-pvc.yaml test-pod.yaml
kubectl get pvc
去nfs查看是否生成目录