夏日清风 - 基于Docker Swarm的极简Serverless实践

在今年4月份的DockerCon压轴的 Moby's Cool Hack Session上,Alex Ellis给大家展现了一个名为Function as a Service (FaaS)项目。FaaS基于Docker Swarm集群上实现了一个极简的Serverless框架,支持将任意Unix进程作为函数实现来对外提供服务。

FaaS 架构

在 FaaS 原型系统中

  1. 任何进程都可以转化成为一个函数,并利用Docker镜像进行打包和交付
  2. 利用 Docker Swarm 集群的资源调度和routing mesh的负载均衡能力简洁地实现了函数的调度能力。其中每个函数对应一个Docker集群中的服务
  3. 基于 Prometheus 实现函数调用监控和自动伸缩

其设计架构非常简单,其中

  • API Gateway 负责接受服务调用,路由请求到后端函数实现,并采集服务调用的指标发送给 Prometheus。 Prometheus 则会根据一段时间内服务调用的次数,回调API Gateway 来动态伸缩服务容器实例数量。
  • Function Watchdog 将HTTP请求转发为进程调用,并将请求数据通过 STDIN 传递给进程,而将进程的 STDOUT 作为 HTTP 响应的结果返回给调用者。将函数进程和Function Watchdog打包成一个容器镜像进行部署。其调用流程如下:

FaaS 在本地部署非常简单

首先你需要准备一个本地的Docker Swarm集群,如果没有,可以安装最新Docker Engine并执行下面命令:

docker swarm init

执行如下命令来部署FaaS

git clone https://github.com/alexellis/faas
cd faas
./deploy_stack.sh

在部署完成之后,我们可以通过如下命令检查FaaS的状态

$ docker stack services func
ID            NAME               MODE        REPLICAS  IMAGE
1a8b2tb19ulk  func_gateway       replicated  1/1       functions/gateway:0.5.6
4jdexem6kppg  func_webhookstash  replicated  1/1       functions/webhookstash:latest
9ju4er5jur9l  func_wordcount     replicated  1/1       functions/alpine:health
e190suippx7i  func_markdown      replicated  1/1       alexellis2/faas-markdownrender:latest
l70j4c7kf99t  func_alertmanager  replicated  1/1       functions/alertmanager:latest
mgujgoa2u8f3  func_decodebase64  replicated  1/1       functions/alpine:health
o44asbnhqbda  func_hubstats      replicated  1/1       alexellis2/faas-dockerhubstats:latest
q8rx49ow3may  func_echoit        replicated  1/1       functions/alpine:health
t1ao5psnsj0s  func_base64        replicated  1/1       functions/alpine:health
vj5z7rpdlo48  func_prometheus    replicated  1/1       functions/prometheus:latest
xmwzd4z7l4dv  func_nodeinfo      replicated  1/1       functions/nodeinfo:latest

随后通过浏览器来访问 http://127.0.0.1:8080/ui FaaS

整个流程非常简单,就像夏日的清风,让人感到自然愉悦。

在阿里云上测试FaaS

由于FaaS是基于Docker Swarm mode集群进行部署的,你首先需要在阿里云容器服务创建一个Swarm mode集群

然后利用如下模板来部署应用

version: "3"
services:

# Core API services are pinned, HA is provided for functions.
    gateway:
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        ports:
            - 8080:8080
        labels:
            aliyun.routing.port_8080: faas
        image: functions/gateway:0.5.6
        networks:
            - functions
        environment:
            dnsrr: "true"  # Temporarily use dnsrr in place of VIP while issue persists on PWD
        deploy:
            placement:
                constraints: [node.role == manager]

    prometheus:
        image: functions/prometheus:latest  # autobuild from Dockerfile in repo.
        command: "-config.file=/etc/prometheus/prometheus.yml -storage.local.path=/prometheus -storage.local.memory-chunks=10000 --alertmanager.url=http://alertmanager:9093"
        ports:
            - 9090:9090
        depends_on:
            - gateway
            - alertmanager
        labels:
            aliyun.routing.port_9090: prometheus
        environment:
            no_proxy: "gateway"
        networks:
            - functions
        deploy:
            placement:
                constraints: [node.role == manager]

    alertmanager:
        image: functions/alertmanager:latest    # autobuild from Dockerfile in repo.
        environment:
            no_proxy: "gateway"
        command:
            - '-config.file=/alertmanager.yml'
        networks:
            - functions
        ports:
            - 9093:9093
        deploy:
            placement:
                constraints: [node.role == manager]

    # Sample functions go here.

    # Service label of "function" allows functions to show up in UI on http://gateway:8080/
    webhookstash:
        image: functions/webhookstash:latest
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Pass a username as an argument to find how many images user has pushed to Docker Hub.
    hubstats:
        image: alexellis2/faas-dockerhubstats:latest
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Node.js gives OS info about the node (Host)
    nodeinfo:
        image: functions/nodeinfo:latest
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Uses `cat` to echo back response, fastest function to execute.
    echoit:
        image: functions/alpine:health
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            fprocess: "cat"
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Counts words in request with `wc` utility
    wordcount:
        image: functions/alpine:health
        labels:
            function: "true"
            com.faas.max_replicas: "10"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            fprocess: "wc"
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Calculates base64 representation of request body.
    base64:
        image: functions/alpine:health
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            fprocess: "base64"
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Decodes base64 representation of request body.
    decodebase64:
        image: functions/alpine:health
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            fprocess: "base64 -d"
            no_proxy: "gateway"
            https_proxy: $https_proxy

    # Converts body in (markdown format) -> (html)
    markdown:
        image: alexellis2/faas-markdownrender:latest
        labels:
            function: "true"
        depends_on:
            - gateway
        networks:
            - functions
        environment:
            no_proxy: "gateway"
            https_proxy: $https_proxy

networks:
    functions:
        driver: overlay

和本地部署相比只是增加了两个 label,定义了API Gatway和Prometheus的路由

  • "aliyun.routing.port_8080: faas" : API Gatway的虚拟域名
  • "aliyun.routing.port_9090: prometheus" : prometheus服务的虚拟域名

然后基于上面模板创建应用,

注:这里的应用名为 “faas_default”,部署完成之后所有函数服务和访问的名空间都基于这个名称。

部署完成之后,我们可以看见相应的服务列表

选择路由列表标签,我们可以看到之前定义的路由地址已经出现在列表中

可以点击连接上面连接访问FaaS的API Gateway和Prometheus服务界面

下面我们来进行一个测试来验证服务的伸缩性,首先,我们参照文档将Prometheus的URL修改为

http://<prometheus-endpoint>/graph?g0.range_input=15m&g0.expr=gateway_service_count&g0.tab=0&g1.range_input=15m&g1.expr=rate(gateway_function_invocation_total%5B20s%5D)&g1.tab=0&g2.range_input=15m&g2.expr=gateway_functions_seconds_sum+%2F+gateway_functions_seconds_count&g2.tab=0

注:其中URL的prometheus-endpoint需要替换为上文中端点地址

然后在本地运行如下命令

while [ true ] ; do curl -X POST http://<faas-endpoint>/function/faas-default_echoit -d 'Hello, Function as a Service'; done

注:命令中路径需要替换faas-endpoint,如果服务名称与faas-default_echoit不同,也请自行调整。

在Prometheus界面可以看到服务调用量的变化

在容器服务的应用服务列表界面,可以看到,faas-default_echoit的容器实例从1个扩容到20个。

当结束测试之后,服务实例也会缩容到一个

如果对创建自己的函数感兴趣,可以参考 Alex 的博客,本文不再赘述

https://blog.alexellis.io/build-and-deploy-with-faas/

总结

FaaS基于Docker Swarm集群技术,实现了一个极简的Serverless框架,支持将任意Unix进程作为函数来对外提供服务。FaaS目前还是一个原型系统,如果大家需要完备的Function as a Service能力,体验无服务器运维,还是建议采用阿里云 FunctionCompute服务。

FaaS框架展示了一些有趣的可能性

  • 将现有程序封装成为函数,可以作为服务方便地集成到应用业务逻辑中。将函数计算和现有微服务架构应用有机结合在一起。
  • 基于Docker和Swarm集群技术,部署运维非常简单。可以在任何地方部署,甚至是ARM设备上。下图来自RICHARD GEE,演示了在树莓派集群上运行FaaS。

时间: 2024-10-30 19:41:26

夏日清风 - 基于Docker Swarm的极简Serverless实践的相关文章

阿里云上搭建Docker Swarm模式集群最佳实践

Docker技术体系和生态在2016年得到飞速发展.成熟,在2016中国容器技术调研报告中也发现了国内绝大部分用户都在关注 Docker,80%的用户都会考虑使用容器技术.那如何能快速的在阿里云上搭建Docker集群呢?本文将讲解如何利用资源编排快速搭建Docker Swarm 模式集群,本例子中将安装Docker1.12,在Docker1.12中提供了Swarm模式,将一组Docker Engine构成一个集群统一管理.调度. 集群架构图如下: 如果已有VPC网络和NAT网关,可以跳过第一步,

品高公开课 | 基于Docker容器的微服务架构实践

小编的话 "品高公开课"系列文章意在分享技术牛人的知识干货,每期主题都不一样哟!期待各位读者在文后发表留言,来一场技术上的交流和思想上的碰撞! 微服务以一种全新的架构设计模式,牵动了互联网应用从设计到运维整个流程方法论的变革. 而以Docker为代表的容器技术则为微服务理念提供了匹配的实现机制.本周五,将由品高软件工程师陈洪杰带讲述微服务架构的故事. 分享嘉宾 陈洪杰,目前就任品高广州云架构产品部--BingoCloud平台的软件开发工程师,拥有Docker,LXC等多个容器平台的项目

基于docker搭建测试环境

layout: post title: 基于docker搭建测试环境 category: 技术 tags: Docker keywords: Docker shipyard jenkins 简介 当web项目开发完毕后,一般会在测试环境上运行一下,供开发部门调错和测试部门测试.对于具有一定业务规模的公司,几十个上百个web服务,每个服务分别占用一个tomcat目录,配置过程繁琐,且无法集中管理.此外,对于公司的新手来讲,需要一定的背景知识才可以上手. 本文主要讲述基于docker搭建测试环境,或

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

简介 移动互联网.物联网和大数据应用的快速发展极大地促进了人们对云计算的需求.但是让应用架构拥有良好的可伸缩性和高可用性并非易事,运维和管控庞大的基础架构更是极大的挑战. 近年来,一个新的架构风格Serverless成了热门话题.对于一个新的技术浪潮,不同人都会有不同解读.本文将分析Serverless的编程模型,并借力Docker容器技术来打造一个最简单的Serverless平台. 概念 Martin Fowler 在Serverless Architectures的描述了Serverless

几种常见的微服务架构方案——ZeroC IceGrid、Spring Cloud、基于消息队列、Docker Swarm

微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果.虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合项目的特点来选择某个合适的微服务架构平台,以此稳妥地实施项目的微服务化改造或开发进程. 本文选自<架构解密:从分布式到微服务>. 本文盘点了四种常用的微服务架构方案,分别是ZeroC IceGrid.Spring Cloud.基于消息队列与Docker Swarm. ZeroC IceGrid微服

基于Docker API的工具综述

本文讲的是基于Docker API的工具综述,[编者的话]考虑到过去三年Docker取得的骄人成绩以及远程API的成熟,毫无疑问,Docker会成为开发者的首选平台.随着Docker的发展壮大,开发者也共享了很多围绕Docker的开源项目,本文中将讨论这些项目是如何使用Docker API的. Docker是在虚拟容器中简易部署应用最前沿技术.之前我们已经知道Docker可以减少开发维护复杂度,使得正在成长中的架构得以实践.这种架构使得整个应用以及底层操作系统以轻量级容器方式创建和部署,而不是依

麻袋理财基于Docker的容器实践:互联网金融征信项目的微服务化之旅

FinTech第一期 征信是互联网金融的核心系统之一,在单体应用到服务化改造中,定义了API Gateway,Scheduler Service,Data Processing Service,Cache Service和Worker Service等服务,并实现了对基于Docker的微服务化. 本次分享的主题是<麻袋理财基于Docker的容器实践>--              征信要做的事情就是从内部外部获取数据,以此对用户的还款意愿进行甄别. 现在市场上也有很多第三方的征信公司,每家征信

网页设计理论:漂亮而不空洞的极简网站设计

作为设计师,我们都知道,一个极简的设计可以实现漂亮的效果. 然而,很多设计师在实现上有些麻烦:要么是没有时间让使用如此少的元素制作的页面看起来漂亮,要么就是最终的结果只是看起来"不完美". 网上有很多关于极简主义设计的文章,而本文的目的是帮你实现一个漂亮而不空洞的极简网站设计 最重要的是,我们将展示一个小的极简网站设计画廊,这样你就可以分析为什么一些设计可以而其它的则不可以. 什么是极简主义设计 极简主义设计已经被描述为最基本的设计,剔除了多余的元素.色彩.形状和纹理. 它的目的是使内

搭建基于Docker的PHP开发环境的详细教程

  这篇文章主要介绍了搭建基于Docker的PHP开发环境的详细教程,Docker是当下虚拟机技术的最佳选择,需要的朋友可以参考下 现在很多开发者都使用Vagrant来管理他们的虚拟机开发环境,Vagrant确实很酷, 不过也有不少缺点(最主要的是它占用太多的资源).在容器技术.Docker和更多类Docker技术出现后,解决这个问题就变得简单了. 免责声明 由于boot2docker的工作方式,本文所述的方法在你的环境中可能无法正常运行.如果需要在非Linux环境下共享文件夹到Docker容器