あらためてKnative入門!(Knative Serving基礎編)

こんにちは、Red Hatソリューションアーキテクトの石川です。 今月の11月2日にアップストリームのKnativeがバージョン1.0としてリリースされました。 プロジェクトがスタートしたのが2018年とのことなので3年の月日を経て満を辞してのリリースだったかなと思います。

f:id:jpishikawa:20211112205542p:plain
https://knative.dev/blog/articles/knative-1.0/

OpenShiftでもKnativeはOpenShift Serverlessというコンポーネントで提供されており、これを使うことでOpenShiftクラスタ上でサーバーレスのアプリケーションを動かすことが出来ます。 (Knative 1.0対応はまだしてないですが…)
今回の記事ではこのKnativeについてあらためてご紹介していきたいと思います。

ちなみに以前にも赤帽ブログでKnativeについて紹介している記事がありますのでそちらも併せてご参照下さい。

rheb.hatenablog.com rheb.hatenablog.com

Knativeの概要

Knativeはサーバーレスでのアプリケーション実行を可能とするOSSのプロジェクトであり、大きくKnative ServingとKnative Eventingという二つの要素で構成されています。

Knative Servingはサーバーレスアプリケーションを公開し、実行する部分を担っており、Knative Eventingは様々なイベント情報とKnative Servingを結びつけ、イベントドリブンなアプリケーション実行を行う役割を持っています。

ちなみに以前はKnative Buildというコンポーネントもあったのですが、そちらはKnativeからスピンアウトしてCIを行うTekton Projectとして独立しました。

一度に全てを説明すると長くなるため今回はこのKnative Servingに焦点を当ててご紹介しようと思います。

Knative Servingは何をしてくれるのか?

さてサーバーレスでのアプリケーション実行ということですがKnative Servingは実際には何をしているのでしょうか。
実はアプリケーションの実行自体は、KubernetesやOpenShiftで普通にアプリケーションを動かすのと同様にPod(コンテナ)で実行しています。
しかしKnative Servingの場合、アプリを実行していないときにこのPodは0までスケールインして完全に停止します。そしてアプリケーションのエンドポイントにアクセスがあったときに初めてPodを起動し、必要な処理を実施し、それが終わればまた停止するというサイクルを繰り返します。 つまり動いてない時はサーバーのリソースが不要(サーバーレス)ということですね。

またKnative Servingのもう一つの特徴として、スケールインだけではなくスケールアウトも出来るという点があります。アプリケーションに対する接続要求が増えれば必要な数だけ自動でPodの数を増やし処理を実行してくれます。
Knative Servingを使わない場合でもPodのスケールアウトは可能ですが、その場合HPA(Horizontal Pod Autoscaler)の設定が必要となるため、Knative Servingの方が楽に実装出来ると言えるでしょう。(HPAとスケールアウトの挙動は異なりますが。)

f:id:jpishikawa:20211112204504p:plain

Knative Servingを使用するにはどうすれば良いのか?

Knative Servingを使用するにはKnativeの"Service"と呼ばれるカスタムリソースを作成する必要があります。
Kubernetesのデフォルトのリソースにもネットワーク機能を提供するServiceリソースがありますが、それとこのKnativeの"Service"は別物です。 これ以外にもKnativeにはまぎらわしい名前のリソースが多数存在するため、本記事上ではKnative/ServiceやDefault/Serviceなど区別を付け記述したいと思います。

Knative/Serviceが作成されると、OpenShiftのデフォルトのリソースとKnativeのカスタムリソースをクラスタ上に自動で作成します。

  1. デフォルトリソース
    ・Deployment:Podのデプロイ
    ・Default/Service:Podへのアクセス
    ・Default/Route:クラスタ外部へのアプリケーションの公開
  2. カスタムリソース
    ・Revision
    ・Configuration
    ・Knative/Route

実はこれ以外にも作成されるリソースはあるのですが、まずは一旦これらについて見ていきましょう。

1のデフォルトリソースについてはDeployment、Default/Service、Default/Routeの3種類となります。OpenShiftやKubernetesの経験がある方であれば、これらが作成されることでアプリケーションコンテナがクラスタにデプロイされ、外部公開されるイメージはなんとなく付くのではないでしょうか。 Knative/Serviceを一つ作成するだけでこれらのリソースは自動で作られるため、例えばKubernetesの仕組みに詳しくないアプリケーションの開発者であっても簡単にクラスタ上でアプリを動かすことが出来ます。

2のカスタムリソースについて、Knative Servingのドキュメントにはそれぞれの関係性を表す以下の図が載っています。

f:id:jpishikawa:20211112205028p:plain

まずKnative/Serviceの情報を元にConfigurationとKnative/Routeという二つのリソースが作成されます。
Knative ServingにおいてデプロイするアプリのバージョンはRevisionという単位で管理されるのですが、ConfigurationがRevisionを作成するためのテンプレート情報を保持しており、それを元にRevisionが作成されます。作成されたRevisionはImmutable(後から変更不可)な性質を持ち、新しいバージョンのアプリがデプロイされると、過去のRevisionの更新を行うのではなく、新たな別のRevisionが作成されることとなります。
Knative/RouteはこれらRevisionに対するトラフィックの振り分け情報を保持しています。デフォルトでは最新のRevisionに100%のトラフィックが振り分けられますが、例えばA/Bテストやカナリアリリースを実施したい場合などに、以前のRevisionと最新のRevisionで9:1などの割合でトラフィックを振り分けることが可能になっています。

このように様々なカスタムリソースが存在していますが、Knative Servingを使用する場合、あくまでこれらは裏側の仕組みであり、利用者の目線では基本的にKnative/Serviceのみを意識すればよく、こちらに対して追加や変更を実施していくこととなります。

Knative/Serviceの作成方法

Knative/Serviceリソースを作成するには大きく以下の3つの方法が考えられます。それぞれ順番に見ていきましょう。
1. yamlを作成しapplyする
2. kn CLIを使用して作成する
3. OpenShiftコンソールから作成する

yamlを作成しapplyする

Knative/Serviceはカスタムリソースの一種であるため、デフォルトのリソースと同様にマニフェストファイルを作成し、それをapplyすることでクラスタにデプロイすることが出来ます。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
 name: helloworld-go
 namespace: default
spec:
 template:
  spec:
   containers:
    - image: gcr.io/knative-samples/helloworld-go
      env:
        - name: TARGET
          value: "Go Sample v1"

apiVersionserving.knative.dev/v1となっていることに注意しましょう。 このマニフェストでは実行するアプリケーションのコンテナイメージと変数を設定しています。

oc apply -fにて準備したマニフェストを適用するとアプリケーションのエンドポイントが作成されます。そちらにアクセスすると変数で設定された値を含むレスポンスが確認することが出来ます。

curl http://helloworld-go-default.apps.mycluster4.bsf7.p1.openshiftapps.com
Hello Go Sample v1!

レスポンス返却時にはコンテナが起動していますが、追加のリクエストが無ければ約90秒ほどで停止します。

oc get pod -w
NAME                                             READY   STATUS    RESTARTS   AGE
helloworld-go-00001-deployment-96bbf98f9-d4m4p   2/2     Running   0          14s
helloworld-go-00001-deployment-96bbf98f9-d4m4p   2/2     Terminating   0          63s
helloworld-go-00001-deployment-96bbf98f9-d4m4p   0/2     Terminating   0          94s
helloworld-go-00001-deployment-96bbf98f9-d4m4p   0/2     Terminating   0          95s
helloworld-go-00001-deployment-96bbf98f9-d4m4p   0/2     Terminating   0          95s 

kn CLIを使用して作成する

KnativeにはknというCLIツールがあり、それを使うことでKnative/Serviceを作成することが出来ます。 CLIのインストール方法についてはKnativeのドキュメントをご参照下さい。

knを使ってyamlを書くパターンと同じ設定のKnative/Serviceを作成する場合は以下のコマンドとなります。

kn service create helloworld-go --env TARGET="Go Sample v1" --image gcr.io/knative-samples/helloworld-go

実行結果としては以下が返却され、最後の行でアプリケーションのエンドポイントが表示されているのが見えます。 (アクセス時の結果は一つ目のパターンと同じため割愛)

Creating service 'helloworld-go' in namespace 'default':

  0.046s The Route is still working to reflect the latest desired specification.
  0.049s Configuration "helloworld-go" is waiting for a Revision to become ready.
  0.067s ...
  4.996s ...
  5.026s Ingress has not yet been reconciled.
  5.117s Waiting for load balancer to be ready
  5.298s Ready to serve.

Service 'helloworld-go' created to latest revision 'helloworld-go-00001' is available at URL:
http://helloworld-go-default.apps.mycluster4.bsf7.p1.openshiftapps.com

OpenShiftコンソールから作成する

これまでの方法はあらかじめアプリケーションのコンテナが準備されていることが前提となっていましたが、OpenShiftコンソールを使うとアプリのソースコードがあればKnative/Serviceを作成することが出来ます。

まずOpenShiftのDeveloperパースペクティブを開き、"+追加"をクリックします。 ここでGitリポジトリを選択し、次の画面に移ります。

f:id:jpishikawa:20211112205057p:plain

デプロイするアプリケーションのソースコードが置かれたGitリポジトリのURLを入力すると、リソースタイプとしてServerlessデプロイメントを選択することが出来ます。このオプションはOpenShift ServerlessのOperatorをインストールしている時のみ表示されます。

f:id:jpishikawa:20211112205128p:plain

Serverlessを選択しアプリケーションを作成すると、トポロジービューからKnative/Serviceが作成され、アクセスのためのエンドポイントが提供されていることが確認出来ます。

f:id:jpishikawa:20211112205147p:plain

このようにOpenShiftコンソールを使うパターンではより簡単にサーバーレスのアプリケーションを実行することが出来ます。

まとめ

今回の記事ではKnative Servingの基礎的な内容についてご紹介させて頂きました。
サーバーレスというと敷居が高いと感じられる方もいらっしゃるかもしれませんが、実際にはわずかなステップで簡単にアプリケーションをデプロイすることが出来ます。 もし自分でも触ってみたいという方がいれば、learn.openshift.comにあるServerlessのコンテンツを無料で触ることも出来るため是非試してみて下さい!

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。