本文收录在容器技术学习系列文章总目录

1、认识存储卷

1.1 背景

  默认情况下容器中的磁盘文件是非持久化的,容器中的磁盘的生命周期是短暂的,这就带来了一系列的问题:第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态;第二,当很多容器在同一Pod中运行的时候,很多时候需要数据文件的共享。Kubernete Volume解决了这个问题。

1.2 介绍

  Docker有一个Volumes的概念,虽然这个Volume有点宽松和管理性比较小。在Docker中,一个 Volume 是一个简单的所在主机的一个目录或者其它容器中的。生命周期是没有办法管理,直到最近才有 local-disk-backed 磁盘。Docker现在提供了磁盘驱动,但是功能非常有限(例如Docker1.7只能挂在一个磁盘每个容器,并且无法传递参数)

  从另外一个方面讲,Kubernetes volume,拥有明确的生命周期,与所在的Pod的生命周期相同。因此,Kubernetes volume独立与任何容器,与Pod相关,所以数据在重启的过程中还会保留,当然,如果这个Pod被删除了,那么这些数据也会被删除。更重要的是,Kubernetes volume 支持多种类型,任何容器都可以使用多个Kubernetes volume

  它的核心,一个 volume 就是一个目录,可能包含一些数据,这些数据对pod中的所有容器都是可用的,这个目录怎么使用,什么类型,由什么组成都是由特殊的volume 类型决定的。

  要使用Volume,pod需要指定Volume的类型和内容(spec.volumes字段),和映射到容器的位置(spec.containers.volumeMounts字段)。

  容器中的进程可以看成由Docker镜像和卷组成的文件系统视图。Docker镜像位于文件系统层次结构的根目录下,任何卷都安装在图像中的指定路径上。卷无法装入其他卷或具有到其他卷的硬链接。Pod中的每个容器必须独立指定每个卷的安装位置。

1.3 存储卷常用类型

  • 非持久性存储

    • emptyDir
    • hostPath
  • 网络连接性存储
    • SAN:iSCSI
    • NFS:nfs,cfs
  • 分布式存储
    • glusterfs、rbd、cephfs
  • 云端存储
    • EBS、Azure Disk、阿里云、gitRepo
$ kubectl explain pod.spec.volumes 查询k8s支持的所有类型存储卷

2、emptyDir存储卷

2.1 emptyDir介绍

  使用emptyDir,当Pod分配到Node上时,将会创建emptyDir,并且只要Node上的Pod一直运行,Volume就会一直存。当Pod(不管任何原因)从Node上被删除时,emptyDir也同时会删除,存储的数据也将永久删除。

  常用于作为临时目录、或缓存使用。

2.2 演示:创建emptyDir存储卷

(1)编写yaml文件,并创建

先创建一个名为html的存储卷;再由2个pod都挂载此存储卷;

pod1基于此存储卷作为nginx的主目录;pod2向此存储卷目录写入东西;

[root@master volumes]# vim vol-emptyDir-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-demo
namespace: default
labels:
app: myapp
tier: frontend
annotations:
along.com/created-by: "cluster admin"
spec:
volumes:
- name: html
emptyDir: {}
containers:
- name: myapp
image: ikubernetes/myapp:v1
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"
- "-c"
- "while true; do echo $(date) >> /data/index.html; sleep 2; done"
[root@master volumes]# kubectl apply -f vol-emptyDir-demo.yaml
pod/pod-vol-demo created

  

(2)验证

---pod创建成功
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-vol-demo 2/2 Running 0 13s 10.244.1.106 node1
---访问业务,输出是pod2的输入
[root@master ~]# curl 10.244.1.106
Tue Jan 29 07:19:13 UTC 2019
Tue Jan 29 07:19:15 UTC 2019
Tue Jan 29 07:19:17 UTC 2019
Tue Jan 29 07:19:19 UTC 2019
Tue Jan 29 07:19:21 UTC 2019
Tue Jan 29 07:19:23 UTC 2019
Tue Jan 29 07:19:25 UTC 2019
Tue Jan 29 07:19:27 UTC 2019
Tue Jan 29 07:19:29 UTC 2019

  

3、hostPath存储卷

3.1 emptyDir介绍

  hostPath允许挂载Node(宿主机)上的文件系统到Pod里面去。如果Pod需要使用Node上的文件,可以使用hostPath。

3.2 hostPath类型

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

3.2 演示:创建hostPath存储卷

(1)编写yaml文件,并创建

创建存储卷,使用DirectoryOrCreate类型,node节点不存在会自动创建

[root@master volumes]# vim vol-hostpath-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: vol-hostpath
namespace: default
spec:
volumes:
- name: html
hostPath:
path: /data/pod/volume1/
type: DirectoryOrCreate
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
[root@master volumes]# kubectl apply -f vol-hostpath-demo.yaml
pod/vol-hostpath created

  

(2)查询验证

[root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
vol-hostpath 1/1 Running 0 3s 10.244.1.111 node1
---在node1上查询是否生产目录
[root@node1 ~]# ll -d /data/pod/volume1/index.html
-rw-r--r-- 1 root root 17 Sep 21 14:44 /data/pod/volume1/index.html

  

(3)验证存储卷功能

---在node1上生成文件
[root@node1 ~]# echo "node01.along.com" > /data/pod/volume1/index.html
---访问pod内服务,显示成功
[root@master volumes]# curl 10.244.1.111
node01.along.com

  

(4)就算pod被删除再重建,只要node还在,存储卷就还在

[root@master volumes]# kubectl delete -f vol-hostpath-demo.yaml
pod "vol-hostpath" deleted
[root@master volumes]# kubectl apply -f vol-hostpath-demo.yaml
pod/vol-hostpath created
[root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
vol-hostpath 1/1 Running 0 3s 10.244.1.112 node1
[root@master volumes]# curl 10.244.1.112
node01.along.com

  

4、共享存储NFS存储卷

4.1 NFS存储卷介绍

  NFS 是Network File System的缩写,即网络文件系统。Kubernetes中通过简单地配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持同时写操作。Pod被删除时,Volume被卸载,内容被保留。这就意味着NFS能够允许我们提前对数据进行处理,而且这些数据可以在Pod之间相互传递。

4.2 演示:创建NFS存储卷

4.2.1 在一台服务器搭建NFS

(1)事前准备

① 修改k8s集群服务的hosts文件,使之能解析nfs服务器

[root@master volumes]# vim /etc/hosts
192.168.130.103 master
192.168.130.104 node1
192.168.130.105 node2
192.168.130.106 nfs

② 在k8s集群服务器,安装nfs-utils 工具

$ yum -y install nfs-utils

  

(2)在106服务器上提供nfs服务

[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# mkdir /data/volumes -p
[root@nfs ~]# vim /data/volumes/index.html
<h1>NFS stor</h1>
[root@nfs ~]# vim /etc/exports
/data/volumes 192.168.130.0/24(rw,no_root_squash)
[root@nfs ~]# systemctl start nfs

  

4.2.1 创建NFS存储卷

(1)编写yaml文件,并创建

[root@master volumes]# vim vol-nfs-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: vol-nfs
namespace: default
spec:
volumes:
- name: html
nfs:
path: /data/volumes
server: nfs
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
[root@master volumes]# kubectl apply -f vol-nfs-demo.yaml
pod/vol-nfs created

  

(2)验证,访问服务成功

[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
vol-nfs 1/1 Running 0 9s 10.244.1.115 node1
[root@master ~]# curl 10.244.1.115
<h1>NFS stor</h1>

删除pod,再创建,也还存在数据。

5、一些不常用的存储卷

5.1 gitRepo

(1)介绍

gitRepo volume将git代码下拉到指定的容器路径中

(2)示例

apiVersion: v1
kind: Pod
metadata:
name: server
spec:
volumes:
- name: git-volume
gitRepo:
repository: "git@github.com:alonghub/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
volumeMounts:
- name: git-volume
mountPath: /usr/share/nginx/html/

  

5.2 glusterfs

  glusterfs,允许将Glusterfs(一个开源网络文件系统)Volume安装到pod中。不同于emptyDir,Pod被删除时,Volume只是被卸载,内容被保留。味着glusterfs能够允许我们提前对数据进行处理,而且这些数据可以在Pod之间“切换”。

  注意::必须先运行自己的GlusterFS安装,然后才能使用它。

  有关更多详细信息,请参阅GlusterFS示例

5.3 RBD

  RBD允许Rados Block Device格式的磁盘挂载到Pod中,同样的,当pod被删除的时候,rbd也仅仅是被卸载,内容保留,rbd能够允许我们提前对数据进行处理,而且这些数据可以在Pod之间“切换”。

  有关更多详细信息,请参阅RBD示例

5.4 cephfs

  cephfs Volume可以将已经存在的CephFS Volume挂载到pod中,与emptyDir特点不同,pod被删除的时,cephfs仅被被卸载,内容保留。cephfs能够允许我们提前对数据进行处理,而且这些数据可以在Pod之间“切换”。

  提示:可以使用自己的Ceph服务器运行导出,然后在使用cephfs。

  有关更多详细信息,请参阅CephFS示例

kubernetes系列10—存储卷详解的更多相关文章

  1. Kubernetes K8S之存储ConfigMap详解

    K8S之存储ConfigMap概述与说明,并详解常用ConfigMap示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS ...

  2. Kubernetes K8S之存储Volume详解

    K8S之存储Volume概述与说明,并详解常用Volume示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

  3. Docker系列05—Docker 存储卷详解

    本文收录在容器技术学习系列文章总目录 1.存储卷介绍 1.1 背景 (1)docker 的 AFUS 分层文件系统 docker镜像由多个只读层叠加面成,启动容器时,docker会加载只读镜像层并在镜 ...

  4. kubernetes系列07—Pod控制器详解

    本文收录在容器技术学习系列文章总目录 1.Pod控制器 1.1 介绍 Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无 ...

  5. Kubernetes K8S之存储Secret详解

    K8S之存储Secret概述与类型说明,并详解常用Secret示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 ...

  6. kubernetes系列08—service资源详解

    本文收录在容器技术学习系列文章总目录 1.认识service 1.1 为什么要使用service Kubernetes Pod 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结 ...

  7. kubernetes系列09—Ingress控制器详解

    本文收录在容器技术学习系列文章总目录 1.认识Ingress 1.1 什么是Ingress? 通常情况下,service和pod仅可在集群内部网络中通过IP地址访问.所有到达边界路由器的流量或被丢弃或 ...

  8. Kubernetes 存储卷详解

    转载自:https://mp.weixin.qq.com/s/Ywx3ju6FP0IShOgI757XYA Volumes 默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说面临两个问 ...

  9. Java容器解析系列(10) Map AbstractMap 详解

    前面介绍了List和Queue相关源码,这篇开始,我们先来学习一种java集合中的除Collection外的另一个分支------Map,这一分支的类图结构如下: 这里为什么不先介绍Set相关:因为很 ...

随机推荐

  1. BZOJ_4378_[POI2015]Logistyka_树状数组

    BZOJ_4378_[POI2015]Logistyka_树状数组 Description 维护一个长度为n的序列,一开始都是0,支持以下两种操作: 1.U k a 将序列中第k个数修改为a. 2.Z ...

  2. 在CentOS下安装Git

    1.安装git依赖包 yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUti ...

  3. Python 魔术方法笔记

    魔术方法总是被__包围, 如__init__ , __len__都是常见的魔术方法,这里主要写一下我遇到的一些魔术方法 setitem 对某个索引值赋值时 即可以进行赋值操作,如 def __seti ...

  4. im2col:将卷积运算转为矩阵相乘

    目录 im2col实现 优缺点分析 参考 博客:blog.shinelee.me | 博客园 | CSDN im2col实现 如何将卷积运算转为矩阵相乘?直接看下面这张图,以下图片来自论文High P ...

  5. Netbeans IDE 安装Emmet插件并解决Emmet插件无效果问题

    Emmet是许多流行文本编辑器的插件,它极大地改进了HTML和CSS工作流程:在Netbeans IDE 下安装Emmet:1.打开Netbeans IDE编辑器,选择 工具—>插件选项,在 可 ...

  6. Python基础面试,看这篇文章画重点吧,Python面试题No1

    为什么有这个系列的文章 一直想写一些更加基础的文章,但是总是想不到好的点子,最近到了就业季,一大堆学生面临就业了,正好,从Python的面试题出发,分析和解答一些常见的面试题,并且总结一些文字. 每一 ...

  7. SpringBoot进阶教程(二十八)整合Redis事物

    Redis默认情况下,事务支持被禁用,必须通过设置setEnableTransactionSupport(true)为使用中的每个redistplate显式启用.这样做会强制将当前重新连接绑定到触发m ...

  8. Asp.Net Core对接钉钉群机器人

    钉钉作为企业办公越来越常用的软件,对于企业内部自研系统提供接口支持,以此来打通多平台下的数据,本次先使用最简单的钉钉群机器人完成多种形式的消息推送,参考钉钉开发文档中自定义机器人环节,此次尝试所花的时 ...

  9. .NETCore 千星项目模块化开发框架 SimplCommerce 详解

    SimplCommerce 是 github 上过千星的.netcore 商城示例项目,本文详解他的模块化框架现实思路,其业务(如产品.订单)不作介绍.因作者文笔水平很差,它又很值得学习和推荐,就算不 ...

  10. Group Convolution分组卷积,以及Depthwise Convolution和Global Depthwise Convolution

    目录 写在前面 Convolution VS Group Convolution Group Convolution的用途 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在 ...