説明
Google Cloud Next '18 で Kubernetes を拡張してサーバレス環境(FaaS環境)を作る事ができる Knative が発表されましたね。
この Knative 上にオープンソースの FaaSツールである riff 環境を作ってみます。
Knative 概要
Knative は以下の3つのコンポーネントから成っていて、それぞれのコンポーネントが疎結合的にそれぞれの機能を担っています。
- Knative-Serving
- Knative-Build
- Knative-Eventing
Knative-Serving
Serving は、Kubernetes と Istio に作られ、サーバレスアプリケーションを稼働させます。
オートスケールし、使われない時には ゼロスケールします。
Knative-Build
Build は、ソースリポジトリ(GitHubなど)からソースを取得し、依存関係の取得、テスト実行、コンテナイメージのビルドを行います。その後、コンテナレジストリへのPushや、Kubernetesクラスタへのデプロイを行います。
Knative-Eventing
Pub/Sub デスティネーションや、KafkaやRabbitMQなどのバスといった様々なデータソースから、イベントストリームを Consume (または Publish) します。
前提
- 実行環境:macOS
- 仮想環境:HyperKit
- Kubernetes環境:Minikube
$ minikube version
minikube version: v0.28.2
手順
構築手順は、大きく次のようになります。
- Kubernetes クラスタ (Minikube クラスタ)の作成
- riff CLI のインストール
- Knative のインストール
- Kubernetes Secret の作成・適用
- ファンクションの作成
1. Kubernetes クラスタ (Minikube クラスタ)の作成
以下のコマンドで Minikube クラスタを作成します。ここでは、前提に書いているように hyperkit を仮想環境に指定していますが(--vm-driver=hyperkit
)、virtualbox や vmwarefusion など指定しても大丈夫でしょう。(動作確認はしてませんが。)
$ minikube start --memory=8192 --cpus=4 \
--kubernetes-version=v1.10.5 \
--vm-driver=hyperkit \
--bootstrapper=kubeadm \
--extra-config=controller-manager.cluster-signing-cert-file="/var/lib/localkube/certs/ca.crt" \
--extra-config=controller-manager.cluster-signing-key-file="/var/lib/localkube/certs/ca.key" \
--extra-config=apiserver.admission-control="LimitRanger,NamespaceExists,NamespaceLifecycle,ResourceQuota,ServiceAccount,DefaultStorageClass,MutatingAdmissionWebhook"
実行後、以下のようにpod が見えてきます。
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-minikube 1/1 Running 0 11s
kube-system kube-addon-manager-minikube 1/1 Running 0 1m
kube-system kube-apiserver-minikube 0/1 Pending 0 7s
kube-system kube-controller-manager-minikube 1/1 Running 0 44s
kube-system kube-dns-86f4d74b45-z76kh 3/3 Running 0 1m
kube-system kube-proxy-4mzh7 1/1 Running 0 1m
kube-system kube-scheduler-minikube 1/1 Running 0 32s
kube-system kubernetes-dashboard-5498ccf677-kt285 1/1 Running 0 1m
kube-system storage-provisioner 1/1 Running 0 1m
2. riff CLI のインストール
riff CLI をインストールします。(バージョン:0.1.0 as of 2018/07/30)
$ curl -LO https://github.com/projectriff/riff/releases/download/v0.1.0/riff-darwin-amd64.tgz \
&& tar xvzf riff-darwin-amd64.tgz \
&& sudo mv riff /usr/local/bin/
$ riff version
Version
riff cli: 0.1.0
3. Knative のインストール
$ riff system install --node-port
※ Waiting for istio-sidecar-injector to start .Error: exit status 1
にようにエラーが出る事があるのですが、その場合は一度 minikbe クラスタを停止し(qinikube stop
)、開始し直すとインストールできます。
$ riff system install --node-port
Installing Istio: https://storage.googleapis.com/riff-releases/istio-riff-0.1.0.yaml
Istio for riff installed
Waiting for istio-sidecar-injector to start .'Running'
Installing Knative Serving: https://storage.googleapis.com/riff-releases/release-no-mon-riff-0.1.0.yaml
Knative Serving for riff installed
Installing Knative Eventing: https://storage.googleapis.com/riff-releases/release-eventing-riff-0.1.0.yaml
Knative Eventing for riff installed
Applying Stub ClusterBus resource: https://storage.googleapis.com/riff-releases/release-eventing-clusterbus-stub-riff-0.1.0.yaml
clusterbus.channels.knative.dev "stub" created
riff system install completed successfully
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
istio-system istio-citadel-7bdc7775c7-llxxq 1/1 Running 2 28m
istio-system istio-cleanup-old-ca-v4m4b 0/1 Completed 0 28m
istio-system istio-egressgateway-795fc9b47-2476t 1/1 Running 3 28m
istio-system istio-ingress-84659cf44c-tj9s6 1/1 Running 3 28m
istio-system istio-ingressgateway-7d89dbf85f-l6j2s 1/1 Running 3 28m
istio-system istio-mixer-post-install-d9ndt 0/1 Completed 0 28m
istio-system istio-pilot-66f4dd866c-m86fs 2/2 Running 6 28m
istio-system istio-policy-76c8896799-pzxmb 2/2 Running 4 28m
istio-system istio-sidecar-injector-645c89bc64-5twvv 1/1 Running 8 28m
istio-system istio-statsd-prom-bridge-949999c4c-czbsf 1/1 Running 2 28m
istio-system istio-telemetry-6554768879-cmhj8 2/2 Running 4 28m
istio-system knative-ingressgateway-5f5dc4b4cd-2nbwt 1/1 Running 1 10m
knative-build build-controller-5cb4f5cb67-5stsw 1/1 Running 1 10m
knative-build build-webhook-6b4c65546b-pdg4m 1/1 Running 3 10m
knative-eventing controller-manager-7747d66d85-b4tv5 2/2 Running 2 2m
knative-eventing eventing-controller-6cd984f789-m26hh 1/1 Running 0 2m
knative-eventing eventing-webhook-7dfd9cfbd9-wrdgz 1/1 Running 0 2m
knative-eventing stub-clusterbus-866c95f68d-qk9km 2/2 Running 0 2m
knative-serving activator-7f5b67b69c-zztzj 2/2 Running 0 2m
knative-serving controller-868ff6d485-7frqr 1/1 Running 0 2m
knative-serving webhook-6d9976c74f-gv7jg 1/1 Running 0 2m
kube-system etcd-minikube 1/1 Running 0 4m
kube-system kube-addon-manager-minikube 1/1 Running 2 31m
kube-system kube-apiserver-minikube 1/1 Running 0 4m
kube-system kube-controller-manager-minikube 1/1 Running 0 4m
kube-system kube-dns-86f4d74b45-2vmns 3/3 Running 8 32m
kube-system kube-proxy-nxxp5 1/1 Running 0 3m
kube-system kube-scheduler-minikube 1/1 Running 2 31m
kube-system kubernetes-dashboard-5498ccf677-vvqd6 1/1 Running 6 32m
kube-system storage-provisioner 1/1 Running 6 32m
4. Kubernetes Secret の作成・適用
DockerHubにコンテナイメージをpushするために使用する認証情報をKubernetes Secretで作成します。
以下のファイルを作成します。
$ vim push-cred.yaml
apiVersion: v1
kind: Secret
metadata:
name: push-credentials
annotations:
build.knative.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
data:
username: <BASE64エンコードしたDockerHubユーザID>
password: <BASE64エンコードしたDockerHubパスワード>
作成したファイルからsecretの定義情報を反映します。
$ kubectl apply -f push-cred.yaml
定義した secret を使用して namespace を初期化します。
ここでは、namespace を default
としています。
$ riff namespace init default --secret push-credentials
5. Function の作成
Functionのサンプルとして、与えた数値を二乗する関数を Node.js で用意しました。
module.exports = x => x ** 2;
上記のJSファイルをGitリポジトリに入れておきます。
ここでは、GitHubを使って以下のリポジトリとしました。
https://github.com/shinyay/node-func-square.git
最後に riff で Function を作成します。
$ riff function create node square \
--git-repo https://github.com/shinyay/node-func-square.git \
--artifact square.js \
--image <DockerHubのユーザID>/node-func-square
上記コマンドを実行すると、DockerHub には、<DockerHubのユーザID>/node-func-square
という名前でイメージが登録されます。
また、square-xxxxxという名前でPodが Minikubeクラスタ上に構成されます。
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default square-00001-deployment-696bf6c86b-fxkdr 3/3 Running 0 22s
default square-00001-q4p97 0/1 Completed 0 8m
istio-system istio-citadel-7bdc7775c7-bfnww 1/1 Running 2 28m
istio-system istio-cleanup-old-ca-4zmxq 0/1 Completed 0 28m
istio-system istio-egressgateway-795fc9b47-nl6g9 1/1 Running 3 28m
istio-system istio-ingress-84659cf44c-nk7sp 1/1 Running 3 28m
istio-system istio-ingressgateway-7d89dbf85f-vldmg 1/1 Running 3 28m
istio-system istio-mixer-post-install-6ttqf 0/1 Completed 0 29m
istio-system istio-pilot-66f4dd866c-26c9v 2/2 Running 4 28m
istio-system istio-policy-76c8896799-f89zq 2/2 Running 4 28m
istio-system istio-sidecar-injector-645c89bc64-cvnqj 1/1 Running 8 28m
istio-system istio-statsd-prom-bridge-949999c4c-hjbkc 1/1 Running 2 28m
istio-system istio-telemetry-6554768879-hn5c5 2/2 Running 4 28m
istio-system knative-ingressgateway-5f5dc4b4cd-mwz4m 1/1 Running 2 24m
knative-build build-controller-5cb4f5cb67-f7hwk 1/1 Running 1 25m
knative-build build-webhook-6b4c65546b-f8dq8 1/1 Running 4 25m
knative-eventing controller-manager-7747d66d85-k465k 2/2 Running 8 24m
knative-eventing eventing-controller-6cd984f789-kstc5 1/1 Running 0 24m
knative-eventing eventing-webhook-7dfd9cfbd9-nxw72 1/1 Running 1 24m
knative-eventing stub-clusterbus-866c95f68d-dkwnc 2/2 Running 0 21m
knative-serving activator-7f5b67b69c-b88xf 2/2 Running 1 24m
knative-serving controller-868ff6d485-rd7xs 1/1 Running 0 24m
knative-serving square-00001-autoscaler-7c64497c6c-zn8qt 2/2 Running 0 22s
knative-serving webhook-6d9976c74f-lmqvs 1/1 Running 2 24m
kube-system etcd-minikube 1/1 Running 0 22m
kube-system kube-addon-manager-minikube 1/1 Running 2 29m
kube-system kube-apiserver-minikube 1/1 Running 0 22m
kube-system kube-controller-manager-minikube 1/1 Running 0 22m
kube-system kube-dns-86f4d74b45-5ngd8 3/3 Running 7 30m
kube-system kube-proxy-vvxh7 1/1 Running 0 21m
kube-system kube-scheduler-minikube 1/1 Running 2 29m
kube-system kubernetes-dashboard-5498ccf677-xk7rd 1/1 Running 5 30m
kube-system storage-provisioner 1/1 Running 5 30m
6. Function の実行
以下のcurlコマンドを実行して、Functionを実行します。
MinikubeのIPアドレスは、minikube ip
コマンドで確認できます。
$ curl \
-w '\n' \
-H 'Host: square.default.example.com' \
-H 'Content-Type: text/plain' \
http://<MinikubeのIPアドレス>:32380 \
-d 5
25
Function に対して 数値 5
を与えています。すると、結果として 二乗された値として 25
が返ってきます。
また、しばらく放置しておくと使用していないFunctionのPodが自動で終了します。
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default square-00001-deployment-696bf6c86b-fxkdr 0/3 Terminating 0 5m
終了している状態で、再度 Function を呼び出すと、Pod が再作成されて機能するようになります。
7. Function 及び Minikube クラスタのクリーンアップ
Function のクリーンアップは以下のコマンドで行います。
ここでは、Function名は、square
です。
$ riff service delete <Function名>
Minikube クラスタのクリーンアップは、以下のコマンドで行います。
$ minikube delete
まとめ
riff と Knative で簡単に FaaS 環境ができてしまいました。
今回は、riff のサイトにも掲載されているシンプルな Node.js のアプリを使用してみましたが、Java などの他の言語でも Function を作ってみようと思います。