如何构建一个简单的CAAS系统

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:


在CAAS系统出现前企业应用架构基本被IAAS/SAAS/PAAS等模式垄断,直到docker的出现为我们打开了另一个扇大门,废话不说了,我们直奔主题

我们先了解下一个简单的CAAS系统是如何为用户提供服务的

  • 企业用户上传它的应用代码或其他代码托管方式,我们生成用户应用的镜像,或者用户直接上传镜像,或者用户直接使用我们提供的基础服务镜像
  • 用户部署他的镜像应用,启动它的镜像容器
  • 用户访问他的应用服务

OK,需求确定了,该搬砖了。

1. 用户镜像制作

既然是一个简单的CAAS系统,我们就不让用户上传代码或者使用第三方代码托管了,直接让他们制作镜像后提交给我们,为此我们需要搭建一个docker私服来让用户上传镜像,假设用户上传的镜像遵循这种格式:docker私服地址/{appId}:{version},这对用户有一定要求,毕竟一些用户可能连docker是啥都不知道就更别奢望让他们编写dockerfile制作镜像交付给我们了。当然如果我们提供一些基础服务镜像(比如mysql服务,redis服务等)给用户那最好了。

2. 启动用户镜像

有了用户制作的镜像,该是启动它的时候了

 
  1. docker pull docker私服地址/{appId}:{version}  
  2. docker run -d docker私服地址/{appId}:{version}  

启动方式很简单,但这并不是我们想要的,毕竟我们是要让用户能够访问到他部署的服务的,假如用户的服务是一个web服务,那你得暴露出用户的web服务端口,这需要我们确定容器的通信方案:

  • 跟宿主机共用一个网络空间
  • 发布一个容器端口,让docker随机选择一个未使用的高位端口
  • 发布一个容器端口,并映射到宿主机上指定端口为外部路由服务
  • 采用docker的'links'来允许容器间通信。 如果一个新容器链接到一个已有容器,新容器将会通过环境变量获得已有容器的链接信息,一个关联的容器将会获得它的对应连接信息,在它处理了那些变量后允许它自动连接。这样就使得同一个宿主机上的容器不需要知道对应服务的端口和地址,就可以直接进行通信

我们简单的CAAS系统暂时还用不到容器间通信,如果跟宿主机共用一个网络空间即--net="host"模式启动的话,那么如果有多个用户上传了镜像,他们的WEB服务端口都是8080,显然宿主机上只能启动一个8080端口,只能有一个用户的容器启动成功,其他的因为端口已经被占用导致启动失败,在这里我们选择第三种模式,选择指定的端口映射来发布容器,这也方便我们后面管理宿主机上的端口资源。OK,启动方式改成下面:

 
  1. docker run -d -p 25701:8080 docker私服地址/{appId}:{version} 

为了不让某个用户的应用占用过多资源导致影响到整个宿主机上其他的应用,我们稍微对用户的资源进行下限制,比如限制用户应用容器的使用内存和CPU权重

 
  1. docker run -d -p 25701:8080 -m 512M -c 1024 docker私服地址/{appId}:{version} 

为了能做到水平扩展,容器服务最好是无状态的的,这样能更好的实现负载均衡和水平扩容。

应用启动成功,我们可以通过在宿主机上访问25701即可访问容器的8080端口服务

在写代码的时候我们通过Docker Remote API client libraries来启动卸载容器,具体代码实现就不多说了。

3. 服务发现

容器启动成功后,用户该如何访问到他的容器服务呢,总不能提供宿主机IP给用户直接访问吧,这就需要我们构建一个服务发现组件了

3.1 服务发现的工作方式:

  • 当每一个服务启动上线之后,他们通过发现工具来注册自身信息
  • 服务的消费者能够在预设的终端查询该服务的相关信息,然后它就可以基于查到的信息与其需要的组件进行交互

为了简便,我们使用zookeeper来作为我们的服务发现工具

首先在容器启动成功后我们将服务注册到zookeeper中,存储的path路径如下:/caas/service/address/{appId}/{version},存储的服务子节点为{containerId}->{宿主机IP}:{服务端口}

例如用户appId01和appId02分别部署了各自的应用版本容器containerId01和containerId02,对应的服务端口分别为25701和25702,那么zk里存储的注册表信息为下:

 
  1. /caas/service/address/appId01/app01Version/containerId01 -> {宿主机IP}:25701 
  2. /caas/service/address/appId02/app02Version/containerId02 -> {宿主机IP}:25702 

如果一个用户部署了多个容器实例,对应的zk注册表信息类似下面:

 
  1. /caas/service/address/{appId}/{version}/containerId01 -> {宿主机IP}:25701 
  2. /caas/service/address/{appId}/{version}/containerId02 -> {宿主机IP}:25702 
  3. /caas/service/address/{appId}/{version}/containerId03 -> {宿主机IP}:25703 
  4. /caas/service/address/{appId}/{version}/containerId04 -> {宿主机IP}:25704 

3.2 故障检测

以上我们完成了服务的注册,注册完服务后为了实现应用的高可用,我们应该还需要对容器进行故障检测,故障检测的方案通常有下面2种:

  • 组件主动请求服务发现心跳方式:组件可以设置一个超时时间,并能定期去请求服务发现来重置超时时间,超时时间达到阀值更新注册表
  • 服务发现主动请求组件心跳方式:服务发现定期的健康检查组件以及当组件出现故障时更新注册表

通常内部自己的服务可以使用第一种方式让组件主动请求服务发现,用户自己写的服务一般不可能费劲的去实现心跳来访问服务发现组件,所以通常会要求用户实现一个服务发现组件能访问的心跳接口,让服务发现组件去主动请求用户的应用,一旦访问失败在重试一定次数后会认为该应用已经出现故障无法继续提供服务,这时可以根据策略来选择直接停止删除该用户容器或者重新启动。

比如服务发现的健康检查组件可以每隔一定时间来访问用户的心跳接口,类似{宿主机IP}:25701/_ping

3.3 注册表安全访问

基于安全方面考虑,通常情况下我们需要对服务发现做相应的访问控制,以便对注册表中的存储信息实现安全访问,可能有以下几种方案可供参考:

  • 服务发现工具可以采用SSL/TLS加密链接
  • 对写入数据进行加密,使用者使用的信息必须用相应的密钥解码从服务发现中获取
  • 服务发现实现访问控制,将不同的键值切分到不同的分组中,根据访问的需要来制定不同的秘钥从而访问相应的分组

这里我们就不说具体的安全方面的实现了,谁让我们是简易版CAAS系统呢。

3.4 分布式配置存储和负载均衡

其实服务发现的注册表存储访问地址只是其中的一个方面,你可以用它来存其他的信息,比如存应用的配置,你可以通过配置动态的调整应用,也可以存容器的相关指标,负载均衡就是一个很好的例子,它可以通过查询服务发现得到各个后端节点承受的流量数,然后根据这个信息来调整配置。具体的负载均衡算法可以根据需求来选择,我们就使用最简单的round bobin算法,即轮询方式访问。这方面的实现涉及到CAAS系统的另一个组件:路由网关,具体后面介绍。

上面我们一直都是使用了zookeeper来作为服务发现工具的,除了zk,我们还可以使用其他的服务发现工具:etcd、consul、crypt、confd,大家有兴趣可以了解下,最重要的是能保证注册表信息的数据一致性。

4. 调度编排

通过上面几步你的CAAS系统基本小有所成了,但这还不够。我们在生产环境里随着用户应用容器的数量增加需要增加宿主机来支撑避免资源不足,或者将某些用户的实例单独部署在指定的宿主机上,这就需要我们实现一个调度器组件。

4.1 宿主选择

CAAS系统是一个分布式系统,在多个宿主机的环境里,我们需要知道用户的应用该部署在哪台宿主机上,如果单机的话那就不需要选择了,直接指定就好了。具体该如何调度需要考虑以下几点:

  • 需要一个默认的调度策略,比如选择可用内存最多的宿主机部署服务或选择cpu最空闲的宿主机部署服务
  • 调度器需要提供覆盖机制,比如2个容器必须部署在同一个宿主机上作为一个单元来运行,比如同一个服务的2个实例容器必须部署在不同机器上来达到高可用
  • 调度器需要满足限制条件,比如给特定的宿主机打标签,比如一些服务需要部署在集群中的每一台宿主机上

4.2 多容器部署调度

随着业务的扩展,我们可能需要提供分组容器管理,将一个集合的容器(通常是有相互依赖关系紧密关联的组件)作为一个单独应用来处理,比如一个web服务容器再加上后端的数据库服务容器组合成一个project来发布。这里就不多做讨论了,我们的简易版系统还没考虑到这步。

4.3 供应

供应是指将一个新主机上线并完成基本配置使得它们能够工作的一个过程,通常在集群管理里用来自动扩展宿主机,管理工具来定义需求额外主机的过程以及自动触发的条件,例如,如果你的应用的负载很高,你可能希望让你的系统增加额外的机器并水平扩展容器以缓解负载,这里我们同样不做实现,简易版就直接手动增加宿主机就好了嘛。

我们在这里举个实现调度器的相对简陋的方案:

主要使用关系型数据库如mysql来存储宿主机信息,调度器查询宿主机的相关指标信息根据调度算法选择相应的宿主机来部署,利用乐观锁来保证并发操作时的数据一致性,利用事务来保证部署和卸载等操作的原子性。这里面可能坑比较多,大家也可以使用现在比较流行的调度器,常用的调度器有:fleet、marathon、Swarm、mesos、Kubernetes、compose,大家有兴趣可以了解下。

5. 网关

上面我们在服务发现的负载均衡方面介绍到了网关,我们把它作为CAAS系统中重要的一个组件,他主要是负责用户请求的转发,举个例子用户部署了容器想要访问它的容器服务,这个请求到达网关后网关根据策略选择相应的后端容器服务然后转发请求。根据用户的设定,动态路由请求到对应容器实例,这相当于一个代理服务器。具体如何选择容器实例服务转发就需要实现负载均衡器,我们可以通过查询服务发现组件来获取相应容器信息来完成。既然是代理服务,我们在中间可以对用户的请求做其他处理,比如做黑名单过滤,做流量统计,做CNames路由等等

假设我们的CAAS网关访问域名是mycaas.gateway.cn,用户在我们后台部署了一个WEB应用容器实例,调度器将他部署在了10.10.10.101宿主机上,容器服务端口映射为25701,用户请求mycaas.gateway.cn到达网关后,网关根据请求信息识别用户查询该用户所有的应用容器信息,得到所有的容器服务地址,根据负载均衡规则代理转发到目标容器服务上。这个查询服务发现的过程中最好实现本地缓存,比如使用zookeeper的缓存减少和避免每次请求都访问服务发现组件,同时代理转发中尽量使用连接池减少开销。

6. 总结

至此我们简单的CAAS系统就架构设计好了,在整个系统中有服务发现/调度器/网关等多个组件协调配合。



作者:David Young

来源:51CTO

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
安全 Linux 网络虚拟化
关于容器云的三种网络设计
【2月更文挑战第9天】容器网络设计:隧道、路由、VLAN。
|
12天前
|
存储 运维 Kubernetes
构建高效稳定的容器化运维环境:Docker与Kubernetes的协同
【4月更文挑战第14天】 在当今快速发展的云计算时代,容器技术以其轻量级、快速部署和易于管理的优势,成为现代应用交付的标准。本文将深入探讨如何通过Docker和Kubernetes的整合使用来构建一个高效且稳定的容器化运维环境。我们将分析Docker容器的基本概念,探索Kubernetes在容器编排方面的强大能力,以及两者结合所带来的益处。文章还将讨论在实际部署中可能遇到的挑战,并提出相应的解决方案。
|
存储 Prometheus Kubernetes
分布式应用打包交付运行的解决方案sealer
通过把分布式应用及其数据库中间件等依赖一起打包以解决复杂应用的交付问题。
|
消息中间件 分布式计算 Kubernetes
 Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。
 Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。
459 0
|
存储 Devops Linux
群晖+DOCKER,一个更好的DEVOPS+WEBOS云平台及综合云OS选型
本文关键字:dualrunning os bootloader设想,dockerized os subsystem appmodel,云devops学编程
763 0
群晖+DOCKER,一个更好的DEVOPS+WEBOS云平台及综合云OS选型
|
Kubernetes 负载均衡 安全
Kubernetes容器平台建设中,F5解决方案好不好?
    近年来,随着OpenStack、Kubernetes等云技术的兴起,应用系统的微服务化、快速迭代对资源的弹性伸缩能力提出了更高的要求。基于多年在负载均衡领域的经验,Kubernetes容器平台建设中,F5解决方案好不好?     F5推出了Kubernetes容器服务解决方案   前不久,民生银行在Kubernetes容器平台建设中,探索使用了一种灵活的软件F5解决方案,在利用F5传统优势的同时,也满足了容器应用的高灵活性要求。
3671 0
基于OpenStack构建企业私有云(1)实验环境准备
基于OpenStack构建企业私有云,能够帮助大家快速的部署两个节点的OpenStack集群。
384 0
基于OpenStack构建企业私有云(1)实验环境准备
|
Kubernetes 测试技术 Linux
容器云之K8s自动化安装方式的选择
目前kubernetes 已经发展到1.5的时代,但在这之前学习和使用kubernetes还是走了不少弯路,第一个问题就是安装,也许你会说安装很简单。照着官网或网上抄一篇就可以装上了…… 而我们使用kubernetes是1.1和1.2版本的时候,那时候最权威的文档应该就是kubernetes.io官网文档……,然而我们在官网进行问题检索的时候会出现(这张图来源网络) 这张图已经很明说明问题了……由于安装过程中的存在的问题,造成之后在使用过程中的一系列问题…… 随着kubernetes的发展(目前已经到达1.5 beta版),和之前相比官方文档也已经更加完善。
2466 0
|
Docker 容器 Cloud Native
微软携手 Docker 打造 CNAB,实现跨分布式应用程序的统一管理
越来越多的组织开始使用云原生的应用程序和基础架构来构建现代化软件环境,但市场上并没有单一的解决方案来定义和打包这些多服务、多格式的分布式应用程序。
2127 0