• OpenFaaS梳理之二:函数入门


    本文是《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,可以将最新模板下载到本地:

    1. [root@localhost openfaas]#faas-cli template pull
    2. 拉取过程略...
    3. [root@localhost openfaas]# ll
    4. total 0
    5. drwxr-xr-x 19 root root 259 Sep 11 19:01 template

     2.执行命令faas-cli new --list,查看模板列表:

    1. [root@localhost openfaas]# faas-cli new --list
    2. Languages available as templates:
    3. - csharp
    4. - dockerfile
    5. - go
    6. - java11
    7. - java11-vert-x
    8. - node
    9. - node12
    10. - node12-debian
    11. - node14
    12. - node16
    13. - node17
    14. - php7
    15. - php8
    16. - python
    17. - python3
    18. - python3-debian
    19. - 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. 控制台提示如下:

    1. [root@localhost openfaas]# faas-cli new add-demo --lang python -p 192.168.79.131:8443/openfaas
    2. Folder: add-demo created.
    3. ___ _____ ____
    4. / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___|
    5. | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
    6. | |_| | |_) | __/ | | | _| (_| | (_| |___) |
    7. \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/
    8. |_|
    9. Function created in folder: add-demo
    10. Stack file written: add-demo.yml

    5. 当前目录下,产生名为add-demo的文件夹,以及名为add-demo.yml的文件:

    1. [root@localhost openfaas]# cat add-demo.yml
    2. version: 1.0
    3. provider:
    4. name: openfaas
    5. gateway: http://192.168.79.139:31112
    6. functions:
    7. add-demo:
    8. lang: python
    9. handler: ./add-demo
    10. image: 192.168.79.131:8443/openfaas/add-demo:latest

    调整函数

    6. 进入add-demo文件夹,看到faas-cli帮我们生成的源码文件handler.py,默认代码如下:

    1. def handle(req):
    2. """handle a request to the function
    3. Args:
    4. req (str): request body
    5. """
    6. return req

    7.  本文对代码稍作修改,输出hello + 输入字符:

    1. def handle(req):
    2. """handle a request to the function
    3. Args:
    4. req (str): request body
    5. """
    6. return "hello " + req

    构建镜像

    8. 回到add-demo.yml所在目录,执行以下命令开始构建函数:

    faas-cli build -f ./add-demo.yml
    1. [root@localhost openfaas]# faas-cli build -f ./add-demo.yml
    2. [0] > Building add-demo.
    3. Clearing temporary build folder: ./build/add-demo/
    4. Preparing: ./add-demo/ build/add-demo/function
    5. Building: 192.168.79.131:8443/openfaas/add-demo:latest with python template. Please wait..
    6. Sending build context to Docker daemon 8.192kB
    7. Step 1/31 : FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/classic-watchdog:0.2.1 as watchdog
    8. 0.2.1: Pulling from openfaas/classic-watchdog
    9. e1749af664ff: Pulling fs layer
    10. e1749af664ff: Verifying Checksum
    11. e1749af664ff: Download complete
    12. e1749af664ff: Pull complete
    13. Digest: sha256:640de69b1d683cbfa73fd3b2d707d33a4e4570164c9795c3be028949688e5c61
    14. Status: Downloaded newer image for ghcr.io/openfaas/classic-watchdog:0.2.1
    15. ---> 021a98fdbddd
    16. Step 2/31 : FROM --platform=${TARGETPLATFORM:-linux/amd64} python:2.7-alpine
    17. 2.7-alpine: Pulling from library/python
    18. aad63a933944: Pulling fs layer
    19. 259d822268fb: Pulling fs layer
    20. 10ba96d218d3: Pulling fs layer
    21. 44ba9f6a4209: Pulling fs layer
    22. 44ba9f6a4209: Waiting
    23. 259d822268fb: Verifying Checksum
    24. 259d822268fb: Download complete
    25. aad63a933944: Verifying Checksum
    26. aad63a933944: Download complete
    27. aad63a933944: Pull complete
    28. 259d822268fb: Pull complete
    29. 44ba9f6a4209: Verifying Checksum
    30. 44ba9f6a4209: Download complete
    31. 10ba96d218d3: Verifying Checksum
    32. 10ba96d218d3: Download complete
    33. 10ba96d218d3: Pull complete
    34. 44ba9f6a4209: Pull complete
    35. Digest: sha256:724d0540eb56ffaa6dd770aa13c3bc7dfc829dec561d87cb36b2f5b9ff8a760a
    36. Status: Downloaded newer image for python:2.7-alpine
    37. ...
    38. ...
    39. ...
    40. Step 28/31 : ENV fprocess="python index.py"
    41. ---> Running in 6774aaf570e4
    42. Removing intermediate container 6774aaf570e4
    43. ---> f61150d41e40
    44. Step 29/31 : EXPOSE 8080
    45. ---> Running in fd957620d4cd
    46. Removing intermediate container fd957620d4cd
    47. ---> 5b3141e89310
    48. Step 30/31 : HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || exit 1
    49. ---> Running in 3c6d9c9cd8c6
    50. Removing intermediate container 3c6d9c9cd8c6
    51. ---> 315f2afdbd13
    52. Step 31/31 : CMD ["fwatchdog"]
    53. ---> Running in 138be2cee36d
    54. Removing intermediate container 138be2cee36d
    55. ---> 457b458259bd
    56. Successfully built 457b458259bd
    57. Successfully tagged 192.168.79.131:8443/openfaas/add-demo:latest

    中间会经历各种过程如拉取基础python镜像和watchdog镜像的过程,具体步骤在构建好的Dockerfile中,后面将会进一步介绍。

    9.查看构建的本地镜像:

    1. [root@localhost add-demo]# docker images
    2. REPOSITORY TAG IMAGE ID CREATED SIZE
    3. 192.168.79.131:8443/openfaas/add-demo latest 457b458259bd 10 minutes ago 87.3MB

    推送仓库

    10.将本地的镜像推送到harbor仓库:

    faas-cli push -f add-demo.yml
    1. [root@localhost openfaas]# faas-cli push -f add-demo.yml
    2. [0] > Pushing add-demo [192.168.79.131:8443/openfaas/add-demo:latest].
    3. The push refers to repository [192.168.79.131:8443/openfaas/add-demo]
    4. ac95f4404c94: Pushed
    5. 01ce4fe2229d: Pushed
    6. 7904ee494a25: Pushed
    7. b5de36552cbb: Pushed
    8. e3376aa4a5c9: Pushed
    9. 9fcae4fbea52: Pushed
    10. c0e341b7fce5: Pushed
    11. 6fa7ff62ba9f: Pushed
    12. aed9982113e1: Pushed
    13. a380b14b73ba: Pushed
    14. 23b373933e28: Pushed
    15. afe7539bff16: Pushed
    16. 12d19aa1751c: Pushed
    17. 879c0d8666e3: Pushed
    18. 20a7b70bdf2f: Pushed
    19. 3fc750b41be7: Pushed
    20. beee9f30bc1f: Pushed
    21. latest: digest: sha256:10a5cb86966c4da7412977e7110b72a5bad8b1cc92e0b986cbdca3cf2ce5d376 size: 4074
    22. [0] < Pushing add-demo [192.168.79.131:8443/openfaas/add-demo:latest] done.
    23. [0] Worker done.
    24. 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
    1. [root@localhost openfaas]# faas-cli login -p openfaas
    2. WARNING! Using --password is insecure, consider using: cat ~/faas_pass.txt | faas-cli login -u user --password-stdin
    3. Calling the OpenFaaS server to validate the credentials...
    4. WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.
    5. credentials saved for admin http://192.168.79.139:31112

    13. 执行部署命令faas-cli deploy -f add-demo.yml,控制台会提示部署成功,还会给出URL:

    1. [root@localhost openfaas]# faas-cli deploy -f add-demo.yml
    2. Deploying: add-demo.
    3. WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.
    4. Deployed. 202 Accepted.
    5. URL: http://192.168.79.139:31112/function/add-demo
    6. You have new mail in /var/spool/mail/root

    14. 此时可以登录到openfaas服务所在的虚拟机,在namespace为openfaas-fn下新增了名为add-demo-xxx的pod,且状态正常:

    1. [root@localhost opt]# kubectl get pod -n openfaas-fn
    2. NAME READY STATUS RESTARTS AGE
    3. add-demo-74595d58fc-jkwzx 0/1 ImagePullBackOff 0 2m3s

    可见我这里 pod的状态是不成功的,这里需要检查下原因:

    kubectl describe pod add-demo-74595d58fc-jkwzx -n openfaas-fn
    1. [root@localhost opt]# kubectl describe pod add-demo-74595d58fc-jkwzx -n openfaas-fn
    2. Name: add-demo-74595d58fc-jkwzx
    3. Namespace: openfaas-fn
    4. Priority: 0
    5. Node: localhost.localdomain/192.168.79.139
    6. Start Time: Sun, 11 Sep 2022 20:06:10 +0800
    7. Labels: faas_function=add-demo
    8. pod-template-hash=74595d58fc
    9. Annotations: cni.projectcalico.org/podIP: 192.168.102.150/32
    10. prometheus.io.scrape: false
    11. Status: Pending
    12. IP: 192.168.102.150
    13. IPs:
    14. IP: 192.168.102.150
    15. Controlled By: ReplicaSet/add-demo-74595d58fc
    16. Containers:
    17. add-demo:
    18. Container ID:
    19. Image: 192.168.79.131:8443/openfaas/add-demo:latest
    20. Image ID:
    21. Port: 8080/TCP
    22. Host Port: 0/TCP
    23. State: Waiting
    24. Reason: ImagePullBackOff
    25. Ready: False
    26. Restart Count: 0
    27. Liveness: http-get http://:8080/_/health delay=2s timeout=1s period=2s #success=1 #failure=3
    28. Readiness: http-get http://:8080/_/health delay=2s timeout=1s period=2s #success=1 #failure=3
    29. Environment:
    30. fprocess: python index.py
    31. Mounts:
    32. /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-kq7sp (ro)
    33. Conditions:
    34. Type Status
    35. Initialized True
    36. Ready False
    37. ContainersReady False
    38. PodScheduled True
    39. Volumes:
    40. kube-api-access-kq7sp:
    41. Type: Projected (a volume that contains injected data from multiple sources)
    42. TokenExpirationSeconds: 3607
    43. ConfigMapName: kube-root-ca.crt
    44. ConfigMapOptional:
    45. DownwardAPI: true
    46. QoS Class: BestEffort
    47. Node-Selectors:
    48. Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
    49. node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    50. Events:
    51. Type Reason Age From Message
    52. ---- ------ ---- ---- -------
    53. Normal Scheduled 5m40s default-scheduler Successfully assigned openfaas-fn/add-demo-74595d58fc-jkwzx to localhost.localdomain
    54. Normal Pulling 4m7s (x4 over 5m39s) kubelet Pulling image "192.168.79.131:8443/openfaas/add-demo:latest"
    55. 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
    56. Warning Failed 4m7s (x4 over 5m39s) kubelet Error: ErrImagePull
    57. Warning Failed 3m56s (x6 over 5m38s) kubelet Error: ImagePullBackOff
    58. Normal BackOff 33s (x21 over 5m38s) kubelet Back-off pulling image "192.168.79.131:8443/openfaas/add-demo:latest"

     可见是镜像拉取失败了,原因大概率是K8s所在的机器没有配置harbor登录的安全项导致的,按照如下方式配置后登陆成功。

    1. [root@localhost opt]# vim /etc/docker/daemon.json
    2. [root@localhost opt]# cat /etc/docker/daemon.json
    3. {
    4. "insecure-registries": [
    5. "192.168.79.131:8443"
    6. ],
    7. "registry-mirrors": [
    8. "https://192.168.79.131:8443"
    9. ]
    10. }
    11. [root@localhost opt]# systemctl daemon-reload
    12. [root@localhost opt]# docker login https://192.168.79.131:8443/ -u admin -p Harbor12345
    13. WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    14. WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    15. Configure a credential helper to remove this warning. See
    16. https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    17. Login Succeeded

     之后,再次查看pod的状态,转为ready

    1. [root@localhost opt]# kubectl get pod -n openfaas-fn
    2. NAME READY STATUS RESTARTS AGE
    3. add-demo-74595d58fc-jkwzx 1/1 Running 0 27m

    15. 此时登录管理页面,http://192.168.79.131:31112,可以看到新增的函数,也可以在页面上验证功能调用是否正常,如下图:

     

     也可以在其他电脑上发起请求测试,如下所示,函数可以正常服务:

    1. [root@localhost openfaas]# curl http://192.168.79.139:31112/function/add-demo -X POST -d '打工人'
    2. hello 打工人
    3. You have new mail in /var/spool/mail/root

    总结

    本节主要梳理openfaas函数构建部署的流程,通过一个简单的python函数演示其具体过程,其中涉及镜像构建的内容和部署还有很多内容并未深究,后文将逐步介绍。

  • 相关阅读:
    .Net Core WebApi 6.0 及Swagger文档基本创建
    实战分析:项目业务模块划分与包名设计思想
    从收集到输出:盘点那些强大的知识管理工具——优秀笔记软件盘点
    怎么使用Git远程删除某个历史提交记录
    云端日历同步大师:iCloud让工作与生活井井有条
    Android apkanalyzer简介
    Redis实战 | 使用Redis 的有序集合(Sorted Set)实现排行榜功能,和Spring Boot集成
    NLP-D31-ARIMA&《人类语言处理》开课&考试&放松
    LoRA微调语言大模型的实用技巧
    Python中的依赖管理是什么? - 易智编译EaseEditing
  • 原文地址:https://blog.csdn.net/akenseren/article/details/126808090