基于Swarm mode 的极简Serverless实践


函数计算(FaaS)是目前最新的云服务模式,阿里云容器服务基于 swarm mode 集群上实现了一个极简的Serverless 框架,支持将任意 Unix 进程作为函数实现来对外提供服务。更多扩展知识,可参考 阿里云函数计算。``

架构原理


在 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


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

  2. 执行如下命令来部署 FaaS[backcolor=transparent] git clone https[backcolor=transparent]:[backcolor=transparent]//github.com/alexellis/faas
  3. [backcolor=transparent] cd faas
  4. [backcolor=transparent] [backcolor=transparent]./[backcolor=transparent]deploy_stack[backcolor=transparent].[backcolor=transparent]sh

部署完成后,您可以通过如下命令检查 FaaS 的状态
  1. [backcolor=transparent] $ docker stack services func
  2. [backcolor=transparent] ID            NAME               MODE        REPLICAS  IMAGE
  3. [backcolor=transparent] [backcolor=transparent]1a8b2tb19ulk[backcolor=transparent]  func_gateway       replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]gateway[backcolor=transparent]:[backcolor=transparent]0.5[backcolor=transparent].[backcolor=transparent]6
  4. [backcolor=transparent] [backcolor=transparent]4jdexem6kppg[backcolor=transparent]  func_webhookstash  replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]webhookstash[backcolor=transparent]:[backcolor=transparent]latest
  5. [backcolor=transparent] [backcolor=transparent]9ju4er5jur9l[backcolor=transparent]  func_wordcount     replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  6. [backcolor=transparent] e190suippx7i  func_markdown      replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       alexellis2[backcolor=transparent]/[backcolor=transparent]faas[backcolor=transparent]-[backcolor=transparent]markdownrender[backcolor=transparent]:[backcolor=transparent]latest
  7. [backcolor=transparent] l70j4c7kf99t  func_alertmanager  replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]alertmanager[backcolor=transparent]:[backcolor=transparent]latest
  8. [backcolor=transparent] mgujgoa2u8f3  func_decodebase64  replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  9. [backcolor=transparent] o44asbnhqbda  func_hubstats      replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       alexellis2[backcolor=transparent]/[backcolor=transparent]faas[backcolor=transparent]-[backcolor=transparent]dockerhubstats[backcolor=transparent]:[backcolor=transparent]latest
  10. [backcolor=transparent] q8rx49ow3may  func_echoit        replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  11. [backcolor=transparent] t1ao5psnsj0s  func_base64        replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  12. [backcolor=transparent] vj5z7rpdlo48  func_prometheus    replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]prometheus[backcolor=transparent]:[backcolor=transparent]latest
  13. [backcolor=transparent] xmwzd4z7l4dv  func_nodeinfo      replicated  [backcolor=transparent]1[backcolor=transparent]/[backcolor=transparent]1[backcolor=transparent]       functions[backcolor=transparent]/[backcolor=transparent]nodeinfo[backcolor=transparent]:[backcolor=transparent]latest

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


在阿里云上测试 FaaS



限制条件


需要具备创建 swarm mode 集群的条件。
  • 默认情况下,您最多可以创建 5 个集群(所有地域下),每个集群中最多可以添加 20 个节点。如果您需要创建更多的集群或添加更多的节点,请提交 工单申请。
  • 随集群一同创建的负载均衡实例只支持按量付费的方式。
  • 用户账户需有 100 元的余额并通过实名认证,否则无法创建按量付费的 ECS 实例和负载均衡。


操作步骤


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

  2. 使用编排模板创建应用,参见 使用编排模板创建应用
    编排示例如下:[backcolor=transparent] version[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"3"
  3. [backcolor=transparent] services[backcolor=transparent]:
  4. [backcolor=transparent] [backcolor=transparent]# Core API services are pinned, HA is provided for functions.
  5. [backcolor=transparent]     gateway[backcolor=transparent]:
  6. [backcolor=transparent]         volumes[backcolor=transparent]:
  7. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] [backcolor=transparent]"/var/run/docker.sock:/var/run/docker.sock"
  8. [backcolor=transparent]         ports[backcolor=transparent]:
  9. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] [backcolor=transparent]8080[backcolor=transparent]:[backcolor=transparent]8080
  10. [backcolor=transparent]         labels[backcolor=transparent]:
  11. [backcolor=transparent]             aliyun[backcolor=transparent].[backcolor=transparent]routing[backcolor=transparent].[backcolor=transparent]port_8080[backcolor=transparent]:[backcolor=transparent] faas
  12. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]gateway[backcolor=transparent]:[backcolor=transparent]0.5[backcolor=transparent].[backcolor=transparent]6
  13. [backcolor=transparent]         networks[backcolor=transparent]:
  14. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  15. [backcolor=transparent]         environment[backcolor=transparent]:
  16. [backcolor=transparent]             dnsrr[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"[backcolor=transparent]  [backcolor=transparent]# Temporarily use dnsrr in place of VIP while issue persists on PWD
  17. [backcolor=transparent]         deploy[backcolor=transparent]:
  18. [backcolor=transparent]             placement[backcolor=transparent]:
  19. [backcolor=transparent]                 constraints[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent][[backcolor=transparent]node[backcolor=transparent].[backcolor=transparent]role [backcolor=transparent]==[backcolor=transparent] manager[backcolor=transparent]]
  20. [backcolor=transparent]     prometheus[backcolor=transparent]:
  21. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]prometheus[backcolor=transparent]:[backcolor=transparent]latest  [backcolor=transparent]# autobuild from Dockerfile in repo.
  22. [backcolor=transparent]         command[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"-config.file=/etc/prometheus/prometheus.yml -storage.local.path=/prometheus -storage.local.memory-chunks=10000 --alertmanager.url=http://alertmanager:9093"
  23. [backcolor=transparent]         ports[backcolor=transparent]:
  24. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] [backcolor=transparent]9090[backcolor=transparent]:[backcolor=transparent]9090
  25. [backcolor=transparent]         depends_on[backcolor=transparent]:
  26. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  27. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] alertmanager
  28. [backcolor=transparent]         labels[backcolor=transparent]:
  29. [backcolor=transparent]             aliyun[backcolor=transparent].[backcolor=transparent]routing[backcolor=transparent].[backcolor=transparent]port_9090[backcolor=transparent]:[backcolor=transparent] prometheus
  30. [backcolor=transparent]         environment[backcolor=transparent]:
  31. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  32. [backcolor=transparent]         networks[backcolor=transparent]:
  33. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  34. [backcolor=transparent]         deploy[backcolor=transparent]:
  35. [backcolor=transparent]             placement[backcolor=transparent]:
  36. [backcolor=transparent]                 constraints[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent][[backcolor=transparent]node[backcolor=transparent].[backcolor=transparent]role [backcolor=transparent]==[backcolor=transparent] manager[backcolor=transparent]]
  37. [backcolor=transparent]     alertmanager[backcolor=transparent]:
  38. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]alertmanager[backcolor=transparent]:[backcolor=transparent]latest    [backcolor=transparent]# autobuild from Dockerfile in repo.
  39. [backcolor=transparent]         environment[backcolor=transparent]:
  40. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  41. [backcolor=transparent]         command[backcolor=transparent]:
  42. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] [backcolor=transparent]'-config.file=/alertmanager.yml'
  43. [backcolor=transparent]         networks[backcolor=transparent]:
  44. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  45. [backcolor=transparent]         ports[backcolor=transparent]:
  46. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] [backcolor=transparent]9093[backcolor=transparent]:[backcolor=transparent]9093
  47. [backcolor=transparent]         deploy[backcolor=transparent]:
  48. [backcolor=transparent]             placement[backcolor=transparent]:
  49. [backcolor=transparent]                 constraints[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent][[backcolor=transparent]node[backcolor=transparent].[backcolor=transparent]role [backcolor=transparent]==[backcolor=transparent] manager[backcolor=transparent]]
  50. [backcolor=transparent]     [backcolor=transparent]# Sample functions go here.
  51. [backcolor=transparent]     [backcolor=transparent]# Service label of "function" allows functions to show up in UI on http://gateway:8080/
  52. [backcolor=transparent]     webhookstash[backcolor=transparent]:
  53. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]webhookstash[backcolor=transparent]:[backcolor=transparent]latest
  54. [backcolor=transparent]         labels[backcolor=transparent]:
  55. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  56. [backcolor=transparent]         depends_on[backcolor=transparent]:
  57. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  58. [backcolor=transparent]         networks[backcolor=transparent]:
  59. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  60. [backcolor=transparent]         environment[backcolor=transparent]:
  61. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  62. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  63. [backcolor=transparent]     [backcolor=transparent]# Pass a username as an argument to find how many images user has pushed to Docker Hub.
  64. [backcolor=transparent]     hubstats[backcolor=transparent]:
  65. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] alexellis2[backcolor=transparent]/[backcolor=transparent]faas[backcolor=transparent]-[backcolor=transparent]dockerhubstats[backcolor=transparent]:[backcolor=transparent]latest
  66. [backcolor=transparent]         labels[backcolor=transparent]:
  67. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  68. [backcolor=transparent]         depends_on[backcolor=transparent]:
  69. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  70. [backcolor=transparent]         networks[backcolor=transparent]:
  71. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  72. [backcolor=transparent]         environment[backcolor=transparent]:
  73. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  74. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  75. [backcolor=transparent]     [backcolor=transparent]# Node.js gives OS info about the node (Host)
  76. [backcolor=transparent]     nodeinfo[backcolor=transparent]:
  77. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]nodeinfo[backcolor=transparent]:[backcolor=transparent]latest
  78. [backcolor=transparent]         labels[backcolor=transparent]:
  79. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  80. [backcolor=transparent]         depends_on[backcolor=transparent]:
  81. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  82. [backcolor=transparent]         networks[backcolor=transparent]:
  83. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  84. [backcolor=transparent]         environment[backcolor=transparent]:
  85. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  86. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  87. [backcolor=transparent]     [backcolor=transparent]# Uses `cat` to echo back response, fastest function to execute.
  88. [backcolor=transparent]     echoit[backcolor=transparent]:
  89. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  90. [backcolor=transparent]         labels[backcolor=transparent]:
  91. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  92. [backcolor=transparent]         depends_on[backcolor=transparent]:
  93. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  94. [backcolor=transparent]         networks[backcolor=transparent]:
  95. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  96. [backcolor=transparent]         environment[backcolor=transparent]:
  97. [backcolor=transparent]             fprocess[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"cat"
  98. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  99. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  100. [backcolor=transparent]     [backcolor=transparent]# Counts words in request with `wc` utility
  101. [backcolor=transparent]     wordcount[backcolor=transparent]:
  102. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  103. [backcolor=transparent]         labels[backcolor=transparent]:
  104. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  105. [backcolor=transparent]             com[backcolor=transparent].[backcolor=transparent]faas[backcolor=transparent].[backcolor=transparent]max_replicas[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"10"
  106. [backcolor=transparent]         depends_on[backcolor=transparent]:
  107. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  108. [backcolor=transparent]         networks[backcolor=transparent]:
  109. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  110. [backcolor=transparent]         environment[backcolor=transparent]:
  111. [backcolor=transparent]             fprocess[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"wc"
  112. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  113. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  114. [backcolor=transparent]     [backcolor=transparent]# Calculates base64 representation of request body.
  115. [backcolor=transparent]     base64[backcolor=transparent]:
  116. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  117. [backcolor=transparent]         labels[backcolor=transparent]:
  118. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  119. [backcolor=transparent]         depends_on[backcolor=transparent]:
  120. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  121. [backcolor=transparent]         networks[backcolor=transparent]:
  122. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  123. [backcolor=transparent]         environment[backcolor=transparent]:
  124. [backcolor=transparent]             fprocess[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"base64"
  125. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  126. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  127. [backcolor=transparent]     [backcolor=transparent]# Decodes base64 representation of request body.
  128. [backcolor=transparent]     decodebase64[backcolor=transparent]:
  129. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] functions[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]health
  130. [backcolor=transparent]         labels[backcolor=transparent]:
  131. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  132. [backcolor=transparent]         depends_on[backcolor=transparent]:
  133. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  134. [backcolor=transparent]         networks[backcolor=transparent]:
  135. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  136. [backcolor=transparent]         environment[backcolor=transparent]:
  137. [backcolor=transparent]             fprocess[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"base64 -d"
  138. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  139. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  140. [backcolor=transparent]     [backcolor=transparent]# Converts body in (markdown format) -> (html)
  141. [backcolor=transparent]     markdown[backcolor=transparent]:
  142. [backcolor=transparent]         image[backcolor=transparent]:[backcolor=transparent] alexellis2[backcolor=transparent]/[backcolor=transparent]faas[backcolor=transparent]-[backcolor=transparent]markdownrender[backcolor=transparent]:[backcolor=transparent]latest
  143. [backcolor=transparent]         labels[backcolor=transparent]:
  144. [backcolor=transparent]             [backcolor=transparent]function[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"true"
  145. [backcolor=transparent]         depends_on[backcolor=transparent]:
  146. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] gateway
  147. [backcolor=transparent]         networks[backcolor=transparent]:
  148. [backcolor=transparent]             [backcolor=transparent]-[backcolor=transparent] functions
  149. [backcolor=transparent]         environment[backcolor=transparent]:
  150. [backcolor=transparent]             no_proxy[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"gateway"
  151. [backcolor=transparent]             https_proxy[backcolor=transparent]:[backcolor=transparent] $https_proxy
  152. [backcolor=transparent] networks[backcolor=transparent]:
  153. [backcolor=transparent]     functions[backcolor=transparent]:
  154. [backcolor=transparent]         driver[backcolor=transparent]:[backcolor=transparent] overlay

和本地部署相比只是增加了两个 label,定义了 API Gatway 和 Prometheus 的路由
  • aliyun.routing.port_8080: faas : API Gatway 的虚拟域名
  • aliyun.routing.port_9090: prometheus: prometheus 服务的虚拟域名

查看应用的 [backcolor=transparent]路由列表

单击路由地址,访问 FaaS 的 API Gateway 和 Prometheus 服务界面。



后续


你可以在这个基础上,测试服务的伸缩性,具体请参考:

展开
收起
反向一觉 2017-10-30 17:15:03 2902 分享 版权
0 条回答
写回答
取消 提交回答

快速交付实现商业价值。

还有其他疑问?
咨询AI助理