Knative でサーバーレス

Kenta Kosugi
14 min readApr 30, 2020

--

今日は OpenShift 上に Knative な環境を構築して、サーバーレスアプリケーションをデプロイしてみたいと思います。

今回利用した OpenShift のバージョンは 4.3 となっています。

おしながき

以下のとおりとなっています。途中で起動された Pod が 0 までスケールダウンするところ見てみましょう。

  1. OpenShift に Serverless Operator のインストールと Knative Serving のインストール
  2. サーバーレスアプリケーションのデプロイ
  3. トラフィック分割

Serveless Operator のインストールと Knatvie Serving のインストール

手順1. OpenShift Web コンソールに管理者権限でログインします。

手順2. 左のメニューから「Operators」→「OperatorHub」の順にアクセスします。

手順3. 検索ボックスに「Serverless」を入れて、「OpenShift Serverless Operator」を選択します。

手順3. Serverless の検索

手順4.「Install」を選択します。

手順4. OpenShift Serverless Operator の詳細画面

手順5.「Installation Mode」は「All namespaces on the cluster (default)」、「Update Channel」は「4.3」、「Approval Strategy」は「Automatic」にし「Subscribe」を選択します。

手順5. インストールモード等の選択

手順7.「default」プロジェクトの「Installed Operator」の画面に遷移しますが、しばらく待つと「default」プロジェクトにもインストールされます。

手順6.「default」プロジェクトにもインストールされた図

ここからは oc コマンドを使用します。

手順8. 管理者権限で oc login を実行します。

$ oc login https://xxxxxxxx -u <user> -p <password>

手順9. knative-serving ネームスペースを作成します。

$ oc create namespace knative-serving
namespace/knative-serving created

手順10. 以下の内容を記載した serving.yaml ファイルを用意します。

apiVersion: operator.knative.dev/v1alpha1
kind: KnativeServing
metadata:
name: knative-serving
namespace: knative-serving

手順11. oc apply コマンドを実行します。

$ oc apply -f ./serving.yaml
knativeserving.operator.knative.dev/knative-serving created

手順12. インストールの状態を確認します。Ready=True になるまで待ちましょう。

$ oc get knativeserving.operator.knative.dev/knative-serving -n knative-serving --template='{{range .status.conditions}}{{printf "%s=%s\n" .type .status}}{{end}}'
DependenciesInstalled=True
DeploymentsAvailable=True
InstallSucceeded=True
Ready=True

手順13. Pod の状態は以下の通りとなります。

$ oc get pods -n knative-serving
NAME READY STATUS RESTARTS AGE
activator-7db4dc788c-6xvdv 1/1 Running 0 2m43s
activator-7db4dc788c-j96h2 1/1 Running 0 2m58s
autoscaler-659dc48d89-x2897 1/1 Running 0 2m57s
autoscaler-hpa-57fdfbb45c-fkdbm 1/1 Running 0 2m47s
autoscaler-hpa-57fdfbb45c-jnjqq 1/1 Running 0 2m47s
controller-dc7886b47-5pt4v 1/1 Running 0 2m41s
controller-dc7886b47-pll4k 1/1 Running 0 2m52s
kn-cli-downloads-7558874f44-w7rfs 1/1 Running 0 3m3s
webhook-7d9644cb4-4lqnk 1/1 Running 0 2m55s

おまけ: OpenShift のコンソールから「Knative Serving」が有効になっているのを確認してみましょう。プロジェクトを「knative-serving」に変更して、「Operators」→「Installed Operators」→「Knative Serving」をみてみると、Serverless Operator をインストール直後にはなかった kantive-serving が作成されているのを確認できます。oc コマンドからではなく、本ページから Web UI でも作成可能です。

これで Serverless Operator のインストールは完了です。

サーバーレスアプリケーションのデプロイ

今回使用するアプリケーションはこちらになります。Quarkus フレームワークを利用しています。

HTTP リクエストを受け取って、「Hi Greeting」というメッセージを返却するだけの簡単なアプリケーションです。必要に応じてソースコードを眺めてみましょう。

Knative Serving を利用するアプリケーションは Pod がアイドルになると、0までスケールダウンし、リクエストイベントが発生すると Pod が起動されます。通常の Java アプリケーションだと起動のたびに Java の BootStrap 処理が走るため、サーバーレスには向いていませんが、Quarkus を利用すると 使い慣れた Java 言語で Linux ネイティブなバイナリアプリケーションを生成することができこうした問題を解決できます。

Linux バイナリで生成したコンテナイメージは Quay に格納されています。

手順13. 一般ユーザーで oc login します。

手順14. knative-test プロジェクトを作成します。

$ oc new-project knative-test
Now using project "knative-test" on server "https://api.cluster-xxxxxxxxx:6443".
You can add applications to this project with the 'new-app' command. For example, try: oc new-app django-psql-exampleto build a new example application in Python. Or use kubectl to deploy a simple Kubernetes application: kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node

手順15. 以下の service.yaml を用意します。

既に作成済みのコンテナイメージを指定しています。Quarkus の Liveness Probe や Readiness Probe についてはこちらを参照ください。

kind が Service になっている点に注意してください。

手順16. oc apply コマンドでデプロイします。

$ oc apply -f ./service.yaml
service.serving.knative.dev/greeter created
おまけ: OpenShift のコンソールから Pod の確認

手順17. Knative Serving の Route をチェックします。

$ oc get rt
NAME URL READY REASON
greeter http://greeter-knative-test.apps.xxxxxxxx True

OpenShift のコンソール上では、左メニューの「Serverless」→「Routes」から確認することができます。

手順18. 上記の URL に Web ブラウザでアクセスします。

Web ブラウザでアクセス

上記のように「Hi greeter => ‘xxxxxxxxx’: 1」と表示されたら成功です。

手順19. しばらく環境を放置します。

手順20. Pod が 0 までスケールダウンされていることを確認します。

$ oc get pods
No resources found in knative-test namespace.

OpenShift のコンソールから「Developer」→「Topology」を確認して、Pod が存在しないことも確認しておきます。

Pod がなくなった状態

手順21. 再度ブラウザから URL にアクセスして、Pod が起動するか確認します。

Pod が生きている状態

これで Serverless アプリケーションのデプロイは完了です。

トラフィック分割

事前に OpenShift のコンソール右上から ? →「Command Line Tools」の順にアクセスし、自身の環境にあった kn コマンドをダウンロードしておきます。

oc コマンドは引き続き一般ユーザーで実行します。

手順22. 新しいリビジョンのサービスを定義します。今回はソースコードには手を加えず、環境変数を読み込むように YAML ファイルを変更します。以下の service2.yaml を用意しましょう。

手順23. oc apply し、新しいバージョンのサービスを適用します。

$ oc apply -f ./service2.yaml
service.serving.knative.dev/greeter configured

手順24. URL をブラウザで開き、メッセージが 「Hi」から「Namaste」に変わっていることを確認します。

この Namaste は YAML ファイルに新たに環境変数 MESSAGE_PREFIX を設定したことによりアプリケーションが default の Hi から環境変数を適用したために動作が変わっています。

env:
- name: MESSAGE_PREFIX
value: Namaste

手順25. リビジョンを確認します。

$ oc get revision
NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON
greeter-mk286 greeter greeter-mk286 2 True
greeter-shxmk greeter greeter-shxmk 1 True

Hi を返す GENERATION 1 と Namaste を返す GENERATION 2 が存在することが確認できます。

手順26. kn コマンドでもリビジョンを確認します。

$ kn revision list
NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
greeter-mk286 greeter 100% 2 9m44s 3 OK / 4 True
greeter-shxmk greeter 1 19m 3 OK / 4 True

上記により、環境変数を適用したアプリケーションにトラフィックが100% 流れることが確認できます。

手順27. kn コマンドを使用して、GENERATION 1 と GENERATION 2 へトラフィックが 50% ずつ流れるよう変更します。

$ kn service update greeter --traffic @latest=50 --traffic greeter-shxmk=50
Updating Service 'greeter' in namespace 'knative-test':
0.390s Ingress has not yet been reconciled.
0.493s Ready to serve.
Service 'greeter' with latest revision 'greeter-mk286' (unchanged) is available at URL:http://greeter-knative-test.apps.xxxxxxxxx

トポロジは以下のようになります。

トラフィックを50%ずつ分割

手順28. 以下のコマンドを実行して10回連続で curl コマンドを実行します。

$ for i in {1..10}; do curl http://greeter-knative-test.apps.cluster-tokyo-6d19.tokyo-6d19.example.opentlc.com; done
Hi greeter => '9861675f8845' : 1
Hi greeter => '9861675f8845' : 2
Hi greeter => '9861675f8845' : 3
Hi greeter => '9861675f8845' : 4
Namaste greeter => '9861675f8845' : 1
Namaste greeter => '9861675f8845' : 2
Hi greeter => '9861675f8845' : 5
Namaste greeter => '9861675f8845' : 3
Namaste greeter => '9861675f8845' : 4
Hi greeter => '9861675f8845' : 6

完全に50% とは行きませんでしたが、ほぼ半分ずつトラフィックが別れたことが確認できました。

今回は以上になります。

--

--

Kenta Kosugi
Kenta Kosugi

Written by Kenta Kosugi

Javaアプリケーションサーバーの開発からCORBA製品のサポート、QA、証券外務員(第一種免許)、ストレージ屋、アーキテクト、SaaS屋と一貫性のない道を歩んでいます。Red Hatに復帰しました。

No responses yet