zoukankan      html  css  js  c++  java
  • k8s之存储卷及pvc

    1.存储卷概述

      因为pod是有生命周期的,pod一重启,里面的数据就没了,所以我们需要数据持久化存储,在k8s中,存储卷不属于容器,而是属于pod,也就是说同一个pod中的容器可以共享一个存储卷,存储卷可以是宿主机上的目录,也可以是挂载在宿主机上的外部设备.

    存储卷类型:

    emptyDIR存储卷:pod一重启,存储卷也删除,这叫emptyDir存储卷,一般用于当做临时空间或缓存关系;

    hostPath存储卷:宿主机上目录作为存储卷,这种也不是真正意义实现了数据持久性;

    SAN(iscsi)或NAS(nfs、cifs):网络存储设备;

    分布式存储:ceph,glusterfs,cephfs,rbd

    云存储:亚马逊的EBS,Azure Disk,阿里云,关键数据一定要有异地备份

    a.emptyDIR存储卷

    vim podtest/pod-vol-demo.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-demo
      namespace: default
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      - name: busybox
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: html
          mountPath: /data/
        command: ["/bin/sh"]
        args: ["-c","while true;do echo $(date) >> /data/index.html; sleep 10;done"]
      volumes:
      - name: html
        emptyDir: {}
    
    volumeMounts:把哪个存储卷挂到pod中的哪个目录下
    emptyDir:不设置意味着对这个参数下的两个选项不做限制
    

    b.hostPath:使用宿主机上目录作为存储卷

    kubectl explain pods.spec.volumes.hostPath.type
    DirectoryOrCreate:要挂载的路径是一个目录,不存在就创建目录;
    Directory:宿主机上必须实现存在目录,如果不存在就报错;
    FileOrCreate:表示挂载的是文件,如果不存在就创建;
    File:表示要挂载的文件必须事先存在,否则就报错.
    
    cat pod-hostpath-vol.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-vol-hostpath
      namespace: default
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: html
        hostPath:
          path: /data/pod/volume1
          type: DirectoryOrCreate
    
    hostPath:宿主机上的目录.
    volumes的名字可以随便取,这是存储卷的名字,但是上面的volumeMounts指定时,
    name必须和存储卷的名字一致,这样两者才建立了联系.
    

    c.nfs做共享存储

    这里为了方便,把master节点当做nfs存储,三个节点均执行
    yum -y install nfs-utils  # 然后在master上启动nfs
    mkdir /data/volumes
    cat /etc/exports
    /data/volumes 10.0.0.0/16(rw,no_root_squash)
    systemctl start nfs
    在node1和node2上试挂载
    mount -t nfs k8s-master:/data/volumes /mnt
    cat pod-vol-nfs.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-vol-nfs
      namespace: default
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: html
        nfs:
          path: /data/volumes
          server: k8s-master
    
    kubectl apply -f pod-vol-nfs.yaml
    此时不管pod被建立在哪个节点上,对应节点上是不存放数据的,数据都在nfs主机上
    

    d.pvc和pv

      用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现.pvc和pv的关系与pod和node关系类似,前者消耗后者的资源,pvc可以向pv申请指定大小的存储资源并设置访问模式.

    在定义pod时,我们只需要说明我们要一个多大的存储卷就行了,pvc存储卷必须与当前namespace的pvc建立直接绑定关系,pvc必须与pv建立绑定关系,而pv是真正的某个存储设备上的空间.

    一个pvc和pv是一一对应关系,一旦一个pv被一个pvc绑定了,那么这个pv就不能被其他pvc绑定了,一个pvc是可以被多个pod所访问的,pvc在名称空间中,pv是集群级别的.

    将master作为存储节点,创建挂载目录

    cd /data/volumes && mkdir v{1,2,3,4,5}
    cat  /etc/exports
    /data/volumes/v1 10.0.0.0/16(rw,no_root_squash)
    /data/volumes/v2 10.0.0.0/16(rw,no_root_squash)
    /data/volumes/v3 10.0.0.0/16(rw,no_root_squash)
    exportfs -arv
    showmount -e
    kubectl explain pv.spec.nfs
    
    accessModes模式有:
    ReadWriteOnce:单路读写,可以简写为RWO;
    ReadOnlyMany:多路只读,可以简写为ROX;
    ReadWriteMany:多路读写,可以简写为RWX 
    
    # 先将存储设备定义为pv
    cat pv-demo.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv001 # 定义pv时不用加名称空间,因为pv是集群级别
      labels:
        name: pv001
    spec:
      nfs:
        path: /data/volumes/v1
        server: k8s-master
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity: # 分配磁盘空间大小
        storage: 3Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv002
      labels:
        name: pv002
    spec:
      nfs:
        path: /data/volumes/v2
        server: k8s-master
      accessModes: ["ReadWriteOnce"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv003
      labels:
        name: pv003
    spec:
      nfs:
        path: /data/volumes/v3
        server: k8s-master
      accessModes: ["ReadWriteMany","ReadWriteOnce"]
      capacity:
        storage: 8Gi
    
    kubectl apply -f pv-demo.yaml
    kubectl get pv
    NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   
    pv001     3Gi        RWO,RWX        Retain           Available
    pv002     5Gi        RWO            Retain           Available
    pv003     8Gi        RWO,RWX        Retain           Available
    

    回收策略:

    如果某个pvc在pv里面存数据了,后来pvc删了,那么pv里面的数据怎么处理

    reclaim_policy:即pvc删了,但pv里面的数据不删除,还保留着;

    recycle:即pvc删了,那么就把pv里面的数据也删了;

    delete:即pvc删了,那么就把pv也删了.

    # 创建pvc的清单文件
    kubectl explain pods.spec.volumes.persistentVolumeClaim
    cat pod-vol-pvc.yaml 
    apiVersion: v1
    kind: PersistentVolumeClaim # 简称pvc
    metadata:
      name: mypvc
      namespace: default # pvc和pod在同一个名称空间
    spec:
      accessModes: ["ReadWriteMany"] # 一定是pv策略的子集
      resources:
        requests:
          storage: 7Gi # 申请一个大小至少为7G的pv
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-vol-pvc
      namespace: default
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        volumeMounts:
        - name: html # 使用的存储卷的名字
          mountPath: /usr/share/nginx/html/ #挂载路径
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: mypvc # 表示要使用哪个pvc
    

    所以pod的存储卷类型如果是pvc,则:pod指定的pvc需要先匹配一个pv,才能被pod所挂载,在k8s 1.10之后,不能手工从底层删除pv.

    参考博客:http://blog.itpub.net/28916011/viewspace-2214804/

  • 相关阅读:
    js上传文件
    IOS怎么实现一个UITableView的下拉刷新
    Android的事件处理-android学习之旅(四十四)
    NIO框架之MINA源代码解析(二):mina核心引擎
    每日五题
    Joda-Time 简介
    用websocket实现后台推送消息
    websoclet简单示例 my 改
    struts2拦截器interceptor的配置方法及使用
    activiti复盘重推的一种简单实现方式:
  • 原文地址:https://www.cnblogs.com/fawaikuangtu123/p/11031171.html
Copyright © 2011-2022 走看看