如何在Ubuntu 16.04上使用Docker Swarm安装和保护OpenFaaS

OpenFaaS是一个免费的开源框架,用于构建和托管无服务器功能。通过对Docker Swarm和Kubernetes的官方支持,它允许您部署应用程序,而无需使用功能强大的API,命令行界面或Web UI来管理底层基础架构。 在本教程中,您将使用在Ubuntu 16.04上运行的Docker Swarm设置和使用OpenFaaS,并通过使用Let's Encypt设置Traefik来保护其Web UI和API。

介绍

无服务器架构从开发人员隐藏服务器实例,并且通常公开允许开发人员在云中运行其应用程序的API。 这种方法可以帮助开发人员快速部署应用程序,因为他们可以将配置和维护实例留给相应的DevOps团队。 它还可以降低基础架构成本,因为通过适当的工具,您可以按需扩展实例。

在无服务器平台上运行的应用程序称为无服务器功能 函数是容器化的,可执行代码,用于执行特定操作。 容器化应用程序可确保您可以在许多计算机上重现一致的环境,从而实现更新和扩展。

OpenFaaS是一个免费的开源框架,用于构建和托管无服务器功能。 通过对Docker SwarmKubernetes的官方支持,它允许您使用功能强大的API,命令行界面或Web UI部署应用程序。 它配备了Prometheus提供的内置指标,支持按需自动扩展,以及从零开始扩展。

在本教程中,您将使用在Ubuntu 16.04上运行的Docker Swarm设置和使用OpenFaaS,并通过使用Let's Encypt设置Traefik来保护其Web UI和API。 这确保了集群中节点之间以及OpenFaaS与其运营商之间的安全通信。

先决条件

要学习本教程,您需要:

  • Ubuntu 16.04在本地计算机上运行。 您可以使用其他发行版和操作系统,但请确保为操作系统使用适当的OpenFaaS脚本,并安装这些先决条件中列出的所有依赖项。
  • gitcurljq安装在本地计算机上。 您将使用git克隆OpenFaaS存储库, curl来测试API,并使用jq将原始JSON响应从API转换为人类可读的JSON。 要为此安装程序安装所需的依赖项,请使用以下命令: sudo apt-get update && sudo apt-get install git curl jq
  • 按照如何在Ubuntu 16.04上安装和使用Docker的第1步和2 安装Docker
  • Docker Hub帐户。 要将功能部署到OpenFaaS,需要在公共容器注册表上发布它们。 我们将在本教程中使用Docker Hub,因为它既免费又广泛使用。 请务必使用docker login命令在本地计算机上使用Docker进行身份验证。
  • 安装了Docker Machine ,遵循如何在Ubuntu 16.04上使用Docker Machine配置和管理远程Docker主机
  • DigitalOcean个人访问令牌。 要创建令牌,请按照以下说明操作
  • 一个包含3个节点的Docker Swarm集群,由Ubuntu 16.04上的如何使用Docker Swarm和DigitalOcean创建Docker容器集群
  • 一个完全注册的域名,其A记录指向Docker Swarm中的一个实例。 在整个教程中,您将看到example.com作为示例域。 您应该将此替换为您自己的域名,您可以在Namecheap上购买,也可以在Freenom上免费获得 您还可以使用您选择的其他域名注册商。

第1步 - 下载OpenFaaS并安装OpenFaaS CLI

要将OpenFaaS部署到Docker Swarm,您需要下载部署清单和脚本。 获取它们的最简单方法是克隆官方OpenFaas存储库并查看代表OpenFaaS版本的相应标记。

除了克隆存储库之外,您还将安装FaaS CLI,这是一个功能强大的命令行实用程序,可用于管理和部署终端中的新功能。 它提供了用于在大多数主要编程语言中创建自己的函数的模板。 第7步中 ,您将使用它来创建Python函数并将其部署在OpenFaaS上。

在本教程中,您将部署OpenFaaS v 0.8.9 虽然部署其他版本的步骤应该类似,但请务必查看项目更改日志以确保没有重大更改。

首先,导航到您的主目录并运行以下命令将存储库克隆到~/faas目录:

cd ~
git clone https://github.com/openfaas/faas.git

导航到新创建的~/faas目录:

cd ~/faas

克隆存储库时,您将从主分支获取包含最新更改的文件。 由于重大更改可以进入主分支,因此不建议在生产中使用。 相反,让我们看看0.8.9标签:

git checkout 0.8.9

输出包含有关成功签出的消息以及有关对此分支提交更改的警告:

Note: checking out '0.8.9'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 8f0d2d1 Expose scale-function endpoint

如果您发现任何错误,请务必按照屏幕上的说明解决这些问题,然后再继续操作。

下载OpenFaaS存储库,完成必要的清单文件后,我们继续安装FaaS CLI。

安装FaaS CLI的最简单方法是使用官方脚本。 在终端中,导航到主目录并使用以下命令下载脚本:

cd ~
curl -sSL -o faas-cli.sh https://cli.openfaas.com

这会将faas-cli.sh脚本下载到您的主目录。 在执行脚本之前,最好检查一下内容:

less faas-cli.sh

您可以按q退出预览。 验证脚本的内容后,可以通过向脚本提供可执行权限并执行它来继续安装。 以root身份执行脚本,以便它自动复制到您的PATH

chmod +x faas-cli.sh
sudo ./faas-cli.sh

输出包含有关安装进度和已安装的CLI版本的信息:

x86_64
Downloading package https://github.com/openfaas/faas-cli/releases/download/0.6.17/faas-cli as /tmp/faas-cli
Download complete.

Running as root - Attempting to move faas-cli to /usr/local/bin
New version of faas-cli installed to /usr/local/bin
Creating alias 'faas' for 'faas-cli'.
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|

CLI:
 commit:  b5597294da6dd98457434fafe39054c993a5f7e7
 version: 0.6.17

如果您看到错误,请确保在继续本教程之前按照屏幕上的说明进行解决。

此时,您已安装FaaS CLI。 要了解有关可以使用的命令的更多信息,请执行CLI而不使用任何参数:

faas-cli

输出显示可用的命令和标志:

  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|


Manage your OpenFaaS functions from the command line

Usage:
  faas-cli [flags]
  faas-cli [command]

Available Commands:
  build          Builds OpenFaaS function containers
  cloud          OpenFaaS Cloud commands
  deploy         Deploy OpenFaaS functions
  help           Help about any command
  invoke         Invoke an OpenFaaS function
  list           List OpenFaaS functions
  login          Log in to OpenFaaS gateway
  logout         Log out from OpenFaaS gateway
  new            Create a new template in the current folder with the name given as name
  push           Push OpenFaaS functions to remote registry (Docker Hub)
  remove         Remove deployed OpenFaaS functions
  store          OpenFaaS store commands
  template       Downloads templates from the specified github repo
  version        Display the clients version information

Flags:
      --filter string   Wildcard to match with function names in YAML file
  -h, --help            help for faas-cli
      --regex string    Regex to match with function names in YAML file
  -f, --yaml string     Path to YAML file describing function(s)

Use "faas-cli [command] --help" for more information about a command.

您现在已成功获取OpenFaaS清单并安装了FaaS CLI,您可以使用它来从终端管理OpenFaaS实例。

~/faas目录包含0.8.9版本的文件,这意味着您现在可以将OpenFaaS部署到Docker Swarm。 在此之前,让我们修改部署清单文件以包含Traefik,它将通过设置Let的加密来保护您的OpenFaaS设置。

第2步 - 配置Traefik

Traefik是一个支持Docker的反向代理,它带有Let's Encrypt提供的SSL支持。 SSL协议通过加密您在节点之间发送和接收的数据,确保您安全地与Swarm群集通信。

要将Traefik与OpenFaaS一起使用,您需要修改OpenFaaS部署清单以包含Traefik并告诉OpenFaaS使用Traefik而不是直接将其服务暴露给互联网。

导航回~/faas目录并在文本编辑器中打开OpenFaaS部署清单:

cd ~/faas
nano ~/faas/docker-compose.yml

注意: Docker Compose清单文件使用YAML格式 ,严格禁止选项卡,并且需要两个空格来缩进。 如果文件格式不正确,清单将无法部署。

OpenFaaS部署由在services指令下定义的若干服务组成,这些服务提供运行OpenFaaS,OpenFaaS API和Web UI以及Prometheus和AlertManager(用于处理指标)所需的依赖关系。

services部分的开头,添加一个名为traefik的新服务,该服务使用traefik:v1.6映像进行部署:

〜/ FAAS /搬运工-compose.yml
version: "3.3"
services:
    traefik:
        image: traefik:v1.6
    gateway:
         ...

Traefik图像来自Traefik Docker Hub存储库 ,您可以在其中找到所有可用图像的列表。

接下来,让我们指示Docker使用command指令运行Traefik。 这将运行Traefik,将其配置为与Docker Swarm一起使用,并使用Let的加密提供SSL。 以下标志将配置Traefik:

  • --docker.* :这些标志告诉Traefik使用Docker并指定它在Docker Swarm集群中运行。
  • --web=true :此标志启用Traefik的Web UI。
  • --defaultEntryPoints--entryPoints :这些标志定义要使用的入口点和协议。 在我们的例子中,这包括端口80上的HTTP和端口443上的HTTPS。
  • --acme.* :这些标志告诉Traefik使用ACME生成Let的加密证书,以使用SSL保护您的OpenFaaS集群。

确保将--acme.domains--acme.email标记中的example.com域占位符替换为您将用于访问OpenFaaS的域。 您可以通过用逗号和空格分隔多个域来指定它们。 电子邮件地址用于SSL通知和警报,包括证书到期警报。 在这种情况下,Traefik将自动处理续订证书,因此您可以忽略到期警报。

image指令下面和gateway上方添加以下代码块:

〜/ FAAS /搬运工-compose.yml
...
    traefik:
        image: traefik:v1.6
        command: -c --docker=true
            --docker.swarmmode=true
            --docker.domain=traefik
            --docker.watch=true
            --web=true
            --defaultEntryPoints='http,https'
            --entryPoints='Name:https Address::443 TLS'
            --entryPoints='Name:http Address::80'
            --acme=true
            --acme.entrypoint='https'
            --acme.httpchallenge=true
            --acme.httpchallenge.entrypoint='http'
            --acme.domains='example.com, www.example.com'
            --acme.email='sammy@example.com'
            --acme.ondemand=true
            --acme.onhostrule=true
            --acme.storage=/etc/traefik/acme/acme.json
...

有了command指令,让我们告诉Traefik哪些端口要暴露给互联网。 Traefik使用端口8080进行操作,而OpenFaaS将使用端口80进行非安全通信,使用端口443进行安全通信。

command指令下面添加以下ports指令。 port-internet : port-docker表示法确保左侧的端口被Traefik暴露到互联网并映射到右侧的容器端口:

〜/ FAAS /搬运工-compose.yml
        ...
        command:
            ...
        ports:
            - 80:80
            - 8080:8080
            - 443:443
        ...

接下来,使用volumes指令,将Docker套接字文件从运行Docker的主机安装到Traefik。 Docker套接字文件与Docker API进行通信,以便管理容器并获取有关它们的详细信息,例如容器数量及其IP地址。 您还将安装名为acme的卷,稍后我们将在此步骤中定义该卷。

networks指令指示Traefik使用与OpenFaaS一起部署的functions网络。 该网络确保功能可以与系统的其他部分(包括API)通信。

deploy指令指示Docker仅在Docker Swarm管理器节点上运行Traefik。

ports指令下面添加以下指令:

〜/ FAAS /搬运工-compose.yml
        ...
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
            - "acme:/etc/traefik/acme"
        networks:
            - functions
        deploy:
            placement:
                constraints: [node.role == manager]

此时, traefik服务块应如下所示:

〜/ FAAS /搬运工-compose.yml
version: "3.3"
services:
    traefik:
        image: traefik:v1.6
        command: -c --docker=true
            --docker.swarmmode=true
            --docker.domain=traefik
            --docker.watch=true
            --web=true
            --defaultEntryPoints='http,https'
            --entryPoints='Name:https Address::443 TLS'
            --entryPoints='Name:http Address::80'            
            --acme=true
            --acme.entrypoint='https'
            --acme.httpchallenge=true
            --acme.httpchallenge.entrypoint='http'
            --acme.domains='example.com, www.example.com'
            --acme.email='sammy@example.com'
            --acme.ondemand=true
            --acme.onhostrule=true
            --acme.storage=/etc/traefik/acme/acme.json
        ports:
            - 80:80
            - 8080:8080
            - 443:443
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
            - "acme:/etc/traefik/acme"
        networks:
          - functions
        deploy:
          placement:
            constraints: [node.role == manager]

    gateway:
        ...

虽然此配置可确保将Traefik与OpenFaaS一起部署,但您还需要配置OpenFaaS以与Traefik配合使用。 默认情况下, gateway服务配置为在端口8080上运行,该端口与Traefik重叠。

gateway服务提供可用于部署,运行和管理功能的API网关。 它处理指标(通过Prometheus)和自动扩展,并托管Web UI。

我们的目标是使用Traefik公开gateway服务,而不是直接将其暴露给互联网。

找到gateway服务,它应如下所示:

〜/ FAAS /搬运工-compose.yml
...
    gateway:
        ports:
            - 8080:8080
        image: openfaas/gateway:0.8.7
        networks:
            - functions
        environment:
            functions_provider_url: "http://faas-swarm:8080/"
            read_timeout:  "300s"        # Maximum time to read HTTP request
            write_timeout: "300s"        # Maximum time to write HTTP response
            upstream_timeout: "300s"     # Maximum duration of upstream function call - should be more than read_timeout and write_timeout
            dnsrr: "true"               # Temporarily use dnsrr in place of VIP while issue persists on PWD
            faas_nats_address: "nats"
            faas_nats_port: 4222
            direct_functions: "true"    # Functions are invoked directly over the overlay network
            direct_functions_suffix: ""
            basic_auth: "${BASIC_AUTH:-true}"
            secret_mount_path: "/run/secrets/"
            scale_from_zero: "false"
        deploy:
            resources:
                # limits:   # Enable if you want to limit memory usage
                #     memory: 200M
                reservations:
                    memory: 100M
            restart_policy:
                condition: on-failure
                delay: 5s
                max_attempts: 20
                window: 380s
            placement:
                constraints:
                    - 'node.platform.os == linux'
        secrets:
            - basic-auth-user
            - basic-auth-password
...

从服务中删除ports指令以避免直接暴露gateway服务。

接下来,将以下lables指令添加到gateway服务的deploy部分。 该指令通过Traefik公开端口8080上的/ui/system/function端点:

〜/ FAAS /搬运工-compose.yml
        ...
        deploy:
            labels:
                - traefik.port=8080
                - traefik.frontend.rule=PathPrefix:/ui,/system,/function
            resources:
            ...            

/ui端点公开了OpenFaaS Web UI,本教程的第6步对此进行了介绍。 /system端点是用于管理OpenFaaS的API端点,而/function端点则公开用于管理和运行功能的API端点。 本教程的第5步详细介绍了OpenFaaS API。

修改后,您的gateway服务应如下所示:

〜/ FAAS /搬运工-compose.yml
...
    gateway:       
        image: openfaas/gateway:0.8.7
        networks:
            - functions
        environment:
            functions_provider_url: "http://faas-swarm:8080/"
            read_timeout:  "300s"        # Maximum time to read HTTP request
            write_timeout: "300s"        # Maximum time to write HTTP response
            upstream_timeout: "300s"     # Maximum duration of upstream function call - should be more than read_timeout and write_timeout
            dnsrr: "true"               # Temporarily use dnsrr in place of VIP while issue persists on PWD
            faas_nats_address: "nats"
            faas_nats_port: 4222
            direct_functions: "true"    # Functions are invoked directly over the overlay network
            direct_functions_suffix: ""
            basic_auth: "${BASIC_AUTH:-true}"
            secret_mount_path: "/run/secrets/"
            scale_from_zero: "false"
        deploy:
            labels:
                - traefik.port=8080
                - traefik.frontend.rule=PathPrefix:/ui,/system,/function
            resources:
                # limits:   # Enable if you want to limit memory usage
                #     memory: 200M
                reservations:
                    memory: 100M
            restart_policy:
                condition: on-failure
                delay: 5s
                max_attempts: 20
                window: 380s
            placement:
                constraints:
                    - 'node.platform.os == linux'
        secrets:
            - basic-auth-user
            - basic-auth-password
...

最后,让我们定义用于存储Let的加密证书的acme音量。 我们可以定义一个空卷,这意味着如果销毁容器,数据将不会持久存在。 如果销毁容器,则下次启动Traefik时将重新生成证书。

在文件的最后一行添加以下volumes指令:

〜/ FAAS /搬运工-compose.yml
...
volumes:
    acme:

完成后,保存文件并关闭文本编辑器。 此时,您已配置Traefik以保护您的OpenFaaS部署和Docker Swarm。 现在,您已准备好在Swarm群集上将其与OpenFaaS一起部署。

第3步 - 部署OpenFaaS

现在您已准备好OpenFaaS部署清单,您已准备好部署它并开始使用OpenFaaS。 要部署,您将使用deploy_stack.sh脚本。 此脚本适用于Linux和macOS操作系统,但在OpenFaaS目录中,您还可以找到适用于WindowsARM系统的相应脚本。

在部署OpenFaaS之前,您需要指示docker docker-machine从Swarm中的一台机器上的脚本执行Docker命令。 在本教程中,我们使用Swarm管理器

如果配置了docker-machine use命令,则可以使用它:

docker-machine use node-1

如果没有,请使用以下命令:

eval $(docker-machine env node-1)

deploy_stack.sh脚本部署deploy_stack.sh所需的所有资源,以便按预期工作,包括配置文件,网络设置,服务和用于OpenFaaS服务器授权的凭据。

让我们执行脚本,这需要几分钟才能完成部署:

~/faas/deploy_stack.sh

输出显示在部署过程中创建的资源列表,以及用于访问OpenFaaS服务器和FaaS CLI命令的凭据。

记下这些凭据,因为在整个教程中您将需要它们来访问Web UI和API:

Attempting to create credentials for gateway..
roozmk0y1jkn17372a8v9y63g
q1odtpij3pbqrmmf8msy3ampl
[Credentials]
 username: admin
 password: your_openfaas_password
 echo -n your_openfaas_password | faas-cli login --username=admin --password-stdin

Enabling basic authentication for gateway..

Deploying OpenFaaS core services
Creating network func_functions
Creating config func_alertmanager_config
Creating config func_prometheus_config
Creating config func_prometheus_rules
Creating service func_alertmanager
Creating service func_traefik
Creating service func_gateway
Creating service func_faas-swarm
Creating service func_nats
Creating service func_queue-worker
Creating service func_prometheus

如果您发现任何错误,请在继续本教程之前按照屏幕上的说明进行解决。

在继续之前,让我们使用部署脚本提供的命令,使用OpenFaaS服务器对FaaS CLI进行身份验证。

该脚本输出了您需要提供给命令的标志,但是您需要添加一个附加标志--gateway ,其中包含OpenFaaS服务器的地址,因为FaaS CLI假定网关服务器在localhost上运行:

echo -n your_openfaas_password | faas-cli login --username=admin --password-stdin --gateway https://example.com

输出包含有关成功授权的消息:

Calling the OpenFaaS server to validate the credentials...
credentials saved for admin https://example.com

此时,您在Docker Swarm集群上部署了功能齐全的OpenFaaS服务器,以及配置为使用新部署的服务器的FaaS CLI。 在测试如何使用OpenFaaS之前,让我们部署一些示例函数来开始。

第4步 - 部署OpenFaaS示例函数

最初,OpenFaaS没有部署任何功能。 要开始测试和使用它,您将需要一些功能。

OpenFaaS项目托管了一些示例函数,您可以在OpenFaaS存储库中找到可用函数列表及其部署清单 一些示例函数包括nodeinfo ,用于显示有关运行函数的节点的信息, wordcount ,用于计算传递的请求中的单词数,以及markdown ,用于将传递的markdown输入转换为HTML输出。

~/faas目录中的stack.yml清单部署了几个示例函数以及上面提到的函数。 您可以使用FaaS CLI进行部署。

运行以下faas-cli命令,该命令获取清单的路径和OpenFaaS服务器的地址:

faas-cli deploy -f ~/faas/stack.yml --gateway https://example.com

输出包含状态代码和指示部署是否成功的消息:

Deploying: wordcount.

Deployed. 200 OK.
URL: https://example.com/function/wordcount

Deploying: base64.

Deployed. 200 OK.
URL: https://example.com/function/base64

Deploying: markdown.

Deployed. 200 OK.
URL: https://example.com/function/markdown

Deploying: hubstats.

Deployed. 200 OK.
URL: https://example.com/function/hubstats

Deploying: nodeinfo.

Deployed. 200 OK.
URL: https://example.com/function/nodeinfo

Deploying: echoit.

Deployed. 200 OK.
URL: https://example.com/function/echoit

如果您发现任何错误,请务必按照屏幕上的说明解决问题。

部署完成后,列出所有功能以确保它们已部署并准备好使用:

faas-cli list --gateway https://example.com

输出包含一系列函数,以及它们的副本号和一个调用计数:

Function                        Invocations     Replicas
markdown                        0               1
wordcount                       0               1
base64                          0               1
nodeinfo                        0               1
hubstats                        0               1
echoit                          0               1

如果您在此处未看到您的功能,请确保成功执行faas-cli deploy命令。

您现在可以使用OpenFaaS示例函数来测试和演示如何使用API​​,Web UI和CLI。 在下一步中,您将首先使用OpenFaaS API列出并运行函数。

第5步 - 使用OpenFaaS API

OpenFaaS附带了一个功能强大的API,可用于管理和执行无服务器功能。 让我们使用Swagger ,一个用于架构,测试和记录API的工具,浏览API文档,然后使用API​​列出和运行函数。

使用Swagger,您可以检查API文档以找出可用的端点以及如何使用它们。 在OpenFaaS存储库中,您可以找到Swagger API规范 ,该规范可与Swagger编辑器一起使用,将规范转换为人类可读的形式。

将Web浏览器导航到http://editor.swagger.io/ 您应该受到以下屏幕的欢迎:

Swagger编辑欢迎页面

在这里,您将找到一个文本编辑器,其中包含示例Swagger规范的源代码,以及右侧的人类可读API文档。

让我们导入OpenFaaS Swagger规范。 在顶部菜单中,单击“ 文件”按钮,然后单击“ 导入URL”

Swagger编辑器导入URL

您将看到一个弹出窗口,您需要在其中输入Swagger API规范的地址。 如果您没有看到弹出窗口,请确保为您的Web浏览器启用了弹出窗口。

在该字段中,输入Swagger OpenFaaS API规范的链接: https://raw.githubusercontent.com/openfaas/faas/master/api-docs/swagger.yml ://raw.githubusercontent.com/openfaas/faas/master/api-docs/swagger.yml

Swagger编辑器输入URL

单击OK按钮后,Swagger编辑器将显示OpenFaaS的API参考,它应如下所示:

Swagger编辑器OpenFaaS API规范

在左侧,您可以看到API参考文件的来源,而在右侧,您可以看到端点列表以及简短描述。 单击端点会显示有关它的更多详细信息,包括它采用的参数,使用的方法以及可能的响应:

Swagger Editor Endpoint详细信息

一旦您知道哪些端点可用以及它们期望的参数,您就可以使用它们来管理您的功能。

接下来,您将使用curl命令与API通信,因此请导航回您的终端。 使用-u标志,您将能够传递在第3步中获得的admin:your_openfaas_password对,而-X标志将定义请求方法。 您还将传递端点URL, https:// example.com /system/functions

curl -u admin:your_openfaas_password -X GET https://example.com/system/functions

您可以在API文档中查看每个端点所需的方法。

在第4步中,您部署了几个示例函数,这些函数应出现在输出中:

[{"name":"base64","image":"functions/alpine:latest","invocationCount":0,"replicas":1,"envProcess":"base64","availableReplicas":0,"labels":{"com.openfaas.function":"base64","function":"true"}},{"name":"nodeinfo","image":"functions/nodeinfo:latest","invocationCount":0,"replicas":1,"envProcess":"","availableReplicas":0,"labels":{"com.openfaas.function":"nodeinfo","function":"true"}},{"name":"hubstats","image":"functions/hubstats:latest","invocationCount":0,"replicas":1,"envProcess":"","availableReplicas":0,"labels":{"com.openfaas.function":"hubstats","function":"true"}},{"name":"markdown","image":"functions/markdown-render:latest","invocationCount":0,"replicas":1,"envProcess":"","availableReplicas":0,"labels":{"com.openfaas.function":"markdown","function":"true"}},{"name":"echoit","image":"functions/alpine:latest","invocationCount":0,"replicas":1,"envProcess":"cat","availableReplicas":0,"labels":{"com.openfaas.function":"echoit","function":"true"}},{"name":"wordcount","image":"functions/alpine:latest","invocationCount":0,"replicas":1,"envProcess":"wc","availableReplicas":0,"labels":{"com.openfaas.function":"wordcount","function":"true"}}]

如果您没有看到如下所示的输出,或者您看到错误,请按照屏幕上的说明解决问题,然后再继续学习本教程。 确保使用推荐的方法和正确的凭据将请求发送到正确的端点。 您还可以使用以下命令检查gateway服务的日志:

docker service logs func_gateway

默认情况下,对curl调用的API响应返回原始JSON而没有新行,这不是人类可读的。 为了解析它,管道curljq实用程序的响应,它将JSON转换为人类可读的形式:

curl -u admin:your_openfaas_password -X GET https://example.com/system/functions | jq

输出现在是人类可读的形式。 您可以看到函数名称,您可以使用它来管理和调用API的函数,调用的数量,以及与Docker相关的标签和副本数量等信息:

[
  {
    "name": "base64",
    "image": "functions/alpine:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "base64",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "base64",
      "function": "true"
    }
  },
  {
    "name": "nodeinfo",
    "image": "functions/nodeinfo:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "nodeinfo",
      "function": "true"
    }
  },
  {
    "name": "hubstats",
    "image": "functions/hubstats:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "hubstats",
      "function": "true"
    }
  },
  {
    "name": "markdown",
    "image": "functions/markdown-render:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "markdown",
      "function": "true"
    }
  },
  {
    "name": "echoit",
    "image": "functions/alpine:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "cat",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "echoit",
      "function": "true"
    }
  },
  {
    "name": "wordcount",
    "image": "functions/alpine:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "wc",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "wordcount",
      "function": "true"
    }
  }
]

让我们使用API /function/ function-name端点来执行其中一个函数并执行它。 此端点可通过POST方法使用,其中-d标志允许您将数据发送到函数。

例如,让我们运行以下curl命令来执行echoit函数,该函数随OpenFaaS开箱即用,并输出您作为请求发送的字符串。 您可以使用字符串"Sammy The Shark"来演示:

curl -u admin:your_openfaas_password -X POST https://example.com/function/func_echoit -d "Sammy The Shark"

输出将显示Sammy The Shark

Sammy The Shark

如果看到错误,请在继续学习本教程之前按照屏幕上的日志解决问题。 您还可以检查gateway服务的日志。

此时,您已使用OpenFaaS API来管理和执行您的功能。 现在让我们来看看OpenFaaS Web UI。

第6步 - 使用OpenFaaS Web UI

OpenFaaS附带一个Web UI,您可以使用它来添加新的和执行已安装的功能。 在此步骤中,您将安装一个函数,用于从FaaS Store生成QR代码并生成示例代码。

首先,将您的Web浏览器指向https:// example.com /ui/ 请注意,需要使用尾部斜杠以避免“未找到”错误。

在HTTP身份验证对话框中,输入在第3步中部署OpenFaaS时获得的用户名和密码。

登录后,您将看到屏幕左侧的可用功能,以及用于安装新功能的“ 部署新功能”按钮。

单击Deploy New Functions以部署新功能。 您将看到FaaS Store窗口,该窗口提供社区测试的功能,您只需单击即可安装:

OpenFaaS Functions存储

除了这些功能,您还可以从Docker镜像手动部署功能。

在本教程中,您将从FaaS Store部署QR代码生成器功能。 找到QR代码生成器 -列表中的Go项目,单击它,然后单击窗口底部的Deploy按钮:

OpenFaaS QR码生成器功能

单击Deploy后 ,将关闭Deploy A New Function窗口并部署该功能。 在窗口左侧的列表中,您将看到qrcode-go功能的列表。 单击此条目以选择它。 主函数窗口将显示函数名称,副本数量,调用计数和图像,以及调用函数的选项:

OpenFaaS二维码功能

让我们生成一个QR码,其中包含您域名的URL。 在“ 请求正文”字段中,键入您要生成的QR代码的内容; 在我们的例子中,这将是“example.com” 完成后,单击“ 调用”按钮。

当您选择TextJSON输出选项时,该函数将输出文件的内容,该内容不可用或不可读:

OpenFaaS生成了QR码

您可以下载回复。 在我们的例子中,它将是一个带有QR码的PNG文件。 为此,请选择“ 下载”选项,然后再次单击“ 调用” 不久之后,您应该下载QR码,您可以使用您选择的图像查看器打开它:

生成的二维码

除了从FaaS存储或Docker镜像部署功能外,您还可以创建自己的功能。 在下一步中,您将使用FaaS命令行界面创建Python函数。

第7步 - 使用FaaS CLI创建功能

在前面的步骤中,您将FaaS CLI配置为与OpenFaaS服务器一起使用。 The FaaS CLI is a command-line interface that you can use to manage OpenFaaS and install and run functions, just like you would over the API or using the Web UI.

Compared to the Web UI or the API, the FaaS CLI has templates for many programming languages that you can use to create your own functions. It can also build container images based on your function code and push images to an image registry, such as Docker Hub.

In this step, you will create a function, publish it to Docker Hub, and then run it on your OpenFaaS server. This function will be similar to the default echoit function, which returns input passed as a request.

We will use Python to write our function. If you want to learn more about Python, you can check out our How To Code in Python 3 tutorial series and our How To Code in Python eBook .

Before creating the new function, let's create a directory to store FaaS functions and navigate to it:

mkdir ~/faas-functions
cd ~/faas-functions

Execute the following command to create a new Python function called echo-input . Make sure to replace your-docker-hub-username with your Docker Hub username, as you'll push the function to Docker Hub later:

faas-cli new echo-input --lang python --prefix your-docker-hub-username --gateway https://example.com

The output contains confirmation about the successful function creation. If you don't have templates downloaded, the CLI will download templates in your current directory:

2018/05/13 12:13:06 No templates found in current directory.
2018/05/13 12:13:06 Attempting to expand templates from https://github.com/openfaas/templates.git
2018/05/13 12:13:11 Fetched 12 template(s) : [csharp dockerfile go go-armhf node node-arm64 node-armhf python python-armhf python3 python3-armhf ruby] from https://github.com/openfaas/templates.git
Folder: echo-input created.
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|


Function created in folder: echo-input
Stack file written: echo-input.yml

The result of the faas-cli new command is a newly-created ~/faas-fucntions/echo-input directory containing the function's code and the echo-input.yml file. This file includes information about your function: what language it's in, its name, and the server you will deploy it on.

Navigate to the ~/faas-fucntions/echo-input directory:

cd ~/faas-fucntions/echo-input

To see content of the directory, execute:

ls

The directory contains two files: handler.py , which contains the code for your function, and requirements.txt , which contains the Python modules required by the function.

Since we don't currently require any non-default Python modules, the requirements.txt file is empty. You can check that by using the cat command:

cat requirements.txt

Next, let's write a function that will return a request as a string.

The handler.py file already has the sample handler code, which returns a received response as a string. Let's take a look at the code:

nano handler.py

The default function is called handle and takes a single parameter, req , that contains a request that's passed to the function when it's invoked. The function does only one thing, returning the passed request back as the response:

def handle(req):
    """handle a request to the function
    Args:
        req (str): request body
    """

    return req

Let's modify it to include additional text, replacing the string in the return directive as follows:

    return "Received message: " + req

Once you're done, save the file and close your text editor.

Next, let's build a Docker image from the function's source code. Navigate to the faas-functions directory where the echo-input.yml file is located:

cd ~/faas-functions

The following command builds the Docker image for your function:

faas-cli build -f echo-input.yml

The output contains information about the build progress:

[0] > Building echo-input.
Clearing temporary build folder: ./build/echo-input/
Preparing ./echo-input/ ./build/echo-input/function
Building: sammy/echo-input with python template. Please wait..
Sending build context to Docker daemon  7.168kB
Step 1/16 : FROM python:2.7-alpine
 ---> 5fdd069daf25
Step 2/16 : RUN apk --no-cache add curl     && echo "Pulling watchdog binary from Github."     && curl -sSL https://github.com/openfaas/faas/releases/download/0.8.0/fwatchdog > /usr/bin/fwatchdog     && chmod +x /usr/bin/fwatchdog     && apk del curl --no-cache
 ---> Using cache
 ---> 247d4772623a
Step 3/16 : WORKDIR /root/
 ---> Using cache
 ---> 532cc683d67b
Step 4/16 : COPY index.py           .
 ---> Using cache
 ---> b4b512152257
Step 5/16 : COPY requirements.txt   .
 ---> Using cache
 ---> 3f9cbb311ab4
Step 6/16 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> dd7415c792b1
Step 7/16 : RUN mkdir -p function
 ---> Using cache
 ---> 96c25051cefc
Step 8/16 : RUN touch ./function/__init__.py
 ---> Using cache
 ---> 77a9db274e32
Step 9/16 : WORKDIR /root/function/
 ---> Using cache
 ---> 88a876eca9e3
Step 10/16 : COPY function/requirements.txt .
 ---> Using cache
 ---> f9ba5effdc5a
Step 11/16 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> 394a1dd9e4d7
Step 12/16 : WORKDIR /root/
 ---> Using cache
 ---> 5a5893c25b65
Step 13/16 : COPY function           function
 ---> eeddfa67018d
Step 14/16 : ENV fprocess="python index.py"
 ---> Running in 8e53df4583f2
Removing intermediate container 8e53df4583f2
 ---> fb5086bc7f6c
Step 15/16 : HEALTHCHECK --interval=1s CMD [ -e /tmp/.lock ] || exit 1
 ---> Running in b38681a71378
Removing intermediate container b38681a71378
 ---> b04c045b0994
Step 16/16 : CMD ["fwatchdog"]
 ---> Running in c5a11078df3d
Removing intermediate container c5a11078df3d
 ---> bc5f08157c5a
Successfully built bc5f08157c5a
Successfully tagged sammy/echo-input:latest
Image: your-docker-hub-username/echo-input built.
[0] < Building echo-input done.
[0] worker done.

If you get an error, make sure to resolve it by following the on-screen instructions before deploying the function.

You will need to containerize your OpenFaaS function in order to deploy it. Containerizing applications ensures that the environment needed to run your application can be easily reproduced, and your application can be easily deployed, scaled, and updated.

For this tutorial, we'll use Docker Hub, as it's a free solution, but you can use any container registry, including your own private registry.

Run the following command to push the image you built to your specified repository on Docker Hub:

faas-cli push -f echo-input.yml

Pushing will take several minutes, depending on your internet connection speed. The output contains the image's upload progress:

[0] > Pushing echo-input.
The push refers to repository [docker.io/sammy/echo-input]
320ea573b385: Pushed 
9d87e56f5d0c: Pushed 
6f79b75e7434: Pushed 
23aac2d8ecf2: Pushed 
2bec17d09b7e: Pushed 
e5a0e5ab3be6: Pushed 
e9c8ca932f1b: Pushed 
beae1d55b4ce: Pushed 
2fcae03ed1f7: Pushed 
62103d5daa03: Mounted from library/python 
f6ac6def937b: Mounted from library/python 
55c108c7613c: Mounted from library/python 
e53f74215d12: Mounted from library/python 
latest: digest: sha256:794fa942c2f593286370bbab2b6c6b75b9c4dcde84f62f522e59fb0f52ba05c1 size: 3033
[0] < Pushing echo-input done.
[0] worker done.

Finally, with your image pushed to Docker Hub, you can use it to deploy a function to your OpenFaaS server.

To deploy your function, run the deploy command, which takes the path to the manifest that describes your function, as well as the address of your OpenFaaS server:

faas-cli deploy -f echo-input.yml --gateway https://example.com

The output shows the status of the deployment, along with the name of the function you're deploying and the deployment status code:

Deploying: echo-input.

Deployed. 200 OK.
URL: https://example.com/function/echo-input

If the deployment is successful, you will see a 200 status code. In the case of errors, follow the provided instructions to fix the problem before continuing.

At this point your function is deployed and ready to be used. You can test that it is working as expected by invoking it.

To invoke a function with the FaaS CLI, use the invoke command by passing the function name and OpenFaaS address to it. After executing the command, you'll be asked to enter the request you want to send to the function.

Execute the following command to invoke the echo-input function:

faas-cli invoke echo-input --gateway https://example.com

You'll be asked to enter the request you want to send to the function:

Reading from STDIN - hit (Control + D) to stop.

Enter the text you want to send to the function, such as:

Sammy The Shark!

Once you're done, press ENTER and then CTRL + D to finish the request. The CTRL + D shortcut in the terminal is used to register an End-of-File (EOF). The OpenFaaS CLI stops reading from the terminal once EOF is received.

After several seconds, the command will output the function's response:

Reading from STDIN - hit (Control + D) to stop.
Sammy The Shark!
Received message: Sammy The Shark!

If you don't see the output or you get an error, retrace the preceding steps to make sure you've deployed the function as explained and follow the on-screen instructions to resolve the problem.

At this point, you've interacted with your function using three methods: the Web UI, the API, and the CLI. Being able to execute your functions with any of these methods offers you the flexibility of deciding how you would like to integrate functions into your existing workflows.

结论

In this tutorial, you've used serverless architecture and OpenFaaS to deploy and manage your applications using the OpenFaaS API, Web UI, and CLI. You also secured your infrastructure by leveraging Traefik to provide SSL using Let's Encrypt.

If you want to learn more about the OpenFaaS project, you can check out their website and the project's official documentation .