OpenFaaS on the Docker EE


FaaS (Function As A Service)是允許客戶開發,運行和管理應用程序功能的一個平台,客戶無需費太多心力建置和維護與開發和啟動應用程序相關以及基礎架構相關的複雜性問題。FaaS 通常運用在微服務應用程序領域,依賴 FaaS 平台模塑建置出的應用程序是實現 serverless 微服務架構的一種方法。而 OpenFaas 是由 Alex Ellis 發起的一個開源專案,藉由 OpenFaaS ® 客戶幾乎可以封裝任何應用程序功能作為一個 serverless 微服務應用。OpenFaaS 可以部署在 Kubernetes 或是 Docker Swarm 環境中。

這篇文章介紹如何在 Docker EE UCP cluster 環境裡以 Docker Swarm 來部署建置 OpenFaas,並且進一步利用 OpenFaas 來部署 serverless 應用程式在 Docker EE UCP cluster 環境裡。

Docker EE 的環境類似之前情況,這裡不再贅述,詳情請參閱本部落格前幾篇 posts。

OpenFaaS 的 docker-compose.yml 文件可以從 Github 取得,

# clone the codes of openfaas
$ git clone https://github.com/openfaas/faas

喜歡使用命令行的朋友, OpenFaas CLI 可以透過下列命令取得,將會有一個 faas-cli 運行文件存放在 /usr/local/bin
# download and install faas-cli
$ curl -sSL https://cli.openfaas.com | sudo sh
x86_64
Downloading package https://github.com/openfaas/faas-cli/releases/download/0.7.7/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:  70ebebb71f015f4edb0c3e1f03ef3d262b1d84f6
version: 0.7.7

從 GitHub 下載源代碼之後可以看到 faas 目錄,在那目錄下有一個 docker-compose.yml 那將是我們要來部署在 Docker EE UCP cluster 環境中的 YAML 文件。我做了一些小小的修改,像是 ports mapping 的定義, secrets 的部分,等等。最後修改後的 docker-compose.yml 文件最後結果如下:

#
# docker-compose.yml 
#
version: "3.3"
services:
    gateway:
        ports:
            - 8181:8080
        image: openfaas/gateway:0.8.3
        networks:
            - functions
        environment:
            functions_provider_url: "http://faas-swarm:8181/"
            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: "true"
            secret_mount_path: "/run/secrets/"
        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

    # Docker Swarm provider
    faas-swarm:
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        # ports:
            # - 8081:8080
        image:  openfaas/faas-swarm:0.3.5
        networks:
            - functions
        environment:
            read_timeout:  "300s"   # set both here, and on your functions
            write_timeout: "300s"   # set both here, and on your functions
            DOCKER_API_VERSION: "1.30"
        deploy:
            placement:
                constraints:
                    - 'node.role == manager'
                    - 'node.platform.os == linux'
            resources:
                # limits:   # Enable if you want to limit memory usage
                #     memory: 100M
                reservations:
                    memory: 100M
            restart_policy:
                condition: on-failure
                delay: 5s
                max_attempts: 20
                window: 380s

    nats:
        image: nats-streaming:0.6.0
        # Uncomment the following port mappings if you wish to expose the 
        # NATS client and/or management ports
        # ports:
        #     - 4222:4222
        #     - 8222:8222
        command: "--store memory --cluster_id faas-cluster"
        networks:
            - functions
        deploy:
            resources:
                limits:
                    memory: 125M
                reservations:
                    memory: 50M
            placement:
                constraints:
                    - 'node.platform.os == linux'

    queue-worker:
        image: functions/queue-worker:0.4.6
        networks:
            - functions
        environment:
            max_inflight: "1"
            ack_wait: "300s"    # Max duration of any async task / request
        deploy:
            resources:
                limits:
                    memory: 50M
                reservations:
                    memory: 20M
            restart_policy:
                condition: on-failure
                delay: 5s
                max_attempts: 20
                window: 380s
            placement:
                constraints:
                    - 'node.platform.os == linux'
    # End services

    # Start monitoring

    prometheus:
        image: prom/prometheus:v2.2.0
        environment:
            no_proxy: "gateway"
        configs:
          - source: prometheus_config
            target: /etc/prometheus/prometheus.yml
          - source: prometheus_rules
            target: /etc/prometheus/alert.rules.yml
        command:
          - '--config.file=/etc/prometheus/prometheus.yml'
        #   - '-storage.local.path=/prometheus'
        ports:
            - 9090:9090
        networks:
            - functions
        deploy:
            placement:
                constraints:
                    - 'node.role == manager'
                    - 'node.platform.os == linux'
            resources:
                limits:
                    memory: 500M
                reservations:
                    memory: 200M

    alertmanager:
        image: prom/alertmanager:v0.15.0-rc.0
        environment:
            no_proxy: "gateway"
        command:
            - '--config.file=/alertmanager.yml'
            - '--storage.path=/alertmanager'
        networks:
            - functions
        # Uncomment the following port mapping if you wish to expose the Prometheus
        # Alertmanager UI.
        # ports:
        #     - 9093:9093
        deploy:
            resources:
                limits:
                    memory: 50M
                reservations:
                    memory: 20M
            placement:
                constraints: 
                    - 'node.role == manager'
                    - 'node.platform.os == linux'
        configs:
            - source: alertmanager_config
              target: /alertmanager.yml


configs:
     prometheus_config:
         file: ./prometheus/prometheus.yml
     prometheus_rules:
         file: ./prometheus/alert.rules.yml
     alertmanager_config:
         file: ./prometheus/alertmanager.yml

networks:
    functions:
        driver: overlay
        attachable: true
        labels:
          - "openfaas=true"

secrets:
    basic-auth-user:
        external: true
    basic-auth-password:
        external: true


還有,因為我啟用了 basic auth, 所以開始部署前,先建立兩個 secrets , 分別是 username 和 password ,方法如下:
# Create secrets for the openfaas portal 
# PLEASE replace the username "faassuperuser" with your favorite ones! 
$ echo "faassuperuser" | docker secret create basic-auth-user - 
ry44cf7ptmrtq79vlpjtg7ukd
# PLEASE replace the password "P@s$w0rd" with your favorite ones!
$ echo "P@s$w0rd" | docker secret create basic-auth-password - 
t9n3fmnwvig2u88mofuasmxi6

# Check
$ docker secret ls
ID                          NAME                  CREATED             UPDATED
l64y7g2fxw7t9j0i2f0j9j0cy   ucp-auth-key          3 weeks ago         3 weeks ago
ry44cf7ptmrtq79vlpjtg7ukd   basic-auth-user       29 seconds ago      29 seconds ago
t9n3fmnwvig2u88mofuasmxi6   basic-auth-password   3 seconds ago       3 seconds ago

接著,用 docker stack deploy 命令部署:
# Deploy OpenFaaS on the Docker EE UCP cluster 
$ docker stack deploy -c docker-compose.yml openfaas 
Creating network openfaas_functions
Creating service openfaas_nats
Creating service openfaas_queue-worker
Creating service openfaas_prometheus
Creating service openfaas_alertmanager
Creating service openfaas_gateway
Creating service openfaas_faas-swarm

根據實體機器以及當時平台具體情況,約略幾秒鐘後,可以用下列命令看到部署成功的情況:
# Check
$ docker stack ls
NAME                SERVICES
openfaas            6
$ docker stack services openfaas 
ID                  NAME                    MODE                REPLICAS            IMAGE                            PORTS
golb2v779c2w        openfaas_gateway        replicated          1/1                 openfaas/gateway:0.8.3           *:8181->8080/tcp
jkdj5pqmrgxt        openfaas_queue-worker   replicated          1/1                 functions/queue-worker:0.4.6     
r0kslvfo2tw9        openfaas_prometheus     replicated          1/1                 prom/prometheus:v2.2.0           *:9090->9090/tcp
sl2pqko37qjc        openfaas_alertmanager   replicated          1/1                 prom/alertmanager:v0.15.0-rc.0   
vnfg7dc2qs2c        openfaas_faas-swarm     replicated          1/1                 openfaas/faas-swarm:0.3.5        
vngukrxftijz        openfaas_nats           replicated          1/1                 nats-streaming:0.6.0             

到這裡,已經成功安裝部署 OpenFaas 在 Docker EE 平台!

也可用瀏覽器打開網址 http://:8181 , 輸入 username 和 password 之後,可看到 OpenFaas 畫面:
(port 是 8181,原因請見上列 docker-compose.yml 中的內容 gateway 區塊,username 和 password 是在 secrets 建立時指定好)


如上圖紅色框框的按鈕,按下 DEPLOY NEW FUNCTION, 會出現如下圖的對話框:





【參考資料】

https://www.openfaas.com/

https://docs.openfaas.com/deployment/docker-swarm/

https://en.wikipedia.org/wiki/Function_as_a_service




留言

這個網誌中的熱門文章

Docker 環境下的 Proxy 配置