产品架构
Caicloud容器云平台CLaaS架构
CLaaS 基于 Docker(操作系统容器引擎)与 Kubernetes(容器编排调度工具), 帮助企业将应用容器化,以应用为中心提高企业的开发运维的质量。Docker 提供封装 Linux 容器镜像, Kubernetes 负责在大规模集群上的集群管理与容器编排。 Caicloud 在以上两大服务之上添加:
- 源代码管理、构建、持续集成与交付流水线
- Cuberentes: 为开源的Kubernetes集群的改良与增强版,优化当前开源版本中一些不足与漏洞
- 多 Cubernetes 联合管理
- 资源监控与日志管理
- 权限管理与应用模板管理
- 负载均衡管理
在 Caicloud 平台中,每个 Cubernetes 集群可以管理 1000+ 的工作节点,每台工作节点上默认同时可运行108个 Linux 容器(上限可调),以最大限度利用当前计算资源;每个容器的实体在集群内都是独立的实体,每个容器会被分配一个可用 IP, 并支持配置容器间的互通网络策略,以灵活控制当前集群内部网络安全。Cubernetes 支持某些容器组做为统一的服务提供者,为这些容器组创建一个服务资源做为这些容器组的负载均衡器,而这些容器组可以手动/自动的横向伸缩,而服务根据后台的容器组的健康状态将收到的流量转发到可用的容器组。
开发人员只需照常提交代码至已有代码库。可持续集成/交付组件与代码库关联,自动构建代码并生成 Docker 镜像,随后触发持续集成测试,测试通过后,自动将最新镜像上传至镜像仓库。根据用户设定的发布策略(发布到哪个集群、哪个服务),Caicloud 会自动从镜像仓库下载镜像并将其集群化,最终以高可用服务的形式运行在用户 Cubernetes 集群中。持续集成/交付任务结束后,会自动向项目组发送持续集成/交付结果,以巨幅提高研发效率和产品质量。
运维人员仅需声明应用的运维策略,Caicloud 将会自运维当前应用。例如:运维人员声明应用副本数 X 与调度策略,并设定容器可用性探针、健康性探针。随后 Cubernetes 集群会自动对该应用进行高可用、负载均衡、监测、自动修复等自动化管理。运维人员还可设定弹性伸缩策略,Caicloud 将按照弹性伸缩策略应对波动性用户并发访问以自动变换应用副本数量。运维人员还可设定应用安全退出策略,以确保在应用容器回收时丢失未正确处理的中间状态。运维人员只需观察监控面板、日志面板及告警通知来收集应用隐患点,与开发人员进行讨论即可,日常的“纯体力”的环境准备,应用上线等问题可交由 Caicloud 自动处理。
Kubernetes介绍
Kubernetes 与主流的分布式管理系统类似,分为 Master 和 Slave。Master 节点上运行的组件有:
组件名 | 功能说明 |
---|---|
apiserver | 作为kubernetes 管理信息的入口,封装了核心对象的增删改查操作,以RESTFul接口方式提供给外部客户和内部组件调用。它维护的REST对象将持久化到etcd。 |
etcd | 持久化 Master 相关状态,这部分信息可被其它组件 watch 以实现内部组件间的服务协作。 |
scheduler | 负责集群的资源调度,为新建的 Pod 分配机器运行。 scheduler 被设计成可拔插,意味着能很方便地替换成其他的调度器。 |
controller-manager | 负责集群内的 Node、Pod 副本、Endpoint、Namespace、Service Account、Resource Quota 等的管理,并执行自动化修复流程,以确保集群处于预期的工作状态。 |
Node 节点上运行的组件有:
组件名 | 功能说明 |
---|---|
kube-proxy | 提供集群内服务均衡,Proxy提供 TCP/UDP sockets 的 proxy,每创建一种 Service,Proxy 主要从 etcd 获取 Services 和Endpoints 的配置信息,在 Node 上启动一个 Proxy 的进程并监听相应的服务端口,当请求发生时,Proxy 会根据负载均衡策略将请求分发到后端正确的容器处理。 |
kubelet | 负责管控 docker 容器,如启动/停止、监控运行状态等。它会定期从 etcd 获取分配到本机的 Pod 信息以启动或停止相应的容器。同时,它也会接收 apiserver 的 HTTP 请求,汇报 Pod 的运行状态。在 kubelet 的内部嵌了一个本机资源监测与容器资源监测的工具 cadvisor |
pod | 由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。同个 Pod 下的容器使用相同的网络命名空间、IP 地址和端口区间,相互之间能通过 localhost 来发现和通信。Pod主要是在容器化环境中建立了一个面向应用的“逻辑主机”模型,它可以包含一个或多个相互间紧密联系的容器。 |
核心概念
分区
分区指的是在 Kubernetes 集群之上的 namespace, 而应用容器运行时需指定运行在某个分区 。 创建分区需分配一片空间 --即 CPU 与内存,此空间并不是真实的从某台节点划出去指定资源,它是一个逻辑概念,只是声明当前分区将会获得指定的资源,在这个分区内的应用容器共享这么多资源。 分区可被理解为一个“租户”,“租户”创建时对应的分区也会创建,每个 “租户”的应用运行在各自的分区内,同时可指定分区网络隔离策略以实现多 “租户”间隔离。
资源配额
Kubernetes 核心功能之一是资源调度,Kubernetes 会计算整个集群的资源总量,例如整个集群一共有 10台 可调度的机器,这10台机器中每台机器的 CPU 都为 8 Core, 内存为 16 G, 即整个集群的资源总量为 80 Core, 内存为 160 G;在创建应用或分区时可申请所需的资源大小以切分当前集群资源,当应用实际运行时并不一定立刻占用指定大小资源量,而创建时的资源申请可确保预留出指定资源空间供其使用。 在 Kubernetes 的资源属性分为“请求” 与 “上限”。整个集群可被“请求” 资源总量为整个集群真实资源总和,考虑到应用真实的运行情况并不一定会真实消耗 “请求”资源配额大小,即当整个集群的资源都被“申请”完后,整个集群的资源真实使用情况也并未达到上限,甚至远未达到上限,但此时又不能创建新的应用,因为所有的资源都被申请出去。 Kubernetes 提出另一个资源属性为“上限”,默认的 Kubernetes 的“上限”总量与“请求”问题相等, Caicloud 支持用户设定集群的“上限”与“请求”的可超用比例,允许用户设定较小的“请求”量与相对较大的“上限”量,帮助用户更充分的利用集群资源。 需要注意的通过配置超用比例,使 Kubernetes 创建出更多的应用。但集群的真实资源量是固定的,当集群内所有应用的资源量使用趋近集群资源总数时,当某些应用消耗的资源未达到当时申请“上限”数且仍需更多资源时,会造成当前应用与所在机器内其它应用形成资源抢占问题,造成应用不稳定现象。 Kubernetes 为保证当前某些核心应用不会被最先受到影响,建议用户为此类核心应用的“请求”与“上限”设定相等大小。
应用模板
通常在企业内,同一套应用会在不同的环境内反复部署,Caicloud 提供应用模板功能支持用户为已建好的应用生成模板,方便后续反复使用。 应用模板中包含全部应用属性,包括更新策略、容器信息与配置文件、负载均衡方式等等。 镜像封装了所有运行时的信息,但一个镜像在不同的环境某些文件是不能一致的,比方说数据源配置文件,不同的环境连向的数据库肯定不一样。 Caicloud 支持给容器上传配置文件,最终保存为一个适应某个运行环境的应用模板。
应用编排
在云计算时代应用往往采用分布式微服务架构。Claas 提供应用编排功能,可以将多个微服务组件编排成一个复合应用,还能将组件间调用链关系、各组件的配置打包存储为应用方案,并版本管理。用户可以使用固化的方案一键部署应用。
权限管理
用户可以对资源拥有管理、读写、只读、无四种权限,并能把拥有管理权限的资源分享不同的权限给他用户。 通过权限组的方式,用户可以分组批量管理分享给其他用户的权限。
容器与镜像
容器就是一种新的打包方式,并不是一个非常新型的东西,这种打包方式可以将应用与其依赖的完整操作系统环境打包在一起,相当于在开发时就将整个应用在生产时的具体运行情况就已经规范好并生成可用的应用实例。而传统上开发给人员只负责产出一个应用包,生产运行在什么操作系统或环境里都是运维部门决定,这就会导致在线上运行的时候因为会出现一些意想不到的问题。即使研发环境与生产环境在项目在初始阶段协调好,但在之后线上环境与开发环境会逐渐偏离,例如线上环境会因为某项问题,将操作系统的某项配置阶段改了。但开发环境不一定会跟着变。 但容器可以很好的解决环境不一致的问题,因为容器是将应用与其整个运行环境都打包了,那这个应用在开发环境运行是这种行为,那在生产也就是这种行为。 容器是不是就是把整个虚机打包了? 其实不是这样的,容器比传统的虚机要轻量很多,传统的虚拟化需要在一大片物理资源上运行一个 Hypervisor, 然后虚拟化出一个个完整的操作系统。而容器是操作系统级的虚拟化,这操作系统上会一个非常薄的容器运行引擎,然后容器会与操作系统上共享一个内核,容器创建时并不需要一个新的操作系统,只是在现有的操作系统上在特定的命名空间内赋予对应的操作系统内核以外的环境并在这个命名空间内运行自身想运行的应用。同时这个命名空间会有对应的资源配额的设定,像传统的虚拟机一样,有 CPU 、 内存大小的配额设定。 但容器的启动的时间是秒级,而操作系统是分钟级的。而且实例大小也处于一个量级,所以容器也特别适合在线的横向扩展。 镜像是容器存储格式,做为一个只读的模板,可被用于创建容器,Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从公共镜像仓库下载一个已经制定好的镜像直接使用。
持久化存储
每个容器的创建均来自于指定的镜像,而镜像本身是只读的,容器运行后内部的应用读写文件是不会被反写入到镜像。因此当某容器退出再重启,之前容器生成的文件或写入的内容被丢失,为保证某些数据文件被持久化,需要为容器挂载外部存储,通常以本地主机存储或外部网络存储,将需要被持久化的文件或目录挂载至容器外部,当容器再重启后自动再挂载至对应位置。 数据卷可以是 emptyDir、hostPath、NFS、GlusterFS,其中 emptyDir 仍然是一种临时存储,当没有容器在使用时,数据被销毁; hostPath 为容器的数据写在某主机磁盘上,只要主机磁盘可被访问,数据就不会丢,并且挂载当前主机磁盘的容器都只会被分配在这台机器上。 NFS 与 GlusterFS 为外部网络存储,即容器可随机的调度在集群内任意主机上,因为文件内容最终写入某一网络挂载点。
应用更新策略
Caicloud 为用户提供三种更新策略,分别为重建、滚动与灰度。当某应用被部署运行在 Caicloud 环境内,用户在更新此应用的配置或镜像, Caicloud 将自动依照当前设定的更新策略升级或回滚应用。 重建即将全部的应用实例立即删除,再部署新的应用实例。 滚动即新创建一定数量(可配置最大超量)新版本的应用实例,等待不可用实例数少于一定数量(可配置最大不可用)后,再删除一定数量(可配置最大超量)旧版本的应用实例,再创建一定数量新版本的应用实例,再删除一定数量旧版本的应用实例,直至达到预期的应用实例数量。 灰度即允许用户部署两个版本的应用同时存在一定时间,当确认新版本无问题后,再全部更新为新版本;或确认新版本存在问题,可将新版本回滚至旧版本。与滚动更新的区别在于,滚动更新虽然是两个版本逐步替换,但中间过程是不间断的,而滚动更新可控制两个版本同时存在的时长。
探针
允许用户为容器应用设定健康检查探针与可用性检查探针,健康检查探针能自动发现当前应用是否处于假死状态,发现后将应用容器重启。可用性检查探针会等待当前应用真实处于可用再将其加入后端服务实例以响应客户端请求。
生命周期处理
允许用户为应用设定应用启动之后与退出之前事件处理机制,为应用启动“预热”与退出前“扫尾”。 同时支持设定应用启动与退出的等待时间,为用户提供更多应用启动与退出时相关控制。
事件
为用户提示当前应用或容器最近一段时间的事件变化,例如容器被分配至某机器运行、正在拉取镜像、容器已创建、容器已销毁或容器创建失败及其原因。
负载均衡
Kubernetes 内置的负载均衡器为 4 层负载,即 kube-proxy。内部应用服务之间的访问时使用服务名完成即可使用 kube-proxy 完成转发,当某应用服务需被集群外的客户端访问时,可通过使用 NodePort(节点端口)访问,其内部机制仍是使用 kube-proxy。 kube-proxy 有两个限制点,1 是 kube-proxy 大量使用了 iptables 的 NAT 表,其网络性能有损耗;2 是 kube-proxy 为 4 层负载,应用服务通常以 http 形式对外暴露服务,即为 7 层传输协议,kube-proxy 在转发时会忽略 7 层传输层数据,例如 session、http header,会出现转发混乱或数据丢失等问题。 Caicloud 允许用户创建外部负载均衡器(nginx),并在对外服务暴露场景下替换 NodePort (7 层转发需要时)。
代码构建
为适用于容器云计算平台的一套持续集成/交付组件,支持 GitHub、GitLab、 SVN 等主流 VCS。允许用户在 VCS repo 内设定 CI 配置文件,支持设定 CD 部署方案 代码构建服务通过 API 建立 VCS服务关联后,VCS 上的commit/push/merge 等动作触发构建;代码构建服务从 VCS 拉取代码库中源码;基于源码中配置文件 CI 配置启动需要的服务容器进行集成测试;集成测试通过后,进入 Pre Build 阶段在指定编译环境容器中编译可执行文件;Build 阶段中将可执行文件拷贝到指定运行环境容器中,打成镜文像推送到 Registry 中;Post Build 阶段会做一些镜像发布后的关联操作,比如推送运行依赖的静态资源件到 CDN 中;镜像发布后可以自动更新现有的应用;构建结束构建结果可以发邮件通知用户。