Kubernetes_k8s持久化存储(亲测可用)

73 阅读11分钟

一、前言

新建具有两个节点的k8s集群,主节点(master节点/m节点)的ip地址是192.168.100.150,从节点(w1节点)的ip地址是192.168.100.151。

本文操作如何将pod中的container容器中的目录映射到宿主机(包括pod所在宿主机和其他任意宿主机),分为三个部分:volumes的使用、pv/pvc的使用、storageClass的使用。
三者的关系是:volumes映射Pod只能映射到自己所在node(实际机器)的目录上;pv/pvc映射通过配置 NFS 服务器可以保证无论Pod在哪个node节点上都映射到 NFS 服务器上,下次无论 Pod 被分配到哪个节点,都从 NFS 服务器加载;storageClass解决的是 pv/pvc 一对一的关系,如果有 N 个pvc,这运维人员需要新建 N 个pv,但是有了storageClass,运维人员只需要建立好一个storageClass,就算有 N 个pvc,这个storageClass 也会自动创建 N个 pv 来给 N个 pvc使用。

本文资源地址www.syjshare.com/res/JF7S1RQ…

二、volumes实现本地持久化存储

2.1 K8S各个Pod之间可以存储和网络的共享

Pod中的各个container,可以实现 共享网络 和 共享存储(即volume)
在这里插入图片描述

2.2 volumes实现本地持久化存储

(1)创建资源

kubectl apply -f volume-pod.yaml

(2)查看pod的运行情况

kubectl get pods -o wide

(3) 进入pod里面的container

# 根据pod名称进入
kubectl exec -it pod-name -- /bin/bash   

在这里插入图片描述
在这里插入图片描述

注意:使用这种volumes目录映射,只能映射到pod所在的物理机器的目录,这是volumes映射的局限,需要部署一个 NFS 服务器,然后通过 PV/PVC 来连接这个 NFS 服务器,解决这个问题。

三、远程服务器持久化存储

3.1 PersistentVolume

官网kubernetes.io/docs/concep…

apiVersion: v1
kind: PersistentVolume   # PV是一个Kind,volume不是一种kind
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi    # 需要使用的远端服务器的存储空间大小(修改)
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce     # 只允许一个Pod进行独占式读写操作
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:              # host是k8s集群内,nfs是k8s集群外
    path: /tmp            # 远端服务器的目录(修改)
    server: 172.17.0.2    # 远端的服务器(修改)

说白了,PV是K8s中的资源,volume的plugin实现,生命周期独立于Pod,封装了底层存储卷实现的细节。

pv的生命周期是独立于pod的

注意:PV的维护通常是由运维人员、集群管理员进行维护的。

3.2 PersistentVolumeClaim

官网kubernetes.io/docs/concep…

有了PV,那Pod如何使用呢?为了方便使用,我们可以设计出一个PVC来绑定PV,然后把PVC交给Pod来使用即可,且听下面的分析。 pod中想要使用这个pv,就是通过pvc来和pv绑定的 pod - pvc - pv - 远端服务器

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:    # 匹配
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi    # 匹配
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

说白了,PVC会匹配满足要求的PV[是根据size和访问模式进行匹配的],进行一一绑定,然后它们的状态都会变成Bound。

也就是PVC负责请求PV的大小和访问方式,然后Pod中就可以直接使用PVC咯。

注意:PVC通常由开发小伙伴维护,开发小伙伴无需关注与存储细节。

3.3 Pod中如何使用PVC (Pod绑定PVC)

官网kubernetes.io/docs/concep…

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"     # ok 不变 
        name: mypd   # ok 不变
  volumes:
    - name: mypd  # ok 不变    volumes 和 pod 绑定,通过name
      persistentVolumeClaim:
        claimName: myclaim    #  pod 和 pvc 绑定,通过claimName

3.4 远程服务器持久化存储实践与测试

背景:使用nginx持久化存储演示

(1)共享存储使用nfs,比如选择在m节点
(2)创建pv和pvc
(3)nginx pod中使用pvc

3.4.1 启动前的配置(配置NFS服务器)

nfs(network file system)网络文件系统,是FreeBSD支持的文件系统中的一种,允许网络中的计算机之间通过TCP/IP网络共享资源。

随便找一个机器搭建NFS服务器(用来作为远程服务器存放),可以是k8s集群内的节点,也可以是k8s集群外的节点。这里在master节点上搭建一个NFS服务器,目录为/nfs/data,然后

01 选择master节点作为nfs的server,所以在master节点上,执行以下命令

# 第一步,启动nfs和rpcbind
# 启动nfs
systemctl status nfs (如果存在就开启 systmctl start nfs ,不过不存在就安装 yum -y install nfs-utils 并 systemctl start nfs)
systemctl status nfs (启动后再次查看状态,状态成功就是表示启动成功了)
systemctl enable nfs  (设置为为开机自启动)

# 启动rpcbind
systemctl restart rpcbind   (重启)
systemctl enable rpcbind    (设置为开机自启动)
systemctl status rpcbind  (查看状态,验证重启成功)


# 第二步,创建nfs目录并授予权限  /nfs/data/     这个目录就是nfs ip那个目录
# 创建nfs目录
mkdir -p /nfs/data/
# 授予权限
chmod -R 777 /nfs/data

# 第三步,编辑export文件并保存
# 编辑export文件   对于/nfs/data目录,授予可读可写权限、根目录权限、同步数据权限
vi /etc/exports
  /nfs/data *(rw,no_root_squash,sync)
  /nfs/data *(rw,no_root_squash,sync,no_subtree_check)  # 新版nfs  
# 使得配置生效
exportfs -r
# 查看生效
exportfs

# 第四步,验证rpcbind、nfs
# 查看rpc服务的注册情况
rpcinfo -p localhost
# showmount测试     
# showmount命令用于查询NFS服务器的相关信息     -e或--exports  显示NFS服务器的输出清单。
showmount -e master-ip  
showmount -e 192.168.100.150    

02 所有node上安装客户端 ps -ef|grep nfs

# 启动nfs
systemctl status nfs (如果存在就开启 systmctl start nfs ,不过不存在就安装 yum -y install nfs-utils 并 systemctl start nfs)
systemctl status nfs (启动后再次查看状态,状态成功就是表示启动成功了)
systemctl enable nfs  (设置为为开机自启动)

# 启动rpcbind
systemctl restart rpcbind   (重启)
systemctl enable rpcbind    (设置为开机自启动)
systemctl status rpcbind  (查看状态,验证重启成功)

注意1:nfs主节点判断nfs是否安装成功了三条
exportfs 或者 cat /etc/exports
rpcinfo -p localhost
showmount -e 192.168.100.150

注意2:nfs主节点和从节点配置的区别
从节点:启动好nfs和rpcbind
主节点:启动好nfs和rpcbind、新建/nfs/data目录、vi /etc/exports、showmount -e 192.168.100.150 测试

注意3:pod - nfs 和 pod - pvc - pv - nfs 两种方式等效,增加了 pvc - pv 这一层只是为了开发和运维解耦,pod - pvc 由开发负责,pv - nfs 由运维负责,如果都是一个人干,可以直接 pod - nfs,不要中间 pvc-pv 这一层

3.4.2 启动并测试

(1)在nfs服务器创建所需要的目录(数据存放目录 因为pvc文件需要这个目录 在宿主机上)

mkdir -p /nfs/data/nginx

(2)定义PV,PVC和Nginx的yaml文件 (三个yaml文件 就是合并为一个yaml文件 nginx-pv-demo.yaml)

网盘中:课堂源码/nginx-pv-demo.yaml

(3)根据yaml文件创建资源并查看资源

# 创建三个
kubectl apply -f nginx-pv-demo.yaml  
# 查看三个
kubectl get pv,pvc   
kubectl get pods -o wide

测试:远程服务器持久化存储
在这里插入图片描述

在这里插入图片描述

四、远程服务器持久化存储的另一种方式(StorageClass自动创建PV)

4.1 StorageClass

上面手动管理PV的方式还是有点low,能不能更加灵活一点呢?
官网kubernetes.io/docs/concep…

nfs githubgithubgithub.com/kubernetes-…

Introduction
A StorageClass provides a way for administrators to describe the “classes” of storage they offer.Different classes might map to quality-of-service levels, or to backup policies, or to arbitrary policies determined by the cluster administrators. Kubernetes itself is unopinionated about what classes represent. This concept is sometimes called “profiles” in other storage systems.

StorageClass 为管理员提供了描述存储 “类” 的方法。不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略(即可以自定义)。Kubernetes 本身并不清楚各种类代表的什么(这种类是k8s不识别的)。这个类的概念在其他存储系统中有时被称为 “配置文件”。

The StorageClass Resource
Each StorageClass contains the fields provisioner, parameters, and reclaimPolicy, which are used when a PersistentVolume belonging to the class needs to be dynamically provisioned. The name of a StorageClass object is significant, and is how users can request a particular class. Administrators set the name and other parameters of a class when first creating StorageClass objects, and the objects cannot be updated once they are created.

每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段,这些字段会在 StorageClass 需要动态分配 PersistentVolume 时会使用到(就是说StorageClass的目的是自动生成pv)。StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。

小结:StorageClass声明存储插件,用于自动创建PV。 说白了就是创建PV的模板,其中有两个重要部分:PV属性和创建此PV所需要的插件。 这样PVC就可以按“Class”来匹配PV。可以为PV指定storageClassName属性,标识PV归属于哪一个Class。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
# 这里加上体现了 "每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段"  
#(provisioner是指定插件)
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: Immediate
01 对于PV或者StorageClass只能对应一种后端存储
02 对于手动的情况,一般我们会创建很多的PV,等有PVC需要使用的时候就可以直接使用了
03 对于自动的情况,那么就由StorageClass来自动管理创建
04 如果Pod想要使用共享存储,一般会在创建PVC,PVC中描述了想要什么类型的后端存储、空间等,K8s从而会匹配对应的PV,
如果没有匹配成功,Pod就会处于Pending状态。Pod中使用只需要像使用volumes一样,指定名字就可以使用了
05 一个Pod可以使用多个PVC,一个PVC也可以给多个Pod使用 (pod和pvc的对应关系是多对多,直接 claimName 匹配)  
06 一个PVC只能绑定一个PV,一个PV只能对应一种后端存储 (pv和pvc的对应关系是一对一,通过 accessModes 和 storage 匹配)
07 一个PV只能绑定一个NFS,但是一个NFS可以绑定多个PV

正是因为 “一个PVC只能绑定一个PV”,所以有了storageClass,storageClass解决的是 pv/pvc 一对一的关系,如果有 N 个pvc,这运维人员需要新建 N 个pv,但是有了storageClass,运维人员只需要建立好一个storageClass,就算有 N 个pvc,这个storageClass 也会自动创建 N个 pv 来给 N个 pvc使用。

有了StorageClass之后的PVC可以变成这样 (新的pvc)

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
accessModes:
    - ReadWriteMany
resources:
 requests:
    storage: 1Mi
  storageClassName: nfs

StorageClass之所以能够动态供给PV,是因为Provisioner,也就是Dynamic Provisioning,通过 storageClass 来关联 pv ,所以需要一个provisioner的镜像,并将其作为deployment运行到k8s中。但是NFS这种类型,K8s中默认是没有Provisioner插件的,需要自己创建,在github上现成的。

4.2 StorageClass实践

这里准备了五个文件,如下:
在这里插入图片描述
一个图看懂五个文件的关联关系
在这里插入图片描述
好了,开始实践 storageClass 根据pvc的连接自动创建pv(可以承受N个pvc的连接,因为可以自动创建N个pv),开始!!!

(1)准备好NFS服务器[并且确保nfs可以正常工作],创建持久化需要的目录

mkdir -p /nfs/data/jack     (这个目录是pv要使用的    )

(2)根据rbac.yaml文件创建资源 【apply第一个yaml文件,是一个身份凭证】

kubectl apply -f rbac.yaml

(3)根据deployment.yaml文件创建资源 【apply第二个yaml文件,是一个来自github的插件 (第一步和第二步就是准备好这两个插件)】

kubectl apply -f deployment.yaml

注意,需要修改deployment.yaml文件中的server,我这里NFS服务器部署在master节点上,所以部署

path: /nfs/data/jack
server: 192.168.100.150 (就是master节点 nfs服务器部署在m节点上)

(4)根据class.yaml创建资源 【apply第三个yaml文件,是storageClass,可以根据pvc的需要自动生成pv】

kubectl apply -f class.yaml

(5)根据pvc.yaml创建资源 【apply第四个yaml文件,是具体的pvc,因为storageClass已经启动了,所以现在可以启动pvc】

kubectl apply -f my-pvc.yaml
kubectl get pvc

(6)根据nginx-pod创建资源 【apply第五个yaml文件,是具体的消费者pod,使用pv/pvc打通好的连接,直接通过claimName连接到pvc,就可以从 NFS服务器 取到数据】

kubectl apply -f nginx-pod.yaml

远程服务器持久化存储的另一种方式,通过StorageClass自动创建PV,启动(五个配置文件)
在这里插入图片描述

测试 pod/nginx 取到了 NFS 服务器的文件

# 进行同步数据测试,进入容器检查
kubectl exec -it nginx bash
cd /usr/jack

在这里插入图片描述

在这里插入图片描述

4.3 PV的状态和回收策略

  • PV的状态

Available:表示当前的pv没有被绑定

Bound:表示已经被pvc挂载

Released:pvc没有在使用pv, 需要管理员手工释放pv

Failed:资源回收失败

没有被使用可以被使用 已经被使用 没有被使用不可以被使用 状态失败

  • PV回收策略

Retain:表示删除PVC的时候,PV不会一起删除,而是变成Released状态等待管理员手动清理

Recycle:在Kubernetes新版本就不用了,采用动态PV供给来替代

Delete:表示删除PVC的时候,PV也会一起删除,同时也删除PV所指向的实际存储空间NFS

注意:目前只有NFS和HostPath支持Recycle策略。AWS EBS、GCE PD、Azure Disk和Cinder支持Delete策略

五、小结

Kubernetes第六篇:k8s持久化存储(亲测可用),完成了。

天天打码,天天进步!!