OpenFaaS-Deploy-Original-Function

OpenFaaS をデプロイすることには成功したが、自作の Fucntion を OpenFaaS にデプロイしようとすると Ready にならない。何か手順が足りないのだろうとログを確認してみた。

ログを確認する

kubectl get events コマンドでログを確認する。

1
2
3
4
5
6
7
8
$ kubectl get events -n openfaas-fn  --sort-by=.metadata.creationTimestamp
...
1m Normal Scheduled pod/hello-f8fb4cb89-7c5bv Successfully assigned openfaas-fn/hello-f8fb4cb89-7c5bv to minikube
20m Normal Pulling pod/hello-f8fb4cb89-7c5bv Pulling image "hello:latest"
103s Warning Failed pod/hello-f8fb4cb89-7c5bv Error: ImagePullBackOff
19m Warning Failed pod/hello-f8fb4cb89-7c5bv Error: ErrImagePull
19m Warning Failed pod/hello-f8fb4cb89-7c5bv Failed to pull image "hello:latest": rpc error: code = Unknown desc = Error response from daemon: pull access denied for hello, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
16m Normal BackOff pod/hello-f8fb4cb89-7c5bv Back-off pulling image "hello:latest"

どうやら何も指定をしないと、Docker Hub から Docker イメージを取得しようと試みるようだ。確認用の自作 Function を公開するのもなんなので、ローカルに Docker リポジトリを構築することにする。

Docker registry をロカールに構築する

ローカルに Docker リポジトリを構築する。

registry を起動する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ docker pull registry
Using default tag: latest
latest: Pulling from library/registry
9b794450f7b6: Already exists
6ba25693af03: Pull complete
9eb68e7589ff: Pull complete
6cf77150f665: Pull complete
339e0c26c7cc: Pull complete
Digest: sha256:5bb9b919833aa955dfe1d1121cc038330b025ec6506ce47066c9192927e3dc3d
Status: Downloaded newer image for registry:latest
docker.io/library/registry:latest
$ docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /var/opt:/var/lib/registry \
registry:latest
6f87e51e96f389b1ab94f063d7763f3cada7d4c83f65c82b2355b74df0990bd3

Docker イメージを push する

確認のため、hello-world イメージを Dockcer Hub から pull し、そのイメージをローカルの Dokcer リポジトリに push してみる。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
$ docker tag hello-world:latest localhost:5000/hello-world
$ docker push localhost:5000/hello-world
Using default tag: latest
The push refers to repository [localhost:5000/hello-world]
f22b99068db9: Pushed
latest: digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792 size: 525

確認

いったん Docker イメージを削除する。

1
2
3
$ docker rmi localhost:5000/hello-world
Untagged: localhost:5000/hello-world:latest
Untagged: localhost:5000/hello-world@sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792

削除されていることを確認する。

1
2
$ docker images | grep hello-world
hello-world latest d1165f221234 5 weeks ago 13.3kB

Docker イメージを pull する。

1
2
3
4
5
6
$ docker pull localhost:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
Digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792
Status: Downloaded newer image for localhost:5000/hello-world:latest
localhost:5000/hello-world:latest

pull できたことを確認する。

1
2
3
$ docker images | grep hello-world
hello-world latest d1165f221234 5 weeks ago 13.3kB
localhost:5000/hello-world latest d1165f221234 5 weeks ago 13.3kB

insecure-registry オプションを付与して minikube を起動する

Docker Registry をローカルで起動する場合、HTTPS でなく HTTP で起動することが多い。そこで、HTTP で Docker Registry にアクセスできるようにinsecure-registry オプションを付与して minikube を起動する。

1
$ minikube start --vm-driver=docker --insecure-registry="192.168.1.100:5000"

すでに minikube が起動している場合は、minikube stop でいったん minikube を停止してから、再度起動する。

独自 Fucntion をビルドする

作業用ディレクトリーに移動して、サンプル Function のテンプレートを作成する。

1
2
3
$ mkdir working
$ cd working
$ faas-cli new --lang go helloworld

ディレクトリー構成

1
2
3
4
5
6
7
8
+- helloworld
| +- handler.js
| +- package.json
+- helloworld.yml
+- template
+- ...
+- go
+- ...

helloworld/handler.js

function.Handle 関数が呼ばれたら引数を含む文字列を表示するみたい。

1
2
3
4
5
6
7
8
9
10
package function

import (
"fmt"
)

// Handle a serverless request
func Handle(req []byte) string {
return fmt.Sprintf("Hello, Go. You said: %s", string(req))
}

template/go/main.go

標準入力から文字列を取得して、それを引数として function.Handle を呼び出すみたい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Copyright (c) Alex Ellis 2017. All rights reserved.
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package main

import (
"fmt"
"io/ioutil"
"log"
"os"

"handler/function"
)

func main() {
input, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("Unable to read standard input: %s", err.Error())
}

fmt.Println(function.Handle(input))
}

修正

helloworld.yml を編集し、イメージをローカル Docker リポジトリから取得するようにする。

1
2
3
4
5
6
7
8
9
version: 1.0
provider:
name: openfaas
gateway: http://192.168.49.2:31112
functions:
helloworld:
lang: node
handler: ./helloworld
image: 192.168.1.9:5000/helloworld:latest

Function をビルドする

Function をビルドし、生成された Docker イメージをローカル Docker リポジトリに push する。

1
2
$ faas-cli build -f helloworld.yml --no-cache
$ docker push 192.168.1.9:5000/helloworld

push までを一括で行う場合は、faas-cli up コマンドを使用する。

1
$ faas-cli up -f helloworld.yml --no-cache

ビルドからデプロイまでの作業に関係するコマンドには以下のものがある。

build
Builds OpenFaaS function containers
deploy
Deploy OpenFaaS functions
publish
Builds and pushes multi-arch OpenFaaS container images
push
Push OpenFaaS functions to remote registry (Docker Hub)
remove
Remove deployed OpenFaaS functionsv
up
Builds, pushes and deploys OpenFaaS function containers

Function をデプロイする。

1
2
3
4
5
6
$ faas-cli deploy -f helloworld.yml
Deploying: helloworld.
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.

Deployed. 202 Accepted.
URL: http://192.168.49.2:31112/function/helloworld

ログを確認し、デプロイに成功したことを確認する。

1
2
3
4
5
6
7
8
9
$ kubectl get events -n openfaas-fn  --sort-by=.metadata.creationTimestamp
LAST SEEN TYPE REASON OBJECT MESSAGE
16s Normal ScalingReplicaSet deployment/helloworld Scaled up replica set helloworld-94d9d4b64 to 1
15s Normal SuccessfulCreate replicaset/helloworld-94d9d4b64 Created pod: helloworld-94d9d4b64-6n8t5
15s Normal Scheduled pod/helloworld-94d9d4b64-6n8t5 Successfully assigned openfaas-fn/helloworld-94d9d4b64-6n8t5 to minikube
14s Normal Pulling pod/helloworld-94d9d4b64-6n8t5 Pulling image "192.168.1.9:5000/helloworld:latest"
3s Normal Pulled pod/helloworld-94d9d4b64-6n8t5 Successfully pulled image "192.168.1.9:5000/helloworld:latest" in 11.110315182s
1s Normal Created pod/helloworld-94d9d4b64-6n8t5 Created container helloworld
0s Normal Started pod/helloworld-94d9d4b64-6n8t5 Started container helloworld

faas-cli list コマンドでも Fucntion が登録出来たことを確認する。

1
2
3
$ faas-cli list --gateway 192.168.49.2:31112
Function Invocations Replicas
helloworld 0 1

--verbose オプションを付与して実行すると、使用しているイメージ名が表示される。

1
2
3
$ faas-cli list --gateway=192.168.49.2:31112 --verbose
Function Image Invocations Replicas
helloworld 192.168.1.9:5000/helloworld:latest 0 1

続けて、kubectl でも Fucntion が登録出来たことを確認する。

1
2
3
$ kubectl -n openfaas-fn get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld 1/1 1 1 6m45s

Function を実行する

実行

標準入力に文字列を入力し、Ctrl+D で読み込みを完了する。

1
2
3
4
$ faas-cli invoke helloworld --gateway=192.168.49.2:31112
Reading from STDIN - hit (Control + D) to stop.
HELLO,WORLD
Hello, Go. You said: HELLO,WORLD

標準入力はパイプを使って echo などから渡すこともできる。

1
2
$ echo TEST_WORD | faas-cli invoke gohash --gateway=192.168.49.2:31112
Hello, Go. You said: TEST_WORD

確認

Function を実行した回数が Invocations に表示される。

1
2
3
$ faas-cli list --gateway 192.168.49.2:31112
Function Invocations Replicas
helloworld 1 1
1
2
3
4
5
6
7
8
9
10
$ kubectl logs deployment/gohash -n openfaas-fn
2021/04/16 19:42:36 Version: 0.8.4 SHA: bbd2e96214264d6b87cc97745ee9f604776dd80f
2021/04/16 19:42:36 Forking: ./handler, arguments: []
2021/04/16 19:42:36 Started logging: stderr from function.
2021/04/16 19:42:36 Started logging: stdout from function.
2021/04/16 19:42:36 Watchdog mode: http
2021/04/16 19:42:36 Timeouts: read: 10s, write: 10s hard: 10s.
2021/04/16 19:42:36 Listening on port: 8080
2021/04/16 19:42:36 Writing lock-file to: /tmp/.lock
2021/04/16 19:42:36 Metrics listening on port: 8081