zoukankan      html  css  js  c++  java
  • 第九课:kubernetes存储

    概述
    介绍kubernetes中为什么需要使用存储
    volume的基本管理方式
    怎样创建PVC与PV
    结合实际场景怎样使用NFS存储

    1. volume介绍与管理

    pod里面定义的一种属性值
    在dokcer的设计实现中,容器中的数据是临时的,当容器被销毁时,其中的数据将会丢失。如果需要(有状态的服务)持久化数据(集群或者日志),那么就需要使用docker数据卷挂载宿主机上的文件或者目录到容器中。在kubernetes中,当pod重建的时候,数据会丢失,另外,一个pod中同时运行多个容器时,容器之间需要共享文件,所以kubernetes通过数据卷挂载的方式来提供pod数据的持久化。

    1.1 区别于docker的volume

    docker也有volume概念,但对它只有少量且松散的管理。在docker中,volume是磁盘上或者另外一个容器内的目录。虽然docker现在也能提供volume驱动程序,但是目前功能还非常有限(截止docker1.7,每个容器只允许有一个volume驱动程序,并且无法将参数传递给卷,并且支持的存储驱动有限)。

    1.2 声明方式

    使用卷时,Pod声明中需要提供卷的类型(.spec.volumes字段)和卷挂载的位置(.spec.containers.volumeMounts字段)

    1.3 kubernetes中常用支持的卷类型

    目前kubernetes支持的数据全,类型如下:

    类型 说明
    EmptyDir 单节点存储
    HostPath 单节点存储
    GCE Persistent Disk 谷歌云存储
    AWS Elastic Block Store AWS云存储
    NFS 网络文件系统
    iSCSI
    GlusterFS
    RBD ceph块存储
    Persistent Volume Claim(PVC)

    图解volume在kubernetes中的位置
    avator

    1.4 kubernetes哪些资源对象使用volume?

    Pod

    1.3.1 案例一:挂载hostpath到pod

    hostPath 卷能将主机节点文件系统上的文件或目录挂载到您的 Pod 中。
    把主机中的/data/nginx/log目录挂载到pod中的/var/log/nginx目录
    需要在所有节点创建目录/data/nginx/log

    node01&node02
    mkdir -p /data/nginx/log
    
    master01
    mkdir -p /root/volume && cd /root/volume
    cat >demo-mount-hostpath.yaml<<EOF
    apiVersiono: v1
    kind: Pod
    metadata:
      name: pod-hostpath
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-log
          mountPath: /var/log/nginx
      volumes:
      - name: nginx-log
        hostPath:
          path: /data/nginx/log
    EOF
    

    启动nginx服务

    [root@master01 volume]# kubectl apply -f demo-mount-hostpath.yaml 
    pod/pod-hostpath created
    [root@master01 volume]# kubectl get pod -o wide
    NAME                                     READY   STATUS      RESTARTS   AGE     IP             NODE             NOMINATED NODE   READINESS GATES
    pod-hostpath                             1/1     Running     0          20s     172.17.15.13   192.168.68.149   <none>           <none>
    

    启用dnstools容器,测试nginx访问,并在node01上查看日志文件内容

    [root@master01 volume]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
    If you don't see a command prompt, try pressing enter.
    dnstools# curl 172.17.15.13
    
    [root@node01 log]# tail access.log -f
    172.17.15.14 - - [18/Aug/2020:04:15:32 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.60.0" "-"
    

    1.3.2 案例二:挂载空目录到POD

    emptyDir类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当pod从node上移除时,emptyDir中的数据会被永久删除。

    说明:容器崩溃并不会导致Pod从节点上移除,因此容器崩溃时emptyDir卷中的数据是安全的。

    emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。
    Pod示例:

    cat > demo-mount-emptydir.yaml<<EOF
    apiVersiono: v1
    kind: Pod
    metadata:
      name: pod-emptydir
    spec:
      containers:
      - name: test-container
        image: patsys/test-webserver
        volumeMounts:
        - name: cache-volume
          mountPath: /cache
      volumes:
      - name: cache-volume
        emptyDir: {}
    EOF
    

    测试:
    从master上打开新建的pod-emptydir的终端,在/cache目录下创建一个测试文件test.txt,在node01上可以查看到在pod里创建的文件,删除pod以后,文件也被移除。

    [root@master01 volume]# kubectl exec -it nginx-7bb7cd8db5-5h2d5 /bin/sh
    / # cd /cache/
    /cache # ls
    /cache # touch test.txt
    test.txt
    #node01
    find / -name "test.txt"
    /var/lib/kubelet/pods/d80a3125-8b2d-485d-9096-e7053797ee93/volumes/kubernetes.io~empty-dir/cache-volume/test.txt
    
    [root@master01 volume]# kubectl delete -f demo-mount-emptydir.yaml  
    pod "pod-emptydir" deleted
    [root@node01 cache-volume]# find / -name "test.txt"
    [root@node01 cache-volume]# 
    

    2. PersistentVolume 与 Persistent Volume Claim

    2.1 持久卷Persistent Volume(PV)

    PV是由管理员设置的存储卷,它是集群的一部分,就像节点是集群中的资源一样,PV也是集群中的资源。PV是与Vloume类似的卷插件,具有独立的生命周期。

    2.1.1 配置方式

    动态和静态方式
    推荐的方式是使用动态配置

    2.1.2 PV回收策略

    PV可以由多种回收策略,包括“Retain”,“Recycle”,“Delete”。对于动态配置的PV来说,默认回收策略为“Delete”。
    "delete",表示当用户删除对应的PVC的时候,动态配置的volume将自动删除。
    "Retain",如果用户删除PVC,对应的PV不会被删除。相反,它将变成Released状态,表示所有的数据可以被手动恢复。
    "Recycle" 该策略已被弃用。

    2.1.3 列出PV

    [root@master01 volume]# kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS          REASON   AGE
    pvc-957bd492-cf4c-4a01-92b7-c76fded6c538   5Gi        RWX            Delete           Bound    monitoring/prometheus-data   managed-nfs-storage            5d20h
    pvc-a0ff4b83-c9f3-430e-92fb-d95878db0f51   5Gi        RWO            Delete           Bound    monitoring/grafana           managed-nfs-storage            5d20h
    

    2.1.4 修改PV回收策略

    选择PV中的一个并更改它的回收策略

    kubectl patch pv <your-pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
    

    2.1.5 PV的访问模式

    1. ReadWriteOnce:最基本的方式,可读可写单个pod挂载
    2. ReadOnlyMany:可以以只读的方式被多个pod挂载
    3. ReadWriteMany:可以以读写的方式被多个pod挂载
      注意:不是每一种存储都支持这三种方式,如共享方式,目前支持的还不多(数据一致性问题),通常简单的实现为NFS。所以在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

    2.1.6 PV支持的存储驱动

    NFS,ISCSI,RBD,HostPath

    2.2 Persistent Volume Claim(PVC)

    PVC是用户对存储PV的请求,它与POD相似,pod消耗节点资源,PVC消耗PV资源。pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定大小和访问模式(例如:可以以读写一次或者只读多次模式挂载)。集群管理员还可以使用StorageClasses来设置动态提供存储。

    2.2.1 PVC存储挂载过程

    1. 集群管理员创建由物理存储支持的PV。管理员不将卷与任何pod关联。
    2. 集群用户创建一个PVC,它将自动绑定到合适的PV。
    3. 用户创建一个使用PVC作为存储的pod。

    2.2.2 PV与volume的区别

    1. PV只能是网络存储,不属于任何的节点,必须可以在每个节点上可以访问。
    2. PV不是定义在pod上,而是独立于pod,是属于kubernetes存储的一部分。
    3. PV目前支持的类型:NFS,ISCSI,RBD,HostPath
    4. volume与使用它的pod之间是一种静态绑定关系,是定义pod里面的一种属性,同时定义了它使用的volume的类型。
    5. volume无法单独创建,因为它不是独立的kubernetes资源对象。

    2.2.3 案例一:PVC挂载NFS(以部署grafana服务为例)

    2.2.3.1 安装NFS服务

    我们在安装监控的时候已经安装了NFS,并且创建了PV,分别挂载到prometheus和grafana两个服务的POD上。
    创建NFS的过程参考“第六课:部署集群监控系统”

    2.2.3.2 关联NFS到PV

    参考我们之前配置监控服务的时候创建的NFS存储,同时创建的2个PV

    [root@master01 grafana]# kubectl get pv pvc-957bd492-cf4c-4a01-92b7-c76fded6c538 -o yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      annotations:
        pv.kubernetes.io/provisioned-by: fuseim.pri/ifs
      creationTimestamp: "2020-08-13T04:54:09Z"
      finalizers:
      - kubernetes.io/pv-protection
      name: pvc-957bd492-cf4c-4a01-92b7-c76fded6c538
      resourceVersion: "414964"
      selfLink: /api/v1/persistentvolumes/pvc-957bd492-cf4c-4a01-92b7-c76fded6c538
      uid: 9d3e3cb5-76ee-42af-9fe5-93a953c7cbc1
    spec:
      accessModes:
      - ReadWriteMany                            #访问模式[ReadWriteOnce|ReadOnlyMany|ReadWriteMany]
      capacity:                                  #容量
        storage: 5Gi                             #PV可用的大小
      claimRef:
        apiVersion: v1
        kind: PersistentVolumeClaim
        name: prometheus-data
        namespace: monitoring
        resourceVersion: "414957"
        uid: 957bd492-cf4c-4a01-92b7-c76fded6c538
      nfs:                                       #NFS配置
        path: /ifs/kubernetes/monitoring-prometheus-data-pvc-957bd492-cf4c-4a01-92b7-c76fded6c538  #NFS路径
        server: 192.168.68.146                   #NFSserver地址
      persistentVolumeReclaimPolicy: Delete      #回收策略[Delete|Retain|Recycle]
      storageClassName: managed-nfs-storage      #存储类名称
      volumeMode: Filesystem
    status:
      phase: Bound
    

    2.2.3.3 创建PVC

    创建PVC并关联到PV,主要关注点:存储类的名称,访问模式,存储空间请求。

    [root@master01 grafana]# more grafana-pvc.yaml 
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: grafana
      namespace: monitoring
    spec:
      storageClassName: managed-nfs-storage      #存储类名称,与PV文件中spec:storageClassName相对应
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
    

    2.2.3.4 pod关联pvc

    创建使用该PVC的Pod

    [root@master01 grafana]# more grafana-deployment.yaml 
    ...
      seec:
        containers:
          volumes:
          - name: grafana-storage
            persistentVolumeClaim:
              claimName: grafana                 #关联PVC的名称,与PVC.yaml内的metadata:name对应
    

    2.3 StorageClass

    为PVC动态分配PV
    每个StorageClass都有一个分配器,用来决定使用哪个卷插件分配PV。

    2.3.1 StorageClass

    在kubernetes中,用户使用pod需要持久化数据(集群),通常情况下,需要集群管理员手工创建PV,然后用户绑定在POD中,提供给pod中的集群使用。假设在大规模的情况下,如果每次都是需要管理员人工创建PV,那么严重影响效率,所以引入了StorageClass,让PVC通过StorageClass自动创建PV。

    2.3.2 StorageClass支持的卷插件

    1. AWS Elastic Block Store
    2. RBD
    3. Local
    4. GlusterFS
    5. CephFS

    2.3.3 StorageClass创建PV流程

    1. 集群管理员预先创建存储类(storageclass)
    2. 用户创建pod,pod中使用指定存储类的持久化存储声明(PVC)
    3. 存储持久化声明(PVC)通知系统,需要一个持久化存储(PV)
    4. 系统读取存储类信息
    5. 系统基于存储类的信息,在后台自动创建PVC需要的PV
    6. 在后台创建完成PV之后,PVC绑定到PV,进行数据的持久化处理
    7. POD通过PVC持久化存储数据

    2.3.4 案例分析:监控服务存储部署

    1.管理员预先创建存储类storageclass名称为:managed-nfs-class
    每个sotrageclass都包含provisionerparameters,reclaimPolicy字段,这些字段在storageclass需要动态分配PV时会用到。

    [root@master01 nfs]# more nfs-class.yaml 
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: managed-nfs-storage
    provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' 匹配nfs-deployment.yaml中env:name:PROVISIONER_NAME
    parameters:
      archiveOnDelete: "true"
    

    2.创建nfs服务

    [root@master01 nfs]# more nfs-deployment.yaml 
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
    ---
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: nfs-client-provisioner
    spec:
      replicas: 1
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: nfs-client-provisioner
        spec:
          serviceAccountName: nfs-client-provisioner
          containers:
            - name: nfs-client-provisioner
              imagePullPolicy: IfNotPresent
              image: quay.io/external_storage/nfs-client-provisioner:latest
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME   #这里的提供者字段需要与storageclass里的想对应
                  value: fuseim.pri/ifs
                - name: NFS_SERVER
                  value: 192.168.68.146
                - name: NFS_PATH
                  value: /ifs/kubernetes
          volumes:
            - name: nfs-client-root
              nfs:
                server: 192.168.68.146
                path: /ifs/kubernetes
    

    3.声明PVC
    创建pvc名称为grafana,关联存储类stroageclass的名称为前面我们创建的managed-nfs-storage

    [root@master01 grafana]# more grafana-pvc.yaml 
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: grafana
      namespace: monitoring
    spec:
      storageClassName: managed-nfs-storage
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
    

    4.PVC会自动生成一个PV,并绑定到PVC

    [root@master01 grafana]# kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS          REASON   AGE
    pvc-a0ff4b83-c9f3-430e-92fb-d95878db0f51   5Gi        RWO            Delete           Bound    monitoring/grafana           managed-nfs-storage            6d2h
    

    这里的PV名称为pvc-a0ff4b83-c9f3-430e-92fb-d95878db0f51并不是我们手动创建的,而是系统通过PVC在后台自动生成的,并且绑定到名称为grafana的pvc上。
    5.在创建服务的deployment文件中引用PVC

    [root@master01 grafana]# more grafana-deployment.yaml
    ...
        volumes:
          - name: grafana-storage
            persistentVolumeClaim:
              claimName: grafana
    ...
    

    6.启动POD后,数据会持久化到nfs上

    [root@master01 monitoring-grafana-pvc-a0ff4b83-c9f3-430e-92fb-d95878db0f51]# ll
    total 1752
    -rw-r--r-- 1 nfsnobody nfsnobody 1794048 Aug 19 15:01 grafana.db
    drwxr-xr-x 3 nfsnobody nfsnobody      36 Aug 14 14:28 plugins
    drwx------ 2 nfsnobody nfsnobody       6 Aug 13 12:53 png
    
  • 相关阅读:
    输入任意十进制数字,转换为任意进制表示
    Integer 原码解读
    Java 中位移运算符 >>,>>>,<<
    解读源码中的问题
    HashMap 源码解读
    js:插入节点appendChild insertBefore使用方法
    冒泡排序实例
    nodejs学习笔记(2)--Express下安装模版引擎ejs
    nodejs学习笔记(1)--express安装问题:express不是内部也或者外部的命令解决方案
    Jquery取得iframe中元素的几种方法
  • 原文地址:https://www.cnblogs.com/Doc-Yu/p/13552794.html
Copyright © 2011-2022 走看看