一、Volume介绍:

 在k8s中Pod的生命周期可能很短,会被频繁地销毁和创建。容器销毁时,保存在容器内部文件系统中的数据都会被清除。

 为了持久化保存容器数据,k8s 提供了卷(Volume)的抽象概念来解决上述问题。

 卷(Volume)的核心是一个目录,其中可能存有数据,Pod 中的容器可以访问该目录中的数据。 所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。

 Kubernetes Volume 支持多种卷类型,包括 emptyDir、hostPath、nfs、local、configMap、AWSElasticBlockStore、Cinder、CSI等。

 按照存储可大概划分为:

  

  临时存储:emptydir   

  半持久化存储:hostpath

  持久化存储:nfs、ceph、Cinder等

 接下来分别介绍几种常用类型:emptyDir、hostPath、nfs(PV、PVC)

二、Volume:emptyDir

 emptyDir 是最基础的 Volume 类型。正如其名字所示,一个 emptyDir Volume 是 Host 上的一个空目录。

 emptyDir Volume 对于容器来说是持久的,对于 Pod 则不是。当 Pod 从节点删除时,Volume 的内容也会被删除。但如果只是容器被销毁而 Pod 还在,则 Volume 不受影响。(emptyDir Volume 的生命周期与 Pod 一致

 Pod 中的所有容器都可以共享 Volume,它们可以指定各自的挂载路径。

 验证示例:

apiVersion: v1
kind: Pod
metadata:
name: producer-consumer
spec:
containers:
- image: busybox
name: producer
volumeMounts:
- mountPath: /producer_dir #挂载到容器中的路径
name: shared-volume
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello; sleep 3000
- image: busybox
name: consumer
volumeMounts:
- mountPath: /consumer_dir #挂载到容器中的路径
name: shared-volume
args:
- /bin/sh
- -c
- cat /consumer_dir/hello; sleep 3000
volumes:
- name: shared-volume
emptyDir: {} #指定存储方式为emptydir
  1. 创建一个名为[shared-volume]的emptyDir的卷
  2. 容器producer 将 shared-volume挂载到 producer_dir 目录
  3. 容器producer 通过echo 命令向hello 文件中写入文本-hello world
  4. 容器consumer 将 shared-volume挂载到 consumer_dir目录
  5. 容器consumer 通过cat命令读取consumer_dir中hello文件内容

  通过命令:kubectl logs 查看读取内容。

# 输出producer-consumer Pod中容器 consumer 的日志:
kubectl logs producer-consumer -c consumer
hello world

  显示容器 consumer 成功读取到 producer 写入的数据,验证了两个容器共享 emptyDir Volume。

三、Volume:hostPath

 hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大应急方式。

 hostPath 的一些用法有:

  • 运行一个需要访问 Docker 内部机制的容器;可使用 hostPath 挂载 /var/lib/docker 路径。
  • 在容器中运行 cAdvisor 时,以 hostPath 方式挂载 /sys
  • 允许 Pod 指定给定的 hostPath 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。

 除了必需的 path 属性之外,用户可以选择性地为 hostPath 卷指定 type,下表为type取值

取值 行为
  空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory 在给定路径上必须存在的目录。
FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File 在给定路径上必须存在的文件。
Socket 在给定路径上必须存在的 UNIX 套接字。
CharDevice 在给定路径上必须存在的字符设备。
BlockDevice 在给定路径上必须存在的块设备。

 hostPath示例:

apiVersion: v1
kind: Pod
metadata:
name: localpod
spec:
containers:
- image: busybox
name: local
volumeMounts:
- mountPath: /localdir #挂载到容器中的路径
name: mydir
- mountPath: loacl.txt
name: myfile
args:
- /bin/sh
- -c
- echo "local dir test" > /localdir/test.txt;
- -c
- cat loacl.txt;
volumes:
- name: mydir
hostPath:
# 确保文件所在目录成功创建。
path: /var/local
type: DirectoryOrCreate
- name: myfile
hostPath:
# 确保文件创建成功
path: /var/local/test.txt
type: FileOrCreate

  步骤:

   1、创建两个hostPath类型的Volume

   2、将这两个卷都挂载到local容器中

   3、容器启动时,写入文件内容“local dir test”,并读取出来。

四、Volume:持久化存储-nfs

 说到持久化存储:就需要提k8s中提供的重要的几种资源类型:

  • PersistentVolume (PV): 外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。
  • StorageClass:另外一种提供存储资源的方式, 提供更多的层级选型, 如iops等参数。 但是具体的参数与提供方是绑定的。 如aws和gce它们提供的storageclass的参数可选项是有不同的。
  • PersistentVolumeClaim (PVC):是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。

 PersistentVolume :

 生命周期:

  • Provisioning- 配置阶段, 分为static, dynamic两种方式。静态的方式是创建一系列的pv,然后pvc从pv中请求。 动态的方式是基于storageclass的。
  • Binding - 绑定阶段, pvc根据请求的条件筛选并绑定对应的pv。 一定pvc绑定pv后, 就会排斥其它绑定,即其它pvc无法再绑定同一个pv,即使这个pv设定的access mode允许多个node读写。 此外 ,pvc 如何匹配不到相应条件的pv, 那么就会显示unbound状态, 直到匹配为止。 需要注意的是,pvc请求100Gi大小的存储,即使用户创建了很多50Gi大小的存储, 也是无法被匹配的。
  • Using- 使用阶段, pods 挂载存储, 即在pod的template文件中定义volumn使用某个pvc。
  • Releasing - 释放阶段, 当pvc对象被删除后, 就处于释放阶段。 在这个阶段, 使用的pv还不能被其它的pvc请求。 之前数据可能还会留存下来, 取决于用户在pv中设定的policy, 见persistentVolumeReclaimPolicy。
  • Reclaiming - 重声明阶段。 到这个阶段, 会告诉cluster如何处理释放的pv。 数据可能被保留(需要手工清除), 回收和删除。动态分配的存储总是会被删除掉的。
  • Recycling - 回收阶段。回收阶段会执行基本的递归删除(取决于volumn plugins的支持),把pv上的数据删除掉, 以使pv可以被新的pvc请求。 用户也可以自定义一个 recycler pod , 对数据进行删除。

 卷模式:

  PV支持两种卷模式:

  • Filesystem  :卷会被 Pod 挂载(Mount) 到某个目录。 如果卷的存储来自某块设备而该设备目前为空,Kuberneretes 会在第一次挂载卷之前 在设备上创建文件系统。
  • Block:将卷作为原始块设备来使用。 这类卷以块设备的方式交给 Pod 使用,其上没有任何文件系统。 这种模式对于为 Pod 提供一种使用最快可能方式来访问卷而言很有帮助,Pod 和 卷之间不存在文件系统层。另外,Pod 中运行的应用必须知道如何处理原始块设备。

 访问模式:

  PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为 对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器 上以只读的方式导出。每个 PV 卷都会获得自身的访问模式集合,描述的是 特定 PV 卷的能力。

访问模式有:

    • ReadWriteOnce (RWO)  -- 卷可以被一个节点以读写方式挂载;
    • ReadOnlyMany (ROX)    -- 卷可以被多个节点以只读方式挂载;
    • ReadWriteMany (RWX)  -- 卷可以被多个节点以读写方式挂载
卷插件 ReadWriteOnce ReadOnlyMany ReadWriteMany
AWSElasticBlockStore - -
AzureFile
AzureDisk - -
CephFS
Cinder - -
CSI 取决于驱动 取决于驱动 取决于驱动
FC -
FlexVolume 取决于驱动
Flocker - -
GCEPersistentDisk -
Glusterfs
HostPath - -
iSCSI -
Quobyte
NFS
RBD -
VsphereVolume - - (Pod 运行于同一节点上时可行)
PortworxVolume -
ScaleIO -
StorageOS - -

 回收策略:

  目前的回收策略有:

  • Retain -- 手动回收
  • Recycle -- 基本擦除 (rm -rf /thevolume/*)
  • Delete -- 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除

  目前,仅 NFS 和 HostPath 支持回收(Recycle)。 AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持删除(Delete)

 持久化存储验证:

  1、nfs服务搭建:

 所有节点安装nfs

yum install -y nfs-common nfs-utils 

 在master节点创建共享目录

[root@k8s-master k8s]# mkdir /nfsdata

 授权共享目录

[root@k8s-master k8s]# chmod 666 /nfsdata

 编辑exports文件

[root@k8s-master k8s]# cat /etc/exports
/nfsdata *(rw,no_root_squash,no_all_squash,sync)

 配置生效

[root@k8s-master k8s]# export -r

 启动rpc和nfs(注意顺序)

[root@k8s-master k8s]# systemctl start rpcbind
[root@k8s-master k8s]# systemctl start nfs

2、创建PV:

#创建Pv:name-pv01
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
labels:
name: pv01
spec:
# 所有节点可共享访问
accessModes: ["ReadWriteMany"]
# 回收策略:清除PV数据
persistentVolumeReclaimPolicy:Recycle
# 指定PV的Class为 nfs
storageClassName:nfs
capacity:
# Pv大小1G
storage: 1Gi
#nfs 服务设置,以及目录设置
nfs:
server: 192.168.115.6
path: /home

  3、创建PVC:

#创建名为mypvc的PVC
apiVersion: v1
kind: PersisitentVolumeClaim
metadata:
name: mypvc
namespace: default
spec:
accessmodes: ["ReadWriteMany"] #所有节点可读写
resources: #指定资源说明
requests: #指定请求
storage: 4Gi #指定请求存储空间的大小   

  4、创建POD使用PVC

#创建Pod并使用PVC
apiVersion: v1
kind: Pod
metadata:
name: pvnginx
labels:
app: pvnginx
spec:
containers:
- name: my-pvnginx
image: nginx
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
volumeMounts:
- name: html
mountPath: /data/html
volumes:
- name: html
persistentVolumeClaim: #指明使用pvc模式
claimname: mypvc #指明使用的pvc名称

总结:  

 1、对于不需要持久化的数据可采用emptyDir类型卷来存储相关数据,其生命周期同Pod相同

 2、当需要访问当前主机文件时,可以采用hostPath类型的卷来实现

 3、PV、PVC在实际场景中应用较多,需要了解透彻:包括PV的动/静态创建、PVC、生命周期等基本概念

参考:

  https://kubernetes.io/zh/docs/concepts/storage/

https://kubernetes.io/zh/docs/concepts/storage/

入门Kubernetes-数据存储的更多相关文章

  1. Kubernetes 持久化数据存储 StorageClass

    文章链接 PV 和 PVC 模式要先创建好 PV,然后再定义好 PVC 进行一对一的绑定.那么如果遇到大集群,也一一的创建吗?这样来说维护成本很高,工作量大.这个时候就有了 Kubernetes 提供 ...

  2. ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调

    近期项目中可能要用到Flash存取数据,并与JS互调,所以就看了一下ActionScript 3.0,现把学习结果分享一下,希望对新手有帮助. 目录 ActionScript 3.0简介 Hello ...

  3. [转]ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调

    本文转自:http://www.cnblogs.com/artwl/p/3396330.html 近期项目中可能要用到Flash存取数据,并与JS互调,所以就看了一下ActionScript 3.0, ...

  4. android入门——数据存储

    首先是SharedPreferences 用户偏好 package com.example.wkp.aboutdata; import android.content.Intent; import a ...

  5. 【Android开发日记】之入门篇(七)——Android数据存储(上)

    在讲解Android的数据源组件——ContentProvider之前我觉得很有必要先弄清楚Android的数据结构. 数据和程序是应用构成的两个核心要素,数据存储永远是应用开发中最重要的主题之一,也 ...

  6. 【Android开发日记】之入门篇(八)——Android数据存储(下)

    废话不多说了,紧接着来讲数据库的操作吧.Come On! 提到数据存储问题,数据库是不得不提的.数据库是用来存储关系型数据的不二利器.Android为开发者提供了强大的数据库支持,可以用来轻松地构造基 ...

  7. [转帖]新手必读,16个概念入门 Kubernetes

    新手必读,16个概念入门 Kubernetes https://www.kubernetes.org.cn/5906.html 2019-09-29 22:13 中文社区 分类:Kubernetes教 ...

  8. iOS开发技术分享(1)— iOS本地数据存储

    iOS开发技术分享(1)— iOS本地数据存储 前言: 我本是一名asp.net程序员,后来加入了iOS游戏开发队伍,到现在也有一年多的时间了.这一年来,每天都干到2.3点钟才睡觉,不为别的,只为了学 ...

  9. iOS数据存储

    [reference]http://www.infoq.com/cn/articles/data-storage-in-ios 谈到数据储存,首先要明确区分两个概念,数据结构和储存方式.所谓数据结构就 ...

  10. 使用百度云 BOS 和 C# SDK 开发数据存储

    Ø  简介 本文主要介绍如何使用百度云的 C# SDK 操作 BOS(Baidu Object Storage/百度对象存储),以及常见问题和解决办法.本文将以以下几点展开学习: 1.   基本介绍 ...

随机推荐

  1. 基于 Spring Security 的前后端分离的权限控制系统

    话不多说,入正题.一个简单的权限控制系统需要考虑的问题如下: 权限如何加载 权限匹配规则 登录 1.  引入maven依赖 1 <?xml version="1.0" enc ...

  2. Java实现适配器模式

    适配器模式(Adapter) 适配器模式涉及到3个角色:要被适配的接口,适配器,目标接口 适配器的工作就是将被适配的接口转换为目标接口 "鸭子类型"就是一个典型的适配器模式:如果它 ...

  3. unity调用安卓方法实现安装apk文件(androidx)

    原文链接:点击打开 unity想要实现安装apk文件需要与安卓通讯,所以需要自己来实现安卓代码. 第一步先要新建一个安卓项目提供给unity来使用,我这里使用的工具是android studio4.1 ...

  4. 7、resync实时备份

    sersync+rsync(增量,无差异备份),resync支持多线程,效果比inotify更好,配置思想和inotify很相似 7.1.在备份服务器上安装并配置rsync服务,实现nfs共享目录,可 ...

  5. Docker搭建EFK日志收集系统,并自定义es索引名

    EFK架构图 一.EFK简介 EFK不是一个软件,而是一套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用,是目前主流的一种日志系统. EFK是三个开源软件的缩写,分 ...

  6. 安卓手机改造服务器——基本环境配置(CentOS7 arm32)

    安装好CentOS系统之后,我们需要对环境进行一些基本的配置,让Linux更好用 写在前面 注意:本文章是针对arm32的CentOS7进行配置的,其他系统或不同架构不要尝试. 配置yum镜像源 1. ...

  7. Network:java中文转byte出现负数问题

    字节的释义 字节(Byte) 是计算机信息技术用于计量存储容量的一种计量单位,通常情况下 1字节 = 8位(bit),也表示一些计算机编程语言中的数据类型和语言字符. 字符与字节 ASCII码:1个英 ...

  8. java -jar 运行springboot项目时内存设置

    java -Xms64m #JVM启动时的初始堆大小 -Xmx128m #最大堆大小 -Xmn64m #年轻代的大小,其余的空间是老年代 -XX:MaxMetaspaceSize=128m # -XX ...

  9. LeetCode周赛5214

    我去,暴力超时,没啥人情味了.难受,一看答案,结果是dp的题目... 思路分析: 1.用个表记录下每个数当前的最大长度,同时是等差,说明有上一个数,那么当前的长度就是上一个数最大加一

  10. HDU2050

    思路分析,被我写到分割问题里面.可以去看看. 贴下代码