VM ベース・アプリの Kubernetes への移動
このチュートリアルでは、費用が発生する場合があります。 コスト見積もりツールを使用して、予測使用量に基づいてコスト見積もりを生成します。
このチュートリアルでは、Kubernetes Service を使用して VM ベースのアプリを Kubernetes クラスターに移動するプロセスについて説明します。Kubernetes Service は、コンテナーと Kubernetes テクノロジーを結合させた強力なツール、直感的なユーザー・エクスペリエンス、標準装備のセキュリティーと分離機能を提供します。これらの機能を使用することで、計算ホストのクラスター内でのコンテナー化アプリのデプロイメント、操作、スケーリング、モニタリングを自動化することができます。
このチュートリアルには、既存のアプリをコンテナー化して Kubernetes クラスターにデプロイする方法の概念を理解するレッスンも含まれています。 VM ベースのアプリをコンテナー化する方法としては、次の選択肢があります。
- モノリシックなアプリケーションのコンポーネントで、独自のマイクロサービスに分割できるものを特定する。 これらのマイクロサービスをコンテナ化し Kubernetesにデプロイすることができます。
- アプリ全体をコンテナー化して Kubernetes クラスターにデプロイします。
アプリのタイプによって、アプリのマイグレーション手順は多岐にわたります。 このチュートリアルでは、一般的な手順と、アプリをマイグレーションする前に考えるべき注意点を取り上げます。
目標
- VMベースのアプリケーションにおけるマイクロサービスの識別方法を理解し、 Kubernetesのコンポーネントのマッピング方法を学びましょう。
- VM ベースのアプリをコンテナー化する方法を学ぶ。
- Kubernetes Service でコンテナーを Kubernetes クラスターにデプロイする方法を学ぶ。
- すべての学習内容を実践し、JPetStore アプリをクラスターで実行する。
アーキテクチャー
VM に基づく従来型のアプリ・アーキテクチャー
仮想マシンに基づく従来型のアプリ・アーキテクチャーの例を以下の図に示します。
{: caption="図
- ユーザーがアプリのパブリック・エンドポイントに要求を送信します。 パブリック・エンドポイントには、ロード・バランサー・サービスがあり、使用可能なアプリ・サーバー・インスタンス間で着信ネットワーク・トラフィックのロード・バランシングを行います。
- ロード・バランサーが、VM で正常に稼働しているアプリ・サーバー・インスタンスの中から選択したインスタンスに要求を転送します。 アプリファイル(アプリコード、構成ファイル、依存関係など)は、アプリサーバーVMに保存されます。
- アプリケーションサーバーは、データベースVM上で稼働する MySQLにアプリケーションデータを保存します。
コンテナー化アーキテクチャー
Kubernetes クラスターで実行する最新のコンテナー・アーキテクチャーの例を以下の図に示します。

- ユーザーがアプリのパブリック・エンドポイントに要求を送信します。 パブリック・エンドポイントには、Ingress アプリケーション・ロード・バランサー (ALB) があり、これがクラスター内のアプリ・ポッド間で着信ネットワーク・トラフィックのロード・バランシングを行います。 ALB は、公開されているアプリへの着信ネットワーク・トラフィックを許可するためのルールの集合です。
- ALB がクラスター内の使用可能なアプリ・ポッドの 1 つに要求を転送します。 アプリ・ポッドが稼働するワーカー・ノードは、仮想マシンの場合もあれば物理マシンの場合もあります。
- アプリ・ポッドが永続ボリュームにデータを保管します。 永続ボリュームを使用して、アプリ・インスタンス間またはワーカー・ノード間でデータを共有できます。
- アプリ・ポッドが IBM Cloud データベース・サービスにデータを保管します。 Kubernetes クラスター内で独自のデータベースを実行することも可能ですが、通常は、マネージド・サービスである Database as a Service (DBaaS) を使用するほうが簡単に構成できるうえに、バックアップやスケーリングの組み込み機能も利用できます。 IBM Cloud カタログ には、多くのタイプのデータベースがあります。
VM、コンテナー、Kubernetes
Kubernetes Service は、Kubernetes クラスターでコンテナー化アプリを実行できるだけでなく、以下のツールや機能も利用できます。
- 直感的なユーザーエクスペリエンスと強力なツール。
- 組み込みのセキュリティと分離により、セキュアなアプリケーションを迅速に提供可能。
- Watson™の認知機能を含むクラウドサービス。
- ステートレスアプリケーションとステートフルワークロードの両方に対して、専用クラスタリソースを管理する能力。
仮想マシンとコンテナーの比較
VM という従来型のアプリはネイティブ・ハードウェア上で稼働します。 1 つのアプリが 1 つのコンピュート・ホストの全リソースを使用することは通常ありません。 ほとんどの組織では、リソースの無駄を回避するために、1 つのコンピュート・ホストで複数のアプリを実行しようとします。 同じアプリのコピーをいくつも実行する場合もありますが、分離を確保する目的で、同じハードウェア上で複数のアプリ・インスタンス (VM) を実行することもあります。 これらのVMには完全なオペレーティングシステムスタックが搭載されているため、実行時とディスクの両方で重複が発生し、効率が比較的悪くなります。
コンテナーは、環境間でアプリをシームレスに移動できるようにアプリとそのすべての依存関係をパッケージ化するための標準的な手段です。 仮想マシンとは異なり、コンテナーはオペレーティング・システムをバンドルしません。 アプリのコード、ランタイム、システム・ツール、ライブラリー、設定のみがコンテナー内にパッケージされます。 コンテナーは、仮想マシンより軽量で移植しやすく、効率的です。
さらに、コンテナーの場合はホスト OS を共有できます。 その結果、重複を減らしつつも分離を実現できます。 また、コンテナーの場合はシステム・ライブラリーやシステム・バイナリーなどの不要なファイルを除けるので、スペースの節約ならびに攻撃可能面の縮小にもなります。 仮想マシンとコンテナーについて詳しくは、 コンテナーとはを参照してください。
Kubernetes のオーケストレーション
Kubernetes は、ワーカーノードのクラスタ内のコンテナ化されたアプリケーションのライフサイクルを管理するコンテナオーケストレーターです。 通常、アプリを実行するためには他にも多くのリソースが必要になります。例えば、他のクラウド・サービスに接続したり鍵を保護したりするために、ボリューム、ネットワーク、シークレットが必要になります。 Kubernetes で、そうしたリソースをアプリに追加することができます。 Kubernetes の鍵となるパラダイムはその宣言モデルにあります。 ユーザーが理想の状態を指定すると、Kubernetes がそれに準拠しようとし、理想の状態を維持します。
このセルフペースKubernetes ワークショップでは、 Kubernetesの初歩的なハンズオン体験をすることができます。 さらに、 Kubernetes 概念 のドキュメントページで、 Kubernetes のコンセプトについて詳しくご覧ください。
お客様のために IBM が行っていること
IBM Cloud Kubernetes Service の Kubernetes クラスターを使用すると、以下のメリットがあります。
- 複数のデータ・センターにクラスターをデプロイできます。
- Ingress とロード・バランサーのネットワーク・オプションを利用できます。
- 動的永続ボリュームを利用できます。
- IBM マネージドの高可用性の Kubernetes マスターを利用できます。
クラスターのサイズ変更
クラスターのアーキテクチャーを設計するときには、可用性、信頼性、複雑性、リカバリーなどとコストを比較する必要があります。 IBM Cloud Kubernetes Service の Kubernetes クラスターは、アプリの要件に応じてアーキテクチャーを選択できるようになっています。 少し計画を立てるだけで、過剰なアーキテクチャーや過剰な投資を避けてクラウド・リソースを最大限に活用できるようになります。 過大評価または過小評価した場合でも、ワーカーノードの数または種類を変更することで、クラスタを簡単にスケールアップまたはスケールダウンできます。
Kubernetes を使用してクラウドで実動アプリを実行するときには、以下の点を検討してください。
- 特定の 1 つの地理的ロケーションからのトラフィックだけを予想していますか。 その場合は、最高のパフォーマンスを得るために、物理的に最も近いロケーションを選択してください。
- 高可用性のためにクラスターのレプリカはいくつ必要ですか。 まずは、開発用、テスト用、実動用の 3 つのクラスターから始めるのが良いでしょう。 複数の環境を作成するための リソースを編成してアクセス権限を割り当てるためのベスト・プラクティス のソリューション・ガイドを確認してください。
- ワーカー・ノードにはどのようなハードウェアが必要ですか。 仮想マシンですか、それともベア・メタルですか?
- ワーカー・ノードは何台必要ですか。 これはアプリのスケールに大きく左右されます。ノードの数が多いほど、アプリの耐障害性は高くなります。
- 高可用性のためにいくつのレプリカが必要ですか。 レプリカ・クラスターを複数のロケーションにデプロイすれば、アプリの可用性が高まり、1 つのロケーションの障害によるアプリの停止を避けられます。
- アプリを起動するために必要な最小限のリソースはどれですか? アプリの実行に必要なメモリー量と CPU を調べるためにアプリをテストをする必要があるでしょう。 そして、アプリをデプロイして起動できるだけの十分なリソースをワーカー・ノードに用意する必要があります。 それから、ポッド仕様の一部としてリソースの割り当て量を指定します。 Kubernetes はその設定に基づいて、要求に対応できるだけの十分な容量を有するワーカー・ノードを選択 (スケジュール) します。 ワーカー・ノードで実行するポッドの数と、その数のポッドに対応するリソース所要量を見積もってください。
- ワーカーノードの数を増やすタイミングは? クラスターの使用量をモニターし、必要に応じてノード数を増やすことができます。 クラスタの健全性の監視 を参照してください。
- 信頼性の高い冗長ストレージが必要ですか。 はいの場合、 NFS用の永続ボリュームの主張を作成するか IBM Cloudをあなたのポッドにバインドします。
- クラスターを仮想プライベート・クラウド・インフラストラクチャーまたはクラシック・インフラストラクチャーでデプロイする必要がありますか? VPC は、プライベート・クラウド環境のセキュリティーとパブリック・クラウドの動的なスケーラビリティーを兼ね備えています。
これまでのステップをより具体的にするために、クラウド上で本番用のウェブアプリケーションを実行し、中程度から高負荷のトラフィックを期待していると仮定しましょう。 必要になるリソースについて検討してみましょう。
- 開発用、テスト用、実動用の 3 つのクラスターをセットアップします。
- 開発およびテスト用クラスタは、最小限のRAMとCPUオプション(例えば、2CPU 4GB、各クラスタに1つのワーカーノード)で開始できます。
- 実動クラスターでは、パフォーマンス、高可用性、耐障害性のために、より多くのリソースが必要になるでしょう。 専用サーバー、あるいはベアメタルオプションを選択し、少なくとも4つのCPU、 16GB、2つのワーカーノードを確保するかもしれません。
データベースを使用する方法を決定する
Kubernetes には、データベースを使用する方法として次の 2 つの選択肢があります。
- Kubernetes クラスター内で独自のデータベースを実行できます。そのためには、データベースを実行するマイクロサービスを作成する必要があります。 例えば、MySQL データベースを使用している場合、以下のステップを実行する必要があります。
- MySQL Dockerfile を作成するには、こちらに例があります。
- データベースの資格情報を保管するためにシークレットを使用する必要があります。 この こちらの例を参照してください。
- Kubernetes にデプロイするデータベースの構成を指定した
deployment.yaml
ファイルが必要です。 この こちらの例を参照してください。
- 2 つ目の選択肢は、マネージド・サービスである Database as a Service (DBaaS) を使用するという方法です。 通常は、このオプションのほうが簡単に構成できるうえに、バックアップやスケーリングの組み込み機能も利用できます。 IBM Cloud カタログ には、多くのタイプのデータベースがあります。 この選択肢を使用する場合は、以下のようにします。
- IBM Cloud カタログからマネージド・サービスである Database as a Service (DBaaS) を作成します。
- データベースの資格情報をシークレットに保管します。 Kubernetesのシークレットセクションにあるストアの認証情報 に関する秘密については、こちらで詳しく説明しています。
- アプリケーションで Database as a Service (DBaaS) を使用します。
アプリケーション・ファイルの保管場所を決定する
Kubernetes Service には、データを保管してポッド間で共有する方法としていくつかの選択肢があります。 どの保管方法でも災害時に同じレベルの持続性と可用性を保持できるわけではありません。
非永続データ・ストレージ
設計上、コンテナーやポッドの存続期間は短く、予期せぬ障害が起こることがあります。 コンテナーのローカル・ファイル・システムにデータを保管できます。 コンテナー内部のデータは、他のコンテナーやポッドと共有できず、コンテナーがクラッシュしたり削除されたりすると失われます。
アプリの永続データ・ストレージを作成する方法
ネイティブの Kubernetes 持続ボリュームを使用することで NFS ファイルストレージまたは ブロックストレージにアプリデータとコンテナデータを保持することができます。
NFS ファイル・ストレージまたはブロック・ストレージをプロビジョンするには、永続ボリューム請求 (PVC) を作成してポッドのストレージを要求する必要があります。 PVCでは、ストレージの種類、ストレージ容量(ギガバイト単位)、IOPS、データ保持ポリシー、ストレージの読み取りおよび書き込み権限を定義する、事前定義済みのストレージクラスから選択することができます。 PVC に基づいて、実際のストレージ・デバイスに相当する永続ボリューム (PV) が IBM Cloud に動的にプロビジョンされます。 PVC をポッドにマウントすると、PV の読み取り/書き込みが可能になります。 PV に保管されているデータは、コンテナーがクラッシュしたりポッドのスケジュールが変更されたりした場合でも利用できます。 IBMは、PVをバックアップする NFSとブロックストレージをクラスタ化し、お客様のデータに高い可用性を提供します。
PVC を作成する場合は、Kubernetes Service ストレージの資料で説明している手順に従ってください。
既存のデータを永続ストレージに移動する方法
ローカル・マシンから永続ストレージにデータをコピーするには、PVC をポッドにマウントする必要があります。 そうすると、ローカル・マシンからポッドの永続ボリュームにデータをコピーできます。
-
データをコピーするには、まず以下のような構成を作成する必要があります。
kind: Pod apiVersion: v1 metadata: name: task-pv-pod spec: volumes: - name: task-pv-storage persistentVolumeClaim: claimName: mypvc containers: - name: task-pv-container image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/mnt/data" name: task-pv-storage
-
次に、ローカル・マシンからポッドにデータをコピーするために、以下のようなコマンドを使用します。
kubectl cp <local_filepath>/<filename> <namespace>/<pod>:<pod_filepath>
-
クラスター内のポッドからローカル・マシンにデータをコピーします。
kubectl cp <namespace>/<pod>:<pod_filepath>/<filename> <local_filepath>/<filename>
永続ストレージのバックアップをセットアップする
ファイル共有とブロック・ストレージは、クラスターと同じロケーションにプロビジョンされます。 ストレージ自体も、高可用性を確保するために、IBM がクラスター化したサーバーでホストされています。 ただし、ファイル共有とブロック・ストレージは自動的にはバックアップされないので、ロケーション全体で障害が発生した場合はアクセス不能になる可能性があります。 データの損失や損傷を防止するためには、定期バックアップをセットアップし、必要時にバックアップを使用してデータをリストアできるようにします。
詳細については NFSとブロックストレージの ストレージオプションの計画」 を参照してください。
コードを準備する
12 の基本原則を適用する
12の要素からなるアプリケーションは、クラウドネイティブなアプリケーションを構築するための方法論です。 アプリをコンテナー化してクラウドに移行し、Kubernetes でオーケストレーションする場合は、この基本原則を理解して適用することが重要です。 IBM Cloud では、この基本原則の一部が必要になります。
以下の主要な原則が必要です。
- コードベース - すべてのソース・コードと構成ファイルをバージョン管理システム (GIT リポジトリーなど) で管理します。DevOps パイプラインを使用してデプロイメントを行う場合は、これが必要です。
- ビルド、リリース、実行 - 12-Factor App では、ビルド、リリース、実行という各ステージを厳密に区別します。 統合 DevOps デリバリー・パイプラインでこれを自動化すれば、アプリをビルドし、テストしてから、クラスターにデプロイできます。 継続的な統合とデリバリーのパイプラインをセットアップする方法については、 Kubernetes のチュートリアル を参照してください。 ソース管理、ビルド、テスト、デプロイの各段階の設定をカバーし、セキュリティスキャナー、通知、分析などの統合を追加する方法を示します。
- 構成 - 構成情報はすべて環境変数に保管します。 サービスの資格情報をアプリ・コードの中にハードコーディングしてはいけません。 資格情報を保管するには、Kubernetes シークレットを使用します。 後で資格情報の詳細を表示します。
Kubernetes シークレットに資格情報を保管する
アプリ・コードの中に資格情報を保管するのは決して良いやり方ではありません。 その代わりに Kubernetesは、パスワード、OAuthトークン、SSHキーなどの機密情報を保持する、いわゆる 「シークレット」 を提供します。 Kubernetes のシークレットはデフォルトで暗号化されるので、pod
定義やコンテナー・イメージに機密データをそのまま保管するよりも安全で柔軟な保管方法になります。
Kubernetes でシークレットを使用する 1 つの方法を以下に示します。
-
cloud-secrets.txt
というファイルを作成し、クラウド・サービスのサービス資格情報をその中に保管します。{ "url": "<SERVICE_URL>", "api_key": <API_Key> }
-
次に、以下のコマンドを実行して Kubernetesを作成し、
kubectl get secrets
を使用して、以下のコマンドを実行後にシークレットが作成されたことを確認しますkubectl create secret generic cloud-service-secret --from-file=cloud-secrets.txt=./cloud-secrets.txt
アプリをコンテナー化する
アプリをコンテナー化するには、コンテナー・イメージを作成する必要があります。
Dockerfile からイメージが作成されます。これは、イメージを構築するための指示とコマンドを含むファイルです。 Dockerfile の別個に保管されている指示の中で、ビルド成果物 (アプリ、アプリの構成、その従属関係) が参照されることもあります。
既存のアプリの Dockerfile を作成するときには、以下のコマンドを使用できます。
- FROM - コンテナーのランタイムを定義するための親イメージを選択します。
- ADD/COPY - 1 つのディレクトリーの内容をコンテナーにコピーします。
- WORKDIR - コンテナー内に作業ディレクトリーを設定します。
- RUN - アプリの実行時に必要なソフトウェア・パッケージをインストールします。
- EXPOSE - ポートをコンテナー外に公開します。
- ENV NAME - 環境変数を定義します。
- CMD - コンテナーの起動時に実行するコマンドを定義します。
画像は通常、一般公開されるレジストリ(パブリックレジストリ)に保存されるか、ユーザーグループに限定したアクセス権を設定したレジストリ(プライベートレジストリ)に保存されます。 Docker Hub などのパブリック・レジストリーは、Docker および Kubernetes の入門として最初のコンテナー化アプリをクラスター内に作成する時に使用できます。 しかし、エンタープライズ・アプリを作成する場合は、不正なユーザーがイメージを使用したり変更したりできないように、IBM Cloud Container Registry で提供されているようなプライベート・レジストリーを使用してください。
アプリをコンテナー化して IBM Cloud Container Registry に保管するには、以下のようにします。
- Dockerfileを作成する必要があります。以下のコードはDockerfileの例です。
# Build JPetStore war FROM openjdk:8 as builder COPY . /src WORKDIR /src RUN ./build.sh all # Use WebSphere Liberty base image from the Docker Store FROM websphere-liberty:latest # Copy war from build stage and server.xml into image COPY --from=builder /src/dist/jpetstore.war /opt/ibm/wlp/usr/servers/defaultServer/apps/ COPY --from=builder /src/server.xml /opt/ibm/wlp/usr/servers/defaultServer/ RUN mkdir -p /config/lib/global COPY lib/mysql-connector-java-3.0.17-ga-bin.jar /config/lib/global
- Dockerfile を作成したら、次はコンテナー・イメージをビルドして IBM Cloud Container Registry にプッシュする必要があります。 以下のようなコマンドでコンテナーをビルドできます。
docker build . -t <image_name> docker push <image_name>
アプリを Kubernetes クラスターにデプロイする
コンテナー・イメージをビルドしてクラウドにプッシュしたら、次は Kubernetes クラスターにデプロイする必要があります。 そのためには、deployment.yaml ファイルを作成しなければなりません。
Kubernetes のデプロイメント YAML ファイルを作成する方法
Kubernetes の deployment.yaml ファイルを作成するには、以下のようにします。
-
deployment.yamlを作成します。以下に deployment YAMLファイルの例を示します。
-
deployment.yamlで、コンテナ のリソース割り当て量を定義し、各コンテナが適切に起動するために必要なCPUとメモリの量を指定することができます。 コンテナーのリソース割り当て量を指定すると、Kubernetes スケジューラーがポッドの配置先にするワーカー・ノードを適切に決定できるようになります。
-
次に、以下のコマンドを使用して、作成したデプロイメントとサービスを表示します
kubectl create -f <filepath/deployment.yaml> kubectl get deployments kubectl get services kubectl get pods
要約
このチュートリアルでは、以下の内容を学びました。
- VM、コンテナー、Kubernetes の違い。
- 環境の種類 (開発、テスト、実動) 別にクラスターを定義する方法。
- データ・ストレージの使用方法と、永続データ・ストレージの重要性。
- 12 の基本原則をアプリに適用する方法と、資格情報のために Kubernetes のシークレットを使用する方法。
- コンテナー・イメージをビルドして IBM Cloud Container Registry にプッシュする方法。
- Kubernetes のデプロイメント・ファイルを作成してコンテナー・イメージを Kubernetes にデプロイする方法。
すべての学習内容を実践して JPetStore アプリをクラスターで実行する
学んだことをすべて実践に移すために、 デモに従ってクラスタ上で JPetStore を実行し、学んだ概念を適用してください。 JPetStore アプリの拡張機能を利用すると、画像分類を別個のマイクロサービスとして実行して、Kubernetes 内のアプリを拡張できます。