はじめに
Canaryデプロイメントは、新しい機能を段階的にデプロイする方法を提供するため、サービスの新しいバージョンを導入するのに役立ちます。アップデートが公開されると、ごく一部のユーザーに段階的に公開されます。これにより、開発者は、すべての人が利用できるようにする前に、更新がどのように実行されるかを確認できます。
Kubernetesは、カナリアのデプロイをネイティブに実行するように設計されています。ただし、このアプローチの欠点は、(レプリカの比率を変更することにより)カナリア展開へのトラフィックを手動で制限する必要があることです。このプロセスを合理化するためのソリューションは、オープンソースのIstioなどのサービスメッシュを使用して、トラフィックの分散とレプリカの数を分離することです。
このチュートリアルでは、カナリアバージョンのアプリをIstio対応クラスターにデプロイし、トラフィックルーティングを制御するようにIstioをセットアップする方法を学習します。
前提条件
- Kubernetesクラスター(minikube)
- kubectlコマンドラインツール
- Istioがインストールされました
- DockerHubアカウント
- Grafanaダッシュボード
ステップ1:Canaryビルド用のDockerイメージとコンテナーをビルドする
アプリのカナリアビルドのデプロイを開始するには、まず、デプロイするバージョンを含むDockerイメージを作成します。
- 画像に必要なファイルが含まれているディレクトリに移動します。この例では、 test-canaryというアプリを使用しています 、同じ名前でディレクトリに保存されます:
cd test-canary
2.docker build
を使用します Dockerイメージをビルドするコマンド。 Docker Hubのユーザー名とイメージ名を使用してコマンドを実行します:
docker build -t [dockerhub-username]/test-canary .
出力は、イメージの作成が成功したことを確認します:
3.docker images
を使用します 画像のリストを表示し、新しい画像がその中にあるかどうかを確認するコマンド:
docker images
4.次に、 docker run
を使用します 以前に作成したイメージでコンテナを構築するコマンド。コンテナに名前を付け、アクセスするポートを選択します:
docker run --name [name] -p [port]:8080 -d [dockerhub-username]/test-canary
操作が成功すると、システムは新しく作成されたコンテナの完全なIDを出力します。
5. docker ps
を使用します 実行中のコンテナを確認するコマンド:
docker ps
6.次に、コンテナに割り当てたポートを使用して、ブラウザ経由でコンテナにアクセスします。
http://localhost:[port]
ブラウザにアプリのコンテンツが表示されます:
7.アプリが機能していることを確認したら、 docker stop
でコンテナを停止します 指図。コンテナIDをコマンドに追加します。これは、 docker ps
の最初の列からコピーできます。 出力:
docker stop [container-id]
8.最後に、イメージをDocker Hubアカウントにプッシュするには、コマンドラインを使用してDockerHubにログインします。
docker login -u [dockerhub-username]
システムはパスワードを要求します。パスワードを入力し、 Enterを押します :
9.ここで、 docker push
を使用して画像をプッシュします :
docker push [dockerhub-username]/test-canary
ステップ2:アプリのデプロイを変更する
カナリアデプロイメントを一般的なアプリデプロイメントに追加するには、テキストエディターを使用して、サービスとデプロイメントの仕様を含むファイルを編集します。
この例では、 app-manifest.yaml
というアプリケーションマニフェストを使用しています :
nano app-manifest.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: markopnap/test-prod
ports:
- containerPort: 8080
上記のマニフェストの例は、Node.jsアプリの製品版を示しています。このアプリのコンテナーは、 markopnap/test-prod
に保存されています。 。カナリアバージョンのアプリケーションを含めるには、まずデプロイを編集します。 ファイルのセクションを追加し、 -v1
を追加します アプリの名前に:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v1
次に、カナリアビルドの仕様を含む別のデプロイメントセクションをファイルの最後に追加します。
---
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: markopnap/test-canary
ports:
- containerPort: 8080
ファイルの編集が終了したら、ファイルを保存し、 kubectl apply
を使用してシステム構成を更新します。 :
kubectl apply -f app-manifest.yaml
ステップ3:Istio仮想サービスを構成する
Istio構成を保存するための新しいyamlファイルを作成します。この例では、 istio.yaml
というタイトルのファイルを使用しています 、ただし、任意の名前を付けることができます:
nano istio.yaml
以前に製品版の展開にIstioを使用した場合、ファイルはすでに存在しており、次のようになります。
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
このファイルには、ゲートウェイを定義する2つのセクションがあります。 およびVirtualService オブジェクト。アプリケーションの両方のバージョンを導入し、ユーザーへの配布のルーティングルールを設定するには、 http
を変更します 下部のセクション。セクションには、サブセットが異なる2つの宛先が含まれている必要があります および重み :
http:
- route:
- destination:
host: nodejs
subset: v1
weight: 90
- destination:
host: nodejs
subset: v2
weight: 10
重量 パラメータは、トラフィックの何パーセントを特定の宛先にルーティングする必要があるかをIstioに指示します。上記の例では、トラフィックの90%が本番バージョンに送られ、10%がカナリアビルドに送られます。
[仮想サービス]セクションを編集したら、ファイルの最後に次の行を追加して、宛先ルールを作成します。 :
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nodejs
spec:
host: nodejs
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
宛先ルールを定義する目的 着信トラフィックを管理し、指定されたバージョンのアプリケーションに送信することです。
ファイルを保存し、 kubectl apply
を使用します 有効にするには:
kubectl apply -f istio.yaml
ステップ4:カナリア展開をテストする
前のステップで設定された構成は、本番デプロイメントおよびカナリアデプロイメントへのトラフィックルーティングを実行します。これをテストするには、 istio-ingressgateway
の外部IPを使用してアプリケーションにアクセスします 、Istioがロードバランサーとして使用します。
istio-ingressgateway
を探します istio-system
で利用可能なサービスのリストにあるサービス 名前空間。 kubectl get
を使用します サービスを一覧表示するには:
kubectl get svc -n istio-system
istio-ingressgateway
をコピーします ブラウザのアドレスバーへの外部IPアドレス:
http://[ingressgateway_ip]
ブラウザには、アプリケーションの製品版が表示される可能性があります。 更新を押します 一部のトラフィックをシミュレートするには、ボタンを複数回押します:
数回経つと、アプリのカナリアバージョンが表示されます。
Grafanaアドオンがインストールされている場合は、着信リクエストの統計を確認して、各デプロイメントのルーティングの割合を確認してください。 Grafanaで、ホームをクリックします アイコン:
ダッシュボード セクションで、 Istioを選択します 、[Istioサービスダッシュボード]をクリックします :
ダッシュボードで、サービスを見つけます フィールドに入力し、アプリケーションに対応するサービスを選択します。この例では、サービスの名前は nodejs.default.svc.cluster.local
です。 。サービスを選択したら、サービスワークロードに移動します セクション:
宛先ワークロードと応答コード別の受信リクエストというタイトルのグラフを選択します 。グラフには、ページを更新して生成したトラフィックが表示されます。この例では、Istioが nodejs-v1
を提供したことは明らかです。 カナリアよりも頻繁にアプリのバージョンnodejs-v2
バージョン。