OpenFaaSをKinD上に構築する
はじめに
Dockerコンテナをノードとして使用して、ローカルのKubernetesクラスターを簡易的に実行するためのKinD(Kubernetes in Docker)というツールがあるらしい。以前OpenFaasをK3sで作ったKubernetesクラスタ上に構築したが、同じことをKinDでもやってみたい。この記事もあらたか元記事を再利用していて、エコである。
検証環境
Ubuntu 22.04
Docker 20.10.21
kind v0.17.0
OpenFaaS 0.15.4
必要なバイナリファイルをインストールする
kind
, kubectl
, helm
, faas-cli
など複数のツールを利用する。今回はarkadeを利用して簡単にインストールしておく。
$ export PATH=$HOME/.arkade/bin:$PATH
$ curl -SLsf https://dl.get-arkade.dev/ | sudo sh
$ arkade get kind
$ arkade get kubectl
$ arkade get helm
$ arkade get faas-cli
KinD Kubernetesクラスタを構築
OpenFaasで自分のFunctionを作成・登録する場合、ローカルレジストリがあった方が何かと都合がよい。まずはdockerコンテナでレジストリを作成しておく。
$ export reg_name='kind-registry'
$ export reg_port='5000'
$ docker run -d --restart=always -p "${reg_port}:5000" --name "${reg_name}" registry:2
KinDでKubernetesクラスタを作成する。
このとき上記で作成したローカルレジストリをミラーとして参照できるようあわせて登録する。
$ cat <<EOF | kind create cluster --name openfaas --config -
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 8080
listenAddress: "0.0.0.0"
protocol: TCP
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
endpoint = ["http://${reg_name}:${reg_port}"]
EOF
Creating cluster "openfaas" ...
✓ Ensuring node image (kindest/node:v1.25.3) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-openfaas"
You can now use your cluster with:
kubectl cluster-info --context kind-openfaas
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
$ kubectl version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.2", GitCommit:"f66044f4361b9f1f96f0053dd46cb7dce5e990a8", GitTreeState:"clean", BuildDate:"2022-06-15T14:22:29Z", GoVersion:"go1.18.3", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v4.5.4
Server Version: version.Info{Major:"1", Minor:"25", GitVersion:"v1.25.3", GitCommit:"434bfd82814af038ad94d62ebe59b133fcb50506", GitTreeState:"clean", BuildDate:"2022-10-25T19:35:11Z", GoVersion:"go1.19.2", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl cluster-info --context kind-openfaas
Kubernetes control plane is running at https://127.0.0.1:35205
CoreDNS is running at https://127.0.0.1:35205/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ docker network connect "kind" "${reg_name}"
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
host: "localhost:${reg_port}"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF
なお、K3sでOpenFaaSを構築した時にはserviceType=LoadBalancer
を指定して外部からサービスを参照できるようにしていた。KinDではその性質上LoadBalancerが利用できないため、NodePortでポート転送できるよう事前にextraPortMapping
を作成している。
HelmチャートでOpenFaaSインストール
Kuberntets上でOpenFaaSそのものはopenfaas
というnamespaceに、deployしたFunctionはopenfaas-fn
というnamescaceに作成する。これらのnamespaceを事前に作成しておく。
$ kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
OpenFaaSをインストールする。
$ helm repo add openfaas https://openfaas.github.io/faas-netes/
$ helm repo update
$ helm install openfaas openfaas/openfaas \
--namespace openfaas \
--set functionNamespace=openfaas-fn \
--set generateBasicAuth=true
# しばらく待つ
$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NAME READY UP-TO-DATE AVAILABLE AGE
alertmanager 1/1 1 1 32m
basic-auth-plugin 1/1 1 1 32m
gateway 1/1 1 1 32m
nats 1/1 1 1 32m
prometheus 1/1 1 1 32m
queue-worker 1/1 1 1 32m
OpenFaaSのデプロイが完了したら、先ほどextraPortMapping
で指定したcontainerPort
をgateway-external
サービスのNodePortで利用するよう修正をしておく。
$ kubectl -n openfaas patch svc/gateway-external --type=json -p='[{"op":"replace", "path":"/spec/ports/0/nodePort", "value":30080}]'
$ kubectl -n openfaas get svc/gateway-external
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gateway-external NodePort 10.96.159.34 <none> 8080:30080/TCP 40m
OpenFaaSでFunctionのインストール
OpenFaaSにFunctionを登録・起動してみる。
まずはOpenFaaSにadminアカウントでログインする。
$ PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo)
$ echo -n $PASSWORD | faas-cli login --username admin --password-stdin
Calling the OpenFaaS server to validate the credentials...
credentials saved for admin http://127.0.0.1:8080
事前にOpenFaaS StoreにはいくつかFuncitonが登録されているので、ここから試しにfiglet
をデプロイしてみる。他にどのようなFunctionがあるかfaas-cli store list
で確認できる。
$ faas-cli store deploy figlet
Deployed. 202 Accepted.
URL: http://127.0.0.1:8080/function/figlet
$ faas-cli list
Function Invocations Replicas
figlet 0 1
デプロイしたFunctionを呼び出す方法は2通り。
ひとつはfaas-cli invoke
コマンドによるもの。デプロイしたFunctionのテストに使うことが多い。
$ echo openfaas | faas-cli invoke figlet
__
___ _ __ ___ _ __ / _| __ _ __ _ ___
/ _ \| '_ \ / _ \ '_ \| |_ / _` |/ _` / __|
| (_) | |_) | __/ | | | _| (_| | (_| \__ \
\___/| .__/ \___|_| |_|_| \__,_|\__,_|___/
|_|
もうひとつはOpenFaaSゲートウェイ( ここでは http://127.0.0.1:8080 )のエンドポイントからFunctionを起動するもの。
$ echo openfaas | curl -X POST -d @- http://127.0.0.1:8080/function/figlet
__
___ _ __ ___ _ __ / _| __ _ __ _ ___
/ _ \| '_ \ / _ \ '_ \| |_ / _` |/ _` / __|
| (_) | |_) | __/ | | | _| (_| | (_| \__ \
\___/| .__/ \___|_| |_|_| \__,_|\__,_|___/
|_|
楽しい🎉
自分でFunctionを作成する
さていよいよ自分でFunctionを登録・起動してみる。Functionは事前にOpenFaaSで用意されているTemplateから作成していく。[1]
まずは最新のTemplateをダウンロードしてくる。
$ faas-cli template pull
$ faas-cli new --list
Languages available as templates:
- csharp
- dockerfile
- go
- java11
- java11-vert-x
- node
- node12
- node12-debian
- node14
- node16
- node17
- php7
- python
- python3
- python3-debian
- ruby
それではpython3テンプレートを利用してFunctionを作成してみる。
Function名はhello-openfaas
。--prefix
はコンテナイメージのprefixのことで、ビルドされたイメージの登録先レジストリを指す。
$ faas-cli new --lang python3 hello-openfaas --prefix localhost:5000
$ ls
hello-openfaas/ hello-openfaas.yml template/
hello-openfaas/handler.py
がFunctionの実体。これを書き換えて以下のように変更する。
$ cat <<EOL > ./hello-openfaas/handler.py
def handle(req):
print("Hello! You said: " + req)
EOL
このFunctionをデプロイする。
faas-cli up
コマンドひとつで以下を一括で実施してくれる。
- コンテナイメージの作成:
faas-cli build
- コンテナイメージのレジストリ登録:
faas-cli push
- Functionのデプロイ:
faas-cli deploy
$ faas-cli up -f hello-openfaas.yml
$ faas-cli list
Function Invocations Replicas
figlet 2 1
hello-openfaas 0 1
無事登録されたFunctionを起動する。
$ echo Nice to meet you! | curl -X POST -d @- http://127.0.0.1:8080/function/hello-openfaas
Hello! You said: Nice to meet you!
できた!
追加でpipモジュールが必要な場合には ./hello-openfaas/requirements.txt
に必要なモジュール名を書いておけばコンテナイメージ作成時に読み込んでくれる。
楽しい🎉[2]
-
もちろん自分でTemplateから作成することも可能 ↩︎
-
OpenFaaS Workshopにより詳細なチュートリアルがある。なお本記事はLab.11まであるチュートリアルのうち、Lab.3程度までの内容。深い。。。 ↩︎
Discussion