1. configMap的原理及作用
就是为了让镜像 和 配置文件解耦,以便实现镜像的可移植性和可复用性,因为一个configMap其实就是一系列配置信息的集合,将来可直接注入到Pod中的容器使用,而注入方式有两种,一种将configMap做为存储卷,一种是将configMap通过env中configMapKeyRef注入到容器中。它通过两种方式实现给Pod传递配置参数:
A. 将环境变量直接定义在configMap中,当Pod启动时,通过env来引用configMap中定义的环境变量。
B. 将一个完整配置文件封装到configMap中,然后通过共享卷的方式挂载到Pod中,实现给应用传参。
secret: 它是一种相对安全的configMap,因为它将configMap通过base64做了编码, 让数据不是明文直接存储在configMap中,起到了一定的保护作用,但对Base64进行反编码,对专业人士来说,没有任何难度,因此它只是相对安全
2. requests未设置时,默认与limits相同。limits未设置时,默认值与集群配置相关。
- 使用requests来设置各容器需要的最小资源
- limits用于限制运行时容器占用的资源,用来限制容器的最大CPU、内存的使用率。当容器申请内存超过limits时会被终止,并根据重启策略进行重启
3. k8s控制器和Pod Template的关系
Pod 本身并不能自愈(self-healing)。如果一个 Pod 所在的 Node (节点)出现故障,或者调度程序自身出现故障,Pod 将被删除;同理,当因为节点资源不够或节点维护而驱逐 Pod 时,Pod 也将被删除。Kubernetes 通过引入 Controller(控制器)的概念来管理 Pod 实例。在 Kubernetes 中,更为推荐的做法是使用 Controller 来管理 Pod,而不是直接创建 Pod。
当一个节点出现故障,控制器可以自动地在另一个节点调度一个配置完全一样的 Pod,以替换故障节点上的 Pod。
控制器通过其中配置的 Pod Template 信息来创建 Pod
在 Kubernetes 中,广泛使用的控制器有:Deployment、StatefulSet、DaemonSet。
4.k8s的设计思想
Kubernetes 项目最主要的设计思想是,从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持更多种类的关系留有余地
5. pod和service
Pod 里的容器共享同一个 Network Namespace、同一组数据卷,从而达到高效率交换信息的目的
而对于另外一种更为常见的需求,比如 Web 应用与数据库之间的访问关系,Kubernetes 项目则提供了一种叫作“Service”的服务。像这样的两个应用,往往故意不部署在同一台机器上,这样即使 Web 应用所在的机器宕机了,数据库也完全不受影响。可是,我们知道,对于一个容器来说,它的 IP 地址等信息不是固定的,那么 Web 应用又怎么找到数据库容器的 Pod 呢?
Kubernetes 项目的做法是给 Pod 绑定一个 Service 服务,而 Service 服务声明的 IP 地址等信息是“终生不变”的。这个Service 服务的主要作用,就是作为 Pod 的代理入口(Portal),从而代替 Pod 对外暴露一个固定的网络地址。
这样,对于 Web 应用的 Pod 来说,它需要关心的就是数据库 Pod 的 Service 信息。不难想象,Service 后端真正代理的 Pod 的 IP 地址、端口等信息的自动更新、维护,则是 Kubernetes 项目的职责。
![](https://img.haomeiwen.com/i6172448/140dce483d2d2d7a.png)
按照这幅图的线索,我们从容器这个最基础的概念出发,首先遇到了容器间“紧密协作”关系的难题,于是就扩展到了 Pod;有了 Pod 之后,我们希望能一次启动多个应用的实例,这样就需要 Deployment 这个 Pod 的多实例管理器;而有了这样一组相同的 Pod 后,我们又需要通过一个固定的 IP 地址和端口以负载均衡的方式访问它,于是就有了 Service。
可是,如果现在两个不同 Pod 之间不仅有“访问关系”,还要求在发起时加上授权信息。最典型的例子就是 Web 应用对数据库访问时需要 Credential(数据库的用户名和密码)信息。那么,在 Kubernetes 中这样的关系又如何处理呢?
Kubernetes 项目提供了一种叫作 Secret 的对象,它其实是一个保存在 Etcd 里的键值对数据。这样,你把 Credential 信息以 Secret 的方式存在 Etcd 里,Kubernetes 就会在你指定的 Pod(比如,Web 应用的 Pod)启动时,自动把 Secret 里的数据以 Volume 的方式挂载到容器里。这样,这个 Web 应用就可以访问数据库了
PV和PVC
PV 描述的,是持久化存储数据卷。这个 API 对象主要定义的是一个持久化存储在宿主机上的目录,比如一个 NFS 的挂载目录。
通常情况下,PV 对象是由运维人员事先创建在 Kubernetes 集群里待用的。
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.244.1.4
path: "/"
而PVC 描述的,则是 Pod 所希望使用的持久化存储的属性。比如,Volume 存储的大小、可读写权限等等。pvc 一般由开发人员创建
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
而用户创建的 PVC 要真正被容器使用起来,就必须先和某个符合条件的 PV 进行绑定。这里要检查的条件,包括两部分:
第一个条件,当然是 PV 和 PVC 的 spec 字段。比如,PV 的存储(storage)大小,就必须满足 PVC 的要求。
而第二个条件,则是 PV 和 PVC 的 storageClassName 字段必须一样。这个机制我会在本篇文章的最后一部分专门介绍。
Pod 需要做的,就是在 volumes 字段里声明自己要使用的 PVC 名字。接下来,等这个 Pod 创建之后,kubelet 就会把这个 PVC 所对应的 PV,也就是一个 NFS 类型的 Volume,挂载在这个 Pod 容器内的目录上。
PVC 和 PV 的设计,其实跟“面向对象”的思想完全一致
PVC 可以理解为持久化存储的“接口”,它提供了对某种持久化存储的描述,但不提供具体的实现;而这个持久化存储的实现部分则由 PV 负责完成。
这样做的好处是,作为应用开发者,我们只需要跟 PVC 这个“接口”打交道,而不必关心具体的实现是 NFS 还是 Ceph。毕竟这些存储相关的知识太专业了,应该交给专业的人去做。
在 Kubernetes 中,实际上存在着一个专门处理持久化存储的控制器,叫作 Volume Controller。这个 Volume Controller 维护着多个控制循环,其中有一个循环,扮演的就是撮合 PV 和 PVC 的“红娘”的角色。它的名字叫PersistentVolumeControlle
所谓容器的 Volume,其实就是将一个宿主机上的目录,跟一个容器里的目录绑定挂载在了一起 而所谓的“持久化 Volume”,指的就是这个宿主机上的目录,具备“持久性”。。即:这个目录里面的内容,既不会因为容器的删除而被清理掉,也不会跟当前的宿主机绑定。这样,当容器被重启或者在其他节点上重建出来之后,它仍然能够通过挂载这个 Volume,访问到这些内容。大多数情况下,持久化 Volume 的实现,往往依赖于一个远程存储服务,比如:远程文件存储(比如,NFS、GlusterFS)、远程块存储(比如,公有云提供的远程磁盘)等等。hostPath 和 emptyDir 类型的 Volume 并不具备这个特征:它们既有可能被 kubelet 清理掉,也不能被“迁移”到其他节点上。
这个准备“持久化”宿主机目录的过程,我们可以形象地称为“两阶段处理”
网友评论