大道至简 - 基于Docker的Serverless探索之旅

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
函数计算FC,每月免费额度15元,12个月
简介: 近年来,一个新的架构风格Serverless成了热门话题。对于一个新的技术浪潮,不同人都会有不同解读。本文将分析Serverless的编程模型,并借力Docker容器技术来打造一个最简单的Serverless平台。

14723986600464

简介

移动互联网、物联网和大数据应用的快速发展极大地促进了人们对云计算的需求。但是让应用架构拥有良好的可伸缩性和高可用性并非易事,运维和管控庞大的基础架构更是极大的挑战。

近年来,一个新的架构风格Serverless成了热门话题。对于一个新的技术浪潮,不同人都会有不同解读。本文将分析Serverless的编程模型,并借力Docker容器技术来打造一个最简单的Serverless平台。

概念

Martin Fowler 在Serverless Architectures的描述了Serverless的不同定义。本文将关注于如下的定义:

Serverless can also mean applications where some amount of server-side logic is still written by the application developer but unlike traditional architectures is run in stateless compute containers that are event-triggered, ephemeral (may only last for one invocation), and fully managed by a 3rd party. One way to think of this is ‘Functions as a service / FaaS’ .

Serverless与跟传统架构不同,由开发者实现的服务端逻辑运行在无状态的计算容器中,它是由事件触发,短暂的(可能只存在于一次请求过程中),完全被第三方管理。另一种思考方式,这是函数服务‘Functions as a Service / FaaS’。

其实Serverless和FaaS是在不同维度概括述这个新架构的特性。Serverless从部署运维形态角度,强调其无需关注底层执行环境的优势;而FaaS则是描述是它以服务化的方式提供函数式计算能力。

在这个领域 AWS Lambda是先行者,随后其他厂商相继推出了自己的函数服务,比如Google Cloud Functions和阿里云函数服务等等。

Servrless 架构分析

Serverless应用通常基于的Event-driven编程范型。它的开发方式和经典的Event-condition-action (ECA)非常类似。其通常包含如下方面

  • 事件(Event)的触发器:用于描述触发应用逻辑
  • 事件处理器: 应该是无状态、原子化的任务,并能够从系统的上下文中进行数据交换。
  • 事件的派发和调度:开发者可以声明事件处理器对底层计算资源需求,由系统根据需求自动分配计算资源并调度执行。

和过于技术范的“Functions as a Service”相比,Serverless显然更容易深入人心,然而这个名词也容易给人带来误解。Serverless应用并非不需要服务器作为计算资源,正确的理解是应用开发人员无需关注计算资源的获取和运维,由平台来按需分配计算资源,并保证应用执行的SLA。

正因为上述目标,Serverless/FaaS平台对底层计算环境的提出了特殊要求:

  • 快速启动:需要对事件请求快速响应,能够在亚秒级完成启动
  • 弹性扩展:可以按照应用需求,自动在群集上分配资源,按需伸缩,无需人工干预。
  • 良好的隔离性:不同应用之间不相互干扰
  • 健壮性:应用逻辑执行失败后,可以快速调度并重新执行

看到这里,我们可以看到容器技术(LXC, CGroup等)非常适合用于提供Serverless的计算环境。每次系统接收到事件,动态启动容器来执行业务逻辑即可。这也是为什么有人戏称 “Serverless” Is Basically CGI In Containers

然而在一个大规模分布式环境中支持Serverless/FaaS和在单机操作系统上调度执行一个CGI进程非常不同。我们需要能够标准化的方式来开发、交付和运维事件处理逻辑;并且需要能够在分布式环境中,有效管理各种资源并进行任务调度,同时还要处理各种失效情况来保证应用的高可用。

很多企业和方案,比如IBM OpenWhisk、Iron.io等等,都把Docker容器作为Serverless平台的基础技术。Docker也介绍了使用Docker容器作为Serverless实现技术的原型:(https://blog.docker.com/2016/06/building-serverless-apps-with-docker/)。 阿里云函数服务也和容器服务团队一起推动基于Docker的Serverless平台实现。

下面我会介绍一个基于Docker的Serverless平台的一个高层次的参考架构,其要点如下:

  • Docker容器作为事件处理的计算环境运行
  • 将函数化事件处理逻辑打包成为Docker镜像,利用镜像仓库进行管理和分发
  • 事件调度器配合Docker集群来调度事件处理执行

14724383718155

利用Docker容器的方法实现Serverless平台,有如下优势:

  • 利用Docker提供的轻量级OS虚拟化能力,能够敏捷地创建事件执行运行环境,并提供基本的资源、安全隔离能力
  • 使用Docker镜像和镜像仓库,简单标准地对事件处理逻辑进行打包和在分布式环境下进行软件分发;通过Docker镜像的版本管理和追踪能力,可以管控应用发布,保证应用在大规模分布式环境中部署的一致性。
  • 在Docker容器内部,开发人员可以自由选择使用不同的语言和框架进行事件处理,容器之间不会相互干扰。
  • Docker容器提供了标准化的外界环境交互的能力,应用逻辑可以通过环境变量、文件卷或者网络来访问上下文状态信息。
  • 对不同实现的Docker容器进行统一的标准化运维处理,大大减少运维的复杂性,可以更好地实现自动化运维
  • 基于Docker编排技术(比如阿里云容器服务等)提供的集群管理和编排能力,可以大大简化事件调度器的实现
  • 受益于成熟的Docker的DevOps流程,可以大大提升开发交付效率

一个简单的基于Docker的Servrless原型实现

下面我们就来基于阿里云容器服务来提供一个最简单的Servrless原型,应用架构如下

我们提供了一个最简单的Serverless Controller。它基于Flask框架实现,可以接受HTTP请求作为事件触发。它运行在Docker集群上,并通过容器服务的Cluster Manager来实现在Docker集群上的任务派发,动态地进行事件处理。

14723969660881

其实例代码可以从Github上获得
https://github.com/denverdino/docker-serverless-sample

我们可以分析它的实现代码:当请求者访问 /test1路径时,controller会触发hello_from_docker事件。它会在Docker集群上自动选择一个节点并基于“hello-world”镜像创建一个容器并执行任务。

@app.route('/test1')
def hello_from_docker():
    container = docker_client.create_container('hello-world')
    docker_client.start(container)
    return 'Hello World from container %s!' % container

由于阿里云容器服务完全兼容Docker Swarm,所以应用可以通过Docker原生API来创建容器来执行事件处理逻辑。整个逻辑非常简洁,也具有很好的灵活性,可以执行任何基于Docker镜像的执行逻辑,比如基于Python实现的爬虫、基于R的数据分析算法等等。

这个方法可以非常快速地上路,但是如果事件处理过程中需要支持任务水平伸缩,故障重试等等特性,还需要复杂的编码来在Docker集群上进行调度执行。由于Docker Swarm等编排管理工具更多地是考虑了长时间运行在线应用的调度算法,而对于Serverless这样的短生命周期或离线应用并没有内置支持。但是阿里云容器服务通过非常简单的方法提供了核心的离线任务调度和支持能力。我们可以方便地利用它来支持Serverless应用。

下面提供了一个简单的示例:当请求者访问 /test2路径时,会触发hello_from_aliyun事件。controller会基于“test_template”模板中的定义在Docker集群上创建一个离线应用。在模板中利用通过声明的方式描述了基于容器的任务:test服务由“registry.cn-hangzhou.aliyuncs.com/denverdino/docker-serverless-sample” 镜像提供(它会动态地生成一个UUID);并且指明该服务需要有10个容器实例来执行,和其重试和释放策略;还可以指明任务执行需要的CPU share, Memory limites等资源需求。容器服务会根据这些声明条件自动化动态地在集群中调度任务。

test_template = '''
version: "2"
labels:
  aliyun.project_type: "batch"
services:
  test:
    image: registry.cn-hangzhou.aliyuncs.com/denverdino/docker-serverless-sample
    restart: no
    cpu_shares:  10
    mem_limit: 100000000
    labels:
      aliyun.scale: "10"
      aliyun.retry_count: "20"
      aliyun.remove_containers: "remove-all"
'''

@app.route('/test2')
def hello_from_aliyun():
    project_name="hello%d" % time.time()
    acs_client.create_project(project_name, template=test_template)
    return 'Hello World from Aliyun %s!' % project_name

如果希望了解容器服务提供的离线计算原语,请参阅在阿里云容器服务中运行离线作业

基于容器服务提供的离线计算原语,可以大大简化事件调度,让开发人员关注与事件处理逻辑自身。同时针对业务需求您可以定制事件控制器的实现来控制数据处理流程,比如提供基于管道或者有向无环图的支持。

借力于容器服务提供的高可靠性,如果Docker节点失效会自动调度到其他节点执行;利用容器服务的弹性资源管理,平台可以动态调整集群规模,让其能够满足应用对资源的需求;阿里云容器服务还提供了集成的日志处理和应用监控能力,可以方便地诊断和管控任务执行。

在阿里云上部署

在阿里云上部署基于容器的Serverless管理应用是非常简单的。可以通过下面的 docker-compose模板实现一键部署:

controller:
  image: registry.cn-hangzhou.aliyuncs.com/denverdino/docker-serverless-controller
  environment:
    - CLUSTER_URL=${CLUSTER_URL}
  labels:
    aliyun.addon: "serverless"
    aliyun.routing.port_5000: serverless

由于需要让事件调度器访问容器集群的manager节点,我们需要配置相应的访问证书和集群访问端点。相关信息可以通过选择集群的连接信息来获得:

14724346376089

在容器服务中为了保证安全访问,集群manager需要通过HTTPS来进行访问,并且通过证书方式进行认证。每个集群的证书不同,而且可以动态地吊销和重新生成证书。在每个节点上的/etc/docker/目录下都会包含针对这个节点的集群的访问证书。在节点上容器应用中一个更加简单获得证书的方法是通过label将其标识为aliyun.addon这样,容器就可以在其内部的/etc/docker/目录下获得集群的访问证书了,具体实现示例请参见Github中代码

这样我们可以方便地在容器服务上部署上述模板,部署时只需填写集群的访问端点即可。

14724353496142

这样一个Serverless控制器就部署完成了
14724425845764

访问不同的访问端点就可以触发相应的事件处理逻辑

14724390557360

总结

Serverless 是一种构建分布式计算的应用的方法,而 Docker 是完美的实现Serverless的基础技术。阿里云容器服务在兼容Docker Swarm集群管理和容器调度的同时提供了针对离线计算,服务管控等众多扩展,使得构建一个无需运维(NoOps)的Serverless应用环境非常简单。

如果需要构建一个真正意义上的Serverless平台,当然还有很多需要考虑的事情:比如提供多租户环境的安全隔离;优化调度逻辑来重用容器,避免每次创建等等。这些问题阿里云函数服务等商业化的Serverless平台都会有系统化的解决之道。

想了解更多容器服务内容,请访问 https://www.aliyun.com/product/containerservice

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
2月前
|
Serverless 应用服务中间件 开发工具
Serverless 应用引擎产品使用之阿里函数计算中,在本地进行调试,并且需要用到Docker如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
2月前
|
监控 Serverless Docker
函数计算常见问题之部署docker-compose
函数计算(Function Compute, FC)是阿里云提供的无服务器计算服务,它允许用户在无需管理服务器的情况下运行代码,但在配置和执行过程中可能遇到报错,本合集致力于梳理FC服务中的常见报错和配置问题,并提供解决方案,帮助用户优化函数执行环境。
211 2
|
27天前
|
运维 Serverless 文件存储
函数计算产品使用问题之在利用Docker镜像部署应用时,容器内的应用如何能访问函数计算配置的NAS挂载
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
28天前
|
IDE Serverless 开发工具
函数计算产品使用问题之如何使用Docker镜像作为执行环境
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
28天前
|
存储 Serverless 对象存储
函数计算产品使用问题之项目打包为docker镜像,该如何部署上去
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
2月前
|
缓存 运维 Serverless
Serverless 应用引擎产品使用之在阿里云函数计算中使用Docker进行部署函数如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
2月前
|
存储 监控 Serverless
Serverless应用引擎(SAE)不支持直接通过Docker Compose进行部署
【2月更文挑战第8天】Serverless应用引擎(SAE)不支持直接通过Docker Compose进行部署
280 1
|
8月前
|
Cloud Native Serverless 计算机视觉
Docker与Serverless计算的集成: Docker容器如何与Serverless计算结合。
集成Docker容器和Serverless计算是一种强大的方式,它结合了容器的可移植性和Serverless的自动伸缩性。在本文中,我们将深入探讨如何将这两种技术结合使用,以实现更灵活的应用程序部署方式。
199 0
|
8天前
|
Shell Linux Docker
docker常用命令大全(基础、镜像、容器、数据卷)
这些命令仅仅是 Docker 命令行工具的冰山一角,但对于日常操作来说已经非常全面。通过熟练地使用这些基础命令,用户可以有效地管理 Docker 的镜像、容器、数据卷和网络。随着用户对 Docker 的深入使用,更高级的命令和选项将会变得必需,但上面列出的命令已经为用户提供了一个坚实的起点。对于初学者来说,理解和掌握这些常用命令是深入学习 Docker 的基础。
99 5
docker常用命令大全(基础、镜像、容器、数据卷)
|
5天前
|
Ubuntu Devops 云计算
ubuntu docker-compose编排容器并且设置自启动
使用Docker Compose编排容器并设置为Ubuntu系统的自启动服务,不仅优化了应用的部署流程,也提升了运行时的可管理性和可靠性。通过上述步骤,您可以轻松实现这一目标。维护此类服务时,记得定期检查和更新您的 `docker-compose.yml`文件,确保所有的服务都符合当前的业务需求和技术标准。在云计算和微服务架构不断演进的今天,掌握Docker Compose等工具对于DevOps和软件工程师来说,变得尤为重要。
22 3

热门文章

最新文章

相关产品

  • 函数计算