<续> Kubernetes 学习
1、 PV Controller、AD Controller 以及 Volume Manager 其实都是通过调用 Volume Plugin 提供的接口,比如 Provision、Delete、Attach、Detach 等去做一些 PV、PVC 的管理。而这些接口的具体实现逻辑是放在 VolumePlugin 中的。 根据源码的位置可将 Volume Plugins 分为 In-Tree 和 Out-of-Tree 两类,
- In-Tree 表示源码是放在 Kubernetes 内部的,和 Kubernetes 一起发布、管理与迭代,缺点及时迭代速度慢、灵活性差; 比如cephfs、glusterfs
- Out-of-Tree 类的 Volume Plugins 的代码独立于 Kubernetes,它是由存储商提供实现的,目前主要有 Flexvolume 和 CSI 两种实现机制,可以根据存储类型实现不同的存储插件。所以我们比较推崇 Out-of-Tree 这种实现逻辑。 比如 CSI、FlexVolume
2、Flexvolume是可被 Kubelet 驱动的可执行文件,host 空间中的二进制程序,是 Volume Plugins 的一个扩展,主要实现 Attach/Detach/Mount/Unmount 这些接口。
Flexvolume默认的存放地址为 "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/alicloud~disk/disk"
所有挂载均需先将远程设备挂载到本地主机,然后从主机通过bind映射到容器内部。
阿里云提供了一个 Flexvolume 的实现:针对阿里云云盘、NAS、OSS存储开发的flexvolume 插件,可以支持kubernetes pod 自动绑定阿里云存储服务。此版本支持Flexvolume、静态pv、对于动态pv尚不支持。
3、CSI 是容器化部署,可以减少环境依赖,增强安全性,丰富插件的功能。Flexvolume 是在 host 空间一个二进制文件( 通过yaml配置进行部署阿里云K8S存储插件,目前支持CentOS 7 操作系统),执行 Flexvolum 时相当于执行了本地的一个 shell 命令,这使得我们在安装 Flexvolume 的时候需要同时安装某些依赖,而这些依赖可能会对客户的应用产生一些影响。因此在安全性上、环境依赖上,会有不好的影响。CSI 是通过 CRD 的形式实现的, CRD(Custom Resource Definition),CRD 在用法上和 Pod 这样的原生资源基本相同,都支持通过 kubectl 命令行或者 K8s API 进行访问和操作。正是 CRD 的灵活和强大,促成了 K8s 周边生态的蓬勃发展。 VolumeSnapshotDataSource 可以实现数据卷的快照功能,
4、 K8s 的元数据部分。该部分主要包括了用来识别资源的标签:Labels, 用来描述资源的注解;Annotations, 用来描述多个资源之间相互关系的 OwnerReference。
资源标签是一种具有标识型的 Key:Value 元数据, 标签主要用来筛选资源和组合资源,可以使用类似于 SQL 查询 select,来根据 Label 查询相关的资源。
元数据是:annotations。一般是系统或者工具用来存储资源的非标示性信息,可以用来扩展资源的 spec/status 的描述
Ownereference,所谓所有者,一般就是指集合类的资源,比如说 Pod 集合,就有 replicaset、statefulset, 集合类资源的控制器会创建对应的归属资源, 可以用来实现级联删除的效果。
5、 Kubernetes 控制器模式依赖声明式的 API。另外一种常见的 API 类型是命令式 API。 控制型模式最核心的就是控制循环的概念。在控制循环中包括了控制器,被控制的系统,以及能够观测系统的传感器,三个逻辑组件。 当然这些组件都是逻辑的,外界通过修改资源 spec 来控制资源,控制器比较资源 spec 和 status,从而计算一个 diff,diff 最后会用来决定执行对系统进行什么样的控制操作,控制操作会使得系统产生新的输出,并被传感器以资源 status 形式上报,控制器的各个组件将都会是独立自主地运行,不断使系统向 spec 表示终态趋近。
6、Deployment 是 Kubernetes 中常见的一种 Workload,支持部署管理多版本的 Pod:Deployment 创建 ReplicaSet,而 ReplicaSet 创建 Pod。他们的 OwnerRef 其实都对应了其控制器的资源。
- Deployment 管理多版本的方式,是针对每个版本的 template 创建一个 ReplicaSet,由 ReplicaSet 维护一定数量的 Pod 副本,而 Deployment 只需要关心不同版本的 ReplicaSet 里要指定多少数量的 Pod;
-
因此Deployment 发布部署的根本原理,就是 Deployment 调整不同版本 ReplicaSet 里的终态副本数,以此来达到多版本 Pod 的升级和回滚。
7、引入了一个 kind 叫 Job,是 job-controller 里面的一种类型, metadata 里面的 name 来指定这个 Job 的名称,在 Job 里面,我们主要重点关注的一个是 restartPolicy 重启策略和 backoffLimit 重试次数限制。Pod 多了一个叫 ownerReferences,这个东西来声明此 pod 是归哪个上一层 controller 来管理,可以看到 ownerReferences 是归 batch/v1,也就是上一个 Job 来管理的。并行运行 Job使用Job 控制器两个参数:一个是 completions(Pod 队列执行次数),一个是 parallelism(并行执行的个数)。 定时任务 CronJob, 其实也可以叫定时运行 Job
8、DaemonSet 也是 Kubernetes 提供的一个 default controller,它实际是做一个守护进程的控制器, DaemonSet 架构设计。DaemonSet 还是一个 controller,它最后真正的业务单元也是 Pod,DaemonSet 其实和 Job controller 特别相似,它也是通过 controller 去 watch API Server 的状态( 这个 node 的状态还是通过 API Server 传递到 ETCD),然后及时地添加 pod。唯一不同的是,它会监控节点的状态,节点新加入或者消失的时候会在节点上创建对应的 pod,然后同时根据你配置的一些 affinity 或者 label 去选择对应的节点:
- 首先是存储,GlusterFS 或者 Ceph 之类的东西,需要每台节点上都运行一个类似于 Agent 的东西,DaemonSet 就能很好地满足这个诉求;
- 另外,对于日志收集,比如说 logstash 或者 fluentd,这些都是同样的需求,需要每台节点都运行一个 Agent,这样的话,我们可以很容易搜集到它的状态,把各个节点里面的信息及时地汇报到上面;
- 还有一个就是,需要每个节点去运行一些监控的事情,也需要每个节点去运行同样的事情,比如说 Promethues 这些东西,也需要 DaemonSet 的支持。
9、 ConfigMap主要是管理一些可变配置信息,比如说我们应用的一些配置文件,或者说它里面的一些环境变量,或者一些命令行参数。 好处在于它可以让一些可变配置和容器镜像进行解耦,这样也保证了容器的可移植性。
只有通过 K8s api 创建的 pod 才能使用 ConfigMap,比如说通过用命令行 kubectl 来创建的 pod,肯定是可以使用 ConfigMap 的,但其他方式创建的 pod,比如说 kubelet 通过 manifest 创建的 static pod,它是不能使用 ConfigMap 的。
10、 Secret 是一个主要用来存储密码 token 等一些敏感信息的资源对象。其中,敏感信息是采用 base-64 编码保存起来的。 ServiceAccount 首先是用于解决 pod 在集群里面的身份认证问题,身份认证信息是存在于 Secret 里面。 Resource,即:容器的一个资源配置管理: 目前内部支持类型有三种:CPU、内存,以及临时存储。 目前资源配置主要分成 request 和 limit 两种类型,一个是需要的数量,一个是资源的界限。CPU、内存以及临时存储都是在 container 下的 Resource 字段里进行一个声明。
SecurityContext 主要是用于限制容器的一个行为,它能保证系统和其他容器的安全 。
11、 InitContainer 和普通 container 的区别,有以下三点内容:
- InitContainer 首先会比普通 container 先启动,并且直到所有的 InitContainer 执行成功后,普通 container 才会被启动;
- InitContainer 之间是按定义的次序去启动执行的,执行成功一个之后再执行第二个,而普通的 container 是并发启动的;
- InitContainer 执行成功后就结束退出 ,而普通容器可能会一直在执行。它可能是一个 longtime 的,或者说失败了会重启,这个也是 InitContainer 和普通 container 不同的地方。
12、在云环境下,技术栈可以是多种多样的。那么如何能够将这些异构的服务组件串联起来,成为了服务治理的一个重大课题。而Sidecar模式为服务治理,提供了一种解决方案。边车(Sidecar)模式,早期有一些摩托车,除了主驾驶位,还带一个边车位,可以额外坐一个人。业务代码进程(相当于主驾驶)共享一个代理(相当于边车),代理除了负责服务发现和负载均衡,还负责动态路由、容错限流、监控度量和安全日志等功能,这些功能是具体业务无关的,属于跨横切面关注点(Cross-Cutting Concerns)范畴。在该模式中,边车附加到父应用程序并为应用程序提供支持功能。 sidecar还与父应用程序共享相同的生命周期,与父项一起创建和退役。边车图案有时被称为搭接图案并且是分解图案。
13、Docker, 当执行docker run时,它会创建并运行容器,但是底层它实际调用的是runc命令。(Docker使用的是LXC但是层次隔离不太完整,所以后来Docker开发了libcontainer,最后演变为了runc。)
——当我们有需求去替换 runc 运行时工具库时,例如替换为安全容器 kata container 或 Google 研发的 gViser,则需要增加对应的shim(kata-shim等),以上两者均有自己实现的 shim。