Kubernetes学习笔记(五):卷
简介
卷是Pod的一部分,与Pod共享生命周期。它不是独立的Kubernetes对象,因此不能单独创建。
卷提供的存储功能不但可以解决容器重启后数据丢失的问题,还可以使数据在容器间共享。
一些卷的类型:
- emptyDir:用于存储临时数据的空目录
- hostPath:用于将目录从工作节点挂载到pod
- gitRepo:通过检出Git仓库的内容来初始化的卷
- nfs:挂载到pod中的nfs共享卷
- configMap、secret、downwardAPI:用于将Kubernetes部分资源和集群信息公开给pod的特殊类型的卷
- persistentVolumeClaim:一种使用预置或者动态配置的持久存储类型
单个容器可以同时使用不同类型的多个卷。
emptyDir
emptyDir卷对于在同一个pod中运行的容器之间共享文件特别有用。但也可以被单个容器用于将数据临时写入磁盘。
下面的例子中,Pod包含两个容器,这个两个容器分别将卷html挂载到容器内的不同路径,实现了文件共享。html-generator每隔一秒写入当前时间到index.html,web-server提供web服务使index.html可以被访问。
# volume-share-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-share
spec:
containers:
- image: alpine # 容器镜像一
name: html-generator
volumeMounts: # 将名为html的卷挂载到容器的/var/html
- name: html
mountPath: /var/html
command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"]
- image: nginx:alpine #容器镜像二
name: web-server
volumeMounts: # 与上面相同的卷卷挂载到容器的/usr/share/nginx/html
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
volumes: # 创建一个名为html的卷
- name: html
emptyDir: {}
创建pod,设置端口转发
-> [root@kube0.vm] [~] k create -f volume-share-pod.yaml
pod/volume-share created
-> [root@kube0.vm] [~] k port-forward volume-share 80:80
Forwarding from 127.0.0.1:80 -> 80
Forwarding from [::1]:80 -> 80
发出请求
-> [root@kube0.vm] [~] curl http://localhost
Sun May 24 01:14:48 UTC 2020
-> [root@kube0.vm] [~] curl http://localhost
Sun May 24 01:14:49 UTC 2020
如果进行下面的改动,emptyDir的内容会存在内存中
volumes:
- name: html
emptyDir:
medium: Memory
gitRepo
gitRepo卷基本上也是一个emptyDir卷,它在容器启动前从git仓库检出填充数据。
当git仓库内容发生改变时,对已存在的Pod内的gitRepo卷是不可见的。但启动新的Pod时会检出最新的。
下面的例子中,该pod创建了一个名为html的gitRepo卷的,创建一个提供web服务的容器web-server,并将卷html挂载到web-server的/usr/share/nginx/html。
# volume-gitrepo-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-gitrepo
spec:
containers:
- image: nginx:alpine
name: web-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
volumes: # 创建一个名为html的gitRepo卷
- name: html
gitRepo:
repository: https://github.com/orccn/kube-dockerfile.git # 仓库地址
revision: master # 分支
directory: . # 检出到卷的根目录
创建pod,设置端口转发
-> [root@kube0.vm] [~] k create -f volume-gitrepo-pod.yaml
pod/volume-gitrepo created
-> [root@kube0.vm] [~] k port-forward volume-gitrepo 80:80
Forwarding from 127.0.0.1:80 -> 80
Forwarding from [::1]:80 -> 80
发出请求
-> [root@kube0.vm] [~] curl http://localhost/etcd/Dockerfile
FROM k8s.gcr.io/etcd:3.4.3-0
hostPath
hostPath卷提供的是映射到工作节点本地的持久存储。所以应仅当需要在工作节点上读写文件时才使用hostPath
下例中,Pod中创建一个名为html的hostPath卷挂载到工作节点的 /tmp/html,容器volume-hostpath将卷html挂载到/var/html,并且向其中写入文件。
# volume-hostpath-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-hostpath
spec:
containers:
- image: alpine
name: volume-hostpath
command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"]
volumeMounts:
- name: html
mountPath: /var/html
volumes:
- name: html
hostPath:
path: /tmp/html
创建volume-hostpath,查看其部署在哪个节点。
-> [root@kube0.vm] [~] k create -f volume-hostpath-pod.yaml
pod/volume-hostpath created
-> [root@kube0.vm] [~] k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
volume-hostpath 1/1 Running 0 9m32s 10.244.1.11 kube1.vm <none> <none>
进入节点kube1.vm
-> [root@kube1.vm] [~] cat /tmp/html/index.html
Sun May 24 02:26:14 UTC 2020
PV与PVC
PV(PersistentVolume持久卷)也是一种资源,并且不属于任何命名空间。它的功能与卷类似,但是它的生命周期是独立于Pod的。PV由集群管理员创建,并被Pod通过PVC(PersistentVolumeClaim,持久卷声明)使用。
在创建PV时,管理员可以指定其大小和支持的访问模式:
- ReadWriteOnce(RWO):仅允许单个节点挂载读写
- ReadOnlyMany(ROX):允许多个节点挂载只读
- ReadWriteMany(RWX):允许多个节点挂载读写
一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。
创建PV
管理员在创建PV时需要指定,PV的大小、访问模式、实际存储类型、路径等。
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
capacity:
storage: 10Mi # 定义大小
accessModes: # 支持单个客户端挂在为读写模式或者多个客户端只读模式
- ReadWriteOnce
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain # 当声明被释放后,PV将被保留
hostPath:
path: /tmp/pv
条件有限,所以存储类型只能先选hostPath用着,接下来创建pv并查看
-> [root@kube0.vm] [~] k create -f pv.yaml
persistentvolume/volume-pv created
-> [root@kube0.vm] [~] k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv 10Mi RWO,ROX Retain Available 4s
创建PVC
假设要部署一个需要持久化存储的Pod,将要用到持久卷,但是不能在Pod中直接使用,需要先声明一个。
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
resources:
requests:
storage: 10Mi
accessModes:
- ReadWriteOnce
storageClassName: ""
PVC创建好后,Kubernetes会寻找适当的PV将其绑定到PVC。持久卷必须要足够大,并且包含声明中指定的访问模式。
-> [root@kube0.vm] [~] k create -f pvc.yaml
persistentvolumeclaim/mypvc created
-> [root@kube0.vm] [~] k get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/mypv 10Mi RWO,ROX Retain Bound default/mypvc 7m11s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mypvc Bound mypv 10Mi RWO,ROX 9s
可以看到持久卷被绑定到default/mypvc声明上,default是mypvc的命名空间。PV不存在命名空间的概念,但是PVC只能在特定命名空间创建。
Pod中使用PVC
# use-pvc-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: use-pvc
spec:
containers: # 这里的内容与volume-share.yaml的一样,所以功能不再赘叙,
- image: alpine
name: html-generator
volumeMounts:
- name: html
mountPath: /var/html
command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"]
volumes:
- name: html
persistentVolumeClaim: # 这里使用了PVC类型,制定了PVC的名字
claimName: mypvc
创建Pod
-> [root@kube0.vm] [~] k create -f use-pvc-pod.yaml
pod/use-pvc created
-> [root@kube0.vm] [~] k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
use-pvc 1/1 Running 0 4m1s 10.244.1.12 kube1.vm <none> <none>
与kube1.vm查看是否写入了内容
-> [root@kube1.vm] [~] cat /tmp/pv/index.html
Sun May 24 06:43:02 UTC 2020
回收PV
删除PVC后,查看PV,可以看到此时的状态是Released,而不是之前的Available。
-> [root@kube0.vm] [~] k delete pvc mypvc
persistentvolumeclaim "mypvc" deleted
-> [root@kube0.vm] [~] k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv 10Mi RWO,ROX Retain Released default/mypvc 35s
这时候在创建PVC,会发现mypvc的状态一直是Pending,因为没有可用的PV。所以,persistentVolumeReclaimPolicy设置为Retain
的PV需要手动删除重建才能恢复可用。
-> [root@kube0.vm] [~] k create -f pvc.yaml
persistentvolumeclaim/mypvc created
-> [root@kube0.vm] [~] k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc Pending 16s
persistentVolumeReclaimPolicy用来设置回收策略,其他两种是Recycle和Delete。可以在现有的PV上更改卷回收策略,比如开始设置为Delete,可以改为Retain。
PV与PVC的声明周期,以及在Pod中的使用
StorageClass
使用PV与PVC可以使开发人员不用关心实际的存储技术,但是仍然需要集群管理人员来支持实际的存储。可以通过创建StorageClass资源解决此问题。
StorageClass的作用是:为引用它的PVC在创建的时候通过置备程序创建一个PV。
工作流程简介:
- 集群管理员根据不同性能及特性创建若干个StorageClass
- 开发人员创建一个引用StorageClass的PVC
- Kubernetes查找引用的StorageClass置备程序,并按照PVC的访问模式和存储大小置备新的PV
因为环境问题,下面的例子使用minikube运行。
创建StorageClass
# storageclass-fast.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: k8s.io/minikube-hostpath
parameters:
type: pd-ssd
运行查看
-> [feifei@ffmac.local] [~/work/k8s] kubectl create -f storageclass-fast.yaml
storageclass.storage.k8s.io/fast created
-> [feifei@ffmac.local] [~/work/k8s] kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
fast k8s.io/minikube-hostpath Delete Immediate false 114m
standard (default) k8s.io/minikube-hostpath Delete Immediate false 117m
创建PVC引用StorageClass
# pvc-storageclass.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-sc
spec:
resources:
requests:
storage: 10Mi
accessModes:
- ReadWriteOnce
storageClassName: fast # 引用了上面名为fast的StorageClass
可以看到,成功创建了一个名为pvc-be95fa9c-0666-4e3b-a2e2-a68c0bbea6f6
的持久卷,绑定的持久卷声明是default/pvc-sc
。访问模式与存储大小与pvc-sc的都一致。
-> [feifei@ffmac.local] [~/work/k8s] kubectl create -f pvc-storageclass.yaml
persistentvolumeclaim/pvc-sc created
-> [feifei@ffmac.local] [~/work/k8s] kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-be95fa9c-0666-4e3b-a2e2-a68c0bbea6f6 10Mi RWO Delete Bound default/pvc-sc fast 3m36s
-> [feifei@ffmac.local] [~/work/k8s] kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-sc Bound pvc-be95fa9c-0666-4e3b-a2e2-a68c0bbea6f6 10Mi RWO fast 3m40s
不指定存储类的动态配置
如果将PVC配置中的storageClassName设置为空,那么创建PVC时将优先绑定到预先配置的PV,而不是由StorageClass配置新的PV。
流程图
小结
- 卷是Pod的一部分,与Pod共享生命周期。它不是独立的Kubernetes对象,因此不能单独创建。
- 卷提供的存储功能不但可以解决容器重启后数据丢失的问题,还可以使数据在容器间共享。
- gitRepo卷基本上相当于emptyDir,它在容器启动前从git仓库检出填充数据。但git仓库与gitRepo的内容并不保持同步。
- hostPath卷提供的是映射到工作节点本地的持久存储
- PV是一种资源,并且不属于任何命名空间。它的功能与卷类似,但是它的生命周期是独立于Pod的。PV由集群管理员创建,并被Pod通过PVC使用。
- PVC创建好后,Kubernetes会寻找适当的PV将其绑定到PVC。持久卷必须要足够大,并且包含声明中指定的访问模式。
- 可以在现有的PV上更改卷回收策略,比如开始设置为Delete,可以改为Retain。
- StorageClass为引用它的PVC在创建的时候通过置备程序创建一个PV
- 如果将PVC配置中的storageClassName设置为空,那么创建PVC时将优先绑定到预先配置的PV,而不是由StorageClass配置新的PV。
Kubernetes学习笔记(五):卷的更多相关文章
- Kubernetes 学习笔记(一):基础概念
个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
- python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍
python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...
- Go语言学习笔记五: 条件语句
Go语言学习笔记五: 条件语句 if语句 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } 竟然没有括号,和python很像.但是有大括号,与python又不一样. 例子: pa ...
随机推荐
- Eclipse Mac OS 安装中文简体语言包
打开Eclipse软件,在导航Eclipse下拉菜单中点开 About Eclipse 查看版本 我的是 Eclipse IDE for Enterprise Java Developers. Ver ...
- Nginx重写请求后将url?后的参数去除
2019独角兽企业重金招聘Python工程师标准>>> 使用?结尾 注意,关键点就在于"?"这个尾缀.重定向的目标地址结尾处如果加了?号,则不会再转发传递 ...
- 疯子的算法总结(九) 图论中的矩阵应用 Part 1+POJ3613 Cow Relays
图的存储有邻接矩阵,那么他就具备一些矩阵的性质,设有一个图的demo[100][100];那么demo[M][N]就是M—>N的距离,若经过一次松弛操作demo[M][N]=demo[M][K] ...
- 怎么避免写出慢SQL
在大多数实际的系统中,慢 SQL 消耗掉的数据库资源,往往是正常 SQL 的几倍.几十倍甚至几百倍. 怎样才能在开发阶段尽量避免写出慢 SQL 呢? 估算数据量 慢 SQL 对数据库的影响,是一个量变 ...
- 自动化API之一 生成开源ERP Odoo App 的RestFul API
1.在服务器上安装开源ERP Odoo 安装步骤请自行百度,本文重点不在于指导安装,以下是安装后PC端效果. Odoo: 2.在Uniconnector平台上注册Odoo App 移动端应用 3.配置 ...
- OSG程序设计之osg::Group
以下是一个简单的模型读取程序: #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osg/N ...
- 拒绝老土!暗黑风格半透平面化主题—InfinityFreedom正式发布
经常听到“路由器界面土点就土点吧,凑合能用就成.” 诚然,路由器重要的是功能,但为什么要辣眼睛呢? 拯救喜欢折腾的你,抢救干涩的眼球,原创OpenWrt主题Infinity Freedom正式发布! ...
- OpenWrt R2020.3.11 去广告 抗污染 加速 PSW 无缝集成 UnPnP NAS
近期更新:OpenWrt R2020.3.11版本2020.03.16编译. 按大家要求,新发布固件携带了编译时用到的全部软件包 加入了国内域名加速解析脚本 解决了原去广告,DNS优化方案与PSW冲突 ...
- C# 判断文件格式的一些总结
前提概述: 项目中 经常会有上传图片的地方 有的时候需要对图片类型做一些要求 这个时候就需要一些判断 虽然前段上传的时候可以去做类型的限制 或者后台接受的时候从file的type 中获取图 ...
- 【FreeRTOS学习02】源码结构/数据类型/命名规则总结
个人不是很喜欢FreeRTOS的编程风格,但是没办法,白嫖人家的东西,只能忍了,这里先简单总结一下: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 ...