アプリ・デプロイメントの計画
アプリを Red Hat OpenShift on IBM Cloud クラスタにデプロイする前に、アプリが正しくアクセスされ、 IBM Cloud の他のサービスと統合できるように、アプリをどのようにセットアップするかを決めます。
Red Hat OpenShift on IBM Cloud へのワークロードの移動
Red Hat OpenShift on IBM Cloud で実行できるワークロードの種類、および、それらのワークロードをセットアップする最適な方法について説明します。
Red Hat OpenShift on IBM Cloud ではどのようなアプリを実行できますか?
- ステートレス・アプリ
- ステートレス・アプリは、Kubernetes のようなクラウド・ネイティブ環境に適しています。 これらのアプリはマイグレーションとスケーリングが簡単です。これは、これらのアプリでは、依存関係が宣言され、構成がコードとは別に保管され、データベースなどのバッキング・サービスが、アプリに結合されたものではなく接続されたリソースとして扱われるためです。 アプリ・ポッドは永続データ・ストレージや安定したネットワーク IP アドレスを必要としないため、ワークロードの需要に応じてポッドを終了、スケジュール変更、およびスケーリングできます。 このアプリでは、永続データに対して Database-as-a-Service が使用されるとともに、NodePort サービス、ロード・バランサー・サービス、または Ingress サービスを使用して安定した IP アドレス上でワークロードが公開されます。
- ステートフル・アプリ
- ステートフル・アプリは、ステートレス・アプリよりも、セットアップ、管理、およびスケーリングが複雑になります。これは、ポッドが永続データと安定したネットワーク ID を必要とするためです。 ステートフル・アプリは、多くの場合、データベース、またはその他の分散型でデータ集中型のワークロードであり、データ自体に近ければ近いほど、処理効率が高くなります。 ステートフル・アプリをデプロイする場合は、永続ストレージをセットアップして、StatefulSet オブジェクトによって制御されるポッドに永続ボリュームをマウントする必要があります。 ステートフル・セット用の永続ストレージとして、ファイル・ストレージ、ブロック・ストレージ、またはオブジェクト・ストレージを追加することを選択できます。 また Portworx をベアメタルワーカーノードにインストールし、 Portworx を高可用性ソフトウェア定義ストレージソリューションとして使用して、ステートフルアプリケーションの永続ストレージを管理することもできます。 ステートフル・セットがどのように機能するかについては、 Kubernetes のドキュメントを参照のこと。
ステートレスなクラウド・ネイティブ・アプリを開発するためのガイドラインはどのようなものですか?
12ファクター・アプリは、以下のように要約された12のファクターにわたってアプリの開発方法を検討するための、言語に中立的な方法論である。
- コード・ベース: デプロイメントのバージョン管理システムで単一のコード・ベースを使用します。 コンテナー・デプロイメントのイメージをプルする際は、
latest
を使用する代わりにテスト済みのイメージ・タグを指定します。 - 依存関係: 外部的な依存関係を明示的に宣言して分離します。
- 構成: デプロイメント固有の構成をコード内ではなく環境変数に保管します。
- バッキング・サービス: データ・ストアやメッセージ・キューなどのバッキング・サービスを、接続されたリソースまたは交換可能なリソースとして扱います。
- アプリのステージ:
build
、release
、run
などの独立したステージを取り入れて、これらのステージを厳格に分離します。 - プロセス: 何も共有しない 1 つ以上のステートレス・プロセスとして実行します。また、データ保存用に永続ストレージを使用します。
- ポート・バインディング: ポート・バインディングは自己完結型であり、明確に定義されたホストとポート上でサービス・エンドポイントを提供します。
- 並行性: レプリカや水平スケーリングなどのプロセス・インスタンスを通じてアプリを管理およびスケーリングします。 デプロイメントに対するリソースの要求と制限を設定します。 Calico ネットワーク・ポリシーによって帯域幅を制限することはできません。
- 廃棄容易性: 最小の起動時間、安全なシャットダウン、突然のプロセス終了への容認を備えた、廃棄可能なアプリを設計します。 コンテナー、ポッド、さらにはワーカー・ノードも廃棄可能であることを意図しているため、アプリもこれらに従って計画してください。
- 開発から生産への同等性 :アプリの継続的インテグレーションと継続的デリバリーのパイプラインをセットアップし、開発中のアプリとプロダクションのアプリの違いを最小限に抑えます。
- ログ: ログをイベント・ストリームとして扱います。外部環境またはホスティング環境によってログ・ファイルが処理されてルーティングされます。 重要: Red Hat OpenShift on IBM Cloud では、ログはデフォルトで有効になっていません。 ログを有効にするには、ログ転送の構成を参照してください。
- 管理プロセス :管理スクリプトがアプリ本体と同じ環境で実行されるように、1回限りの管理スクリプトはアプリと一緒に保管し、 Kubernetes ジョブオブジェクトとして実行します。 Kubernetes クラスタで実行したい大規模パッケージのオーケストレーションには、次のようなパッケージ・マネージャの使用を検討してください。 Helm.
サーバーレス・アプリは使用できますか?
サーバーレス・アプリおよびジョブは、IBM Cloud Code Engine サービスを使用して実行できます。Code Engine は、イメージを作成することもできます。
既にアプリがあります。 どうすれば Red Hat OpenShift on IBM Cloud にマイグレーションできますか?
以下の一般的な手順を実行することで、アプリをコンテナー化できます。
- 依存関係を分離し、プロセスを個別のサービスに分離し、アプリのステートフルネスを可能な限り減らすためのガイドとして、 12ファクター・アプリを使用する。
- 使用する適切な基本イメージを見つけます。 Docker ハブから公開されている画像、 公開されている IBM 画像を 使用することもできますし、プライベート IBM Cloud Container Registry で独自の画像を作成し管理することもできます。
- アプリを実行するために必要なもののみを Docker イメージに追加します。
- アプリを変更する一般的な状況を確認します。
- ローカル・ストレージを利用する代わりに、永続ストレージまたはクラウド Database as a Service のソリューションを使用してアプリのデータをバックアップすることを計画してください。
- 時間をかけて、アプリのプロセスをリファクタリングしてマイクロサービスに変換します。
アプリを変更する一般的な状況
Red Hat OpenShift には、厳密なセキュリティー・コンテキスト制約などのように、コミュニティー Kubernetes とは異なるデフォルト設定があります。 ここでは、Red Hat OpenShift クラスターにデプロイするためにアプリの変更が必要になる状況としてよくある状況について説明します。
シナリオ | 対処方法 |
---|---|
root として実行するアプリ。 ポッドが CrashLoopBackOff 状況で失敗する可能性があります。 |
ポッドに特権的なアクセス権限が必要になります。 デプロイメントに特権的なアクセス権限を付与する手順の例を参照してください。 詳細については、 セキュリティコンテキスト制約(SCC)の管理 ( Red Hat OpenShift )のドキュメントを参照してください。 |
Docker で実行するように設計されたアプリ。 このようなアプリは、多くの場合、コンテナー・ランタイム・エンジンに依存したロギング・ツールやモニター・ツールであり、コンテナー・ランタイム API を直接呼び出してコンテナーのログ・ディレクトリーにアクセスします。 | Red Hat OpenShift では、CRI-O コンテナー・ランタイムによる実行に対応したイメージでなければなりません。 詳細については、 CRI-O コンテナ・エンジンの使用を参照してください。 |
アプリは、マウントされたストレージ・デバイスに書き込めない非 root のユーザー ID で永続ファイル・ストレージを使用しています。 | アプリのデプロイメントのセキュリティー・コンテキストを調整して runAsUser を 0 に設定します。 |
サービスをポート 80 か、1024 より小さい別のポートで公開する。 「Permission denied 」というエラーが表示される可能性があります。 |
1024 より小さいポートは、始動プロセス用に予約されている特権ポートです。 以下の解決策のいずれかを選択するとよい:
|
その他のユース・ケースと状況 | データベース、Web フレームワーク・アプリケーション、CI/CD のマイグレーションについては、 Red Hat OpenShift の資料を参照してください。 |
デプロイメントに特権的なアクセス権を付与する手順の例
root 権限で実行するアプリがある場合は、Red Hat OpenShift クラスターに設定されているセキュリティー・コンテキスト制約の下で機能するようにデプロイメントを変更する必要があります。 例えば、特権的なアクセス権を制御するためのサービス・アカウントをプロジェクトにセットアップしてから、そのサービス・アカウントを使用するようにデプロイメントを変更することができます。
始める前に、Red Hat OpenShift クラスターにアクセスします。
-
クラスター管理者として、プロジェクトを作成します。
oc adm new-project <project_name>
-
作成する後続のリソースがプロジェクト名前空間に入るように、プロジェクトをターゲットにします。
oc project <project_name>
-
プロジェクトのサービス・アカウントを作成します。
oc create serviceaccount <sa_name>
-
特権セキュリティー・コンテキスト制約をプロジェクトのサービス・アカウントに追加します。
privileged
SCC にあるポリシーを確認するには、oc describe scc privileged
を実行します。 SCC について詳しくは、 Red Hat OpenShift の資料を参照してください。oc adm policy add-scc-to-user privileged -n <project_name> -z <sa_name>
-
デプロイメント構成ファイル内で、特権サービス・アカウントを参照し、そのセキュリティー・コンテキストを privileged に設定します。
spec.template.spec
で、serviceAccount: <sa_name>
を追加します。spec.template.spec.containers
で、securityContext: privileged: true
を追加します。
例
apiVersion: apps/v1 kind: Deployment metadata: name: myapp_deployment labels: app: myapp spec: ... template: ... spec: serviceAccount: <sa_name> containers: - securityContext: privileged: true ...
-
アプリの構成ファイルをデプロイします。
oc apply -f <filepath/deployment.yaml>
-
ポッドが Running の状況であることを確認します。 ポッドにエラー状況が表示されている場合、または、ある状況で止まったまま変わらない場合は、そのポッドの詳細を表示し、**「イベント」**セクションを確認してデプロイメントのトラブルシューティングを開始します。
oc get pods
アプリの Kubernetes オブジェクトについて
Kubernetes では、ポッド、デプロイメント、ジョブなどの多くのタイプのオブジェクトを YAML 構成ファイルで宣言します。 これらのオブジェクトで記述される内容としては、実行されているコンテナー化アプリ、これらのアプリで使用されるリソース、アプリの再始動、更新、複製などの動作を管理しているポリシーなどが挙げられます。 詳細については、 Kubernetes のドキュメントを参照してください。
アプリをコンテナーに配置する必要があると思っていました。 ポッドとは何ですか?
ポッドとは、 Kubernetes が管理できる最小の配備ユニットである。 コンテナー (またはコンテナーのグループ) をポッドに格納して、そのポッドの構成ファイルを使用して、そのコンテナーを実行する方法および他のポッドとリソースを共有する方法をそのポッドに通知します。 ポッドに入れたコンテナはすべて共有コンテキストで実行され、仮想マシンまたは物理マシンを共有することになる。
- コンテナーに格納するもの
- 使用するアプリケーションのコンポーネントについて検討するときには、CPU やメモリーなどのリソース要件がそれらのコンポーネントの間で大きく異なるかどうかを考慮してください。 例えば、コンポーネントによっては、リソースを他の領域に転用するために一時的に稼働停止することが許容され、ベスト・エフォート方式で実行できる場合があります。 別のコンポーネントは、顧客に対応するものであるため、常時稼働させることが非常に重要である可能性があります。 これらは、別々のコンテナーに分けてください。 いつでも、これらを同じポッドにデプロイすることで、同期的に一緒に実行されるようにすることができます。
- ポッドに格納するもの
- 同じアプリの複数のコンテナーが常に同じポッドに格納される必要はありません。 ステートフルでありスケーリングが困難なコンポーネント (データベース・サービスなど) がある場合は、そのコンポーネントを異なるポッドに格納して、そのワークロードを処理するための十分なリソースを備えたワーカー・ノード上でそのポッドをスケジュールしてください。 コンテナーが正常に動作し、別々のワーカー・ノード上で実行される場合は、複数のポッドを使用してください。 同じマシンに配置して一緒にスケーリングする必要があるコンテナーは、まとめて同じポッドに格納します。
では、ポッドが使えるなら、なぜさまざまな種類のオブジェクトが必要なのか?
ポッドの YAML ファイルは簡単に作成できます。 次のように数行で記述できます。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
ここからさらに設定を進めます。 ポッドが実行されているノードがダウンした場合は、そのポッドも一緒にダウンするため、そのポッドがスケジュール変更されることはありません。 代わりに、ポッドの再スケジュール、レプリカセット、ローリングアップデートをサポートする デプロイメントを使用します。
基本的なデプロイメントは、ポッドと同じくらい簡単に作成できます。 ただし、spec
内で単独でコンテナーを定義する代わりに、デプロイメントの replicas
内で template
と spec
を指定します。 テンプレートには、次の例のようにコンテナー用の独自の spec
が含まれています。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
ポッドのアンチアフィニティーやリソース制限などの機能を、同じ YAML ファイルにさらに追加できます。
デプロイメントに追加できるさまざまな機能の詳細については、 アプリのデプロイメントYAMLファイルを作成するを 参照してください。
どのようなタイプの Kubernetes オブジェクトをアプリ用に作成できますか?
アプリ YAML ファイルを準備するとき、アプリの可用性、パフォーマンス、セキュリティーを高めるための多くの選択肢があります。 例えば、1 つのポッドを用意する代わりに、Kubernetes コントローラー・オブジェクトを使用してレプリカ・セット、ジョブ、デーモン・セットなどのワークロードを管理できます。 ポッドとコントローラの詳細については、 Kubernetes のドキュメントを参照してください。 ポッドのレプリカ・セットを管理するデプロイメントは、アプリの一般的なユース・ケースです。
例えば、kind: Deployment
オブジェクトは、アプリ・ポッドをデプロイするための良い選択です。このオブジェクトを使用すると、ポッドの可用性を高めたい場合にレプリカ・セットを指定できるからです。
次の表は、Kubernetes ワークロード・オブジェクトを作成する場合にそのタイプはさまざまである理由を示しています。
オブジェクト | 説明 |
---|---|
Pod |
ポッドはワークロードの最小デプロイ可能単位であり、単一または複数のコンテナーを保持できます。 コンテナと同様に、ポッドは使い捨てで、アプリ機能のユニットテストによく使われる。 アプリのダウン時間を回避するために、デプロイメントなどの Kubernetes コントローラーを使用してポッドをデプロイすることを検討してください。 デプロイメントは、複数のポッド、レプリカ、ポッド・スケーリング、ロールアウトなどの管理に役立ちます。 |
ReplicaSet |
レプリカ・セットは、ポッドの複数のレプリカが実行されるようにして、ポッドがダウンした場合にポッドをスケジュール変更します。 ポッドのスケジューリングの動作をテストするためにレプリカ・セットを作成することもできますが、アプリの更新、ロールアウト、スケーリングを管理するには、代わりにデプロイメントを作成してください。 |
Deployment |
デプロイメントは、ポッドまたはポッドテンプレートの レプリカセットを管理するコントローラです。 デプロイメントなしでポッドまたはレプリカ・セットを作成してアプリ機能をテストすることもできます。 実動レベルのセットアップでは、デプロイメントを使用して、アプリの更新、ロールアウト、スケーリングを管理してください。 |
StatefulSet |
デプロイメントと同様、ステートフル・セットはポッドのレプリカ・セットを管理するコントローラーです。 デプロイメントと違って、ステートフル・セットでは、スケジュール変更後も状態を維持する固有のネットワーク ID がポッドに設定されます。 クラウドでワークロードを実行する場合は、ステートレスになるようにアプリを設計するようにしてください。こうすることで、サービス・インスタンスが相互に独立して実行され、障害が発生してもサービスが中断されなくなります。 ただし、データベースなど、アプリによってはステートフルでなければならないものもあります。 そのような場合は、ステートフル・セットを作成し、ステートフル・セットの永続ストレージとしてファイル・ストレージ、ブロック・ストレージ、または オブジェクト・ストレージを使用することを検討してください。 また Portworx をベアメタルワーカーノードにインストールし、 Portworx を高可用性ソフトウェア定義ストレージソリューションとして使用して、ステートフルセットの永続ストレージを管理することもできます。 |
DaemonSet |
クラスター内のどのワーカー・ノードでも同じポッドを実行する必要がある場合は、デーモン・セットを使用します。 クラスターにワーカー・ノードが追加されると、デーモン・セットによって管理されるポッドが自動的にスケジュールされます。 代表的なユース・ケースとしては、logstash や prometheus などのログ・コレクターがあります。これらのログ・コレクターは、各ワーカー・ノードからログを収集して、クラスターまたはアプリの正常性に関する洞察を提供します。 |
Job |
ジョブは、1 つ以上のポッドが完了まで正常に実行されるようにします。 レンダリングする特定のフレーム、送信する電子メール、変換するファイルなど、別々の、しかし関連する作業項目の並列処理をサポートするために、キューやバッチジョブのためのジョブを使用することができる。 特定の時間にジョブを実行するようにスケジュールするには CronJob . |
アプリ構成で変数を使用するにはどうすればよいですか? これらの変数をYAMLに追加するには?
データをYAMLファイルにハードコーディングする代わりに、デプロイメントに変数情報を追加するには、 Kubernetes ConfigMap
もしくは Secret
オブジェクトを使うことができます。
構成マップまたはシークレットを取り込むには、それをポッドにマウントする必要があります。 構成マップまたはシークレットは、ポッドが実行される直前にポッドと結合されます。 デプロイメントの仕様とイメージを多くのアプリで再利用できますが、その後、カスタマイズした構成マップとシークレットをスワップアウトすることもできます。 特にシークレットはローカル・ノード上のストレージを大量に専有する場合があるため、適宜計画してください。
どちらのリソースでもキーと値のペアが定義されますが、状況に応じて使い分けてください。
- Configmap
- デプロイメントで指定されたワークロードに機密性の高くない構成情報を提供します。 主に 3 つの方法で構成マップを使用できます。
- ファイル・システム: ファイル全体または変数セットをポッドにマウントできます。 値に設定されたファイルのキー名の内容に基づいて、エントリーごとにファイルが作成されます。
- 環境変数: コンテナー仕様の環境変数を動的に設定します。
- コマンドラインオプション:コンテナ仕様で使用するコマンドラインオプションを設定する。
- シークレット
- 以下のような機密情報をワークロードに提供します。 クラスターの他のユーザーがシークレットに対するアクセス権限を持っている場合があるため、シークレット情報はそれらのユーザーと共有される可能性があることを知っておいてください。
- 個人情報 (PII): E メール・アドレスなどの機密情報や、企業コンプライアンスや政府規制に必要な他のタイプの情報をシークレットに保管します。
- 資格情報: 意図しない情報漏洩のリスクを軽減するために、パスワード、鍵、トークンなどの資格情報をシークレットに入れます。 例えば、クラスターにサービスをバインドすると、シークレットに資格情報が保管されます。
シークレットをさらに保護したいですか? クラスター管理者に連絡してクラスター内の鍵管理サービス・プロバイダーを有効にしてもらい、新しいシークレットと既存のシークレットを暗号化します。
自分のアプリが正しいリソースを持っていることを確認するには?
アプリのYAMLファイルを指定する とき、アプリのコンフィギュレーションに Kubernetes。 特に、YAMLファイルで定義された各コンテナの リソース制限とリクエストを設定します。
さらに、アプリ・デプロイメントに影響を与える可能性がある以下のようなリソース制御をクラスター管理者がセットアップすることもできます。
どうすればアプリ構成に機能を追加できますか?
デプロイメントに何を含めることができるかについては、YAML ファイルでのアプリ要件の指定を参照してください。 この例には以下のオプションが含まれている。
- レプリカ・セット
- ラベル
- アフィニティー
- イメージ・ポリシー
- ポート
- リソースの要求と制限
- Liveness Probe と Readiness Probe
- ポートにアプリ・サービスを公開するための サービス。
- Configmaps を使用して、コンテナー環境変数を設定します。
- シークレット: コンテナー環境変数を設定します。
- ストレージ用にコンテナにマウントされる 永続ボリューム。
どうすれば Watson などの IBM サービスをアプリに追加できますか?
アプリへのサービスの追加を参照してください。
可用性の高いデプロイメントの計画
セットアップ時に複数のワーカー・ノードとクラスターを分散させる範囲を広くすればするほど、各ユーザーがアプリのダウン時間を経験する可能性は低くなります。
アプリのセットアップ方法を以下にまとめます。下に行くほど可用性が高くなります。
- 単一ノード上のレプリカセットで管理される n+2 ポッドによるデプロイメント。
- n+2 個のポッドをレプリカ・セットによって管理し、単一のゾーン・クラスター内の複数のノードに分散させる (アンチアフィニティー) デプロイメント。
- n+2 個のポッドをレプリカ・セットによって管理し、複数のゾーンにまたがる複数ゾーン・クラスター内の複数のノードに分散させる (アンチアフィニティー) デプロイメント。
また、グローバルなロードバランサーを使って、異なる地域にある複数のクラスタを接続することもできる。
アプリの可用性を向上させるにはどうすればよいですか?
アプリの可用性を向上させるには、以下の選択肢を検討してください。
- デプロイメントとレプリカ・セットを使用してアプリとその依存項目をデプロイする
- デプロイメントとは、アプリのすべてのコンポーネントとその依存項目を宣言するために使用できる Kubernetes リソースのことです。 デプロイメントでは、すべてのステップを書き留める必要はなく、代わりにアプリに集中できます。 複数のポッドをデプロイすると、ポッドをモニターするデプロイメント用にレプリカ・セットが自動的に作成され、指定された数のポッドが稼働中であることが保証されます。 ポッドがダウンすると、応答しなくなったポッドがレプリカ・セットによって新しいポッドに置き換えられます。 デプロイメントを使用して、ローリング更新中に追加するポッドの数や、一度に使用不可にできるポッドの数など、アプリの更新戦略を定義できます。 ローリング更新の実行時には、デプロイメントによって、リビジョンが動作しているかどうかが確認され、障害が検出されるとロールアウトが停止されます。 デプロイメントでは、異なるオプションを持つ複数のリビジョンを同時にデプロイすることができます。 例えば、実稼働環境にプッシュする前に、デプロイメントをテストすることができます。 デプロイメントを使用することによって、デプロイしたリビジョンを追跡できます。 更新が期待どおりに機能しない場合に、この履歴を使用して以前のバージョンにロールバックすることができます。
- アプリのワークロードに十分なレプリカ数、プラス 2 を組み込む
- アプリの可用性と耐障害性を高めるために、予想されるワークロードを処理する最低限の数のレプリカに加えて予備のレプリカを組み込むことを検討してください。 ポッドがクラッシュし、そのポッドがレプリカ・セットによってリカバリーされなかった場合に、予備のレプリカでワークロードを処理できます。 2 つが同時に障害を発生した場合に対応できるようにするには、2 つ余分にレプリカを組み込みます。 この構成は N+2 パターンです。N は着信ワークロードを処理するレプリカの数、+2 は追加の 2 つのインスタンスです。 クラスターに十分なスペースがある限り、必要な数のポッドを作成できます。
- 複数のノードにポッドを分散させる (アンチアフィニティー)
- デプロイメントを作成するときに、各ポッドを同じワーカー・ノードにデプロイすることもできます。 これは親和性、あるいはコロケーションとして知られている。 ワーカー・ノードの障害からアプリを保護するには、標準クラスターで
podAntiAffinity
オプションを使用して、複数のワーカー・ノードにポッドを分散させるようにデプロイメントを構成します。 「優先」と「必須」という 2 つのタイプのポッド・アンチアフィニティーを定義できます。 詳細については、 Kubernetes のドキュメント「 Assigning Pods to Nodes 」を参照してください。 アプリ・デプロイメント内のアフィニティーの例については、アプリ・デプロイメント YAML ファイルの作成を参照してください。 - 複数のゾーンまたはリージョンにポッドを分散させる
- ゾーン障害からアプリを保護するには、別々のゾーンに複数のクラスターを作成するか、または複数ゾーン・クラスター内のワーカー・プールにゾーンを追加することができます。 マルチゾーン・クラスターは、特定のクラシック用のマルチゾーンまたは VPC 用のマルチゾーン (ダラスなど) でのみ提供されています。 複数のクラスターを別々のゾーンに作成する場合は、グローバル・ロード・バランサーをセットアップする必要があります。 レプリカ・セットを使用し、ポッドのアンチアフィニティーを指定すると、Kubernetes はアプリ・ポッドをノード間で分散させます。 複数のゾーンにノードがある場合、ポッドはゾーン間で分散され、アプリの可用性が向上します。 アプリを 1 つのゾーンのみで実行するように制限する場合は、ポッドのアフィニティーを構成するか、または 1 つのゾーン内にワーカー・プールを作成してラベル付けすることができます。
- マルチゾーン・クラスターのデプロイでは、アプリのポッドはノードに均等に分散されますか?
- ポッドはゾーン間で均等に分散されますが、ノード間では必ずしも均等になるとは限りません。 例えば、3 つの各ゾーンにノードが 1 つずつあるクラスターがある場合、6 つのポッドからなるレプリカ・セットをデプロイすると、ポッドは各ノードに 2 つずつ配分されます。 しかし、3 つの各ゾーンにノードが 2 つずつあるクラスターの場合は、6 つのポッドからなるレプリカ・セットをデプロイすると、各ゾーンに 2 つのポッドがスケジュールされますが、必ずしもノードごとに 1 つのポッドがスケジュールされるとは限りません。 スケジューリングをさらにコントロールするには、 ポッド・アフィニティを設定します。
- あるゾーンがダウンした場合、他のゾーンの残りのノードにどのようにポッドが再スケジュールされるのですか?
- それはデプロイメントに使用されているスケジューリング・ポリシーによって異なります。 ノード固有のポッド・アフィニティが含まれている場合、ポッドは再スケジュールされません。 そうしていない場合、ポッドは他のゾーンの使用可能なワーカー・ノード上に作成されますが、バランスが取れていない可能性があります。 例えば、2 つのポッドが使用可能な 2 つのノードに分散される場合もあれば、使用可能な容量がある 1 つのノードに両方のポッドがスケジュールされる場合もあります。 同様に、使用不可になっていたゾーンが回復した場合も、ポッドが自動的に削除されて、ノード間でリバランスされるわけではありません。 ゾーンのバックアップ後にゾーン間でポッドのバランスを調整したい場合は、 Kubernetes descheduler を設定してください。 マルチゾーン・クラスタでは、ゾーンごとのワーカー・ノード容量を50%に保ち、ゾーン障害からクラスタを保護するのに十分な容量を確保するようにしてください。
- 自分のアプリを地域全体に広げたい場合はどうすればよいですか?
- リージョンの障害からアプリを保護するには、別のリージョンに2つ目のクラスターを作成し、クラスターを接続するために グローバルなロードバランサーをセットアップ し、デプロイメントYAMLを使用して、アプリ用の ポッドアンチアフィニティーで複製レプリカセットをデプロイします。
- アプリケーションに永続的なストレージが必要な場合は?
- IBM Cloudant や IBM Cloud Object Storageなどのクラウド・サービスを使用します。
どうすればアプリをスケーリングできますか?
ワークロードの使用状況に応じてアプリを動的に追加/除去するには、アプリのスケーリングを参照して、水平ポッド自動スケーリングを有効にするための手順を確認してください。
アプリのバージョン管理と更新
新バージョンのアプリに向けて準備するために、多大な労力が費やされます。 IBM Cloud と Kubernetes の更新ツールを使用すると、アプリのさまざまなバージョンをロールアウトできます。
どうすれば更新と管理がしやすいようにデプロイメントを編成できますか?
デプロイメントに含めるものを把握したところで、これらすべての異なる YAML ファイルを管理する方法についての疑問が生じるかもしれません。 当然ながら、Kubernetes 環境内でデプロイメントによって作成されるオブジェクトについても同様でしょう。
以下のヒントは、デプロイメント YAML ファイルの編成に役立ちます。
- Git などのバージョン管理システムを使用します。
- 相互に密接に関連する Kubernetes オブジェクトを同じ YAML ファイルにまとめます。 例えば、
deployment
を作成する場合は、service
ファイルもその YAML ファイルに追加するとよいでしょう。 以下の例のように、---
でオブジェクトを区切ってください。apiVersion: apps/v1 kind: Deployment metadata: ... --- apiVersion: v1 kind: Service metadata: ...
oc apply -f
コマンドを使用して、単一ファイルだけでなくディレクトリー全体に適用できます。- Kubernetes リソースの YAML 構成の記述、カスタマイズ、および再利用に役立つよう使用可能な
kustomize
プロジェクトを試してみます。
YAML ファイル内では、デプロイメントを管理するためのメタデータとしてラベルやアノテーションを使用できます。
- ラベル
- ラベルは
key:value
ペアで、ポッドやデプロイメントなどの Kubernetes オブジェクトに付けることができる。 ラベルには任意の値を使用でき、ラベル情報に基づいてオブジェクトを簡単に選択できます。 ラベルは、オブジェクトをグループ分けするための基盤となります。 以下の例をラベルの参考にしてください。app: nginx
version: v1
env: dev
- アノテーション
- 注釈は、
key:value
ペアであるという点で、ラベルと似ている。 アノテーションは、各種のツールやライブラリーで活用できる、非識別情報に適しています。例えば、オブジェクトの取得元に関する追加情報、そのオブジェクトの使用方法、関連する追跡リポジトリーへのポインター、そのオブジェクトに関するポリシーなどを保持します。 アノテーションに基づいてオブジェクトを選択することはありません。
アプリの更新戦略としては、どのようなものを使用できますか?
アプリを更新するには、以下のようなさまざまな戦略から選択できます。 最初はローリング・デプロイメントや即時切り替えから始めて、その後で複雑なカナリア・デプロイメントに進むことができます。
- ローリング・デプロイメント
- Kubernetes 固有の機能を使用して、
v2
デプロイメントを作成したり、以前のv1
デプロイメントを段階的に置き換えたりできます。 このアプローチでは、アプリが以前のバージョンと互換性を持つ必要があるため、v2
アプリのバージョンを提供されているユーザーは、変更を経験することはありません。 詳しくは、アプリを更新するためのローリング・デプロイメントの管理を参照してください。 - 即時切り替え
- 即時切り替え (ブルー/グリーン・デプロイメントとも呼ばれます) では、同じアプリの 2 つのバージョンを同時に実行するために通常の 2 倍のコンピュート・リソースが必要になります。 この手法を使用すると、ほぼリアルタイムでユーザーを新しいバージョンに切り替えることができます。 サービスラベルセレクタ(
version: green
やversion: blue
など)を使用して、リクエストが正しいアプリバージョンに送信されるようにしてください。 新しいversion: green
デプロイメントを作成して、このデプロイメントの準備が完了するまで待ってから、version: blue
デプロイメントを削除できます。 あるいは、 ローリング更新を実行できますが、その場合はmaxUnavailable
パラメーターを0%
に設定して、maxSurge
パラメーターを100%
に設定します。 - カナリア・デプロイメントまたは A/B デプロイメント
- さらに複雑な更新戦略であるカナリア・デプロイメントでは、指定した比率 (5% など) のユーザーのみが新しいアプリ・バージョンを利用できるようにします。 新しいアプリ・バージョンのパフォーマンスに関するメトリックをロギング・ツールとモニタリング・ツールで収集し、A/B テストを実行してから、より多くのユーザーに更新をロールアウトします。 他のデプロイメント方式と同様に、アプリにラベル (
version: stable
やversion: canary
など) を割り当てることが非常に重要です。
どうすればアプリのデプロイメントを自動化できますか?
複数のクラスター、パブリック環境とプライベート環境、または複数のクラウド・プロバイダーでアプリを実行する場合は、これらの環境を横断してデプロイメント戦略をどのように成功させるかが課題となります。 IBM Cloud および他のオープン・ソース・ツールを使用すると、アプリケーションをパッケージ化してデプロイメントの自動化に役立てることができます。
- 継続的な統合とデリバリー (CI/CD) パイプラインのセットアップ
- アプリの構成ファイルが Git などのソース制御管理システムで編成されている場合は、パイプラインを構築することで、コードをテストして、
test
やprod
などの別々の環境にデプロイできます。 クラスター管理者と協力して継続的統合/継続的デリバリーをセットアップします。 - アプリ構成ファイルのパッケージ化
- Kustomize や Helm などのツールを使用してアプリをパッケージ化します。
kustomize
プロジェクトを使用して、Kubernetes リソースの YAML 構成の記述、カスタマイズ、再利用を行うことができます。- パッケージ HelmKubernetes パッケージ・マネージャーを使えば、アプリが必要とするすべての Kubernetes リソースを Helm チャートで指定できます。 次に、Helm を使用して YAML 構成ファイルを作成して、これらのファイルをクラスターにデプロイできます。 また、ブロック ストレージ プラグインなどを使用 して、 IBM Cloud が提供する Helm チャートを統合し、クラスターの機能を拡張することもできます。
YAML ファイル・テンプレートを作成しようとしていますか? そのために Helm を使っている人もいるし、次のような他のコミュニティ・ツールを試してみるのもいいだろう。 ytt
.
サービス・ディスカバリーのセットアップ
Red Hat OpenShift クラスター内の各ポッドには IP アドレスが割り当てられています。 ただし、アプリをクラスターにデプロイする際は、サービス・ディスカバリーやネットワーキングのためにポッドの IP アドレスを利用しないことをお勧めします。 ポッドは頻繁に動的に削除および置換されるからです。 代わりに、Kubernetes サービスを使用してください。このサービスはポッドのグループを表し、cluster IP
と呼ばれる当サービスの仮想
IP アドレスを通じて安定したエントリー・ポイントを提供します。 詳しくは、 Kubernetes 「 サービス 」のドキュメントを参照。
自分のサービスが正しいデプロイメントに接続され、すぐに使えるようになっていることを確認するにはどうすればよいですか?
ほとんどのサービスについては、そのサービスの .yaml
ファイルにセレクターを追加することで、そのラベルによってアプリを実行するポッドにそのセレクターが適用されるようにします。 多くの場合、アプリが最初に起動したとき、すぐにリクエストを処理させたくはないだろう。 デプロイメントに Readiness Probe を追加することで、準備ができていると見なされるポッドのみにトラフィックが送信されるようにします。 ラベルを使い、レディネスプローブを設定するサービスのデプロイの例については、この
NGINX YAMLをチェックしてください。
場合によっては、サービスでラベルを使用することが望ましくないことがあります。 例えば、外部データベースを使用している場合や、そのサービスでクラスター内の異なる名前空間内の別のサービスを参照することを希望する場合があります。 このような場合は、エンドポイント・オブジェクトを手動で追加して、このオブジェクトをそのサービスにリンクする必要があります。
どうすればサービスをインターネットで公開できますか?
NodePort、LoadBalancer、および Ingress という 3 タイプのサービスを外部ネットワーキング用に作成できます。
クラスター・タイプに依存するいくつかのオプションがあります。 詳しくは、ネットワーク・サービスの計画を参照してください。
- 標準クラスター: NodePort サービス、ロード・バランサー・サービス、または Ingress サービスを使用することによって、アプリを公開できます。
- Calico を使用してプライベートになったクラスター: NodePort サービス、ロード・バランサー・サービス、または Ingressサービスを使用することによって、アプリを公開できます。 同時に、パブリック・ノード・ポートをブロックするために、Calico preDNAT ネットワーク・ポリシーを使用する必要もあります。
クラスター内で必要な Service
オブジェクトの数を計画する際は、Kubernetes では iptables
を使用してネットワーキングとポート転送の規則が処理されることに留意してください。 いくつもの (例えば 5000) サービスをクラスターで実行すると、パフォーマンスに影響する可能性があります。
アプリの保護
アプリを計画して開発するときには、セキュア・イメージの維持、機密情報の暗号化、およびアプリ・ポッドとクラスター内のその他のポッドおよびサービスとの間のトラフィックを制御するための以下のオプションを検討してください。
- イメージのセキュリティー
- アプリを保護するには、イメージを保護し、イメージの整合性を確保する検査を実施する必要があります。 イメージとレジストリーの保護に関するトピックで、セキュアなコンテナー・イメージを確保するために取れる対策を確認してください。 例えば、脆弱性アドバイザーを使用して、コンテナー・イメージのセキュリティー状況を検査できます。 組織の IBM Cloud Container Registry 名前空間にイメージを追加すると、脆弱性アドバイザーがそのイメージを自動的にスキャンして、セキュリティー問題や潜在的な脆弱性を検出します。 セキュリティー問題が検出されると、報告された脆弱性の解決に役立つ指示が提供されます。 まずは、脆弱性アドバイザーを使用したイメージ・セキュリティーの管理を参照してください。
- Kubernetes シークレット
- アプリをデプロイするときは、資格情報や鍵といった機密情報を YAML 構成ファイル、構成マップ、またはスクリプトに保管しないでください。 代わりに、レジストリー資格情報用のイメージ・プル・シークレットなどの Kubernetes シークレットを使用してください。 そして、それらのシークレットをデプロイメント YAML ファイルで参照できます。
- シークレットの暗号化
- 鍵管理サービス (KMS) プロバイダーを使用して、クラスター内に作成する Kubernetes シークレットを暗号化できます。 まずは、KMS プロバイダーを使用したシークレットの暗号化およびシークレット暗号化の確認を参照してください。
- ポッド・トラフィック管理
- Kubernetes ネットワーク・ポリシーは、内部ネットワーク・トラフィックからポッドを保護します。 例えば、多くのポッドまたはすべてのポッドで特定ポッド/サービスへのアクセスが不要である場合に、デフォルトでポッドがそのポッド/サービスにアクセスできないようにしたいのであれば、Kubernetes ネットワーク・ポリシーを作成して、そのポッド/サービスへの ingress トラフィックをブロックできます。 また Kubernetes ネットワーク・ポリシーは、別々の名前空間内のポッドとサービスの通信方法を制御して、名前空間の間のワークロードの分離を実施するのに役立ちます。 Kubernetes 1.21 以降を実行するクラスターの場合、Kubernetes API サーバーとの通信にポッドで使用されるサービス・アカウント・トークンは、時間制限付きで、自動的にリフレッシュされ、特定の対象ユーザー (ポッド) に有効範囲が設定されており、ポッドが削除されると無効化されます。 API サーバーとの通信を続行するには、リフレッシュされたトークン値を定期的に (毎分など) 読み取るようにアプリを設計する必要があります。 詳細については、 バウンド・サービス・アカウント・トークンを参照してください。
アクセスの管理およびアプリの正常性の監視
アプリをデプロイした後に、アプリにアクセスできるユーザーを管理し、アプリの正常性とパフォーマンスを監視できます。
どうすればアプリ・デプロイメントにアクセスできるユーザーを制御できますか?
アカウント管理者とクラスター管理者は、さまざまなレベル (クラスター、Red Hat OpenShift プロジェクト、ポッド、コンテナー) でアクセス権限を制御できます。
IBM Cloud IAM を使用すれば、個々のユーザー、グループ、またはサービス・アカウントに、クラスター・インスタンス・レベルで許可を割り当てることができます。 クラスター内の特定の名前空間にユーザーを制限することによって、クラスター・アクセス権限の適用範囲をさらに絞り込むことができます。 詳しくは、クラスター・アクセス権限の割り当てを参照してください。
ポッド・レベルでアクセス権限を制御するには、セキュリティー・コンテキスト制約 (SCC) を構成できます。
アプリ・デプロイメント YAML 内に、ポッドまたはコンテナーのセキュリティー・コンテキストを設定できます。 詳しくは、 Kubernetes のドキュメントをご覧ください。
アプリをデプロイした後、どうすればその正常性をモニターできますか?
クラスターの IBM Cloud ロギングおよびモニタリングをセットアップできます。