本記事
本記事では実際にKuberenetes上でKnativeとKubelessを使ってみて、使い勝手などをレビューしたいと思います。
目次
なぜCloud FunctionsやAWS Lamndaではだめなの
以下の記事が非常に参考になりました。
- Google側としてもKnativeに推していく
- OpenSourceなものとして運用APIはなければならなく、それがKnative
- Kuberenetesをオープンソース化したのと同じで、Cloud Funtionsに似たようなプロダクトがあったが「デフォルトスタンダードになることが目的」
つまり要約すると以下の通りだと思います。
Cloud FunctionsやAWS Lamndaなどプラウドプロバイダーで争うのではなくオープンソース化して事実上の標準を作ることを目的にKnativeは実装されている。そのためにKubernetes上で実行される。
そのためいろんなパートナーと連携して、作っているのです。
これはCloud DataflowのためにApache BeamをOSS化したことにも非常に似ていると思います。
Knative
Knativeとは
Kuberenetes上でモダンなサーバレスをビルド、デプロイ、実行するためのプラットフォームである。
公式サイト
特徴
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とは
ドキュメント
ソースコード
これはServerlessなアプリケーションを作る本体です。
以下のような特徴があります。
- Serverlessコンテナの高速デプロイ
- 0への自動スケールダウン
- コードと設定のスナップショットを作ることができる
ServiceはRouteによってルーティングをしてConfigurationでRevisionを管理しています。
Bulidとは
ドキュメント
ソースコード
ビルドとはコンテナオーケストレーションをするCloud Nativeなビルドシステムを提供するものでbulid, testing, ソースコードのdeployingのまだ開発者が用意しなればなりません。
これによって**コンテナイメージを作成しますが、そのビルドフローを定義します。
以下のようなCloud Provderを使うことができます。
Buildpack (Cloud Foundry) Google Container Builder Bazel Kaniko Jib
インストールして使ってみる
1. Istioをインストールします
以前、Istioのサービスメッシュを構築するエントリを書いたのでこちらをご覧ください。
この記事のように構築すると以下のようになります。
$ 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をインストールする
Serving
とBuild
コンポーネントをインストールします。
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である
公式サイト
特徴
以下の様な特徴があります。
- 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
以下のように確認することができます。
関数をみるとスナップショットがみられます。
KnativeとKubelessの比較
執筆時のものです。
Knative | Kubeless | |
---|---|---|
GitHubStar | 751(serving)/275(build)/67(eventing) | 3,609 |
People | 4 | 46 |
Main maitaner | Bitnami | |
Container Builder | ✅ | ❌ |
Container less? | ❌ | ✅ (意識は必要なし) |
Dependency | Istio | none |
Dashboard | ❌ | ✅ |
RivisionControl | ✅ | ❌ |
Resource | ❌ | ✅ |
Cloud Pub/Sub Support | ✅ | ❌ |
Amazon Kinesis Support | ✅ | ✅ |
ここからは主観です。
Knative | Kubeless | |
---|---|---|
Docのクオリティ(3星満点) | ⭐️ | ⭐️⭐️ |
そのものの使い勝手 | ❌ | ✅ |
サービスメッシュとの相性 | ✅(Istio) | ❌(特に良し悪しなし) |
運用のしやすさ | ❌(かなり規模が大きい) | ✅(コンパクトで導入しやすい) |