目次


Knative でルーティング機能を管理する

Knative でワークロードを公開する仕組みについて

Comments

Knative でのルーティング

KnativeKubernetes の機能を拡張するオープンソース・プラットフォームです。その目的は、最新のソース中心のコンテナー化されたサーバーレス・アプリケーションを作成できるようにすることにあります。 Knative は Istio を統合することで、簡単にワークロードをインターネットに公開して、モニタリング、制御できるようにしています。 このチュートリアルでは、Knative のトラフィック管理機能に焦点を当てます。

目標

このチュートリアルでは、次の方法を学びます。

  • アプリケーションの新しいリビジョンをロールアウトする
  • アプリケーションの前のリビジョンにロールバックする

前提条件

このチュートリアルでは読者が一連の Knative 入門ラボを完了し、 Knative の基本概念を理解していること、すでに IBM Cloud Kubernetes Service クラスターを作成し、Knative をインストールしていることを前提としています。 このチュートリアルを完了するには、クラスターが作成済みになっている必要があります。

以下の演習にまだ取り組んでいない場合は、このチュートリアルの手順を開始する前に完了してください。

サンプル・アプリケーションをデプロイする

Knative を使用するには次の 2 つの方法があります。

  • 下位レベルの Knative リソース (ルート、構成など) を直接管理する
  • 上位レベルの Knative サービス・リソースを管理して、基礎となる下位レベルのリソースは Knative に管理させる

このチュートリアルでは単純にするために、2 番目の方法を使用します。

このチュートリアルでサンプルとして使用する helloworld プログラムは、このサンプルを編集したものです。

  1. サンプル・アプリケーションのリポジトリーを複製し、そこに含まれている yaml ファイルを使用できるようにします。
    git clone github.com/IBM/knative-routing-tutorial
  2. Knative 入門で、kaniko ビルド・テンプレートを使用して Dockerfile ファイルからコンテナー・イメージをビルドする方法を学びました。まだ kaniko ビルド・テンプレートをクラスターにインストールしていない場合は、次のコマンドを使ってインストールしてください。
    kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
  3. helloworld1.yaml ファイルを使用して、helloworld プログラムをデプロイします。このファイルの内容を確認しましょう。
    apiVersion: serving.knative.dev/v1alpha1
    kind: Service
    metadata:
      name: helloworld-go
      namespace: default
    spec:
      runLatest:
        configuration:
          build:
            apiVersion: build.knative.dev/v1alpha1
            kind: Build
            spec:
              serviceAccountName: build-bot
              source:
                git:
                  url: https://github.com/IBM/knative-routing-tutorial
                  revision: master
              template:
                name: kaniko
                arguments:
                - name: IMAGE
                  value: registry.ng.bluemix.net/<NAMESPACE>/helloworld-go:1
                - name: DOCKERFILE
                  value:/workspace/helloworld1/Dockerfile
          revisionTemplate:
            spec:
              serviceAccountName: build-bot
              container:
                image: registry.ng.bluemix.net/<NAMESPACE>/helloworld-go:1
                env:
                - name: TARGET
                  value: "Go Sample v1"

    この yaml ファイルは、git リポジトリー内のソース・コードからアプリケーションをビルドして、ビルドしたコンテナー・イメージをプライベート・コンテナー・レジストリーにプッシュします。その上で、コンテナーをレジストリーからプルして実行します。
  4. helloworld1.yaml ファイルを編集して、独自のコンテナー・レジストリーの名前空間を指すようにする必要があります。<NAMESPACE> のすべてのインスタンスを、Knative 入門で作成したコンテナー・レジストリーの名前空間で置き換えてください。この作業が完了したら、helloworld1.yaml ファイルをクラスターに適用します。
    kubectl apply -f helloworld1.yaml

    ビルド・プロセスが実行されてプログラムが動作可能な状態になるまでには、しばらく時間がかかる場合があります。 サービスを表示すると、進捗状況をモニタリングできます。
    kubectl get ksvc helloworld-go
  5. サービスが実行可能な状態になったことが出力に示されたら、手順を進めます。次のような出力が表示されるまで待ってください。
    NAME            DOMAIN                                                                 LATESTCREATED         LATESTREADY           READY     REASON
    helloworld-go   helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud   helloworld-go-00001   helloworld-go-00001   True

    上記の出力から、サービスのホスト名が helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud であることがわかります。

    サービスのホスト名の一般的な形式は、service-name.service-namespace.ingress-subdomain です。

    service nameservice-namespace は service yaml ファイルによって決定されます。この例の場合、yaml では名前空間を指定していないので、default 名前空間が使用されています。

    ingress subdomain は、クラスターにアクセスするためのパブリック URL です。これは、クラスターに付けた名前とクラスターが位置する場所によって異なってきます。

サービスのホスト名がわかったので、helloworld アプリケーションに対して curl コマンドを実行できます。以下の curl コマンドに含まれるサービス名の部分は実際の名前で置き換えてください。

curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud

Hello Go Sample v1! のようなレスポンス・メッセージが表示されるはずです。

アプリケーションの新しいバージョンをロールアウトする

サンプル・アプリケーションに変更を加えて、単純な静的メッセージではなく、もう少し面白味のあるレスポンスが返されるようにしましょう。 前のステップでは、新しいイメージをビルドしてデプロイするために、アプリケーションの元のバージョンをまるごと置き換えました。 けれども何らかの時点で、新しい機能を徐々にユーザーにロールアウトする必要も出てくるでしょう。 その場合は、service yaml ファイル内で「リリース」モードという機能を使用します。

以下に、次に使用する yaml ファイル helloworld2.yaml を記載します。

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: helloworld-go
  namespace: default
spec:
  release:
    # Ordered list of 1 or 2 revisions. 
    # First revision is traffic target "current"
    # Second revision is traffic target "candidate"
    revisions: ["helloworld-go-00001", "helloworld-go-00002"]
    rolloutPercent: 50 # Percent [0-99] of traffic to route to "candidate" revision
    configuration:
      build:
        apiVersion: build.knative.dev/v1alpha1
        kind: Build
        spec:
          serviceAccountName: build-bot
          source:
            git:
              url: https://github.com/IBM/knative-routing-tutorial
              revision: master
          template:
            name: kaniko
            arguments:
            - name: IMAGE
              value: registry.ng.bluemix.net/<NAMESPACE>/helloworld-go:2
            - name: DOCKERFILE
              value:/workspace/helloworld2/Dockerfile
      revisionTemplate:
        spec:
          serviceAccountName: build-bot
          container:
            image: registry.ng.bluemix.net/<NAMESPACE>/helloworld-go:2

このファイルでは、ビルドするサービスのポッド構成を変更して別のイメージを使用しているだけでなく、前の yaml ファイルの「runLatest」の部分を「release」で置き換えています。リリース・モードを使用すると、次のことが可能になります。

  • 2 つのバージョンのリストを指定して、それらのバージョンの間でトラフィックを分割する。 この例では、前のリビジョン helloworld-go-00001 と新しく作成するリビジョン helloworld-go-00002 の間でトラフィックを分割します。
  • 上記のリストにある 2 番目のリビジョンにルーティングするトラフィックのパーセンテージを指定する。この例では、トラフィックの 50 パーセントが新しいリビジョンに転送されるようになっています。

独自のコンテナー・レジストリーの名前空間を指すように helloworld2.yaml ファイルを編集します。<NAMESPACE> のすべてのインスタンスを、Knative ラボで作成したコンテナー・レジストリーの名前空間で置き換えてください。 この作業が完了したら、helloworld2.yaml ファイルをクラスターに適用します。

kubectl apply -f helloworld2.yaml

前と同じように kubectl get ksvc helloworld-go を使用して、新しいリビジョンが使用可能になるまでモニタリングします。使用可能な状態になったら、次のコマンドを使用して、ルートが 2 つのリビジョン間でトラフィックを分割していることを確認します。

knctl route list

次のような出力が表示されます。

Routes in namespace 'default'

Name           Domain                                                                Traffic                     Annotations  Conditions  Age
helloworld-go  helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud  50% -> helloworld-go-00001  -            3 OK / 3    15m
                                                                                     50% -> helloworld-go-00002
                                                                                     0% -> helloworld-go

curl を何回か実行すると、最初のバージョンから返されたレスポンスの他に新しいレスポンスも表示されるはずです。

$ curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello and have a wonderful day!

$ curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello Go Sample v1!

Grafana を使用してトラフィックをモニタリングする

この Knative インストール済み環境には、PrometheusGrafana も組み込まれています。 Prometheus は、多次元の時系列データを収集して保管できるオープンソースのモニタリング・ツールです。 Grafana は、グラフとダッシュボードでメトリクス・データを視覚化するために使用できるメトリクス分析プラットフォームです。 この 2 つのツールを使用すれば、サービスの 2 つのバージョンの間でトラフィックが分割される様子を観察することができます。

  1. Grafana を開くには、次のコマンドを入力します。
    kubectl port-forward --namespace knative-monitoring \
    $(kubectl get pods --namespace knative-monitoring \
    --selector=app=grafana --output=jsonpath="{.items..metadata.name}") \
    3000

    これにより、Grafana のローカル・プロキシーがポート 3000 上で起動します。
  2. http://localhost:3000 にアクセスして Grafana UI を表示します。

    ページが開いたら、画面の上部にあるドロップダウンのダッシュボード選択メニューをクリックし、「Knative Serving - Revision HTTP Requests (Knative Serving - リビジョン HTTP リクエスト)」を選択します。 ダッシュボードが開いたら、「Configuration (構成)」ドロップダウン・メニューをクリックし、「helloworld-go」を選択します。

  3. 別のシェルで、helloworld-go サービスに対する curl リクエストのループを実行します。それには次のようにします。
    for i in `seq 1 5000`; do curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud; done

    Request Volume By Revision (リビジョンごとのリクエスト量)」ダッシュボードで、リビジョン 1 と 2 の間でトラフィックが均等に分割されていることを確認できるはずです。 grafana
    grafana
  4. 後でまた戻れるよう、Grafana ウィンドウは開いたままにしておきます。

リリース・モードでのサービス・ホスト名の追加

サービス・リリース・モードを使用すると、特定のバージョンにアクセスするためのサービス・ホスト名が追加で作成されます。 これらのホスト名を確認するには、次のコマンドを使用します。

knctl route show --route helloworld-go

次のような出力が表示されます。

Route 'helloworld-go'

Name             helloworld-go
Domain           helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Internal Domain  helloworld-go.default.svc.cluster.local
Age              1h

Targets

Percent  Revision             Service  Domain
50%      helloworld-go-00001  -        current.helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
~        helloworld-go-00002  -        candidate.helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
0%       helloworld-go-00002  -        latest.helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud

Conditions

Type                Status  Age  Reason  Message
AllTrafficAssigned  True     1h  -       -
IngressReady        True     1h  -       -
Ready               True     1h  -       -

以下のサブドメインが追加されています。

  • current。リビジョン・リスト内の最初のリビジョン (この例の場合、helloworld-go-00001) にトラフィックをルーティングします。
  • candidate。リビジョン・リスト内の 2 番目のリビジョン (この例の場合、helloworld-go-00002) にトラフィックをルーティングします。
  • latest。サービスの最新リビジョン (この例の場合、2 番目のリビジョンと同じ helloworld-go-00002) にトラフィックをルーティングします。

必要に応じて、これらのホスト名を使用して特定のリビジョンを試すことができます。

$ curl current.helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello Go Sample v1!
$ curl candidate.helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello and have a super day!

アプリケーションの以前のバージョンにロールバックする

ロールアウトをテストしていて、サービスの新しいリビジョンで何らかの問題が見つかったとしたら、新しいユーザーをそのリビジョンにはルーティングしたくないはずです。

その場合、サービスを編集するには次のコマンドを使用します。

kubectl edit ksvc helloworld-go

編集用のウィンドウが開き、サービスの現在の yaml 定義が表示されます。rolloutPercent というキーを見つけて、その値を 0 に変更してからファイルを保存します。

これにより、すべてのトラフィックがリビジョン・リスト内の最初のリビジョンにルーティングされるようになります。

$ curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello Go Sample v1!

$ curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello Go Sample v1!

Grafana ウィンドウを見ると、すべてのトラフィックがリビジョン 1 にルーティングされるようになったことを確認できるはずです。

grafana
grafana

アプリケーションの最新バージョンにロールフォワードする

テストがうまく行って、すべてのユーザーを新しいリビジョンにルーティングしたいとします。 その場合、サービスの yaml ファイルを編集して、リビジョン・リストを変更します。現時点で、rolloutPercent は次のようになっているとします。

    revisions:
    - helloworld-go-00001
    - helloworld-go-00002
    rolloutPercent: 50

次のように変更します。

    revisions:
    - helloworld-go-00002
    rolloutPercent: 0

これにより、すべてのトラフィックがサービスの最新バージョンにルーティングされるようになります。

$ curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello and have a wonderful day!

$ curl helloworld-go.default.mycluster6.us-south.containers.appdomain.cloud
Hello and have a super day!

Grafana ウィンドウを見ると、すべてのトラフィックがリビジョン 2 にルーティングされるようになったことを確認できるはずです。

grafana
grafana

次のステップ

お疲れさまでした!これでチュートリアルは完了です。このチュートリアルでは、Knative のルーティング機能を使用して、アプリケーションの新しいリビジョンをロールアウトする方法、以前のリビジョンにロールバックする方法を学びました。次のステップとして、クラウド上での Knative パイプラインの開発または Knative を使用した CD パイプラインのセットアップに挑戦してください。さらに、このリンク先のページで他のさまざまな Knative 関連のコンテンツを調べることもできます。


ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing
ArticleID=1066490
ArticleTitle=Knative でルーティング機能を管理する
publish-date=08212019