第4章 Blue-Green デプロイメント
4.1. 概要
このトピックでは、インプレースアップグレード方法に代わるノードホストのアップグレード方法について説明します。
Blue-Green デプロイメント のアップグレード方式はインプレース方式と同様のフローに基づいて実行されます。この場合もマスターおよび etcd サーバーが最初にアップグレードされます。ただし、インプレースアップグレードを実行する代わりに、新規ノードホストの並列環境が作成されます。
この方式では、管理者は新規デプロイメントの検証後、古いノードホストセット (例: 「Blue」デプロイメント) から新規セット (例: 「Green デプロイメント) にトラフィックを切り換えることができます。問題が検出される場合も、古いデプロイメントへのロールバックを簡単かつすぐに実行できます。
Blue-Green がソフトウェアについてのデプロイの証明済みの有効なストラテジーであるものの、トレードオフも常にあります。すべての環境が Blue-Green デプロイメントの適切な実行に必要な同じアップタイム要件を満たしている訳でもなく、これに必要なリソースがある訳でもありません。
OpenShift Container Platform 環境では、Blue-Green デプロイメントに最も適した候補はノードホストです。すべてのユーザープロセスはこれらのシステムで実行され、OpenShift Container Platform インフラストラクチャーの重要な部分もこれらのリソースで自己ホストされます。アップタイムはこれらのワークロードで最も重要であり、Blue-Green デプロイメントによって複雑性が増すとしてもこれを確保できる場合には問題になりません。
この方法の実際の実装は要件に応じて異なります。通常、主な課題は、この方法を容易に実行するための追加の容量を確保することにあります。
図4.1 Blue-Green デプロイメント
![Blue-Green Deployment Upgrade](https://access.redhat.com/webassets/avalon/d/OpenShift_Container_Platform-3.9-Upgrading_Clusters-ja-JP/images/c4df06a0a295db626e48d3c8b1cef48c/blue-green-deployment.gif)
4.2. Blue-Green アップグレードの準備
「インプレースアップグレード」で説明されている方法を使用してマスターと etcd ホストをアップグレードした後に、以下のセクションを参照して残りのノードホストの Blue-Green アップグレードの環境を準備します。
4.2.1. ソフトウェアエンタイトルメントの共有
管理者は Blue-Green デプロイメント間で Red Hat ソフトウェアエンタイトルメントを一時的に共有するか、または Red Hat Satellite などのシステムでインストールコンテンツへのアクセスを提供する必要があります。これは、以前のノードホストからのコンシューマー ID を共有して実行できます。
アップグレードされるそれぞれの古いノードホストで、コンシューマー ID であるその
system identity
値を書き留めておいてください。# subscription-manager identity | grep system system identity: 6699375b-06db-48c4-941e-689efd6ce3aa
古いノードホストに置き換わるそれぞれの新規 RHEL 7 または RHEL Atomic Host 7 システムで、直前の手順のそれぞれのコンシューマー ID を使用して登録します。
# subscription-manager register --consumerid=6699375b-06db-48c4-941e-689efd6ce3aa
正常なデプロイメントの後に、subscription-manager clean
で古いホストを登録解除し、環境が非コンプライアンスの状態にならないようにします。
4.2.2. Blue ノードのラベリング
実稼働の現在のノードホストに blue
または green
のいずれかのラベルが付けられていることを確認する必要があります。以下の例では、現在の実稼働環境は blue
となり、新規の環境は green
になります。
クラスターに認識されるノード名の現在の一覧を取得します。
$ oc get nodes
すべてのホストに適切なノードラベルがあることを確認します。すべてのマスターはスケジュール対象 (Schedulable) ノードホストとして設定される必要があります (それらが Pod ネットワークに加わり、Web コンソール Pod を実行できるようにするために必要です)。クラスター管理を強化するには、各ホストにタイプ (
type=master
またはtype=node
など) を記述するラベルを追加します。たとえば、マスターでもあるノードホストに
type=master
のラベルを付けるには、それぞれの関連する<node_name>
について以下を実行します。$ oc label node <node_name> type=master
マスター以外のノードホストに
type=node
のラベルを付けるには、それぞれの関連する<node_name>
について以下を実行します。$ oc label node <node_name> type=node
または、
type=master
を使用して特定ノードにラベル付けしており、残りのノードすべてにtype=node
のラベルを付ける必要がある場合、--all
オプションを使用しても、type=
がすでに設定されたすべてのホストは上書きされません。$ oc label node --all type=node
現行の実稼働環境のマスター以外のノードホストに
color=blue
のラベルを付けます。たとえば、直前の手順で記述されたラベルを使用します。$ oc label node -l type=node color=blue
上記のコマンドでは、
-l
フラグはセレクターtype=node
を使用して環境のサブセットに一致するように設定され、すべての一致項目にはcolor=blue
のラベルが付けられます。
4.2.3. Green ノードの作成およびラベリング
置き換えられるノードホストについて、これと同じ数の新規ノードホストを既存クラスターに追加することで新規の Green 環境を作成します。「ホストの既存クラスターへの追加」で説明されている通常インストール (advanced install) 方式を使用できます。
これらの新規ノードの追加時に、以下の Ansible 変数を使用します。
-
各ノードホストに
openshift_node_labels
変数を設定して、これらのホストのインストール時にcolor=green
ラベルを自動的に適用します。また、oc label node
コマンドを使用して、必要な場合にインストール後にラベルをいつでも調整することができます。 -
ノードが 健全であるとみなされるまでワークロードのスケジューリングを遅らせるために (健全性については後の手順で検証します)、各ホストノードに
openshift_schedulable=false
変数を設定し、これらが初期の時点でスケジュール対象外となるようにします。
new_nodes ホストグループの例
以下を既存のインベントリーに追加します。事前にインベントリーに置かれているすべてのものはそのままの状態にする必要があります。
[new_nodes] node4.example.com openshift_node_labels="{'region': 'primary', 'color':'green'}" openshift_schedulable=false node5.example.com openshift_node_labels="{'region': 'primary', 'color':'green'}" openshift_schedulable=false node6.example.com openshift_node_labels="{'region': 'primary', 'color':'green'}" openshift_schedulable=false infra-node3.example.com openshift_node_labels="{'region': 'infra', 'color':'green'}" openshift_schedulable=false infra-node4.example.com openshift_node_labels="{'region': 'infra', 'color':'green'}" openshift_schedulable=false
4.2.4. Green ノードの検証
新規 Green ノードが健全な状態にあることを確認します。以下のチェックリストを実行します。
新規ノードがクラスターに検出され、Ready 状態にあることを確認します。
$ oc get nodes ip-172-31-49-10.ec2.internal Ready 3d
Green ノードに適切なラベルがあることを確認します。
$ oc get nodes --show-labels ip-172-31-49-10.ec2.internal Ready 4d beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m4.large,beta.kubernetes.io/os=linux,color=green,failure-domain.beta.kubernetes.io/region=us-east-1,failure-domain.beta.kubernetes.io/zone=us-east-1c,hostname=openshift-cluster-1d005,kubernetes.io/hostname=ip-172-31-49-10.ec2.internal,region=us-east-1,type=infra
クラスターの診断チェックを実行します。
$ oc adm diagnostics [Note] Determining if client configuration exists for client/cluster diagnostics Info: Successfully read a client config file at '/root/.kube/config' Info: Using context for cluster-admin access: 'default/internal-api-upgradetest-openshift-com:443/system:admin' [Note] Performing systemd discovery [Note] Running diagnostic: ConfigContexts[default/api-upgradetest-openshift-com:443/system:admin] Description: Validate client config context is complete and has connectivity ... [Note] Running diagnostic: CheckExternalNetwork Description: Check that external network is accessible within a pod [Note] Running diagnostic: CheckNodeNetwork Description: Check that pods in the cluster can access its own node. [Note] Running diagnostic: CheckPodNetwork Description: Check pod to pod communication in the cluster. In case of ovs-subnet network plugin, all pods should be able to communicate with each other and in case of multitenant network plugin, pods in non-global projects should be isolated and pods in global projects should be able to access any pod in the cluster and vice versa. [Note] Running diagnostic: CheckServiceNetwork Description: Check pod to service communication in the cluster. In case of ovs-subnet network plugin, all pods should be able to communicate with all services and in case of multitenant network plugin, services in non-global projects should be isolated and pods in global projects should be able to access any service in the cluster. ...
4.3. レジストリーおよびルーターのカナリアデプロイメント
一般的に、レジストリーおよびルーター Pod はそれらが新規 (Green) インフラストラクチャーノードホストに移行するまでスケーリングされます。これらの Pod については、カナリア デプロイメント方法が一般的に使用されます。
これらの Pod のスケーリングによって、それらの Pod は新規インフラストラクチャーノードですぐにアクティブになります。それらのデプロイメント設定を新規イメージにポイントすると、ローリングアップデートが起動します。ただし、ノードの非アフィニティーおよび Blue ノードがスケジュール対象外 (Unschedulable) のままであることにより、ユーザーアプリケーションの古いノードへのデプロイメントは失敗します。
この時点で、レジストリーおよびルーターのデプロイメントは Pod の元の数に縮小される可能性があります。いつの時点でも、元の数の Pod は依然として利用可能なままであるため、容量を失うことなく、ダウンタイムを防ぐことができます。
4.4. Green ノードの準備
Pod を Blue 環境から Green に移行するために、必要なコンテナーイメージをプルする必要があります。レジストリーについてのネットワークの待機時間およびロードにより、環境に十分な容量が組み込まれていない場合は遅延が生じる可能性があります。
多くの場合、実行中のシステムへの影響を最小限に抑えるための最良の方法として、新規ノードに到達する新規 Pod デプロイメントをトリガーすることができます。これは、新規イメージストリームをインポートして実行できます。
メジャーリリースの OpenShift Container Platform (および一部の非同期エラータ更新) では、Source-to-Image (S2I) のユーザーのビルダーイメージについての新規イメージストリームを導入しています。インポート時に、イメージ変更トリガーで設定されるビルドおよびデプロイメントが自動的に作成されます。
ビルドをトリガーする別の利点として、各種のビルダーイメージ、Pod インフラストラクチャーイメージおよびデプロイヤーなどの多数の補助イメージをすべてのノードホストに効果的に取り込める点があります。Green ノードは 準備完了 (予想される負荷の増加に対応できる状態にある) とみなされると、他のすべてのものが後の手順のノードの退避で移行するため、結果として処理がより迅速になります。
アップグレードプロセスに進む準備ができたら、以下の手順に従って Green ノードを準備します。
Green ノードをスケジュール対象 (Schedulable) に設定し、新規 Pod がそれらのノードにのみ到達するようにします。
$ oc adm manage-node --schedulable=true --selector=color=green
Blue ノードを無効にし、それらをスケジュール対象外 (Unschedulable) に設定して新規 Pod がそれらのノードで実行されないようにします。
$ oc adm manage-node --schedulable=false --selector=color=blue
- 「手動によるインプレースアップグレード」で説明されているようにデフォルトのイメージストリームおよびテンプレートを更新します。
「手動によるインプレースアップグレード」で説明されているように最新イメージをインポートします。
このプロセスでは多数のビルドをトリガーする可能性があることに留意してください。ただし、ビルドは Green ノードで実行されるため、これが Blue デプロイメントのトラフィックに影響を与えることはありません。
クラスター内のすべての namespace (プロジェクト) でのビルドプロセスをモニターするには、以下を実行します。
$ oc get events -w --all-namespaces
大規模な環境では、ビルドはほとんど停止することがありません。しかしながら、管理上のイメージのインポートによって大きな増減が生じます。
4.5. Blue ノードの退避および使用停止
大規模デプロイメントでは、退避の調整方法を定めるのに役立つ他のラベルを使用できます。ダウンタイムを防ぐための最も保守的な方法として、一度に 1 つのノードホストを退避する方法があります。
サービスがゾーンの非アフィニティーを使用して複数の Pod で構成されている場合、ゾーン全体を一度に退避できます。使用されるストレージボリュームが新規ゾーンで利用可能であることを確認することは重要です。これについての詳細はクラウドプロバイダーごとに異なる場合があるためです。
OpenShift Container Platform 3.2 以降では、ノードホストの退避はノードサービスの停止時に常にトリガーされます。ノードのラベリングは非常に重要であり、ノードに誤ったラベルが付けられていたり、コマンドが汎用化されたラベルの付いたノードで実行される場合は問題が生じる可能性があります。マスターホストにも color=blue
のラベルが付けられている場合には注意が必要です。
アップグレードプロセスに進む準備ができたら、以下の手順に従います。
以下のオプションのいずれかに従ってすべての Blue ノードを退避し、削除します。
オプション A: 以下のコマンドを使ってすべての
color=blue
ノードを手動で退避してからこれらを削除します。$ oc adm manage-node --selector=color=blue --evacuate $ oc delete node --selector=color=blue
オプション B:
delete
コマンドを実行する前にマスターをフィルターにかけます。以下のコマンドを実行して削除する Blue ノードホストの一覧を確認します。このコマンドの出力には、
color=blue
ラベルを持つが、type=master
ラベルを持たないすべてのノードホストの一覧が含まれます。クラスター内のすべてのホストにはcolor
およびtype
ラベルの両方が割り当てられている必要があります。ノードの一覧をさらに制限する必要がある場合は、追加のフィルターを適用するようにコマンドを変更できます。$ oc get nodes -o go-template='{{ range .items }}{{ if (eq .metadata.labels.color "blue") and (ne .metadata.labels.type "master") }}{{ .metadata.name }}{{ "\n" }}{{end}}{{ end }}'
削除する Blue ノードの一覧を確認したら、このコマンドを実行してノードの一覧を削除します。
$ for i in $(oc get nodes -o \ go-template='{{ range .items }}{{ if (eq .metadata.labels.color "blue") and (ne .metadata.labels.type "master") }}{{ .metadata.name }}{{ "\n" }}{{end}}{{ end }}'); \ do oc delete node $i done
- Blue ノードホストに Pod が含まれなくなり、それらが OpenShift Container Platform から削除されたら、それらの電源をオフにしても問題がありません。安全上の措置として、アップグレードに問題がある場合には、ホストを短時間そのままにしておくと良いでしょう。
- これらのホストを停止する前に、すべての必要なスクリプトまたはファイルが取得されていることを確認します。指定した期間と容量に問題がないことを確認した後に、これらのホストを削除します。