Kekeの日記

エンジニア、読書なんでも

Knative、KubelessでServerlessFunctionを構成する

f:id:bobchan1915:20181009171851p:plain

本記事

本記事では実際にKuberenetes上でKnativeとKubelessを使ってみて、使い勝手などをレビューしたいと思います。

目次

なぜCloud FunctionsやAWS Lamndaではだめなの

以下の記事が非常に参考になりました。

www.atmarkit.co.jp

  • Google側としてもKnativeに推していく
  • OpenSourceなものとして運用APIはなければならなく、それがKnative
  • Kuberenetesをオープンソース化した野と同じで、Cloud Funtionsに似たようなプロダクトがあったが「デフォルトスタンダードになることが目的」

つまり要約すると以下の通りだと思います。

Cloud FunctionsやAWS Lamndaなどプラウドプロバイダーで争うのではなくオープンソース化して事実上の標準を作ることを目的にKnativeは実装されている。そのためにKubernetes上で実行される。

そのためいろんなパートナーと連携して、作っているのです。

これはCloud DataflowのためにApache BeamをOSS化したことにも非常に似ていると思います。

Knative

Knativeとは

https://github.com/knative/docs/raw/master/images/knative-audience.svg?sanitize=true

Kuberenetes上でモダンなサーバレスをビルド、デプロイ、実行するためのプラットフォームである。

公式サイト

cloud.google.com

特徴

Knativeには以下のような特徴があります。

  • 基本的なプリミティブなベースである
    • コンテナベースアプリケーションをビルドして、コードど実行するためのMiddelWareを多く提供している
    • 開発者がコードを書くことだけに注目できる
  • 開発者にやさしいソフトウェア
    • いろんなワークフローなど再利用な可能なコンポーネントを提供している
  • いろんな人気の開発パターンをサポートしている
    • Knativeは開発経験にフォーコスヌルので、いろんなGitOpsやDockerOpsなどのパターンに対応している
  • 高い柔軟性と操作のしやすさ
    • 既存のCI/CDツールに簡単に導入しやすいようになっている
  • オペレーターフレンドリー
    • いろんなクラウドプロバイダーで実行できるようにデザインされている
    • Istioのサービスメッシュ下にも導入できる(Istioに依存している)。

また公式ドキュメントの中でKnative featuresとしてかかれてある機能を表にします。

feature 説明
Serving ゼロにスケールするようなリクエスト駆動型のモデルであり、ライフサイクル管理などを行う。
Build コンテナオーケストレーションをするCloud Nativeなビルドシステムを提供する。
Events 普遍的な購読のことで、イベントの管理をする
Server-less add-on on GKE GCPがサーバーレスをマネジメントできるadd-onのこと

それぞれ別々のエントリを後日書こうと思っています。ここでは簡単に説明しようと思います。

Servingとは

ドキュメント

github.com

ソースコード

github.com

これはServerlessなアプリケーションを作る本体です。

以下のような特徴があります。

  • Serverlessコンテナの高速デプロイ
  • 0への自動スケールダウン
  • コードと設定のスナップショットを作ることができる

ServiceはRouteによってルーティングをしてConfigurationでRevisionを管理しています。

https://github.com/knative/serving/raw/master/docs/spec/images/object_model.png

Bulidとは

ドキュメント

github.com

ソースコード

github.com

ビルドとはコンテナオーケストレーションをするCloud Nativeなビルドシステムを提供するものでbulid, testing, ソースコードのdeployingのまだ開発者が用意しなればなりません。

これによって**コンテナイメージを作成しますが、そのビルドフローを定義します。

以下のようなCloud Provderを使うことができます。

Buildpack (Cloud Foundry)
Google Container Builder
Bazel
Kaniko
Jib

インストールして使ってみる

1. Istioをインストールします

以前、Istioのサービスメッシュを構築するエントリを書いたのでこちらをご覧ください。

www.1915keke.com

この記事のように構築すると以下のようになります。

$ kubectl get pods --namespace=istio-system

istio-citadel-d9f7867d9-7g5bx             1/1       Running     0          54s
istio-cleanup-secrets-xtl6g               0/1       Completed   0          57s
istio-egressgateway-59c7ffdc66-p2p6d      1/1       Running     0          55s
istio-galley-5d88fbc9cc-pd467             1/1       Running     0          55s
istio-ingressgateway-5c75fc767d-wh2vd     1/1       Running     0          55s
istio-pilot-b558b668b-ttvsp               2/2       Running     0          54s
istio-policy-66cf88696b-bxr5q             2/2       Running     0          54s
istio-security-post-install-zx26l         0/1       Completed   0          57s
istio-sidecar-injector-75b877b78f-6qckb   1/1       Running     0          54s
istio-telemetry-5f94f5f78c-7mcdk          2/2       Running     0          54s
prometheus-84674c99f8-tls26               1/1       Running     0          54s
2. Knative Componentsをインストールする

ServingBuildコンポーネントをインストールします。

kubectl apply --filename https://github.com/knative/serving/releases/download/v0.1.1/release.yaml

それぞれ確認しています。

kubectl get pods --namespace knative-serving

activator-96c7bcbf5-s9jcx     2/2       Running   0          1m
controller-7685bc648b-r9lpc   1/1       Running   0          1m
webhook-846f69848c-cvkkl      1/1       Running   0          1m

kubectl get pods --namespace knative-build

build-controller-7459fbf5cc-55t65   1/1       Running   0          34s
build-webhook-cf8d8c5d9-fbnsk       1/1       Running   0          34s
3. Knativeデプロイメントを作る

Knativeではデプロイメントを作るには.yamlを書かないといけませんが、今回はサンプルアプリケーションをデプロイしていきます。

これはServiceが管理しています。

サンプルとしては以下のようなものがあります。

apiVersion: serving.knative.dev/v1alpha1
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"

そしてデプロイします。もちろん直接IPは指定せずに使ったりしていきたいのでtype: Serviceとなっています。

kubectl apply --f service.yaml

helloworld-go-00001-deployment-6875cd69c-k4tz4   0/2       Pending   0          5s

このときに

  • KnativeによってRevisionという一意のバージョン番号が割り当てられます
  • PodのScalerやingressやLBなどを自動で設定してくれます

ここで確認してみます。

kubectl get pod --namespace=default

helloworld-go-00001-deployment-54d7b5888-4cqkq   2/2       Running   0          21m

kubectl get service --namespace=default

helloworld-go                 ClusterIP   10.63.248.224   <none>        80/TCP         21m
helloworld-go-00001-service   NodePort    10.63.252.159   <none>        80:31805/TCP   21m

kubectl get svc --namespace istio-system

...
knative-ingressgateway   LoadBalancer   10.63.250.108   35.200.31.80   80:32380/TCP,443:32390/TCP,32400:32400/TCP                                                   2h
...

kubectl get pod --namespace istio-system

...
knative-ingressgateway-575fbcc886-nsv54   1/1       Running     16         2h
...
4. Knative Functionを叩いてみる

IPアドレスは以下の様に取得できます。

export IP_ADDRESS=$(kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.status.loadBalancer.ingress[0].ip}')
export HOST_URL=$(kubectl get services.serving.knative.dev helloworld-go  --output jsonpath='{.status.domain}')

そしてRequestを送ってみます。

curl -H "Host: ${HOST_URL}" http://${IP_ADDRESS}
Hello World: Go Sample v1!
5. クリーンアップ
kubectl delete --f service.yaml

Kubeless

Kubelessとは

Knativeと同様のKubernetesNativeなServerless Platformである

公式サイト

Kubeless

特徴

以下の様な特徴があります。

  • Python, Node.js, Ruby, PHP, Golang, .NET, Ballerinaランタイムやカスタムランタイムをサポート。kubeless get-server-configで確認できます。
  • CLIで使える
  • KafkaメッセージやHTTPイベント駆動
  • Prometheusモニタリングで関数呼び出しとレイテンシを取得
  • Serverlessフレームワークプラグインである

インストールして使ってみる

1. kubeless CLIツールのインストール

macOS用のreleaseをダウンロードして解凍します。

export RELEASE=$(curl -s https://api.github.com/repos/kubeless/kubeless/releases/latest | grep tag_name | cut -d '"' -f 4)

export OS=$(uname -s| tr '[:upper:]' '[:lower:]')
curl -OL https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless_$OS-amd64.zip && \
  unzip kubeless_$OS-amd64.zip && \
  sudo mv bundles/kubeless_$OS-amd64/kubeless /usr/local/bin/

2. Namespace, RBAC, CRDsを設定する

export RELEASE=$(curl -s https://api.github.com/repos/kubeless/kubeless/releases/latest | grep tag_name | cut -d '"' -f 4)
kubectl create ns kubeless
kubectl create -f https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless-$RELEASE.yaml

3. 関数をデプロイ

以下のようなtest.pyを作ります。

def hello(event, context):
  print event
  return event['data']

そしてdeployします。

$ kubeless function deploy hello --runtime python2.7 \
                                --from-file test.py \
                                --handler test.hello

ここではCLIとソースファイルからデプロイしましたが、以下のように.yamlを書いてデプロイすることもできます。

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  name: get-python
  namespace: default
spec:
  runtime: python2.7
  timeout: "180"
  handler: helloget.foo
  deps: ""
  checksum: sha256:d251999dcbfdeccec385606fd0aec385b214cfc74ede8b6c9e47af71728f6e9a
  function-content-type: text
  function: |
    def foo(event, context):
        return "hello world"

確認します。

kubectl get functions

hello     26s

呼び出してみます。

kubeless function call hello --data 'Hello world!'

Hello World!

どうなっているかというとPodがデプロイされています。

kubectl get pods

hello-9c48d456b-rzccx                          1/1       Running   0          46s

kubectl get svc

hello     ClusterIP   10.63.240.150   <none>        8080/TCP         2m

つまりDNS問い合わせをすればクラスタ内からhello.kubelessのホスト名でアクセスできます。

4. Dashboardを使ってみる

以下のようにしてデプロイします。

kubectl create -f https://raw.githubusercontent.com/kubeless/kubeless-ui/master/k8s.yaml

以下のように確認することができます。

f:id:bobchan1915:20181009224514p:plain

関数をみるとスナップショットがみられます。

f:id:bobchan1915:20181009224547p:plain

KnativeとKubelessの比較

執筆時のものです。

Knative Kubeless
GitHubStar 751(serving)/275(build)/67(eventing) 3,609
People 4 46
Main maitaner Bitnami Google
Container Builder
Container less? ✅ (意識は必要なし)
Dependency Istio none
Dashboard
RivisionControl
Resource
Cloud Pub/Sub Support
Amazon Kinesis Support

ここからは主観です。

Knative Kubeless
Docのクオリティ(3星満点) ⭐️ ⭐️⭐️
そのものの使い勝手
サービスメッシュとの相性 ✅(Istio) ❌(特に良し悪しなし)
運用のしやすさ ❌(かなり規模が大きい) ✅(コンパクトで導入しやすい)