Kubernetes in Docker (KinD) で OpenFaaS を動かす!
OpenFaaS が気になる、でもそのために Kubernetes 動かすのもなぁ…
そんなときに、サクッと Kubernetes をコンテナ上で動かせる Kubernetes in Docker (KinD) を使えば、簡単に OpenFaaS オタメシ環境が構築できます!
はじめに
Kubernetes in Docker (KinD)
、Dockerコンテナをノードとしてふるまわせ、従来通り kubectl
などでコントロールできるすごいやつです。形容詞kindと同じつづりなのでググらびりてぃが恐ろしく低いですが、「Kubernetes in Docker」で調べると情報が出てきます。
ノードの数だけDockerコンテナが立ち上がり、それらを消してしまえばまた環境をまっさらにできるので、まさに Kubernetes オタメシにはもってこいの環境です。主に Kubernetes 自体の開発用途で使われているんだとか。
今回はその簡単に作ったり壊したりできる Kubernetes 環境を使って、 OpenFaaS を使えるようにしてみたいと思います。
手順
では早速
用意するもの
- Dockerが使えるマシン(筆者の環境は Ubuntu 18.04 x86_64 16GBメモリ)
sudo
なしでDockerが扱えるように、作業するユーザーをdocker
グループに入れて下さい
1. KinD の導入
まずは Go を導入します。下記サイトに従って導入しました。
Download and install - The Go Programming Language
wget https://golang.org/dl/go1.16.4.linux-amd64.tar.gz sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.16.4.linux-amd64.tar.gz
そして下記を ~/.profile に追記。
export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:$(go env GOPATH)/bin
いったんログアウトしてからログインし、go version
などでgoが導入できたことを確認。
次に、KinD
本体を導入します。公式ドキュメント にあるように 下記コマンドで導入できます。
GO111MODULE="on" go get sigs.k8s.io/kind@v0.10.0
2. KinD の動作確認
KinD を使った Kubernetes のクラスタ起動は下記コマンドで行えます。
kind create cluster
クラスタ削除は下記
kind delete cluster
簡単です。
3. ローカルレジストリの作成
FaaS のハンドラ(Pod)は指定したDockerのレジストリからコンテナイメージがpullされ実行されます。
オタメシで使うようなコンテナイメージを Docker Hub に上げるわけにもいかないので、ローカルにレジストリをDockerでたちあげ、それを参照するように設定します。
下記URLを参考にシェルスクリプトを作成し、クラスタを立ち上げる時はそのシェルスクリプトを実行するようにしました。
#!/bin/sh set -o errexit reg_name='kind-registry' reg_port='5000' running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2> /dev/null || true)" if [ "${running}" != 'true' ]; then docker run \ -d --restart=always -p "${reg_port}:5000" --name "${reg_name}" \ registry:2 fi cat <<EOF | NO_PROXY=${NO_PROXY},${reg_name} kind create cluster --config=- kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 containerdConfigPatches: - |- [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"] endpoint = ["http://${reg_name}:${reg_port}"] EOF docker network connect "kind" "${reg_name}" || true 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
ここで、kind create cluster
を実行するときに NO_PROXY=${NO_PROXY},${reg_name}
として、NO_PROXY環境変数を設定しました。下記URLにあるように、KinDはクラスタ立ち上げ時の環境変数を見て、ノード内のポッドが通信できるように渡してくれるんですが、今回立てたレジストリはプロキシを通してしまうとコンテナイメージをプルできなくなるので、明示する必要があります。(プロキシを使用していない環境であれば必要ありません。)
https://kind.sigs.k8s.io/docs/user/quick-start/#configure-kind-to-use-a-proxy
4. openfaasをインストールする
下記手順に従ってopenfaasを導入していきます。
まずはopenfaas の管理ツールである faas-cli
を導入します。
curl -sL https://cli.openfaas.com | sudo sh
次に、3.で作成したシェルスクリプトを実行して立ち上げたクラスタに対して、arkade
を使用して openfaas
を導入します。
arkade
とは、Kubernetes で利用できるサービスを導入できるマーケットプレイスアプリらしいです。
下記コマンドで arkade を導入して、、、
curl -SLsf https://dl.get-arkade.dev/ | sudo sh
kubernetes に openfaas を導入します。
arkade install openfaas
5. openfaas に外からアクセスできるようにする
ここまででは openfaas にアクセスできないので管理用のWebアプリ「gateway」にアクセスできるようにポートフォワーディングを設定します。
kubectl rollout status -n openfaas deploy/gateway kubectl port-forward -n openfaas svc/gateway 8080:8080 --address 0.0.0.0 &
こうすることで、Dockerのノード内で実行されている gateway にアクセスすることができるようになります。
--address 0.0.0.0
を指定しているのは、リモートホストからアクセスできるようにしたかったためです。(省略すれば localhost からのみアクセス可能になります)
上記を実行した後に 「<IPアドレス>:8080」にアクセスすると下記のように管理画面が開けばOKです
6. 自作Functionをデプロイしてみる
Local Registry with KinD - OpenFaaS
コチラにある内容を試せば自作Functionがデプロイできることを試せます。
筆者はプロキシ必須の環境で試したので、めちゃくちゃハマったんですが、この PyDictionary を使ったサンプル、通信が伴うのでまず pydict/handler.py
は
from PyDictionary import PyDictionary dictionary = PyDictionary() def handle(word): return word # return dictionary.meaning(word)
といった感じで通信を行わない、オウム返しのFunctionで試すのがよいと思います。
また、Function実行時の環境変数を指定したい場合は
version: 1.0 provider: name: openfaas gateway: http://127.0.0.1:8080 functions: pydict: lang: python3-flask-debian handler: ./pydict image: localhost:5000/pydict:latest environment: http_proxy: http://proxy.host.example:8080/ https_proxy: http://proxy.host.example:8080/ no_proxy: localhost,127.0.0.1
といった感じで、 pydict.yml
ファイルに environment
を書けばよいでしょう。(要調査)
参考
色々ドハマりしたときに役立ったコマンドなど
デプロイした Functionがいつまでたっても Not Ready のまま
いつまでたってもReadyにならない。デプロイしたFunctionがどこでコケているのか、ログを見ましょう。
kubectl logs -n openfaas-fn deploy/pydict
ノードからローカルのレジストリにアクセスできているか確認したい
正しく環境変数など設定できているか確認するために、Kubernetesのノードが動いているDockerコンテナに入り込んでしまって、 curl kind-registry:5000
とか叩いてしまうのも手です。
docker exec -it kind-control-plane bash
終わりに
以上、OpenFaaS を Kubernetes in Docker で試してみる、といった内容でした。 (本当は faasd でやりたかったんだけど、プロキシでドハマりして情報が少なすぎて断念した)