序章

サービスの新しいバージョンを導入する場合、古いバージョンを段階的に廃止する過程で、ユーザートラフィックの制御された割合を新しいバージョンのサービスにシフトすることが望ましい場合がよくあります。 この手法は、カナリア展開と呼ばれます。

Kubernetesクラスターオペレーターは、ラベルデプロイメントを使用して、カナリアデプロイメントをネイティブにオーケストレーションできます。 ただし、この手法には特定の制限があります。トラフィックの分散とレプリカの数が結合されます。つまり、実際には、トラフィックをカナリアリリースに制限するには、レプリカの比率を手動で制御する必要があります。 つまり、10 % o fトラフィックをカナリア展開に転送するには、10個のポッドのプールが必要です。1個のポッドが10 % o fのユーザートラフィックを受信し、他の9個が残りを受信します。

Istio サービスメッシュを使用してデプロイすると、レプリカ数とトラフィック管理を明確に分離できるため、この問題に対処できます。 Istioメッシュにより、トラフィックの分散と管理をレプリカのスケーリングから切り離す、きめ細かいトラフィック制御が可能になります。 レプリカの比率を手動で制御する代わりに、トラフィックの割合とターゲットを定義でき、残りはIstioが管理します。

このチュートリアルでは、IstioとKubernetesを使用してカナリアデプロイメントを作成します。 デモNode.jsアプリケーションの2つのバージョンをデプロイし、 VirtualServiceおよびDestinationRule リソースを使用して、新しいバージョンと古いバージョンの両方へのトラフィックルーティングを構成します。 これは、Istioを使用して将来のカナリア展開を構築するための良い出発点になります。

前提条件

  • ロールベースのアクセス制御(RBAC)が有効になっているKubernetes1.10+クラスター。 このセットアップでは、3つのノードを持つ DigitalOcean Kubernetesクラスターを使用しますが、別の方法を使用してクラスターを自由に作成できます。

<$>[注] ノート: このセットアップには、少なくとも8GBの使用可能なメモリと4vCPUを備えたクラスターを強くお勧めします。 このチュートリアルでは、DigitalOceanの標準の4GB/2vCPUドロップレットのうち3つをノードとして使用します。 <$>

  • The kubectl 開発サーバーにインストールされ、クラスターに接続するように構成されたコマンドラインツール。 インストールについてもっと読むことができます kubectl 公式ドキュメントにあります。
  • Dockerが開発サーバーにインストールされています。 Ubuntu 18.04を使用している場合は、 Ubuntu18.04にDockerをインストールして使用する方法の手順1と2に従ってください。 それ以外の場合は、他のオペレーティングシステムへのインストールについて、公式ドキュメントに従ってください。 必ず非rootユーザーをに追加してください docker リンクされたチュートリアルのステップ2で説明されているように、グループ。
  • DockerHubアカウント。 これを設定する方法の概要については、DockerHubのこの紹介を参照してください。
  • Istioは、KubernetesでIstioをインストールして使用する方法の手順に従ってインストールおよび構成されます。 また、 Grafana テレメトリアドオンを有効にして、外部アクセス用に構成する必要があります。

ステップ1—アプリケーションのパッケージ化

前提条件のチュートリアルIstioをKubernetesでインストールして使用する方法では、ノードデモDockerイメージを作成してサメ情報アプリケーションを実行し、このイメージをDockerHubにプッシュしました。 このステップでは、別のイメージを作成します。カナリアの展開に使用するアプリケーションの新しいバージョンです。

私たちのオリジナルのデモアプリケーションは、サメ情報ページでサメに関するいくつかの友好的な事実を強調しました。

しかし、新しいカナリアバージョンでは、いくつかの恐ろしい事実を強調することにしました。

最初のステップは、この2番目のバージョンのアプリケーションのコードを次のディレクトリに複製することです。 node_image. 次のコマンドを使用して、 DigitalOceanCommunityGitHubアカウントからnodejs-canary-appリポジトリのクローンを作成します。 このリポジトリには、アプリケーションの2番目の恐ろしいバージョンのコードが含まれています。

  1. git clone https://github.com/do-community/nodejs-canary-app.git node_image

に移動します node_image ディレクトリ:

  1. cd node_image

このディレクトリには、新しいバージョンのサメ情報アプリケーションのファイルとフォルダが含まれています。このアプリケーションは、元のアプリケーションと同様に、より恐ろしい事実に重点を置いて、サメに関する情報をユーザーに提供します。 アプリケーションファイルに加えて、ディレクトリには、アプリケーションコードを使用してDockerイメージを構築するための手順が記載されたDockerfileが含まれています。 Dockerfileの手順の詳細については、Dockerを使用してNode.jsアプリケーションを構築する方法のステップ3を参照してください。

アプリケーションコードとDockerfileが期待どおりに機能することをテストするには、 docker build コマンドを使用してイメージをビルドしてタグ付けし、イメージを使用してデモコンテナを実行します。 を使用して -t フラグ docker build イメージにDockerHubユーザー名のタグを付けて、テスト後にDockerHubにプッシュできるようにします。

次のコマンドを使用してイメージをビルドします。

  1. docker build -t your_dockerhub_username/node-demo-v2 .

The . コマンドで、ビルドコンテキストが現在のディレクトリであることを指定します。 画像に名前を付けました node-demo-v2、参照するには node-demo 画像KubernetesでIstioをインストールして使用する方法でを作成しました。

ビルドプロセスが完了すると、 dockerimagesを使用してイメージを一覧表示できます。

  1. docker images

イメージビルドを確認する次の出力が表示されます。

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/node-demo-v2 latest 37f1c2939dbf 5 seconds ago 77.6MB node 10-alpine 9dfa73010b19 2 days ago 75.3MB

次に、 docker run このイメージに基づいてコンテナを作成します。 このコマンドには、次の3つのフラグが含まれます。

  • -p:これにより、コンテナーのポートが公開され、ホストのポートにマップされます。 ポートを使用します 80 ホスト上にありますが、そのポートで別のプロセスを実行している場合は、必要に応じてこれを自由に変更する必要があります。 これがどのように機能するかについての詳細は、ポートバインディングに関するDockerドキュメントのこの説明を参照してください。
  • -d:これは、コンテナをバックグラウンドで実行します。
  • --name:これにより、コンテナにカスタマイズされた名前を付けることができます。

次のコマンドを実行して、コンテナーを作成します。

  1. docker run --name node-demo-v2 -p 80:8080 -d your_dockerhub_username/node-demo-v2

dockerpsを使用して実行中のコンテナーを検査します。

  1. docker ps

アプリケーションコンテナが実行されていることを確認する出力が表示されます。

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 49a67bafc325 your_dockerhub_username/node-demo-v2 "docker-entrypoint.s…" 8 seconds ago Up 6 seconds 0.0.0.0:80->8080/tcp node-demo-v2

これで、ブラウザでサーバーIPにアクセスして、セットアップをテストできます。 http://your_server_ip. アプリケーションは次のランディングページを表示します。

Get Shark Info ボタンをクリックして、より恐ろしいサメ情報を入手してください。

アプリケーションをテストしたので、実行中のコンテナーを停止できます。 使用する docker ps もう一度 CONTAINER ID:

  1. docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 49a67bafc325 your_dockerhub_username/node-demo-v2 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:80->8080/tcp node-demo-v2

dockerstopでコンテナを停止します。 必ず交換してください CONTAINER ID 独自のアプリケーションとともにここにリストされています CONTAINER ID:

  1. docker stop 49a67bafc325

イメージをテストしたので、DockerHubにプッシュできます。 まず、前提条件で作成したDockerHubアカウントにログインします。

  1. docker login -u your_dockerhub_username

プロンプトが表示されたら、DockerHubアカウントのパスワードを入力します。 この方法でログインすると、 ~/.docker/config.json ルート以外のユーザーのホームディレクトリに、DockerHubのクレデンシャルを使用してファイルします。

dockerpushコマンドを使用してアプリケーションイメージをDockerHubにプッシュします。 交換することを忘れないでください your_dockerhub_username 独自のDockerHubユーザー名を使用:

  1. docker push your_dockerhub_username/node-demo-v2

これで、2つのアプリケーションイメージがDockerHubに保存されました。 node-demo 画像、および node-demo-v2. ここで、前提条件のチュートリアル Istio With Kubernetes をインストールして使用する方法で作成したマニフェストを変更して、トラフィックをアプリケーションのカナリアバージョンに転送します。

ステップ2—アプリケーションデプロイメントの変更

Kubernetes でIstioをインストールして使用する方法では、アプリケーションサービスおよび展開用の仕様を使用してアプリケーションマニフェストを作成しましたオブジェクト。 これらの仕様は、各オブジェクトの望ましい状態を記述します。 このステップでは、アプリケーションの2番目のバージョンのデプロイメントを、Istioがこれらのリソースを管理できるようにするバージョンラベルとともに、このマニフェストに追加します。

前提条件のチュートリアルのセットアップ手順に従うと、次のディレクトリが作成されます。 istio_project と2つ yaml マニフェスト: node-app.yaml、ServiceオブジェクトとDeploymentオブジェクトの仕様が含まれています。 node-istio.yaml、IstioVirtualServiceおよびGatewayリソースの仕様が含まれています。

に移動します istio_project 今すぐディレクトリ:

  1. cd
  2. cd istio_project

開ける node-app.yamlnano または、アプリケーションマニフェストに変更を加えるためのお気に入りのエディター:

  1. nano node-app.yaml

現在、ファイルは次のようになっています。

〜/ istio_project / node-app.yaml
apiVersion: v1
kind: Service
metadata:
  name: nodejs
  labels: 
    app: nodejs
spec:
  selector:
    app: nodejs
  ports:
  - name: http
    port: 8080 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs
  labels:
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nodejs
  template:
    metadata:
      labels:
        app: nodejs
        version: v1
    spec:
      containers:
      - name: nodejs
        image: your_dockerhub_username/node-demo
        ports:
        - containerPort: 8080

このファイルの内容の詳細については、KubernetesでIstioをインストールして使用する方法ステップ3を参照してください。

デプロイメントにはすでにバージョンラベルが含まれています metadatatemplate ポッドとサービスに関するIstioの推奨事項に続くフィールド。 これで、アプリケーションの2番目のバージョンを表す2番目のDeploymentオブジェクトの仕様を追加し、 name 最初のDeploymentオブジェクトの

まず、既存のDeploymentオブジェクトの名前を次のように変更します nodejs-v1:

〜/ istio_project / node-app.yaml
...
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-v1
  labels:
    version: v1
...

次に、このデプロイメントの仕様の下に、2番目のデプロイメントの仕様を追加します。 自分の画像の名前をに追加することを忘れないでください image 分野:

〜/ istio_project / node-app.yaml
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-v2
  labels:
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nodejs
  template:
    metadata:
      labels:
        app: nodejs
        version: v2
    spec:
      containers:
      - name: nodejs
        image: your_dockerhub_username/node-demo-v2
        ports:
        - containerPort: 8080

最初の展開と同様に、この展開では version このデプロイメントに対応するアプリケーションのバージョンを指定するためのラベル。 この場合、 v2 この展開に関連付けられているアプリケーションのバージョンを v1、これは最初の展開に対応します。

また、ポッドv2 展開は実行されます node-demo-v2 前のステップで作成したカナリア画像。

編集が終了したら、ファイルを保存して閉じます。

アプリケーションマニフェストを変更したら、次の変更に進むことができます。 node-istio.yaml ファイル。

ステップ3—仮想サービスを使用したトラフィックの重み付けと宛先ルールの追加

KubernetesでIstioをインストールして使用する方法では、ゲートウェイオブジェクトと仮想サービスオブジェクトを作成して、外部トラフィックをIstioメッシュに送り、アプリケーションサービスにルーティングできるようにしました。 ここでは、仮想サービス構成を変更して、アプリケーションサービスサブセットへのルーティングを含めます— v1v2. また、宛先ルールを追加して、適用するルーティングルールに追加のバージョンベースのポリシーを定義します。 nodejs アプリケーションサービス。

を開きます node-istio.yaml ファイル:

  1. nano node-istio.yaml

現在、ファイルは次のようになっています。

〜/ istio_project / node-istio.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: nodejs-gateway
spec:
  selector:
    istio: ingressgateway 
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nodejs
spec:
  hosts:
  - "*"
  gateways:
  - nodejs-gateway
  http:
  - route:
    - destination:
        host: nodejs

このマニフェストの仕様の詳細については、KubernetesでIstioをインストールして使用する方法のステップ4を参照してください。

最初の変更は、仮想サービスです。 現在、このリソースはメッシュに入るトラフィックを nodejs-gateway 私たちに nodejs アプリケーションサービス。 私たちがやりたいのは、トラフィックの80%を元のアプリケーションに送信し、20%を新しいバージョンに送信するルーティングルールを構成することです。 カナリアのパフォーマンスに満足したら、トラフィックルールを再構成して、すべてのトラフィックを新しいアプリケーションバージョンに徐々に送信できます。

単一にルーティングする代わりに destination、元のマニフェストで行ったように、追加します destination 両方のアプリケーションサブセットのフィールド:元のバージョン(v1)とカナリア(v2).

このルーティングルールを作成するには、仮想サービスに次の追加を行います。

〜/ istio_project / node-istio.yaml
...
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nodejs
spec:
  hosts:
  - "*"
  gateways:
  - nodejs-gateway
  http:
  - route:
    - destination:
        host: nodejs
        subset: v1
      weight: 80
    - destination:
        host: nodejs
        subset: v2
      weight: 20

追加したポリシーには、次の2つの宛先が含まれています。 subset 私たちの nodejs アプリケーションの元のバージョンを実行しているサービス、 v1、 そしてその subset カナリアを走らせている、 v2. サブセット1は着信トラフィックの80%を受信し、カナリアは20%を受信します。

次に、トラフィックが適切なサービスにルーティングされた後、着信トラフィックにルールを適用する宛先ルールを追加します。 この場合、構成します subset 適切なバージョンラベルを使用してトラフィックをポッドに送信するフィールド。

仮想サービス定義の下に次のコードを追加します。

〜/ istio_project / node-istio.yaml
...
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nodejs
spec:
  host: nodejs
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

私たちのルールは、私たちのサービスサブセットへのトラフィックを保証します。 v1v2、適切なラベルでポッドに到達します。 version: v1version: v2. これらは、アプリケーションのデプロイメント仕様に含めたラベルです。

ただし、必要に応じて、サブセットレベルで特定のトラフィックポリシーを適用して、カナリアの展開をさらに具体化することもできます。 このレベルでのトラフィックポリシーの定義の詳細については、公式のIstioドキュメントを参照してください。

編集が終了したら、ファイルを保存して閉じます。

アプリケーションマニフェストが改訂されたら、構成の変更を適用し、Grafanaテレメトリアドオンを使用してアプリケーショントラフィックデータを調べる準備が整います。

ステップ4—構成変更の適用とトラフィックデータへのアクセス

アプリケーションマニフェストは更新されますが、これらの変更をKubernetesクラスターに適用する必要があります。 kubectl apply コマンドを使用して、既存の構成を完全に上書きせずに変更を適用します。 これを行うと、アプリケーションへのリクエストを生成し、IstioGrafanaダッシュボードで関連データを確認できるようになります。

構成をアプリケーションのServiceオブジェクトとDeploymentオブジェクトに適用します。

  1. kubectl apply -f node-app.yaml

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

Output
service/nodejs unchanged deployment.apps/nodejs-v1 created deployment.apps/nodejs-v2 created

次に、行った構成の更新を適用します node-istio.yaml、これには、仮想サービスと新しい宛先ルールへの変更が含まれます。

  1. kubectl apply -f node-istio.yaml

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

Output
gateway.networking.istio.io/nodejs-gateway unchanged virtualservice.networking.istio.io/nodejs configured destinationrule.networking.istio.io/nodejs created

これで、アプリケーションへのトラフィックを生成する準備が整いました。 ただし、それを行う前に、まず、 grafana 実行中のサービス:

  1. kubectl get svc -n istio-system | grep grafana
Output
grafana ClusterIP 10.245.233.51 <none> 3000/TCP 4d2h

関連するポッドも確認してください。

  1. kubectl get svc -n istio-system | grep grafana
Output
grafana-67c69bb567-jpf6h 1/1 Running 0 4d2h

最後に、 grafana-gateway ゲートウェイと grafana-vs 仮想サービス:

  1. kubectl get gateway -n istio-system | grep grafana
Output
grafana-gateway 3d5h
  1. kubectl get virtualservice -n istio-system | grep grafana
Output
grafana-vs [grafana-gateway] [*] 4d2h

これらのコマンドからの出力が表示されない場合は、KubernetesでIstioをインストールして使用する方法の手順2および5を確認してください。 Istioをインストールする際のGrafanaテレメトリアドオンと、GrafanaサービスへのHTTPアクセスを有効にする方法。

これで、ブラウザでアプリケーションにアクセスできます。 これを行うには、に関連付けられた外部IPが必要になります istio-ingressgateway LoadBalancerサービスタイプであるサービス。 私たちは nodejs-gateway KubernetesでIstioをインストールして使用する方法でゲートウェイマニフェストを作成するときに、このコントローラーを使用するゲートウェイ。 ゲートウェイマニフェストの詳細については、そのチュートリアルのステップ4を参照してください。

の外部IPを取得します istio-ingressgateway 次のコマンドでサービスします。

  1. kubectl get svc -n istio-system

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

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana ClusterIP 10.245.85.162 <none> 3000/TCP 42m istio-citadel ClusterIP 10.245.135.45 <none> 8060/TCP,15014/TCP 42m istio-galley ClusterIP 10.245.46.245 <none> 443/TCP,15014/TCP,9901/TCP 42m istio-ingressgateway LoadBalancer 10.245.171.39 ingressgateway_ip 15020:30707/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:30285/TCP,15030:31668/TCP,15031:32297/TCP,15032:30853/TCP,15443:30406/TCP 42m istio-pilot ClusterIP 10.245.56.97 <none> 15010/TCP,15011/TCP,8080/TCP,15014/TCP 42m istio-policy ClusterIP 10.245.206.189 <none> 9091/TCP,15004/TCP,15014/TCP 42m istio-sidecar-injector ClusterIP 10.245.223.99 <none> 443/TCP 42m istio-telemetry ClusterIP 10.245.5.215 <none> 9091/TCP,15004/TCP,15014/TCP,42422/TCP 42m prometheus ClusterIP 10.245.100.132 <none> 9090/TCP 42m

The istio-ingressgateway を備えた唯一のサービスである必要があります TYPE LoadBalancer、および外部IPを持つ唯一のサービス。

ブラウザでこの外部IPに移動します。 http://ingressgateway_ip.

次のランディングページが表示されます。

Get SharkInfoボタンをクリックします。 2つのサメ情報ページのいずれかが表示されます。

このページの[更新]を数回クリックします。 恐ろしいバージョンよりも、より親しみやすいサメの情報ページが頻繁に表示されるはずです。

5〜6回更新して負荷を生成したら、Grafanaダッシュボードに移動できます。

ブラウザで、次のアドレスに移動します。 istio-ingressgateway GrafanaGatewayマニフェストで定義されている外部IPとポート: http://ingressgateway_ip:15031.

次のランディングページが表示されます。

ページ上部のホームをクリックすると、istioフォルダーのあるページが表示されます。 ドロップダウンオプションのリストを取得するには、istioフォルダーアイコンをクリックします。

このオプションのリストから、Istioサービスダッシュボードをクリックします。

これにより、別のドロップダウンメニューが表示されたランディングページが表示されます。

選択する nodejs.default.svc.cluster.local 利用可能なオプションのリストから。

ページのサービスワークロードセクションに移動すると、宛先および応答コード別の受信リクエストを確認できます。

ここでは、200と304のHTTP応答コードの組み合わせが表示され、成功したことを示します OKNot Modified 反応。 ラベル付けされた応答 nodejs-v1 ラベル付けされた回答よりも数が多いはずです nodejs-v2、マニフェストで定義したパラメーターに従って、着信トラフィックがアプリケーションサブセットにルーティングされていることを示します。

結論

このチュートリアルでは、IstioとKubernetesを使用してCanaryバージョンのデモNode.jsアプリケーションをデプロイしました。 トラフィックの80%を元のアプリケーションサービスに送信し、20%を新しいバージョンに送信できるようにする仮想サービスと宛先ルールのリソースを作成しました。 新しいバージョンのアプリケーションのパフォーマンスに満足したら、必要に応じて構成設定を更新できます。

Istioでのトラフィック管理の詳細については、ドキュメントの関連する高レベルの概要と、Istioのbookinfoおよびhelloworldサンプルを使用する特定の例を参照してください。アプリケーション。