如何在DigitalOceanKubernetes上使用OpenFaaS运行无服务器功能
作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。
介绍
通常,在 Internet 上托管软件应用程序需要对单体系统进行基础架构管理、规划和监控。 与这种传统方法不同,无服务器架构(也称为功能即服务或FaaS)将您的应用程序分解为功能。 这些功能是无状态的、自包含的、事件触发的、功能完整的实体,它们通过您管理的 API 进行通信,而不是通过底层硬件和显式基础设施供应。 与普通应用程序相比,功能在设计上具有可扩展性、可移植性、设置速度更快且更易于测试。 为了使无服务器架构在原则上正常工作,它需要一种与平台无关的打包和编排功能的方式。
OpenFaaS 是一个开源框架,用于在 Kubernetes 上实现无服务器架构,使用 Docker 容器来存储和运行功能。 它允许将任何程序打包为容器并通过命令行或集成的 Web UI 作为函数进行管理。 OpenFaaS 对指标有出色的支持,并在需求增加时为功能提供自动缩放。
在本教程中,您将在您的域中将 OpenFaaS 部署到您的 DigitalOcean Kubernetes 集群,并使用免费的 Let's Encrypt TLS 证书对其进行保护。 您还将探索其 Web UI 并使用官方命令行工具 faas-cli 部署现有和新功能。 最后,您将拥有一个灵活的系统来部署无服务器功能。
先决条件
- 一个 DigitalOcean Kubernetes 集群,您的连接配置为
kubectl
默认值。 集群必须至少有 8GB RAM 和 4 个 CPU 内核可用于 OpenFaaS(如果使用量更大,则需要更多内核)。 创建集群时,在 Connect to your Cluster 步骤下显示了有关如何配置kubectl
的说明。 要在 DigitalOcean 上创建 Kubernetes 集群,请参阅 Kubernetes 快速入门 。 - Docker 安装在您的本地计算机上。 按照您的发行版的第 1 步和第 2 步,请参阅 如何安装 Docker。
- Docker Hub 上的一个帐户,用于存储您将在本教程中创建的 Docker 映像。
- faas-cli,用于管理 OpenFaaS 的官方 CLI 工具,安装在本地计算机上。 多平台使用说明,请访问【X51X】官方文档【X68X】。
- 安装在本地计算机上的 Helm 包管理器。 为此,请完成第 1 步并添加 如何使用 Helm 3 包管理器 教程在 Kubernetes 集群上安装软件的第 2 步中的
stable
存储库。 - Nginx Ingress Controller 和 Cert-Manager 使用 Helm 安装在您的集群上,以便使用 Ingress Resources 公开 OpenFaaS。 如需指导,请遵循 如何使用 Helm 在 DigitalOcean Kubernetes 上设置 Nginx 入口。
- 用于托管 OpenFaaS 的完全注册域名,指向 Nginx Ingress 使用的负载均衡器。 本教程将自始至终使用
openfaas.your_domain
。 您可以在 Namecheap 上购买一个域名,在 Freenom 上免费获得一个域名,或者使用您选择的域名注册商。
注意: 您在本教程中使用的域名必须与“如何在 DigitalOcean Kubernetes 上设置 Nginx Ingress”先决条件教程中使用的域名不同。
第 1 步 — 使用 Helm 安装 OpenFaaS
在这一步中,您将使用 Helm 将 OpenFaaS 安装到您的 Kubernetes 集群并在您的域中公开它。
作为 Nginx 入口控制器先决条件的一部分,您创建了示例服务和入口。 在本教程中您将不需要它们,因此您可以通过运行以下命令来删除它们:
kubectl delete -f hello-kubernetes-first.yaml kubectl delete -f hello-kubernetes-second.yaml kubectl delete -f hello-kubernetes-ingress.yaml
由于您将函数部署为 Kubernetes 对象,因此将它们和 OpenFaaS 本身存储在集群中的单独命名空间中会很有帮助。 OpenFaaS 命名空间将称为 openfaas
,函数命名空间将是 openfaas-fn
。 通过运行以下命令在集群中创建它们:
kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
您将看到以下输出:
Outputnamespace/openfaas created namespace/openfaas-fn created
接下来,您需要添加托管 OpenFaaS 图表的 OpenFaaS Helm 存储库。 为此,请运行以下命令:
helm repo add openfaas https://openfaas.github.io/faas-netes/
Helm 将显示以下输出:
Output"openfaas" has been added to your repositories
刷新 Helm 的图表缓存:
helm repo update
您将看到以下输出:
OutputHang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "openfaas" chart repository ...Successfully got an update from the "jetstack" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈
在安装 OpenFaaS 之前,您需要自定义一些图表参数。 您将它们存储在本地计算机上的一个名为 values.yaml
的文件中。 使用文本编辑器创建并打开文件:
nano values.yaml
添加以下行:
值.yaml
functionNamespace: openfaas-fn generateBasicAuth: true ingress: enabled: true annotations: kubernetes.io/ingress.class: "nginx" hosts: - host: openfaas.your_domain serviceName: gateway servicePort: 8080 path: /
首先,通过将 openfaas-fn
分配给 functionNamespace
变量来指定存储函数的命名空间。 通过将 generateBasicAuth
设置为 true
,您可以命令 Helm 在访问 OpenFaaS Web UI 时设置强制身份验证,并为您生成管理员用户名和密码登录组合。
然后,您启用 Ingress 创建并进一步配置它以使用 Nginx Ingress Controller 并在您的域中提供 gateway
OpenFaaS 服务。
请记住将 openfaas.your_domain
替换为先决条件中所需的域。 完成后,保存并关闭文件。
最后,使用自定义值将 OpenFaaS 安装到 openfaas
命名空间中:
helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml
您将看到以下输出:
OutputRelease "openfaas" does not exist. Installing it now. NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)
输出显示安装成功。 运行以下命令以显示 admin
帐户的密码:
echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode) | tee openfaas-password.txt
使用 tee
同时将解码后的密码写入输出和名为 openfaas-password.txt
的文件。 请注意输出,这是您的 admin
帐户的 OpenFaaS 密码。
您可以通过运行以下命令来查看 OpenFaaS 容器是否可用:
kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
当所有列出的部署变为 ready
时,键入 CTRL + C
退出。
您现在可以在 Web 浏览器中导航到指定的域。 提示时输入 admin
作为用户名和随附的密码。 您将看到 OpenFaaS Web UI:
您已成功安装 OpenFaaS 并在您的域中公开了它的控制面板。 接下来,您将使用 Let's Encrypt 的免费 TLS 证书保护它。
第 2 步 — 为您的域启用 TLS
在此步骤中,您将使用 cert-manager 提供的 Let's Encrypt 证书保护您公开的域。
为此,您需要在 values.yaml
中编辑入口配置。 打开它进行编辑:
nano values.yaml
添加突出显示的行:
值.yaml
generateBasicAuth: true ingress: enabled: true annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: letsencrypt-prod tls: - hosts: - openfaas.your_domain secretName: openfaas-crt hosts: - host: openfaas.your_domain serviceName: gateway servicePort: 8080 path: /
tls
块定义了您的站点的证书(在 hosts
下列出)将存储其证书的 Secret,这些证书由 letsencrypt-prod
ClusterIssuer 颁发。 通常,集群中每个 Ingress 的指定 Secret 必须不同。
请记住将 openfaas.your_domain
替换为您想要的域,然后保存并关闭文件。
通过运行以下命令将更改应用到集群:
helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml
您将看到以下输出:
OutputRelease "openfaas" has been upgraded. Happy Helming! NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 2 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)
您需要等待几分钟,让 Let's Encrypt 服务器为您的域颁发证书。 同时,您可以通过检查以下命令的输出来跟踪其进度:
kubectl describe certificate openfaas-crt -n openfaas
输出的结尾将类似于以下内容:
OutputEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 24m cert-manager Generated a new private key Normal Requested 16m cert-manager Created new CertificateRequest resource "openfaas-crt-1017759607" Normal Issued 16m cert-manager Certificate issued successfully
当输出的最后一行显示Certificate issued successfully
时,可以按CTRL + C
退出。 在浏览器中刷新您的域以进行测试。 您会在浏览器的地址栏左侧看到挂锁,表示您的连接是安全的。
您已经使用 Let's Encrypt 提供的免费 TLS 证书保护了您的 OpenFaaS 域。 现在,您将使用 Web UI 并从中管理功能。
第 3 步 — 通过 Web UI 部署功能
在本节中,您将探索 OpenFaaS Web UI,然后从中部署、管理和调用函数。
OpenFaaS Web UI 有两个主要部分:左侧是列出已部署功能的列,以及中央面板,您将在其中看到有关所选功能的详细信息并能够与之交互。
要部署新功能,请单击左上角 OpenFaaS 徽标下方的 Deploy New Function 按钮。 您将看到一个对话框,要求您选择一个函数:
FROM STORE 选项卡列出了来自官方 OpenFaaS 函数库 的预制函数,您可以立即部署这些函数。 每个函数都有一个简短的描述,您可以选择函数右侧的链接图标来查看其源代码。 要从此列表中部署存储功能,请选择它,然后单击 DEPLOY 按钮。
您还可以通过切换到 CUSTOM 选项卡来提供自己的功能:
在这里,您需要指定专门为 OpenFaaS 配置并在 Docker 注册表(例如 Docker Hub)中可用的函数的 Docker 映像。 在此步骤中,您将从 OpenFaaS 商店部署一个预制函数,然后在接下来的步骤中,您将创建自定义函数并将其部署到 Docker Hub。
您将部署 NodeInfo
函数,该函数返回有关其所部署机器的信息,例如 CPU 架构、内核数、可用的总 RAM 内存和正常运行时间(以秒为单位)。
从存储函数列表中,选择 NodeInfo 并单击 DEPLOY。 它很快就会出现在部署的功能列表中。
选择它。 在屏幕的中央部分,您将看到有关已部署功能的基本信息。
功能状态实时更新,应快速切换到Ready
。 如果它在 Not Ready
停留的时间更长,则很可能是您的集群缺乏资源来接受新的 pod。 您可以关注 如何调整 Droplets 以获取有关如何解决此问题的信息。
一旦 Ready
,就可以通过显示的 URL 访问部署的函数。 要对其进行测试,您可以导航到浏览器中的 URL,或从位于函数信息下方的 Invoke function 面板调用它。
您可以在 Text、JSON 和 Download 之间进行选择,以指示您期望的响应类型。 如果您希望请求是 POST
而不是 GET
,您可以在 Request body 字段中提供请求数据。
要调用 nodeinfo
函数,请单击 INVOKE 按钮。 OpenFaaS 将根据选定的选项制作和执行 HTTP 请求,并用接收到的数据填写响应字段。
响应状态为HTTP 200 OK
,表示请求执行成功。 响应正文包含 NodeInfo 函数收集的系统信息,这意味着它可以正确访问并正常工作。
要删除功能,请从列表中选择它,然后单击页面右上角的垃圾桶图标。 出现提示时,单击 OK 进行确认。 该函数的状态将变为 Not Ready
(这意味着它正在从集群中删除)并且该函数将很快从 UI 中完全消失。
在此步骤中,您使用了 OpenFaaS Web UI,并从中部署和管理功能。 您现在将了解如何使用命令行部署和管理 OpenFaaS 功能。
第 4 步 — 使用 faas-cli 管理功能
在本节中,您将配置 faas-cli 以使用您的集群。 然后,您将通过命令行部署和管理现有功能。
为避免每次运行 faas-cli 时都必须指定 OpenFaaS 域,您将其存储在名为 OPENFAAS_URL
的环境变量中,faas-cli 将在执行期间自动获取并使用其值。
在您的主目录中打开 .bash_profile
进行编辑:
nano ~/.bash_profile
添加以下行:
~/.bash_profile
. . . export OPENFAAS_URL=https://openfaas.your_domain
请记住将 openfaas.your_domain
替换为您的域,然后保存并关闭文件。
为避免再次登录,请手动评估文件:
. ~/.bash_profile
现在,确保您在本地机器上安装了 faas-cli。 如果您还没有安装它,请按照 官方文档 中概述的说明进行安装。
然后,通过运行以下命令设置您的登录凭据:
cat ~/openfaas-password.txt | faas-cli login --username admin --password-stdin
输出将如下所示:
OutputCalling the OpenFaaS server to validate the credentials... credentials saved for admin https://openfaas.your_domain
要从商店部署函数,请运行以下命令:
faas store deploy function_name
您可以尝试通过运行来部署 nodeinfo
:
faas store deploy nodeinfo
您将看到如下输出:
OutputDeployed. 202 Accepted. URL: https://openfaas.your_domain/function/nodeinfo
要列出已部署的功能,请运行 faas list
:
faas list
您现有的功能将显示:
OutputFunction Invocations Replicas nodeinfo 0 1
要获取有关已部署函数的详细信息,请使用 faas describe
:
faas describe nodeinfo
输出将类似于:
Name: nodeinfo Status: Ready Replicas: 1 Available replicas: 1 Invocations: 0 Image: functions/nodeinfo-http:latest Function process: URL: https://openfaas.your_domain/function/nodeinfo Async URL: https://openfaas.your_domain/async-function/nodeinfo Labels: faas_function : nodeinfo uid : 514253614 Annotations: prometheus.io.scrape : false
您可以使用 faas invoke
调用函数:
faas invoke nodeinfo
您将收到以下消息:
OutputReading from STDIN - hit (Control + D) to stop.
然后,您可以提供请求正文。 如果这样做,方法将是 POST
而不是 GET
。 当您完成输入数据,或希望请求为 GET
时,按 CTRL + D
。 然后 faas-cli 将执行推断的请求并输出响应,类似于 Web UI。
要删除函数,请运行 faas remove
:
faas remove nodeinfo
您将获得以下输出:
OutputDeleting: nodeinfo. Removing old function.
再次运行 faas list
可以看到 nodeinfo
被删除:
OutputFunction Invocations Replicas
在此步骤中,您已使用 faas-cli 从命令行部署、列出、调用和删除集群中的函数。 在下一步中,您将创建自己的函数并将其部署到您的集群。
第 5 步 — 创建和部署新功能
现在,您将使用 faas-cli 创建一个示例 Node.JS 函数并将其部署到您的集群。
您将创建的结果函数将被打包为 Docker 容器并发布在 Docker Hub 上。 为了能够发布容器,您需要通过运行以下命令登录:
docker login
当提示完成登录过程时,输入您的 Docker Hub 用户名和密码。
您将把示例 Node.JS 函数存储在名为 sample-js-function
的文件夹中。 使用以下命令创建它:
mkdir sample-js-function
导航到它:
cd sample-js-function
通过运行以下命令,使用 JS 函数的模板填充目录:
faas new sample-js --lang node
输出将如下所示:
Output2020/03/24 17:06:08 No templates found in current directory. 2020/03/24 17:06:08 Attempting to expand templates from https://github.com/openfaas/templates.git 2020/03/24 17:06:10 Fetched 19 template(s) : [csharp csharp-armhf dockerfile go go-armhf java11 java11-vert -x java8 node node-arm64 node-armhf node12 php7 python python-armhf python3 python3-armhf python3-debian ru by] from https://github.com/openfaas/templates.git Folder: sample-js created. ___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| Function created in folder: sample-js Stack file written: sample-js.yml ...
正如输出中所写,函数本身的代码在文件夹 sample-js
中,而函数的 OpenFaaS 配置在文件 sample-js.yaml
中。 在 sample-js
目录(类似于常规 Node.JS 项目)下有两个文件,handler.js
和 package.json
。
handler.js
包含实际的 JS 代码,在调用函数时将返回响应。 处理程序的内容如下所示:
sample-js-function/sample-js/handler.js
"use strict" module.exports = async (context, callback) => { return {status: "done"} }
它导出一个带有两个参数的 lambda 函数,一个带有请求数据的 context
和一个可用于传回响应数据的 callback
,而不仅仅是返回它。
打开此文件进行编辑:
nano sample-js/handler.js
如下更改突出显示的行:
sample-js-function/sample-js/handler.js
"use strict" module.exports = async (context, callback) => { return {status: "<h1>Hello Sammy!</h1>"} }
完成后,保存并关闭文件。 此 OpenFaaS 函数将在调用时将 Hello Sammy!
写入响应。
接下来,打开配置文件进行编辑:
nano sample-js.yml
它将如下所示:
示例-js-function/示例-js.yml
version: 1.0 provider: name: openfaas gateway: https://openfaas.your_domain functions: sample-js: lang: node handler: ./sample-js image: sample-js:latest
对于 provider
,它指定 openfaas
和默认网关。 然后,它定义 sample-js
函数,指定它的语言 (node
)、它的处理程序和 Docker 映像名称,您需要修改这些名称以包含您的 Docker Hub 帐户用户名,如下所示:
示例-js-function/示例-js.yml
version: 1.0 provider: name: openfaas gateway: http://127.0.0.1:8080 functions: sample-js: lang: node handler: ./sample-js image: your_docker_hub_username/sample-js:latest
保存并关闭文件。
然后,构建 Docker 映像,将其推送到 Docker Hub,并将其部署到您的集群上,同时运行以下命令:
faas up -f sample-js.yml
会有很多输出(主要来自 Docker),会这样结束:
Output. . . [0] < Pushing sample-js [your_docker_hub_username/sample-js:latest] done. [0] Worker done. Deploying: sample-js. Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/sample-js
调用新部署的函数以确保它正常工作:
faas invoke sample-js
按 CTRL + D
。 您将看到以下输出:
Output<h1>Hello Sammy!</h1>
这意味着该功能已正确打包和部署。
您可以通过运行删除该功能:
faas remove sample-js
现在,您已在集群中的 OpenFaaS 实例上成功创建并部署了自定义 Node.JS 函数。
结论
您已经在 DigitalOcean Kubernetes 集群上部署了 OpenFaaS,并准备好部署和访问预制和自定义功能。 现在,您可以实现功能即服务架构,这可以提高资源利用率并为您的应用程序带来性能改进。
如果您想了解更多有关高级 OpenFaaS 功能的信息,例如针对您部署的功能的 autoscaling 和 monitoring 它们的性能,请访问 官方文档 。