zl程序教程

您现在的位置是:首页 >  工具

当前栏目

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

Docker 基于 实践 Serverless Swarm
2023-09-11 14:21:06 时间

15007215609278

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

FaaS 架构

在 FaaS 原型系统中

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

image

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

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

image

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

image

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

在阿里云上测试FaaS

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

image

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

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服务的虚拟域名

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

image

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

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

image

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

image

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

image

image

下面我们来进行一个测试来验证服务的伸缩性,首先,我们参照文档将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界面可以看到服务调用量的变化

image

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

image

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

image

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

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

image

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

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

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

image


Docker 多容器编排Swarm(六) Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
易立 易立,阿里云资深专家,目前负责阿里云容器服务和区块链服务研发。之前曾在IBM中国开发中心工作,担任资深技术专员。关注Docker/Kubernetes等云原生计算和Hyperledger Fabric/Ethereum等区块链技术。