企业级运维之云原生与Kubernetes实战课程
第一章第5讲 Kubernetes存储
视频地址:https://developer.aliyun.com/learning/course/913/detail/14599
摘要:本小节主要内容为存储卷介绍,包括:Persistent Volumes(PV)、Persistent VolumesClaim(PVC)的特点及使用。
目录
- Volume存储卷介绍
- Persistent Volumes(PV)
- Persistent VolumesClaim(PVC)
一、Volume存储卷介绍
1. 什么是存储卷
K8s容器运行时,在没有做日志持久化的情况下,容器重启后导致日志丢失,这时就需要一个中间设备,既可以被Pod调用将日志输出,又可以被分析应用读取(如Grafana、Elastic)进行相关分析,这个中间设备就是存储卷。
2. 存储卷类型
a. 本地存储/hostpath
- Emptydir:当 Pod 被分配给节点时,先创建 emptyDir 卷,并且只要该 Pod 在该节点上运行,该卷就会存在,它最初是空的,Pod 中的容器可以读取和写入emptyDir 卷中的相同文件,该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir 中的数据将被永久删除。如果Pod发生重启,而emptydir使用了medium(内存)模式,则有可能没有被删除。
- Hostpath:将宿主机上的目录挂载到Pod上,实现容器与宿主机的共享。
b. 网络存储
云厂商阿里、aws、google会提供类似云盘、OSS、NAS等的网络存储。
c. Projected Volume
- ConfigMap
- ConfigMap提供了向Pod注入数据的方法,以键值对方式存储在K8s系统中;
- 两种使用方式:环境变量引用、数据卷的方式挂载;
- 可以定义一个Pod,以环境变量的形式进行使用,引用configmap或者通过挂载数据卷的方式,定义Volume类型为configmap,再去引用configmap信息,数据卷的方式挂载是以文件的方式挂载到容器的定义的路径下;
- 两种方式区别:configmap热更新时如果使用环境变量方式,需要手动方式更新环境变量,Pod所引用的configmap才会生效;而使用数据卷挂载方式,更新configmap时Pod所引用的configmap会生效(有10秒到1分钟的延迟)。
- Secret
Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。Secret 有几种类型:
- Opaque:base64编码格式的Secret,用来存储密码、密钥等,相当来说不安全;
- SA(ServiceAccout):用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的特点目录中。每个Pod都有SA,路径/run/secrets/kubernets.io/serviceaccount,包含了公钥、namespace、token;
- 其他:像tls客户端或服务端进行数据加密,ssh的身份认证secret;用于储存镜像仓库的认证信息的dockerconfigjson,在镜像拉取时,可以通过引用的方式使用。
d. PVC与PV体系
二、Persistent Volumes(PV)
1. Pod中声明的volume的生命周期与Pod相同,常见场景:
a. Pod销毁重建(如Deployment管理的Pod镜像升级);
b. 宿主机故障迁移(如StatefulSet管理的Pod带远程volume迁移);
c. 多Pod共享同一个数据volume;
d. 数据volume snapshot,resize等功能的扩展实现;
2. PV的不足之处
使用Pod Volumes无法准确表达数据volume复用/共享语义,新功能扩展很难实现。
3. PV的优化
如果能将存储与计算分离,使用不同的组件(Controllers)管理存储与计算资源,解耦PodVolume的生命周期关联,可以很好解决这些场景下的问题。
PV(Persistent Volumes)定义一种存储资源类似CPU和Memory,类型可以为云盘、NAS可以是只读(RO)、可读可写(RW)等。
三、Persistent VolumesClaim(PVC)
1. PVC是什么
存储对于上层应用Pod而言,并不关心底层存储是通过哪种方式创建,而是注重存储大小、挂载的方式,这时需要定义存储格式、类型,由定义去找符合条件的存储,于是PVC就产生了。
2. 有了PV,为什么又设计了PVC
- 职责分离,PVC中只用声明自己需要的存储size、access mode(单node独占还是多node共享、只读还是读写访问)等业务真正关心的存储需求(不用关心存储实现细节),PV和其对应的后端存储信息则由交给cluster admin统一运维和管控,安全访问策略更容易控制。
- PVC简化了User对存储的需求,PV才是存储的实际信息的承载体,通过kube-controller-manager中的PersisentVolumeController将PVC与合适的PV bound到一起,从而满足User对存储的实际需求。
- PVC像是面向对象编程中抽象出来的接口,PV是接口对应的实现。
3. Static Volume Provisioning
Static Volume Provisioning表示已在集群中创建完成存储资源,在Pod指定时,同时通过PVC进行分配挂载存储卷。
Static Volume Provisioning的不足:
Cluster Admin需要提前规化或预测存储需求,而User的需求是多样化的,很容易导致 User提交的PVC找不到合适的PV。
更好的方式:
Cluster Admin只创建不同类型存储的模板,User在PVC中指定使用哪种存储模板以及自己需要的大小、访问方式等参数,然后K8s自动生成相应的PV对象。
4. Dynamic Volume Provisioning
集群没有提供可用PV,通过PVC的Storage Class创建所需要的PV,然后挂载到Pod上。这就是声明定义创建PV,而不需要关注创建的细节,K8s则会结合PVC和SC两者的信息动态创建PV对象。
5. 静态使用PV、PVC(以云盘为例)
- 编写yaml创建一个PV,定义PV名字、大小等信息(可以使用命令kubectl get pv查看);
- 编写PVC的yaml文件,定义PVC名称、PVC接入方式、需要PV的大小,然后创建PVC后会自动绑定上面创建的PV;
5. 动态使用PV、PVC
动态PV、PVC不需要定义PV资源,只需要在Storage Class(可以认为是存储插件进行调用资源)的yaml中定义名称、调用的存储插件、文件的形式、是否加密、回收模式等信息,然后创建Storage Class,再创建statefulset类型的Pod与之关联;
statefulset创建多个副本数是有序的,首先创建完成一个Pod副本后才会创建下一个,且副本名字无论是删除或重拉后都是不变的,挂载的存储会重新挂载到新拉起的Pod上。
假如statefulset创建了三个Pod,进行更新为2个副本后,删除的副本一定是最后创建的那个副本。
statefulset特点:
- Pod名称是statefulset-序号
- 有序部署
- 有序删除
- 有序拓展
访问方式可以通过Pod的名字或headless名字如:
headless nginx.namespace.svc.cluster.local
web-0.nginx1.default.svc.cluster.local
statefulset的使用场景:
- 应用需要稳定持久化存储;
- 应用是有序的,无论Pod发生什么变化,Pod启动后状态是不变的;
- 应用需要稳定的网络标识。