IstioとKubernetesを使用してカナリアをデプロイする方法
序章
サービスの新しいバージョンを導入する場合、古いバージョンを段階的に廃止する過程で、ユーザートラフィックの制御された割合を新しいバージョンのサービスにシフトすることが望ましい場合がよくあります。 この手法は、カナリア展開と呼ばれます。
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番目の恐ろしいバージョンのコードが含まれています。
- git clone https://github.com/do-community/nodejs-canary-app.git node_image
に移動します node_image
ディレクトリ:
- cd node_image
このディレクトリには、新しいバージョンのサメ情報アプリケーションのファイルとフォルダが含まれています。このアプリケーションは、元のアプリケーションと同様に、より恐ろしい事実に重点を置いて、サメに関する情報をユーザーに提供します。 アプリケーションファイルに加えて、ディレクトリには、アプリケーションコードを使用してDockerイメージを構築するための手順が記載されたDockerfileが含まれています。 Dockerfileの手順の詳細については、Dockerを使用してNode.jsアプリケーションを構築する方法のステップ3を参照してください。
アプリケーションコードとDockerfileが期待どおりに機能することをテストするには、 docker build コマンドを使用してイメージをビルドしてタグ付けし、イメージを使用してデモコンテナを実行します。 を使用して -t
フラグ docker build
イメージにDockerHubユーザー名のタグを付けて、テスト後にDockerHubにプッシュできるようにします。
次のコマンドを使用してイメージをビルドします。
- docker build -t your_dockerhub_username/node-demo-v2 .
The .
コマンドで、ビルドコンテキストが現在のディレクトリであることを指定します。 画像に名前を付けました node-demo-v2
、参照するには node-demo
画像KubernetesでIstioをインストールして使用する方法でを作成しました。
ビルドプロセスが完了すると、 dockerimagesを使用してイメージを一覧表示できます。
- docker images
イメージビルドを確認する次の出力が表示されます。
OutputREPOSITORY 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
:これにより、コンテナにカスタマイズされた名前を付けることができます。
次のコマンドを実行して、コンテナーを作成します。
- docker run --name node-demo-v2 -p 80:8080 -d your_dockerhub_username/node-demo-v2
dockerpsを使用して実行中のコンテナーを検査します。
- docker ps
アプリケーションコンテナが実行されていることを確認する出力が表示されます。
OutputCONTAINER 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
:
- docker ps
OutputCONTAINER 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
:
- docker stop 49a67bafc325
イメージをテストしたので、DockerHubにプッシュできます。 まず、前提条件で作成したDockerHubアカウントにログインします。
- docker login -u your_dockerhub_username
プロンプトが表示されたら、DockerHubアカウントのパスワードを入力します。 この方法でログインすると、 ~/.docker/config.json
ルート以外のユーザーのホームディレクトリに、DockerHubのクレデンシャルを使用してファイルします。
dockerpushコマンドを使用してアプリケーションイメージをDockerHubにプッシュします。 交換することを忘れないでください your_dockerhub_username
独自のDockerHubユーザー名を使用:
- 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
今すぐディレクトリ:
- cd
- cd istio_project
開ける node-app.yaml
と nano
または、アプリケーションマニフェストに変更を加えるためのお気に入りのエディター:
- nano 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を参照してください。
デプロイメントにはすでにバージョンラベルが含まれています metadata
と template
ポッドとサービスに関するIstioの推奨事項に続くフィールド。 これで、アプリケーションの2番目のバージョンを表す2番目のDeploymentオブジェクトの仕様を追加し、 name
最初のDeploymentオブジェクトの
まず、既存のDeploymentオブジェクトの名前を次のように変更します nodejs-v1
:
...
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v1
labels:
version: v1
...
次に、このデプロイメントの仕様の下に、2番目のデプロイメントの仕様を追加します。 自分の画像の名前をに追加することを忘れないでください image
分野:
...
---
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メッシュに送り、アプリケーションサービスにルーティングできるようにしました。 ここでは、仮想サービス構成を変更して、アプリケーションサービスサブセットへのルーティングを含めます— v1
と v2
. また、宛先ルールを追加して、適用するルーティングルールに追加のバージョンベースのポリシーを定義します。 nodejs
アプリケーションサービス。
を開きます node-istio.yaml
ファイル:
- nano 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
).
このルーティングルールを作成するには、仮想サービスに次の追加を行います。
...
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
適切なバージョンラベルを使用してトラフィックをポッドに送信するフィールド。
仮想サービス定義の下に次のコードを追加します。
...
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nodejs
spec:
host: nodejs
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
私たちのルールは、私たちのサービスサブセットへのトラフィックを保証します。 v1
と v2
、適切なラベルでポッドに到達します。 version: v1
と version: v2
. これらは、アプリケーションのデプロイメント仕様に含めたラベルです。
ただし、必要に応じて、サブセットレベルで特定のトラフィックポリシーを適用して、カナリアの展開をさらに具体化することもできます。 このレベルでのトラフィックポリシーの定義の詳細については、公式のIstioドキュメントを参照してください。
編集が終了したら、ファイルを保存して閉じます。
アプリケーションマニフェストが改訂されたら、構成の変更を適用し、Grafanaテレメトリアドオンを使用してアプリケーショントラフィックデータを調べる準備が整います。
ステップ4—構成変更の適用とトラフィックデータへのアクセス
アプリケーションマニフェストは更新されますが、これらの変更をKubernetesクラスターに適用する必要があります。 kubectl apply コマンドを使用して、既存の構成を完全に上書きせずに変更を適用します。 これを行うと、アプリケーションへのリクエストを生成し、IstioGrafanaダッシュボードで関連データを確認できるようになります。
構成をアプリケーションのServiceオブジェクトとDeploymentオブジェクトに適用します。
- kubectl apply -f node-app.yaml
次の出力が表示されます。
Outputservice/nodejs unchanged
deployment.apps/nodejs-v1 created
deployment.apps/nodejs-v2 created
次に、行った構成の更新を適用します node-istio.yaml
、これには、仮想サービスと新しい宛先ルールへの変更が含まれます。
- kubectl apply -f node-istio.yaml
次の出力が表示されます。
Outputgateway.networking.istio.io/nodejs-gateway unchanged
virtualservice.networking.istio.io/nodejs configured
destinationrule.networking.istio.io/nodejs created
これで、アプリケーションへのトラフィックを生成する準備が整いました。 ただし、それを行う前に、まず、 grafana
実行中のサービス:
- kubectl get svc -n istio-system | grep grafana
Outputgrafana ClusterIP 10.245.233.51 <none> 3000/TCP 4d2h
関連するポッドも確認してください。
- kubectl get svc -n istio-system | grep grafana
Outputgrafana-67c69bb567-jpf6h 1/1 Running 0 4d2h
最後に、 grafana-gateway
ゲートウェイと grafana-vs
仮想サービス:
- kubectl get gateway -n istio-system | grep grafana
Outputgrafana-gateway 3d5h
- kubectl get virtualservice -n istio-system | grep grafana
Outputgrafana-vs [grafana-gateway] [*] 4d2h
これらのコマンドからの出力が表示されない場合は、KubernetesでIstioをインストールして使用する方法の手順2および5を確認してください。 Istioをインストールする際のGrafanaテレメトリアドオンと、GrafanaサービスへのHTTPアクセスを有効にする方法。
これで、ブラウザでアプリケーションにアクセスできます。 これを行うには、に関連付けられた外部IPが必要になります istio-ingressgateway
LoadBalancerサービスタイプであるサービス。 私たちは nodejs-gateway
KubernetesでIstioをインストールして使用する方法でゲートウェイマニフェストを作成するときに、このコントローラーを使用するゲートウェイ。 ゲートウェイマニフェストの詳細については、そのチュートリアルのステップ4を参照してください。
の外部IPを取得します istio-ingressgateway
次のコマンドでサービスします。
- kubectl get svc -n istio-system
次のような出力が表示されます。
OutputNAME 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応答コードの組み合わせが表示され、成功したことを示します OK
と Not Modified
反応。 ラベル付けされた応答 nodejs-v1
ラベル付けされた回答よりも数が多いはずです nodejs-v2
、マニフェストで定義したパラメーターに従って、着信トラフィックがアプリケーションサブセットにルーティングされていることを示します。
結論
このチュートリアルでは、IstioとKubernetesを使用してCanaryバージョンのデモNode.jsアプリケーションをデプロイしました。 トラフィックの80%を元のアプリケーションサービスに送信し、20%を新しいバージョンに送信できるようにする仮想サービスと宛先ルールのリソースを作成しました。 新しいバージョンのアプリケーションのパフォーマンスに満足したら、必要に応じて構成設定を更新できます。
Istioでのトラフィック管理の詳細については、ドキュメントの関連する高レベルの概要と、Istioのbookinfoおよびhelloworldサンプルを使用する特定の例を参照してください。アプリケーション。