天天看点

@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)

文章目录

  • ​​kubernetes(k8s)数据持久化Volume​​
  • ​​一、数据持久化​​
  • ​​1、Vlolume概述​​
  • ​​2、数据卷的分类​​
  • ​​3、常用的四种数据卷​​
  • ​​4、Pod使用Volume步骤:​​
  • ​​5、 volume基本资源清单​​
  • ​​二、emptyDir(临时存储卷)​​
  • ​​1、emptyDir的简述​​
  • ​​2、emptyDir的使用方法​​
  • ​​4、emptyDir的使用​​
  • ​​三、hostPath(节点存储卷)​​
  • ​​1、hostpath的概述:​​
  • ​​2、hostpath支持数据类型​​
  • ​​3、hostpath的使用​​
  • ​​四、nfs存储卷(pv、pvc)​​
  • ​​1、nfs存储卷的概述​​
  • ​​2、pv、pvc的介绍​​
  • ​​3、PV和PVC的生命周期​​
  • ​​4、存储管理机制​​
  • ​​5、简述pv过载过程​​
  • ​​【pv、pvc的使用(全部节点必须安装nfs)】​​
  • ​​1、安装nfs​​
  • ​​2、nfs存储卷(创建pv、pvc)​​
  • ​​3、nfs存储卷的挂载使用(单节点挂载)​​
  • ​​4、nfs存储卷(多点挂载使用)​​
  • ​​5、案列(数据持久化)​​
  • ​​【 使用存储卷搭建lnmp】​​
  • ​​1、创建资源清单(数据库)​​
  • ​​2、创建资源清单(web+php)​​
  • ​​3、测试部署(lnmp)​​
  • ​​五、StorageClass(存储类别)​​
  • ​​1、简述StorageClass​​
  • ​​2、StorageClass的使用​​
  • ​​【helm安装nfs(storageclass)】​​
  • ​​1、使用storageclasses​​
  • ​​【CSI存储机制】​​
  • ​​1、CSI部署架构​​
  • ​​2、CSI主要包括两个组件:​​
  • ​​【CSI Controller】​​
  • ​​【CSI Node】​​

kubernetes(k8s)数据持久化Volume

一、数据持久化

Pod是由容器组成的,而容器宕机或停止之后,数据就随之丢了,那么这也就意味着我们在做Kubernetes集群的时候就不得不考虑存储的问题,而存储卷就是为了Pod保存数据而生的
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。
 首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失——容器以干净点状态(镜像最初点状态)重新启动。
 其次,在pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的volume就能很好的解决了这些问题      

1、Vlolume概述

Volume 提供了对各种 backend 的抽象,容器在使用 Volume 读写数据的时候不需要关心数据到底是存放在本地节点的文件系统中呢还是云硬盘上。对它来说,所有类型的 Volume 都只是一个目录
 
Kubernetes中的Volume提供了在容器中挂载外部存储的能力
Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后才可以使用相应的Volume      

2、数据卷的分类

本地(hostPath,emptyDir等)
 网络(NFS,Ceph,GlusterFS等)
 公有云(AWS EBS等)
 K8S资源(configmap,secret等)      

3、常用的四种数据卷

emptyDir
hostPath
NFS
云存储(ceph, glasterfs...)      
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)

4、Pod使用Volume步骤:

1、在Pod上定义存储卷,并关联至目标存储服务上;

2、在需要用到存储卷的容器上,挂载其所属Pod的存储卷      

5、 volume基本资源清单

spec:
  volumes:
  - name <string>        #存储卷名称标识,仅可使用DNS标签格式的字符,在当前Pod中必须唯一
    VOL_TYPE <Object>    #存储卷插件及具体的目标存储供给方的相关配置
  containers:
  - name: ...
    image: ...
    volumeMounts:
    - name <string>        #要挂载的存储卷的名称,必须匹配存储卷列表中的某项定义
      mountPatch <string>  #容器文件系统上的挂载点路径
      readOnly <boolean>   #是否挂载为只读模式,默认为"否"
      subPath <string>     #挂载存储卷上的一个子目录至指定的挂载点
      subPathExpr <string>       #挂载由指定的模式匹配到的存储卷的文件或目录至挂载点
      mountPropagation <string>  #挂载卷的传播模式      

二、emptyDir(临时存储卷)

1、emptyDir的简述

1》emptyDir存储卷是Pod对象生命周期中的一个临时目录,类似于Docker上的docker挂载卷,在Pod对象启动时即被创建,而在Pod对象被移除时会被一并删除
2》不具有持久能力的emptyDir存储卷只能用于某些特殊场景中
3》emptyDir只是一个临时挂载的文件,pod删除后,该目录也会在node节点上被删除;但是容器崩溃时,该文件还存在



#例如:      

2、emptyDir的使用方法

1》暂存空间,例如用于基于磁盘的合并排序

2》用作长时间计算崩溃恢复时的检查点

3》Web服务器容器提供数据时,保存内容管理器容器提取的文件      

4、emptyDir的使用

案列一
#编写资源清单:
[root@m01 /hzl]# cat emptydir.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: emptydir                   #注意大小写
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent   #镜像拉取策略
    volumeMounts:
    - mountPath: /hzl/      #添加容器内部的挂载点
      name: emptydir-name
 
 
 volumes:
  - name: emptydir-name
    emptyDir: {}            #创建一个空目录
      sizeLimit: 1G         #目录容量大小为1G





#创建pod
[root@m01 /hzl]# kubectl apply -f emptydir.yaml 
pod/emptydir created





#查看Pod
[root@ubuntu-200 ~]# kubectl get pods -o wide
NAME                READY   STATUS             RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES
emptydir-pod        1/1     Running            0          17s     10.244.2.62   ubuntu-210   <none>           <none>




#进入容器并在容器中创建文件测试
[root@ubuntu-200 ~]# kubectl exec -it emptydir-pod -- bash
root@emptydir-pod:/# ls -l /cache/
total 0
root@emptydir-pod:/cache# touch /cache/nginx-emptydir.log
root@emptydir-pod:/cache# echo nginx-emptydir > /cache/nginx-emptydir.log 
root@emptydir-pod:/cache# cat /cache/nginx-emptydir.log 
nginx-emptydir





#在node节点上查找临时存储的文件位置
[root@ubuntu-210 ~]# find / -name nginx-emptydir.log
/var/lib/kubelet/pods/95dcb0a8-61f7-42e3-aa35-e7f1a1872b20/volumes/kubernetes.io~empty-dir/cache-volume/nginx-emptydir.log





#查看文件内容
[root@ubuntu-210 ~]# cat /var/lib/kubelet/pods/95dcb0a8-61f7-42e3-aa35-e7f1a1872b20/volumes/kubernetes.io~empty-dir/cache-volume/nginx-emptydir.log
nginx-emptydir





#在master节点上删除pod
[root@ubuntu-200 ~]# kubectl delete -f volume-emptyDir.yaml 
pod "emptydir-pod" deleted





#在node节点上查看临时存储是否还存在
[root@ubuntu-210 ~]# cat /var/lib/kubelet/pods/95dcb0a8-61f7-42e3-aa35-e7f1a1872b20/volumes/kubernetes.io~empty-dir/cache-volume/nginx-emptydir.log
cat: /var/lib/kubelet/pods/95dcb0a8-61f7-42e3-aa35-e7f1a1872b20/volumes/kubernetes.io~empty-dir/cache-volume/nginx-emptydir.log: No such file or directory
[root@ubuntu-210 ~]# ll /var/lib/kubelet/pods/95dcb0a8-61f7-42e3-aa35-e7f1a1872b20/volumes/kubernetes.io~empty-dir/cache-volume/
ls: cannot access '/var/lib/kubelet/pods/95dcb0a8-61f7-42e3-aa35-e7f1a1872b20/volumes/kubernetes.io~empty-dir/cache-volume/': No such file      
案列二
#编写资源清单
kind: Deployment
apiVersion: apps/v1
metadata:
  name: emptydir
spec:
  selector:
    matchLabels:
      app: emptydir
  template:
    metadata:
      labels:
        app: emptydir
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /data/
              name: emptydir-name
        - name: php
          image: registry.cn-hangzhou.aliyuncs.com/k8sos/web:discuz-php-v1
          volumeMounts:
            - mountPath: /opt/
              name: emptydir-name
      volumes:
        - name: emptydir-name
          emptyDir: {}
          
 
 #创建pod
 [root@m01 /hzl]# kubectl  apply -f emptydir.yaml 
deployment.apps/emptydir unchanged



#查看pod状态
 [root@m01 /hzl]# kubectl get pod -o wide -w
NAME                        READY   STATUS    RESTARTS   AGE    IP           NODE    NOMINATED NODE   READINESS GATES
emptydir-7d5cdb7b48-qzqqg   2/2     Running   0          107s   10.244.2.2   nod02   <none>           <none>





#################################### 测试  ########################################

#进入容器nginx(进入到挂载目录)
[root@m01 /hzl]# kubectl exec -it emptydir-7d5cdb7b48-qzqqg -c nginx -- bash
root@emptydir-7d5cdb7b48-qzqqg:/# cd /data/
root@emptydir-7d5cdb7b48-qzqqg:/data# touch hzl.txt
root@emptydir-7d5cdb7b48-qzqqg:/data# tail -f hzl.txt   #使用tail进行监控




#进入容器php(进入到挂载目录)
[root@m01 /hzl]#  kubectl exec -it emptydir-7d5cdb7b48-qzqqg -c php -- bash
[root@emptydir-7d5cdb7b48-qzqqg html]# cd /opt/
[root@emptydir-7d5cdb7b48-qzqqg html]# ls 
[root@emptydir-7d5cdb7b48-qzqqg html]# hzl.txt    #文件在也在php容器中,实现了容器内部数据共享
[root@emptydir-7d5cdb7b48-qzqqg html]# echo ‘666’ > hzl.txt





#查看文件容器nginx状态
[root@emptydir-7d5cdb7b48-qzqqg:/data# tail -f hzl.txt   
666
#在nginx容器删除文件hzl.txt
[root@emptydir-7d5cdb7b48-qzqqg:/data# rm -rf hzl.txt



#查看容器php的状态
[root@emptydir-7d5cdb7b48-qzqqg html]# ll     #查看文件已经不存在了





#总结 :      

三、hostPath(节点存储卷)

hostPath类型则是映射node文件系统中的文件或者目录到pod里。在使用hostPath类型的存储卷时,也可以设置type字段,支持的类型有文件、目录、File、Socket、CharDevice和BlockDevice

1、hostpath的概述:

hostPath是挂载node 主机上的(当pod运行在那台主机上,hostPtah就相当于docker挂载到当前系统)
hostPath类型的存储卷是指将工作节点上某个文件系统的目录或文件挂载于Pod中的一种存储卷,它独立于Pod资源的生命周期,因而具有持久性。但它是工作节点本地的存储空间,仅适用于特定情况下的存储卷使用要求,例如,将工作节点上的文件系统关联为Pod的存储卷,从而使得容器访问节点文件系统上的数据。这一点在运行有管理任务的系统级Pod资源需要访问节点上的文件时尤为有用      

2、hostpath支持数据类型

DirectoryCreate:如果在给定的路径上没有任何东⻄存在,那么将根据需要在那⾥创建⼀个空⽬录,权限设置为 0755,与 Kubelet 具有相同的组和所有权;

Directory:     给定的路径下必须存在⽬录;

FileOrCreate:  如果在给定的路径上没有任何东⻄存在,那么会根据需要创建⼀个空⽂件,权限设置为0644,与 Kubelet 具有相同的组和所有权;

File:          给定的路径下必须存在⽂件;

Socket:        给定的路径下必须存在 UNIX 套接字;

CharDevice:    给定的路径下必须存在字符设备;

BlockDevice:   给定的路径下必须存在块设备;

“” :            空字符串,默认配置,在关联hostPath存储卷之前不进行任何检查      

3、hostpath的使用

案列二
#查看文档:https://kubernetes.io/docs/concepts/storage/volumes#hostpath
[root@m01 /hzl]# kubectl explain pod.spec.volumes.hostPath
KIND:     Pod
VERSION:  v1

RESOURCE: hostPath <Object>
.......
.....




#创建资源配置清单
[root@m01 /hzl]# cat hostpath.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: hostpath
spec:
  selector:
    matchLabels:
      app: hostpath
  template:
    metadata:
      labels:
        app: hostpath
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /opt/
              name: hostpath-name
      volumes:
        - name: hostpath-name
          hostPath:
            path: /opt/hzl/hhh
            type: DirectoryCreate



#创建pod
[root@m01 /hzl]# kubectl apply -f hostpath.yaml 
deployment.apps/hostpath created





#查看pod状态
[root@m01 /hzl]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
hostpath-6b8bd7459d-bpfhb   1/1     Running   0          25s
[root@m01 /hzl]# kubectl get pods -o wide     #查看部署到node位置
NAME                        READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
hostpath-6b8bd7459d-bpfhb   1/1     Running   0          3m11s   10.244.1.4   nod01   <none>           <none>





#在node01上查看(给定挂载的位置没有东西,就会自己创建并授权755)
[root@nod01 /opt]# ll
总用量 1
drwxr-xr-x 3 root root  17 8月   9 21:46 hzl
[root@nod01 /hzl]# cd /opt/hzl/hhh/
[root@nod01 /opt/hzl/hhh]# pwd 
/opt/hzl/hhh



ps : 使用DirectoryCreate类型,挂载目录点,不管存不存在,都不影响正常挂载。即,如果挂载点存存在,则直接挂载,如果不存在,则自动创建目录并挂载

#################################### 测试   ####################################
#更改资源清单
[root@m01 /hzl]# vim hostpath.yaml
.......
....
volumes:
        - name: hostpath-name
          hostPath:
            path: /opt/hzl/hhh
            type: Directory      #更改数据类型
            
            
            
 
#创建pod
[root@m01 /hzl]# kubectl apply -f hostpath.yaml 
deployment.apps/hostpath configured



#查看pod(节点为node02)
[root@m01 /hzl]# kubectl get pod
NAME                        READY   STATUS              RESTARTS   AGE
hostpath-6b8bd7459d-bpfhb   1/1     Running             0          13m
hostpath-b5fb78645-9fd4r    0/1     ContainerCreating   0          33s    #查看发现一直在创建中
[root@m01 /hzl]# kubectl get pod -o wide 
NAME                        READY   STATUS              RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
hostpath-6b8bd7459d-bpfhb   1/1     Running             0          17m     10.244.1.4   nod01   <none>           <none>
hostpath-b5fb78645-9fd4r    0/1     ContainerCreating   0          4m46s   <none>       nod02   <none>           <none>








#查看详情
[root@m01 /hzl]# kubectl describe pods hostpath-b5fb78645-9fd4r 
.......
...
Events:
  Type     Reason       Age                 From               Message
  ----     ------       ----                ----               -------
  Normal   Scheduled    107s                default-scheduler  Successfully assigned default/hostpath-b5fb78645-9fd4r to nod02
  Warning  FailedMount  43s (x8 over 107s)  kubelet            MountVolume.SetUp failed for volume "hostpath-name" : hostPath type check failed: /opt/hzl/ is not a directory      #查看原因为挂载时找不到目录而一直等待
  
  
  



#手动创建目录(nod02)
[root@nod02 ~]# cd /opt/
[root@nod02 /opt]# mkdir  hzl
[root@nod02 /opt]# ll
总用量 1
drwxr-xr-x 2 root root   6 8月   9 22:04 hzl
[root@nod02 /opt]# 



#查看pod状态(m01)
[root@m01 /hzl]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
hostpath-b5fb78645-9fd4r   1/1     Running   0          6m38s   #查看pod已经正常创建运行


ps      
案列二
#编写资源清单
[root@m01 /hzl]# cat volume-hostPath-test.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-test-pod
spec:
  containers:
  - name: nginx-hostpath
    image: nginx
    volumeMounts:
    - mountPath: /var/logs/
      name: data-log
  #定义hostPath卷名,和宿主机共享的路径
  volumes:
  - name: data-log
    hostPath:
      path: /data/logs
      

#创建pod
[root@m01 /hzl]# kubectl apply -f volume-hostPath-test.yaml
[root@m01 /hzl]# kubectl get pods -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
hostpath-test-pod   1/1     Running   0          66m   10.244.2.65   ubuntu-210   <none>           <none>



#在node节点上的共享目录上创建文件
[root@m01 /hzl]# echo 111 > /data/logs/1.txt
[root@m01 /hzl]# cat /data/logs/1.txt 
111




#在master节点上进入pod,查看挂载卷的文件内容
[root@m01 /hzl]# kubectl exec -it hostpath-test-pod -- bash
root@hostpath-test-pod:/# cat /var/logs/1.txt 
111



#在pod内查看和创建创建文件
root@hostpath-test-pod:/# ls /var/logs/
1.txt
root@hostpath-test-pod:/# echo ’666‘ > /var/logs/2.txt
root@hostpath-test-pod:/# cat /var/logs/2.txt 
666
root@hostpath-test-pod:/# ls /var/logs/
1.txt 2.txt

#在Node节点上查看pod内部创建的文件
[root@m01 /hzl]# cat /data/logs/2.txt 
666




#删除Pod
[root@m01 /hzl]# kubectl delete -f  volume-hostPath-test.yaml 
pod "hostpath-test-pod" deleted




#Node节点上查看文件是否存在
[root@m01 /hzl]# ll /data/logs/
total 16
drwxr-xr-x 2 root root 4096 Dec  8 08:46 ./
drwxr-xr-x 4 root root 4096 Dec  8 07:34 ../
-rw-r--r-- 1 root root    4 Dec  8 08:43 1.txt
-rw-r--r-- 1 root root    4 Dec  8 08:46 2.txt #可看到在Pod内部创建的文件依然存在,没有随pod的删除而删除,已初步实现了持久化.
[root@m01 /hzl]# cat /data/logs/2.txt 
666      

四、nfs存储卷(pv、pvc)

nfs卷能将NFS(网络文件系统)挂载到你的pod中。不像emptyDir,当删除Pod时,nfs卷的内容被保留,卷仅仅是被卸载。另外,NFS是文件系统级共享服务,它支持同时存在的多路挂载请求

1、nfs存储卷的概述

nfs使得我们可以挂载已经存在的共享到我们的Pod中,和emptyDir不同的是,当Pod被删除时,emptyDir也会被删除。但是nfs不会被删除,仅仅是解除挂在状态而已,这就意味着NFS能够允许我们提前对数据进行处理,而且这些数据可以在Pod之间相互传递,并且nfs可以同时被多个pod挂在并进行读写



ps      

2、pv、pvc的介绍

PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。 集群中的资源就像一个节点是一个集群资源。 PV是诸如卷之类的卷插件,但是具有独立于使用PV的任何单个pod的生命周期。 该API对象捕获存储的实现细节,即NFS,iSCSI或云提供商特定的存储系统

PersistentVolumeClaim(PVC)是用户存储的请求。PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC),定义的时候直接指定大小,pvc必须与对应的pv建立关系,pvc会根据定义去pv申请,而pv是由存储空间创建出来的。pv和pvc是kubernetes抽象出来的一种存储资源      

3、PV和PVC的生命周期

将PV看作可用的存储资源,PVC则是对存储资源的需求
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)
(1)#资源供应

 k8s支持两种资源的供应模式:静态模式(Static)和动态模式(Dynamic)。资源供应的结果就是创建好的PV

    1>静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置。

    2>动态模式:集群管理员无需手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种类型。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及与PVC的绑定。PVC可以声明Class为"",说明该PVC禁止使用动态模式。




(2)#资源绑定
 在定义好PVC之后,系统将根据PVC对存储资源的要求(存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与定义的PVC进行绑定,应用就可以使用这个PVC了。
 如果系统中没有这个PV,则PVC则会一直处理Pending状态,直到系统中有符合条件的PV。PV一旦绑定到PVC上,就会被PVC独占,不能再与其他PVC进行绑定。
 当PVC申请的存储空间比PV的少时,整个PV的空间就都能够为PVC所用,可能会造成资源的浪费。
 如果资源供应使用的是动态模式,则系统在为PVC找到合适的StorageClass后,将自动创建一个PV并完成与PVC的绑定。





(3)#资源使用
 Pod使用Volume定义,将PVC挂载到容器内的某个路径进行使用。
 Volume的类型为Persistent VolumeClaim,在容器挂载了一个PVC后,就能被持续独占使用。多个Pod可以挂载到同一个PVC上。

volumes:
  - name: pv
    persistentVolumeClaim:
      claimName: pvc




(4)#资源释放
 当存储资源使用完毕后,可以删除PVC,与该PVC绑定的PV会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被保留在存储设备上,只有在清除之后该PV才能被再次使用。




(5)#资源回收      

4、存储管理机制

静态资源供应模式下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制:
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)
动态资源供应模式下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV),并供Pod使用的存储管理机制
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)

5、简述pv过载过程

1>用户提交一个包含PVC的POD

2>调度器把根据各种调度算法把该POD分配到某个节点,比如node01

3>Node01上的kubelet等待Volume Manager准备存储设备

4>PV控制器调用存储插件创建PV并与PVC进行绑定

5>Attach/Detach Controller或Volume Manager通过存储插件实现设备的attach。(这一步是针对块设备存储)

6>Volume Manager等待存储设备变为可用后,挂载该设备到/var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 类型 >/<Volume 名字 >目录上

7>Kubelet被告知卷已经准备好,开始启动POD,通过映射方式挂载到容器中      

【pv、pvc的使用(全部节点必须安装nfs)】

1、安装nfs

[root@m01 /hzl]# yum install nfs-utils rpcbind  -y
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * elrepo: mirrors.tuna.tsinghua.edu.cn
 * epel: mirror.sjtu.edu.cn
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
.......
...



#配置文件添加
[root@m01 /hzl]# mkdir -p /nfs/v{1..3}
[root@m01 /hzl]# cat > /etc/exports <<EOF
> /nfs/v1  192.168.15.0/24(rw,no_root_squash)
> /nfs/v2  192.168.15.0/24(rw,no_root_squash)
> /nfs/v3  192.168.15.0/24(rw,no_root_squash)
> EOF




#启动 nfs rpcbind
[root@m01 /hzl]# systemctl enable --now rpcbind nfs-server.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.




#查看配置状态
[root@m01 /hzl]# exportfs -arv
exporting 192.168.15.0/24:/nfs/v3
exporting 192.168.15.0/24:/nfs/v2
exporting 192.168.15.0/24:/nfs/v1





#查看挂载点
[root@m01 /hzl]#  showmount -e
Export list for m01:
/nfs/v3 192.168.15.0/24
/nfs/v2 192.168.15.0/24
/nfs/v1 192.168.15.0/24      

2、nfs存储卷(创建pv、pvc)

#编写资源清单 :pv
[root@m01 /hzl]# cat pv1.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv1
  labels:
    app: pv1
spec:
  nfs:
    path: /nfs/v1
    server: 192.168.15.55
  accessModes:
    - "ReadWriteMany"
  capacity:
    storage: 2Gi



[root@m01 /hzl]# cat pv2.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv2
  labels:
    app: pv2
spec:
  nfs:
    path: /nfs/v2
    server: 192.168.15.55
  accessModes:
    - "ReadWriteMany"
  capacity:
    storage: 10Gi



[root@m01 /hzl]# cat pv3.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv3
  labels:
    app: pv3
spec:
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /nfs/v3
    server: 192.168.15.55
  accessModes:
    - "ReadWriteMany"
  capacity:
    storage: 10Gi




#创建所有:pv
[root@m01 /hzl]# kubectl apply -f pv1.yaml 
persistentvolume/pv1 created
[root@m01 /hzl]# kubectl apply -f pv2.yaml 
persistentvolume/pv2 created
[root@m01 /hzl]# kubectl apply -f pv3.yaml 
persistentvolume/pv3 created




#查看所有:pv
[root@m01 /hzl]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    2Gi        RWX            Retain           Available                                   12m
pv2    10Gi       RWX            Retain           Available                                   2s
pv3    10Gi       RWX            Recycle          Available                                   98s







#######################################################################


#创建资源清单 :pvc
[root@m01 /hzl]# cat pvc1.yaml 
piVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
spec:
  accessModes:
    - "ReadWriteMany"
  resources:
    requests:
      storage: "6Gi"





[root@m01 /hzl]# cat pvc2.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc3
spec:
  accessModes:
    - "ReadWriteMany"
  resources:
    requests:
      storage: "6Gi"







#创建:pvc
[root@m01 /hzl]# kubectl apply -f pvc1.yaml 
persistentvolumeclaim/pvc1 created
[root@m01 /hzl]# kubectl apply -f pvc2.yaml 
persistentvolumeclaim/pvc2 created







#查看pv,pvc(根据设定pvc的大小自动关联所合适的pv)
[root@m01 /hzl]# kubectl get pv,pvc      

3、nfs存储卷的挂载使用(单节点挂载)

#编写资源清单
[root@m01 /hzl]# cat deployment.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: test-rwo
spec:
  selector:
    matchLabels:
      app: rwo
  template:
    metadata:
      labels:
        app: rwo
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /data/  #容器内的挂载点
              name: rwo
      volumes:
        - name: rwo
          persistentVolumeClaim:
            claimName: pvc1     



#创建pod
[root@m01 /hzl]# kubectl apply -f deployment.yaml 
deployment.apps/test-rwo unchanged





#查看pod(已经正常运行)
[root@m01 /hzl]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
test-rwo-6dcb5687f-sxlmq   1/1     Running   0          2m27s

#查看详情(nginx已经正常运行到node02上)
[root@m01 /hzl]# kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE    IP           NODE    NOMINATED NODE   READINESS GATES
test-rwo-6dcb5687f-sxlmq   1/1     Running   0          7m1s   10.244.2.5   nod02   <none>           <none>




#查看pvc绑定状态(绑定成功状态)

[root@m01 /hzl]# kubectl get pv,pvc
NAME                   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM          STORAGECLASS   REASON   AGE
persistentvolume/pv1   2Gi        RWX            Retain           Available                                          86m
persistentvolume/pv2   10Gi       RWX            Retain           Bound       default/pvc3                           18s
persistentvolume/pv3   10Gi       RWX            Recycle          Bound       default/pvc1                           75m

NAME                         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc1   Bound    pv3      10Gi       RWX                           68m
persistentvolumeclaim/pvc3   Bound    pv2      10Gi       RWX                           3s


################################### 测试   #####################################

#进入容器测试
[root@m01 /hzl]# kubectl exec -it test-rwo-6dcb5687f-sxlmq -- bash
root@test-rwo-6dcb5687f-sxlmq:/# cd /data/
root@test-rwo-6dcb5687f-sxlmq:/data# ls
root@test-rwo-6dcb5687f-sxlmq:/data# touch hzl.txt
root@test-rwo-6dcb5687f-sxlmq:/data# ls
hzl.txt




#查看挂载目录测试状态(文件已创建)
[root@m01 /nfs/v3]# cd /nfs/v3/
[root@m01 /nfs/v3]# pwd
/nfs/v3
[root@m01 /nfs/v3]# ls
hzl.txt     




#删除pv、pvc
[root@m01 /hzl]# kubectl delete pv pvc3 
persistentvolume "pvc3" deleted
[root@m01 /hzl]# kubectl delete pv pv2 
persistentvolume "pv2" deleted



#查看挂载点状态
[root@m01 /nfs/v3]# ll
总用量 0
-rw-r--r-- 1 root root 0 8月  10 00:56 hzl.txt



ps :      

4、nfs存储卷(多点挂载使用)

#更改pv、pvc策略
[root@m01 /hzl]# cat pv2.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv2
  labels:
    app: pv2
spec:
  nfs:
    path: /nfs/v2
    server: 192.168.15.55
  accessModes:
    - "ReadOnlyMany"    #更改模式
  capacity:
    storage: 10Gi


[root@m01 /hzl]# cat pvc3.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc3
spec:
  accessModes:
    - "ReadOnlyMany"    #更改模式
  resources:
    requests:
      storage: "6Gi"


#编写资源清单
[root@m01 /hzl]# cat deployment1.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: test-rwo-2
spec:
  selector:
    matchLabels:
      app: test-rwo-2
  template:
    metadata:
      labels:
        app: test-rwo-2
    spec:
      containers:
        - name: nginx1
          image: nginx
          volumeMounts:
            - mountPath: /data/
              name: test-rwo
       
      volumes:
        - name: test-rwo
          persistentVolumeClaim:
            claimName: pvc3



#创建pv,pvc
[root@m01 /hzl]# kubectl apply -f pv2.yaml
persistentvolumeclaim/pv2 unchanged
[root@m01 /hzl]# kubectl apply -f pvc3.yaml
persistentvolumeclaim/pvc3 unchanged
#创建pod
[root@m01 /hzl]# kubectl apply -f deployment1.yaml 
deployment.apps/test-rwo-2 unchanged



#查看pc,pvc(pvc3已经绑定pv2上)
[root@m01 /hzl]# kubectl get pv,pvc
NAME                   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM          STORAGECLASS   REASON   AGE
persistentvolume/pv1   2Gi        RWX            Retain           Available                                          155m
persistentvolume/pv2   10Gi       ROX            Retain           Bound       default/pvc3                           18s
persistentvolume/pv3   10Gi       RWX            Recycle          Bound       default/pvc1                           144m

NAME                         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc1   Bound    pv3      10Gi       RWX                           137m
persistentvolumeclaim/pvc3   Bound    pv2      10Gi       ROX                           10s




#查看pod
[root@m01 /hzl]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
test-rwo-2-66ddb84cf7-tw4mx   1/1     Running   0          31m
test-rwo-6dcb5687f-s496r      1/1     Running   0          13s




[root@m01 /hzl]# kubectl exec -it test-rwo-2-66ddb84cf7-tw4mx -- bash
Defaulted container "nginx1" out of: nginx1, nginx2
root@test-rwo-2-66ddb84cf7-tw4mx:/# cd /data/
root@test-rwo-2-66ddb84cf7-tw4mx:/data# touch 123.txt
root@test-rwo-2-66ddb84cf7-tw4mx:/data# ls
123.txt



[root@m01 /hzl]# kubectl exec -it test-rwo-6dcb5687f-s496r -- bash
root@test-rwo-2-66ddb84cf7-tw4mx:/# cd /data/
root@test-rwo-2-66ddb84cf7-tw4mx:/data# ls
123.txt      

5、案列(数据持久化)

#先配置nfs服务器
[root@C8_58 test]# yum -y install nfs-utils
[root@C8_58 test]# cat /etc/exports
/data/test *(rw)
[root@C8_58 test]# mkdir -p /data/test
[root@C8_58 test]# echo nginx web > /data/test/index.html
[root@C8_58 test]# systemctl restart nfs-server

#测试能否正常挂载
[root@ubuntu-220 ~]# apt -y install nfs-server
[root@ubuntu-220 ~]# showmount -e 10.0.0.58
Export list for 10.0.0.58:
/data/test *
[root@ubuntu-220 ~]# mount -t nfs 10.0.0.58:/data/test /mnt/
[root@ubuntu-220 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
udev                  955M     0  955M   0% /dev
tmpfs                 198M   13M  185M   7% /run
/dev/sda2              98G  5.4G   88G   6% /
tmpfs                 986M     0  986M   0% /dev/shm
tmpfs                 5.0M     0  5.0M   0% /run/lock
tmpfs                 986M     0  986M   0% /sys/fs/cgroup
/dev/loop1             97M   97M     0 100% /snap/core/9665
/dev/loop0             98M   98M     0 100% /snap/core/10444
/dev/sda3             976M  146M  764M  16% /boot
/dev/sda5              95G   61M   91G   1% /data
tmpfs                 198M     0  198M   0% /run/user/0
10.0.0.58:/data/test   50G  390M   50G   1% /mnt

#编写资源清单
[root@ubuntu-200 ~]# cat volume-nfs.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-nfs
  labels:
    app: nginx-nfs
spec:
  containers:
  - name: nginx-nfs
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: my-nfs-volume
  volumes:
  - name: my-nfs-volume
    nfs:
      server: 10.0.0.58
      path: /data/test

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
  - name: http
    port: 81
    targetPort: 80
    nodePort: 30016
    protocol: TCP
  type: NodePort
  selector:
    app: nginx-nfs

#创建Pod及service
[root@ubuntu-200 ~]# kubectl apply -f volume-nfs.yaml
[root@ubuntu-200 ~]# kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
nginx-nfs   1/1     Running   0          24m   10.244.2.67   ubuntu-210   <none>           <none>
[root@ubuntu-200 ~]# kubectl get service nginx-service -o wide
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE   SELECTOR
nginx-service   NodePort   10.104.177.209   <none>        81:30016/TCP   25m   app=nginx-nfs

#进入Pod查看是否挂载成功
[root@ubuntu-200 ~]# kubectl exec -it nginx-nfs -- bash
root@nginx-nfs:/# cat /usr/share/nginx/html/index.html 
nginx web




##########################################################################



#编辑资源清单
[root@ubuntu-200 ~]# cat volume-nfs-redis.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: volume-nfs-redis
  labels:
    app: redis
spec:
  containers:
  - name: redis
    image: redis:alpine
    securityContext:    #配置了这项,需要在nfs服务器让id为999的账户对共享的命令有读写写权限
      runAsUser: 999
    ports:
    - containerPort: 6379
      name: redisport
    volumeMounts:
    - mountPath: /data
      name: redisdata
  volumes:
  - name: redisdata
    nfs:
      server: 10.0.0.58
      path: /data/redis
      readOnly: false 

#创建pod
[root@ubuntu-200 ~]# kubectl apply -f volume-nfs-redis.yaml

#进入Pod
[root@ubuntu-200 ~]# kubectl exec -it volume-nfs-redis -- /bin/sh
#登录redis并创建
/data $ redis-cli 
127.0.0.1:6379> set name yang
OK
127.0.0.1:6379> get name
"yang"
127.0.0.1:6379> bgsave
#查看创建的redis文件
/data $ ls -l
total 4
-rw-r--r--    1 1099     nobody         120 Dec  9 13:19 dump.rdb

#在nfs服务器主机上也能看到
[root@C8_58 ~]# ll /data/redis/
total 4
-rw-r--r-- 1 redis nobody 120 Dec  9 21:19 dump.rdb

#删除镜像,重新创建一次
[root@ubuntu-200 ~]# kubectl delete -f volume-nfs-redis.yaml 
pod "volume-nfs-redis" deleted
[root@ubuntu-200 ~]# kubectl apply  -f volume-nfs-redis.yaml 
pod/volume-nfs-redis created
[root@ubuntu-200 ~]# kubectl get pod -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
volume-nfs-redis   1/1     Running   0          8s    10.244.2.71   ubuntu-210   <none>           <none>

#再次进入pod,可看到数据仍然存在,已实现持久化.
[root@ubuntu-200 ~]# kubectl exec -it volume-nfs-redis  -- /bin/sh
/data $ ls
dump.rdb
/data $ redis-cli 
127.0.0.1:6379> get name
"yang"      

【 使用存储卷搭建lnmp】

1、创建资源清单(数据库)

#资源清单编写:(数据库)
[root@m01 /hzl]# cat mysql.yaml 
kind: Namespace
apiVersion: v1
metadata:
  name: mysql
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysql
  namespace: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
            - name: MYSQL_DATABASE
              value: discuz
          livenessProbe:
            exec:
              command:
                - "/bin/sh"
                - "-c"
                - "cat /etc/mysql/my.cnf"
            initialDelaySeconds: 0
            periodSeconds: 3
            timeoutSeconds: 1
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            tcpSocket:
              port: 3306
            initialDelaySeconds: 30
            periodSeconds: 1
            timeoutSeconds: 1
            successThreshold: 3
            failureThreshold: 1
---
kind: Service
apiVersion: v1
metadata:
  name: mysql
  namespace: mysql
spec:
  ports:
    - port: 3306
      targetPort: 3306
      protocol: TCP
      name: mysql
  selector:
    app: mysql




#创建pod
[root@m01 /hzl]# kubectl apply -f mysql.yaml 
namespace/mysql unchanged
deployment.apps/mysql configured
service/mysql unchanged



#查看pod
[root@m01 /hzl]# kubectl get -n mysql pods
NAME                     READY   STATUS    RESTARTS   AGE
mysql-7795495b8b-b2lwq   1/1     Running   0          28m



#查看svc
[root@m01 /hzl]# kubectl get svc -n mysql
NAME    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
mysql   ClusterIP   10.102.58.127   <none>        3306/TCP   36m      

2、创建资源清单(web+php)

#资源清单编写:
[root@m01 /hzl]# cat descuz.yaml 
kind: Namespace
apiVersion: v1
metadata:
  name: web
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: discuz
  labels:
    app: discuz
spec:
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /nfs/discuz
    server: 192.168.15.55
  accessModes:
    - "ReadWriteMany"
  capacity:
    storage: 10Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: discuz
  namespace: web
spec:
  accessModes:
    - "ReadWriteMany"
  resources:
    requests:
      storage: "6Gi"
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: discuz
  namespace: web
spec:
  replicas: 5
  selector:
    matchLabels:
      app: discuz
  template:
    metadata:
      labels:
        app: discuz
    spec:
      containers:
        - name: php
          image: registry.cn-hangzhou.aliyuncs.com/k8sos/web:discuz-php-v1
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: /usr/share/nginx/html/
              name: discuz
        - name: nginx
          image: registry.cn-hangzhou.aliyuncs.com/k8sos/web:discuz-v1
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: /usr/share/nginx/html/
              name: discuz
      volumes:
        - name: discuz
          persistentVolumeClaim:
            claimName: discuz
---
kind: Service
apiVersion: v1
metadata:
  name: discuz
  namespace: web
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      name: http
      nodePort: 30080
  type: NodePort
  selector:
    app: discuz
    
  
  
  
#创建pod  
[root@m01 /hzl]# kubectl apply -f discuz.yaml 
namespace/discuz unchanged
deployment.apps/discuz configured
service/discuz unchanged   
   
    
    
    
#查看pod    
[root@m01 /hzl]# kubectl get -n web pods
NAME                      READY   STATUS    RESTARTS   AGE
discuz-587854655b-5h4q8   2/2     Running   0          15m
discuz-587854655b-97wr2   2/2     Running   0          15m
discuz-587854655b-9ktlb   2/2     Running   0          15m
discuz-587854655b-lzqf2   2/2     Running   0          15m
discuz-587854655b-vjqm9   2/2     Running   0          15m




#查看pv,pvc状态
[root@m01 /hzl]# kubectl get svc -n web 
NAME     TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
discuz   NodePort   10.102.201.10   <none>        80:30080/TCP   17m
[root@m01 /hzl]# kubectl get pv,pvc      

3、测试部署(lnmp)

#查看svc
[root@m01 /hzl]# kubectl get svc -n web 
NAME     TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
discuz   NodePort   10.102.201.10   <none>        80:30080/TCP   17m
 
 
 
 
#给配置文件添加权限(用户www)
[root@m01 /nfs]# useradd www
[root@m01 /nfs]# chown +777 -R /nfs/discuz/   #授最高权限
[root@m01 /nfs]# chown www.www -R /nfs/discuz/
[root@m01 /nfs]# ll
总用量 4
drwxrwxrwx 14 www  www  4096 8月  10 04:01 discuz


#使用浏览器测试:ok      
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)

五、StorageClass(存储类别)

PV是需要运维人员手动创建的,开发操作PVC,可是大规模集群中可能会有很多PV,如果这些PV都需要运维手动来处理这也是一件很繁琐的事情,所以就有了动态供给概念,也就是Dynamic Provisioning。而我们上面的创建的PV都是静态供给方式,也就是Static Provisioning。而动态供给的关键就是StorageClass,它的作用就是创建PV模板

每一个存储类都包含provisioner、parameters和reclaimPolicy这三个参数域,当一个属于某个类的PersistentVolume需要被动态提供时,将会使用上述的参数域

1、简述StorageClass

1>StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,一方面减少了用户对存储资源细节的关注,另一方面减少了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应

2>StorageClass的定义主要包括名称、后端存储的提供者(privisioner)和后端存储的相关参数配置

3>StorageClass一旦被创建,就无法修改,如需修改,只能删除重建      
基本框架:
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)

2、StorageClass的使用

​​【helm官方网站】​​
@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)
1)# 下载helm
[root@m01 /hzl]# wget https://get.helm.sh/helm-v3.3.4-linux-amd64.tar.gz
--2021-08-10 10:35:32--  https://get.helm.sh/helm-v3.3.4-linux-amd64.tar.gz
正在解析主机 get.helm.sh (get.helm.sh)... 152.199.39.108, 2606:2800:247:1cb7:261b:1f9c:2074:3c
# 解压
[root@m01 /hzl]# tar xf helm-v3.3.4-linux-amd64.tar.gz





2)# 安装工作目录
[root@m01 /hzl]# mv linux-amd64/helm /usr/local/bin/





3)# 验证安装
[root@m01 /hzl]# helm version
version.BuildInfo{Version:"v3.3.4", GitCommit:"a61ce5633af99708171414353ed49547cf05013d", GitTreeState:"clean", GoVersion:"go1.14.9"}





4)#添加仓库
# 阿里云镜像仓库(推荐使用)
[root@m01 /hzl]# helm repo add ali-stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
"ali-stable" has been added to your repositories
# 官方仓库
[root@m01 /hzl]# helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories





5)# 查看仓库列表
[root@m01 /hzl]# helm repo list
NAME        URL                                                   
ali-stable  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
bitnami    https://charts.bitnami.com/bitnami   






6)#创建helm使用目录(缓存、配置文件、数据存放目录)
[root@m01 ~]# mkdir -p  $HOME/.cache/helm 
[root@m01 ~]# mkdir -p $HOME/.config/helm 
[root@m01 ~]# mkdir -p $HOME/.local/share/helm





7)#查找搜索安装包
[root@m01 /hzl]# helm search repo nginx 
NAME                              CHART VERSION  APP VERSION  DESCRIPTION                                       
ali-stable/nginx-ingress          0.9.5          0.10.2      An nginx Ingress controller that uses ConfigMap...
ali-stable/nginx-lego            0.3.1                      Chart for nginx-ingress-controller and kube-lego  
bitnami/nginx                    9.4.2          1.21.1      Chart for the nginx server                        
bitnami/nginx-ingress-controller  7.6.18        0.48.1      Chart for the nginx Ingress controller            
bitnami/kong                      3.8.1          2.5.0        Kong is a scalable, open source API layer (aka ...
ali-stable/gcloud-endpoints      0.1.0                      Develop, deploy, protect and monitor your APIs ...







8)# 使用helm下载mysql测试
[root@m01 /hzl]# helm search repo mysql   #搜索mysql
NAME                              CHART VERSION  APP VERSION  DESCRIPTION                                       
ali-stable/mysql                  0.3.5                      Fast, reliable, scalable, and easy to use open-...
bitnami/mysql                      8.8.3          8.0.26      Chart to create a Highly available MySQL cluster  
ali-stable/percona                0.3.0                      free, fully compatible, enhanced, open source d...
ali-stable/percona-xtradb-cluster  0.0.2          5.7.19      free, fully compatible, enhanced, open source d...
bitnami/phpmyadmin                8.2.11        5.1.1        phpMyAdmin is an mysql administration frontend    
ali-stable/gcloud-sqlproxy        0.2.3                      Google Cloud SQL Proxy                            
ali-stable/mariadb                2.1.6          10.1.31      Fast, reliable, scalable, and easy to use open-...
bitnami/mariadb                    9.4.2          10.5.12      Fast, reliable, scalable, and easy to use open-...
bitnami/mariadb-cluster            1.0.2          10.2.14      DEPRECATED Chart to create a Highly available M...
bitnami/mariadb-galera            5.11.2        10.5.11      MariaDB Galera is a multi-master database clust...
[root@m01 /hzl]# helm pull bitnami/mysql
[root@m01 /hzl]# ll |grep mysql
-rw-r--r-- 1 root root    38954 8月  10 11:05 mysql-8.8.3.tgz      

【helm安装nfs(storageclass)】

1)#使用helm安装
[root@m01 ~]# helm repo add ckotzbauer https://ckotzbauer.github.io/helm-charts
"ckotzbauer" has been added to your repositories    #添加仓库
[root@m01 ~]# helm search repo nfs-client        #搜索nfs-client
NAME                              CHART VERSION  APP VERSION  DESCRIPTION                                       
ckotzbauer/nfs-client-provisioner  1.0.2          3.1.0        nfs-client is an automatic provisioner that use...
[root@m01 ~]# helm pull ckotzbauer/nfs-client-provisioner     #使用helm进行拉取
[root@m01 ~]# ll |grep nfs-client-provisioner
-rw-r--r-- 1 root root      4802 8月  10 2021 nfs-client-provisioner-1.0.2.tgz
[root@m01 ~]# tar xf nfs-client-provisioner-1.0.2.tgz 






2)#跟改文件使用参(下图所示)
[root@m01 ~/nfs-client-provisioner]# vim values.yaml 






3)#安装nfs
[root@m01 ~/nfs-client-provisioner]# helm install nfs  ./
NAME: nfs
LAST DEPLOYED: Tue Aug 10 11:50:50 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
#卸载
[root@m01 ~/nfs-client-provisioner]# helm uninstall nfs





4)#查看pod
[root@m01 ~/nfs-client-provisioner]# kubectl  get pods
NAME                                          READY   STATUS    RESTARTS   AGE
nfs-nfs-client-provisioner-5c854cb79b-pph46   1/1     Running   0          2m17s





5)#查看创建的nfs集群(默认命名空间为default)
[root@m01 ~/nfs-client-provisioner]# kubectl get storageclasses.storage.k8s.io 
NAME                        PROVISIONER                                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-storagclass (default)   cluster.local/nfs-nfs-client-provisioner   Delete          Immediate           true                   4m4s







------------------------------------------------------------------------------------------------------------------------------------------------------
(问题1)
#添加配置文件(如果有报错,使用此参数)
[root@m01 /hzl]#  vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
....
- --feature-gates=RemoveSelfLink=false         #自动链接
......
....
[root@m01 /hzl]# kubectl delete -n kube-system pod kube-apiserver
[root@m01 /hzl]# kubectl apply -f kube-apiserver.yaml 

(问题2)
#创建使用目录 
[root@m01 /hzl]# mkdir /nfs/v1 -p
[root@m01 /hzl]# chown +777 -R /nfs/v1`      

1、使用storageclasses

#资源清单编写
[root@m01 /hzl]# cat sc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  namespace: default
  name: test-nfs
  labels:
    app: test-nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-storagclass  #名称与创建时nfs时一致
  resources:
    requests:
      storage: 8Gi

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: test-nfs-storageclass
  namespace: default
  labels:
    app: test-nfs
spec:
  selector:
    matchLabels:
      app: test-nfs
  template:
    metadata:
      labels:
        app: test-nfs
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: test-nfs
      volumes:
        - name: test-nfs
          persistentVolumeClaim:
            claimName: test-nfs





#创建pod
[root@m01 /hzl]# kubectl apply -f sc.yaml 
persistentvolumeclaim/test-nfs unchanged
deployment.apps/test-nfs-storageclass unchanged






#查看已挂载(正常绑定)
[root@m01 /hzl]# kubectl get pvc
NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
pvc1       Bound    pv3                                        10Gi       RWX                              13h
test-nfs   Bound    pvc-693904ab-62f6-45b1-8539-bb6d0f8c4053   8Gi        RWX            nfs-storagclass   15m



ps      

【CSI存储机制】

Container Storage Interface(CSI)机制,用于在kubenetes和外部存储系统之间建立一套标准的存储管理接口,通过该接口为容器提供存储服务

1、CSI部署架构

@kubernetes(k8s)数据持久化Volume存储卷(emptyDir、hostPath、NFS、StorageClass)

2、CSI主要包括两个组件:

CSI Controller

CSI Node

【CSI Controller】
#在Pod内部署两个容器:      
【CSI Node】
#在此Pod上部署如下两个容器:

(1)与kubelet通信的辅助sidecar容器node-driver-register,主要功能是将存储驱动注册到kubelet中


(2)CSI Driver存储驱动容器,由第三方存储提供商提供,主要功能是接收kubelet的调用,需要实现一系列与Node相关的CSI接口,例如NodePublishVolume接口(用于将Volume挂载到容器内的目标路径)、NodeUnpublishVolume接口(用于从容器中卸载Volume),等等。






ps :      

继续阅读