概要
Kubernetes上でサーバーレスを動かすためのOSSフレームワークのKnativeを試した
Knativeとは
KubernetesとIstioが協調して動作し、サーバーレスのプラットフォームを提供するOSSフレームワーク
Google, Red Hat, IBMなど有名所がコントリビューションしている!
Serverless
イベントドリブンで動作し、リクエストに応じたスケールするものを指しているっぽい。
ここでいうServerlessは所謂PaaSとFaaSの両方を指している模様。
リクエストに応じたスケールを行うため、リクエストがないときはコンテナを動作させない挙動をとる(起動中のコンテナが0になる)
コンポーネント
Knativeは以下の3つのコンポーネントで成り立っている
- Build
- ソースからコンテナの生成を司る
- Knative側でJibやBazelなどのビルドツールを用いてソースコードのコンテナ化を行う
- Eventing
- イベントの管理を司る
- イベントドリブンを実現するための機構
- 外部(PubSubやGCSなど)からのイベントを抽象化してServingへ受け渡す
- FaaS的な?
- Serving
- コンテナの起動を司る
- リクエストドリブンでコンテナのデプロイを行う
- リクエストに応じてオートスケールが行われ、リクエストがない場合はコンテナは0台になる
- ネットワーク周りはIstioにお任せ
- PaaS的な?
試す
公式のGKEドキュメントを参考に構築する。
docs/Knative-with-GKE.md at master · knative/docs
0. 前提
- Knative v0.10.0
- GKE 1.10.5-gke.3
1. GKE Clusterの作成
$ export CLUSTER_NAME=knative $ export CLUSTER_ZONE=asia-northeast1-a $ gcloud container clusters create $CLUSTER_NAME \ --zone=$CLUSTER_ZONE \ --cluster-version=latest \ --machine-type=n1-standard-4 \ --enable-autoscaling --min-nodes=1 --max-nodes=10 \ --enable-autorepair \ --scopes=service-control,service-management,compute-rw,storage-ro,cloud-platform,logging-write,monitoring-write,pubsub,datastore \ --num-nodes=3
2. cluster-admin権限を現在のユーザーへ与える
$ kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole=cluster-admin \ --user=$(gcloud config get-value core/account)
3. Istioのインストール
$ kubectl apply -f https://raw.githubusercontent.com/knative/serving/v0.1.0/third_party/istio-0.8.0/istio.yaml $ kubectl label namespace default istio-injection=enabled $ kubectl get pods -n istio-system
4. Knativeのインストール
チュートリアルではServing/Buildの2つだけインストールし、Eventingはまた別のチュートリアルが用意されていた。
4.1. Servingコンポーネントのインストール
$ kubectl apply -f https://github.com/knative/serving/releases/download/v0.1.0/release.yaml $ kubectl get pods -n knative-serving
4.2. Buildコンポーネントのインストール
$ kubectl apply -f https://raw.githubusercontent.com/knative/serving/v0.1.0/third_party/config/build/release.yaml $ kubectl get pods -n knative-build
5. sample appのデプロイ
$ cat <<EOL | kubectl apply -f - apiVersion: serving.knative.dev/v1alpha1 # Current version of Knative kind: Service metadata: name: helloworld-go # The name of the app namespace: default # The namespace the app will use spec: runLatest: configuration: revisionTemplate: spec: container: image: gcr.io/knative-samples/helloworld-go # The URL to the image of the app env: - name: TARGET # The environment variable printed out by the sample app value: "Go Sample v1" EOL
6. 動作確認
6.1. curlで叩いてみる
$ export IP_ADDRESS=$(kubectl get svc knative-ingressgateway -n istio-system -o 'jsonpath={.status.loadBalancer.ingress[0].ip}') $ export HOST_URL=$(kubectl get services.serving.knative.dev helloworld-go -o jsonpath='{.status.domain}') $ curl -H "Host: ${HOST_URL}" http://${IP_ADDRESS} Hello World: Go Sample v1!
6.2. コンテナが0台になるのを待ってからcurlで叩く
- コンテナのデプロイをして、コンテナがRunningの状態になっていることを確認
- しばらく待機するとコンテナが0台になる(だいたい5分ぐらいで0台になった
- 0台の状態でリクエストを送ってコンテナが立ち上がることを確認
手癖で
$ k get pods --watch
って打ってるけど、$ alias k=kubectl
をかけているだけのもの。
所感
デプロイ後接続テストを kubectl port-forward
でポートフォワードしてたけど、途中でpodの数が0/3になるなどして「これが scale-to-zeroかー」ってなってた(だいたい5分ぐらい目を離したスキに)
サーバーレスを感じてとても良い
あとKnativeのスタックは諸々大きすぎて、k8s本体だけじゃなくてIstio/zipkin/prometheusなどが入ってて、学習コストが高いなぁと。
"GKE Serverless add-on"の実態はマネージドKnativeらしく、ココらへん使うとカジュアルに ロックインされないサーバーレス が手に入るんだろうか
とりあえず次はEventingを試したい。
AWSのKinesisからGKE上のKnativeとかできたら熱いなー