Knativeを試してみる

概要

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で叩く

  1. コンテナのデプロイをして、コンテナがRunningの状態になっていることを確認
  2. しばらく待機するとコンテナが0台になる(だいたい5分ぐらいで0台になった
  3. 0台の状態でリクエストを送ってコンテナが立ち上がることを確認 f:id:y-ohgi:20180804180906p:plain 手癖で $ 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を試したい。
AWSKinesisからGKE上のKnativeとかできたら熱いなー

参考