本文是《OpenFaaS梳理》系列的第二篇,在Kubernetes环境把OpenFaaS在搭建好之后,终于可以开始开发函数了;
本篇的主题是熟悉OpenFaaS的函数操作,包括:开发、部署、使用。
本篇demo函数使用的语言是python;
Demo函数:一个简单helloworld函数,将输入的参数加hello字符串输出;
函数操作的流程如下所示,后面会按照这个流程去执行:
前提条件
本文中的操作会用到工具faas-cli,前文已提到过此工具可以部署在任意电脑上;因为需要远程连接OpenFaaS,请确保faas-cli所在机器上安装docker服务,因为构建镜像时会用到。
其中本人在开发时候是在windows下开发的,当时k8s和openfaas部署在公司服务器上,win10下安装了docker-desktop,但是安装其需要本机开启Hyper-V,开启中需要禁止本机的虚拟机使用,而现在的openfaas和harbor部署在虚拟机上,因此弃用,将faas-cli部署在harbor所在的虚拟机上。
下载模板
1. OpenFaaS官方提供了编程语言模板,执行命令faas-cli template pull,可以将最新模板下载到本地:
[root@localhost openfaas]#faas-cli template pull
拉取过程略...
[root@localhost openfaas]# ll
total 0
drwxr-xr-x 19 root root 259 Sep 11 19:01 template
2.执行命令faas-cli new --list,查看模板列表:
[root@localhost openfaas]# faas-cli new --list
Languages available as templates:
- csharp
- dockerfile
- go
- java11
- java11-vert-x
- node
- node12
- node12-debian
- node14
- node16
- node17
- php7
- php8
- python
- python3
- python3-debian
- ruby
创建函数
3. 执行以下命令即可创建函数,add-demo是函数名,python是语言类型,192.168.79.131:8443/openfaas 是docker镜像名字的前缀(后文将会将镜像推送到harbor仓库,这里提前将镜像的仓库地址准备好):
faas-cli new add-demo --lang python -p 192.168.79.131:8443/openfaas
4. 控制台提示如下:
[root@localhost openfaas]# faas-cli new add-demo --lang python -p 192.168.79.131:8443/openfaas
Folder: add-demo created.
___ _____ ____
/ _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) | __/ | | | _| (_| | (_| |___) |
\___/| .__/ \___|_| |_|_| \__,_|\__,_|____/
|_|
Function created in folder: add-demo
Stack file written: add-demo.yml
5. 当前目录下,产生名为add-demo的文件夹,以及名为add-demo.yml的文件:
[root@localhost openfaas]# cat add-demo.yml
version: 1.0
provider:
name: openfaas
gateway: http://192.168.79.139:31112
functions:
add-demo:
lang: python
handler: ./add-demo
image: 192.168.79.131:8443/openfaas/add-demo:latest
调整函数
6. 进入add-demo文件夹,看到faas-cli帮我们生成的源码文件handler.py,默认代码如下:
def handle(req):
"""handle a request to the function
Args:
req (str): request body
"""
return req
7. 本文对代码稍作修改,输出hello + 输入字符:
def handle(req):
"""handle a request to the function
Args:
req (str): request body
"""
return "hello " + req
构建镜像
8. 回到add-demo.yml所在目录,执行以下命令开始构建函数:
faas-cli build -f ./add-demo.yml
[root@localhost openfaas]# faas-cli build -f ./add-demo.yml
[0] > Building add-demo.
Clearing temporary build folder: ./build/add-demo/
Preparing: ./add-demo/ build/add-demo/function
Building: 192.168.79.131:8443/openfaas/add-demo:latest with python template. Please wait..
Sending build context to Docker daemon 8.192kB
Step 1/31 : FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/classic-watchdog:0.2.1 as watchdog
0.2.1: Pulling from openfaas/classic-watchdog
e1749af664ff: Pulling fs layer
e1749af664ff: Verifying Checksum
e1749af664ff: Download complete
e1749af664ff: Pull complete
Digest: sha256:640de69b1d683cbfa73fd3b2d707d33a4e4570164c9795c3be028949688e5c61
Status: Downloaded newer image for ghcr.io/openfaas/classic-watchdog:0.2.1
---> 021a98fdbddd
Step 2/31 : FROM --platform=${TARGETPLATFORM:-linux/amd64} python:2.7-alpine
2.7-alpine: Pulling from library/python
aad63a933944: Pulling fs layer
259d822268fb: Pulling fs layer
10ba96d218d3: Pulling fs layer
44ba9f6a4209: Pulling fs layer
44ba9f6a4209: Waiting
259d822268fb: Verifying Checksum
259d822268fb: Download complete
aad63a933944: Verifying Checksum
aad63a933944: Download complete
aad63a933944: Pull complete
259d822268fb: Pull complete
44ba9f6a4209: Verifying Checksum
44ba9f6a4209: Download complete
10ba96d218d3: Verifying Checksum
10ba96d218d3: Download complete
10ba96d218d3: Pull complete
44ba9f6a4209: Pull complete
Digest: sha256:724d0540eb56ffaa6dd770aa13c3bc7dfc829dec561d87cb36b2f5b9ff8a760a
Status: Downloaded newer image for python:2.7-alpine
...
...
...
Step 28/31 : ENV fprocess="python index.py"
---> Running in 6774aaf570e4
Removing intermediate container 6774aaf570e4
---> f61150d41e40
Step 29/31 : EXPOSE 8080
---> Running in fd957620d4cd
Removing intermediate container fd957620d4cd
---> 5b3141e89310
Step 30/31 : HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || exit 1
---> Running in 3c6d9c9cd8c6
Removing intermediate container 3c6d9c9cd8c6
---> 315f2afdbd13
Step 31/31 : CMD ["fwatchdog"]
---> Running in 138be2cee36d
Removing intermediate container 138be2cee36d
---> 457b458259bd
Successfully built 457b458259bd
Successfully tagged 192.168.79.131:8443/openfaas/add-demo:latest
中间会经历各种过程如拉取基础python镜像和watchdog镜像的过程,具体步骤在构建好的Dockerfile中,后面将会进一步介绍。
9.查看构建的本地镜像:
[root@localhost add-demo]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.79.131:8443/openfaas/add-demo latest 457b458259bd 10 minutes ago 87.3MB
推送仓库
10.将本地的镜像推送到harbor仓库:
faas-cli push -f add-demo.yml
[root@localhost openfaas]# faas-cli push -f add-demo.yml
[0] > Pushing add-demo [192.168.79.131:8443/openfaas/add-demo:latest].
The push refers to repository [192.168.79.131:8443/openfaas/add-demo]
ac95f4404c94: Pushed
01ce4fe2229d: Pushed
7904ee494a25: Pushed
b5de36552cbb: Pushed
e3376aa4a5c9: Pushed
9fcae4fbea52: Pushed
c0e341b7fce5: Pushed
6fa7ff62ba9f: Pushed
aed9982113e1: Pushed
a380b14b73ba: Pushed
23b373933e28: Pushed
afe7539bff16: Pushed
12d19aa1751c: Pushed
879c0d8666e3: Pushed
20a7b70bdf2f: Pushed
3fc750b41be7: Pushed
beee9f30bc1f: Pushed
latest: digest: sha256:10a5cb86966c4da7412977e7110b72a5bad8b1cc92e0b986cbdca3cf2ce5d376 size: 4074
[0] < Pushing add-demo [192.168.79.131:8443/openfaas/add-demo:latest] done.
[0] Worker done.
You have new mail in /var/spool/mail/root
11. 在harbor上查看推送的镜像
此时要关注的是K8S环境如何能访问到此镜像;
要注意的是OpenFaaS默认的镜像拉取策略是Always,即每次都远程拉取,本文这里用的是虚拟机上安装的harbor仓库,因此登录后执行192.168.79.131:8443/openfaas/add-demo:latest 即可推送到远程仓库;
部署函数
12. 执行如下指令登录openfaas服务,其中openfaas为前文部署的openfaas的登录面
faas-cli login -p openfaas
[root@localhost openfaas]# faas-cli login -p openfaas
WARNING! Using --password is insecure, consider using: cat ~/faas_pass.txt | faas-cli login -u user --password-stdin
Calling the OpenFaaS server to validate the credentials...
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.
credentials saved for admin http://192.168.79.139:31112
13. 执行部署命令faas-cli deploy -f add-demo.yml,控制台会提示部署成功,还会给出URL:
[root@localhost openfaas]# faas-cli deploy -f add-demo.yml
Deploying: add-demo.
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.
Deployed. 202 Accepted.
URL: http://192.168.79.139:31112/function/add-demo
You have new mail in /var/spool/mail/root
14. 此时可以登录到openfaas服务所在的虚拟机,在namespace为openfaas-fn下新增了名为add-demo-xxx的pod,且状态正常:
[root@localhost opt]# kubectl get pod -n openfaas-fn
NAME READY STATUS RESTARTS AGE
add-demo-74595d58fc-jkwzx 0/1 ImagePullBackOff 0 2m3s
可见我这里 pod的状态是不成功的,这里需要检查下原因:
kubectl describe pod add-demo-74595d58fc-jkwzx -n openfaas-fn
[root@localhost opt]# kubectl describe pod add-demo-74595d58fc-jkwzx -n openfaas-fn
Name: add-demo-74595d58fc-jkwzx
Namespace: openfaas-fn
Priority: 0
Node: localhost.localdomain/192.168.79.139
Start Time: Sun, 11 Sep 2022 20:06:10 +0800
Labels: faas_function=add-demo
pod-template-hash=74595d58fc
Annotations: cni.projectcalico.org/podIP: 192.168.102.150/32
prometheus.io.scrape: false
Status: Pending
IP: 192.168.102.150
IPs:
IP: 192.168.102.150
Controlled By: ReplicaSet/add-demo-74595d58fc
Containers:
add-demo:
Container ID:
Image: 192.168.79.131:8443/openfaas/add-demo:latest
Image ID:
Port: 8080/TCP
Host Port: 0/TCP
State: Waiting
Reason: ImagePullBackOff
Ready: False
Restart Count: 0
Liveness: http-get http://:8080/_/health delay=2s timeout=1s period=2s #success=1 #failure=3
Readiness: http-get http://:8080/_/health delay=2s timeout=1s period=2s #success=1 #failure=3
Environment:
fprocess: python index.py
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-kq7sp (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-kq7sp:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m40s default-scheduler Successfully assigned openfaas-fn/add-demo-74595d58fc-jkwzx to localhost.localdomain
Normal Pulling 4m7s (x4 over 5m39s) kubelet Pulling image "192.168.79.131:8443/openfaas/add-demo:latest"
Warning Failed 4m7s (x4 over 5m39s) kubelet Failed to pull image "192.168.79.131:8443/openfaas/add-demo:latest": rpc error: code = Unknown desc = Error response from daemon: unknown: repository openfaas/add-demo not found
Warning Failed 4m7s (x4 over 5m39s) kubelet Error: ErrImagePull
Warning Failed 3m56s (x6 over 5m38s) kubelet Error: ImagePullBackOff
Normal BackOff 33s (x21 over 5m38s) kubelet Back-off pulling image "192.168.79.131:8443/openfaas/add-demo:latest"
可见是镜像拉取失败了,原因大概率是K8s所在的机器没有配置harbor登录的安全项导致的,按照如下方式配置后登陆成功。
[root@localhost opt]# vim /etc/docker/daemon.json
[root@localhost opt]# cat /etc/docker/daemon.json
{
"insecure-registries": [
"192.168.79.131:8443"
],
"registry-mirrors": [
"https://192.168.79.131:8443"
]
}
[root@localhost opt]# systemctl daemon-reload
[root@localhost opt]# docker login https://192.168.79.131:8443/ -u admin -p Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
之后,再次查看pod的状态,转为ready
[root@localhost opt]# kubectl get pod -n openfaas-fn
NAME READY STATUS RESTARTS AGE
add-demo-74595d58fc-jkwzx 1/1 Running 0 27m
15. 此时登录管理页面,http://192.168.79.131:31112,可以看到新增的函数,也可以在页面上验证功能调用是否正常,如下图:
也可以在其他电脑上发起请求测试,如下所示,函数可以正常服务:
[root@localhost openfaas]# curl http://192.168.79.139:31112/function/add-demo -X POST -d '打工人'
hello 打工人
You have new mail in /var/spool/mail/root
总结
本节主要梳理openfaas函数构建部署的流程,通过一个简单的python函数演示其具体过程,其中涉及镜像构建的内容和部署还有很多内容并未深究,后文将逐步介绍。