次の方法で共有


コンテナーとオーケストレーターの活用

ヒント

このコンテンツは、Azure 用のクラウド ネイティブ .NET アプリケーションの設計に関する電子ブックからの抜粋であり、.NET Docs またはオフラインで読み取ることができる無料のダウンロード可能な PDF として入手できます。

Azure eBook 用の Cloud Native .NET アプリの表紙サムネイル。

コンテナーとオーケストレーターは、モノリシックデプロイアプローチに共通する問題を解決するように設計されています。

モノリシック デプロイに関する課題

従来、ほとんどのアプリケーションは 1 つのユニットとしてデプロイされてきました。 このようなアプリケーションはモノリスと呼ばれます。 複数のモジュールまたはアセンブリで構成されている場合でも、アプリケーションを 1 つのユニットとしてデプロイするこの一般的なアプローチは、図 3-1 に示すようにモノリシック アーキテクチャと呼ばれます。

モノリシック アーキテクチャ。

図 3-1 モノリシック アーキテクチャ。

シンプルさの利点はありますが、モノリシック アーキテクチャは多くの課題に直面しています。

デプロイメント

さらに、アプリケーションの再起動が必要です。これは、デプロイ中にダウンタイムゼロの手法が適用されない場合、可用性に一時的に影響する可能性があります。

スケーリング

モノリシック アプリケーションは単一のマシン インスタンス上で完全にホストされ、多くの場合、高い機能を備えたハードウェアが必要です。 モノリスのいずれかの部分でスケーリングが必要な場合は、アプリケーション全体の別のコピーを別のコンピューターにデプロイする必要があります。 モノリスでは、アプリケーション コンポーネントを個別にスケーリングすることはできません。 スケーリングを必要としないコンポーネントをスケーリングすると、非効率的でコストの高いリソース使用量が発生します。

環境

モノリシック アプリケーションは、通常、オペレーティング システム、ランタイム、およびライブラリの依存関係が事前にインストールされているホスティング環境にデプロイされます。 この環境は、アプリケーションが開発またはテストされた環境と一致しない場合があります。 アプリケーション環境間の不整合は、モノリシックデプロイの問題の一般的な原因です。

結合

モノリシック アプリケーションでは、その機能コンポーネント間で高い結合が発生する可能性があります。 ハード境界がなければ、システムの変更は、多くの場合、意図せず、コストのかかる副作用をもたらします。 新機能/修正は、複雑で時間がかかり、実装にコストがかかります。 更新には広範なテストが必要です。 結合により、コンポーネントのリファクタリングや代替実装でのスワップも困難になります。 懸念事項を厳密に分離して構築した場合でも、モノリシックなコードベースが終わりのない『特殊なケース』によって劣化するにつれて、アーキテクチャの浸食が生じます。

プラットフォームロックイン

モノリシック アプリケーションは、1 つのテクノロジ スタックで構築されます。 統一性を提供する一方で、このコミットメントはイノベーションの障壁になる可能性があります。 新しい機能とコンポーネントは、アプリケーションの現在のスタックを使用して構築されます。最新のテクノロジの方が適している場合でも可能です。 長期的なリスクは、テクノロジ スタックが古くなり、廃止されることです。 アプリケーション全体を新しい最新のプラットフォームに再設計することは、コストとリスクが最も高くなります。

コンテナーとオーケストレーターの利点は何ですか?

第 1 章でコンテナーを導入しました。 Cloud Native Computing Foundation (CNCF) により、マイクロサービスのコンテナー化がクラウドネイティブ トレイル マップ (クラウドネイティブ体験を始める企業向けのガイダンス) の最初のステップと優先順位が付けられていることを取り上げました。 このセクションでは、コンテナーの利点について説明します。

Docker は、最も一般的なコンテナー管理プラットフォームです。 Linux または Windows の両方のコンテナーで動作します。 コンテナーは、任意のシステムで同じように実行される、個別の再現可能なアプリケーション環境を提供します。 この側面により、クラウドネイティブ サービスの開発とホストに最適です。 コンテナーは互いに分離されます。 同じホスト ハードウェア上の 2 つのコンテナーは、競合を引き起こすことなく、異なるバージョンのソフトウェアを持つことができます。

コンテナーは、プロジェクト成果物になり、ソース管理にチェックインされる単純なテキスト ベースのファイルによって定義されます。 完全なサーバーと仮想マシンの更新には手動での作業が必要ですが、コンテナーは簡単にバージョン管理されます。 コンテナーで実行するように構築されたアプリは、ビルド パイプラインの一部として自動ツールを使用して開発、テスト、デプロイできます。

コンテナーは不変です。 コンテナーを定義したら、まったく同じ方法でコンテナーを再作成して実行できます。 この不変性は、コンポーネントベースの設計に役立ちます。 アプリケーションの一部が他の部分と異なる方法で進化する場合、最も頻繁に変更されるパーツをデプロイできる場合に、アプリ全体を再デプロイする理由は何ですか? アプリのさまざまな機能と横断的な懸念は、別々のユニットに分割できます。 図 3-2 は、モノリシック アプリが特定の機能を委任することによってコンテナーとマイクロサービスを利用する方法を示しています。 アプリ自体の残りの機能もコンテナー化されています。

バックエンドでマイクロサービスを使用するようにモノリシック アプリを分割する。

図 3-2 モノリシック アプリを分解してマイクロサービスを受け入れる。

各クラウド ネイティブ サービスは、個別のコンテナーに構築およびデプロイされます。 各自で必要に応じて更新できます。 個々のサービスは、各サービスに適したリソースを持つノードでホストできます。 各サービスが実行される環境は不変であり、開発、テスト、運用環境間で共有され、簡単にバージョン管理されます。 アプリケーションのさまざまな領域間の結合は、モノリス内のコンパイル時の依存関係ではなく、サービス間の呼び出しまたはメッセージとして明示的に発生します。 また、アプリの残りの部分に変更を加えることなく、特定の機能を最適に組み込むテクノロジを選択することもできます。

コンテナー化されたサービスには、自動管理が必要です。 大規模な個別にデプロイされたコンテナーのセットを手動で管理することはできません。 たとえば、次のタスクについて考えてみましょう。

  • コンテナー インスタンスは、多数のマシンのクラスターに対してどのようにプロビジョニングされますか?
  • デプロイ後、コンテナーはどのようにして検出し、相互に通信しますか?
  • コンテナーをオンデマンドでスケールインまたはスケールアウトするにはどうすればよいですか?
  • 各コンテナーの正常性を監視する方法
  • ハードウェアとソフトウェアの障害からコンテナーを保護する方法
  • ダウンタイムを発生させず、ライブ アプリケーションのコンテナーをアップグレードする方法

コンテナー オーケストレーターは、これらの問題とその他の懸念事項に対処し、自動化します。

クラウドネイティブのエコシステムでは、Kubernetes が事実上のコンテナー オーケストレーターになりました。 これは、Cloud Native Computing Foundation (CNCF) によって管理されるオープンソース プラットフォームです。 Kubernetes は、マシン クラスター全体でコンテナー化されたワークロードのデプロイ、スケーリング、運用上の懸念を自動化します。 ただし、Kubernetes のインストールと管理は非常に複雑です。

より優れたアプローチは、クラウド ベンダーのマネージド サービスとして Kubernetes を活用することです。 Azure クラウドには、Azure Kubernetes Service (AKS) という名前のフル マネージド Kubernetes プラットフォームが用意されています。 AKS は、Kubernetes の管理の複雑さと運用上のオーバーヘッドを抽象化します。 クラウド サービスとして Kubernetes を使用する。Microsoft は、それを管理およびサポートする責任を負います。 AKS は、他の Azure サービスや開発ツールとも緊密に統合されています。

AKS はクラスター ベースのテクノロジです。 フェデレーション仮想マシンまたはノードのプールが Azure クラウドにデプロイされます。 これらは一緒に高可用性環境またはクラスターを形成します。 クラスターは、クラウドネイティブ アプリケーションに対してシームレスで単一のエンティティとして表示されます。 内部的には、AKS は、負荷を均等に分散する定義済みの戦略に従って、コンテナー化されたサービスをこれらのノードにデプロイします。

スケーリングの利点は何ですか?

コンテナー上に構築されたサービスでは、Kubernetes などのオーケストレーション ツールによって提供されるスケーリングの利点を活用できます。 設計上、コンテナーはそれ自体についてのみ知っています。 連携する必要がある複数のコンテナーを作成したら、より高いレベルで整理する必要があります。 多数のコンテナーとその共有依存関係 (ネットワーク構成など) を整理することで、オーケストレーション ツールを使用して 1 日を節約できます。 Kubernetes は、コンテナーのグループに対して抽象化レイヤーを作成し、ポッドに整理 します。 ポッドは、 ノードと呼ばれるワーカー マシンで実行されます。 この編成された構造は、 クラスターと呼ばれます。 図 3-3 は、Kubernetes クラスターのさまざまなコンポーネントを示しています。

Kubernetes クラスター コンポーネント。 図 3-3 Kubernetes クラスター コンポーネント。

コンテナー化されたワークロードのスケーリングは、コンテナー オーケストレーターの重要な機能です。 AKS では、コンテナー インスタンスとコンピューティング ノードという 2 つのディメンションにわたる自動スケーリングがサポートされています。 これらの機能を組み合わせることで、AKS は需要の急増に迅速かつ効率的に対応し、リソースを追加することができます。 AKS でのスケーリングについては、この章の後半で説明します。

宣言型と命令型

Kubernetes では、宣言型と命令型の両方の構成がサポートされています。 命令型アプローチでは、さまざまなコマンドを実行して、方法の各ステップで何を行うかを Kubernetes に指示します。 このイメージを実行します。 このポッドを削除します。 このポートを公開します。 宣言型のアプローチでは、マニフェストと呼ばれる構成ファイルを作成して、何を行うかではなく、必要なものを記述します。 Kubernetes はマニフェストを読み取り、目的の終了状態を実際の終了状態に変換します。

命令型コマンドは、学習と対話型の実験に最適です。 ただし、信頼性の高い反復可能なデプロイを提供するコード アプローチとしてインフラストラクチャを採用するために、Kubernetes マニフェスト ファイルを宣言によって作成する必要があります。 マニフェスト ファイルはプロジェクト成果物になり、Kubernetes デプロイを自動化するために CI/CD パイプラインで使用されます。

命令型コマンドを使用してクラスターを既に構成している場合は、 kubectl get svc SERVICENAME -o yaml > service.yamlを使用して宣言型マニフェストをエクスポートできます。 このコマンドは、次のようなマニフェストを生成します。

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2019-09-13T13:58:47Z"
  labels:
    component: apiserver
    provider: kubernetes
  name: kubernetes
  namespace: default
  resourceVersion: "153"
  selfLink: /api/v1/namespaces/default/services/kubernetes
  uid: 9b1fac62-d62e-11e9-8968-00155d38010d
spec:
  clusterIP: 10.96.0.1
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

宣言型構成を使用する場合は、構成ファイルが配置されているフォルダーに対して kubectl diff -f FOLDERNAME を使用して、コミットする前に行われる変更をプレビューできます。 変更を適用する必要がある場合は、 kubectl apply -f FOLDERNAMEを実行します。 フォルダー階層を再帰的に処理する -R を追加します。

他の Kubernetes 機能 (デプロイの 1 つ) で宣言型構成を使用することもできます。 宣言型デプロイは、リリース、更新、スケーリングの管理に役立ちます。 新しい変更のデプロイ、負荷のスケールアウト、または以前のリビジョンへのロールバックの方法について、Kubernetes デプロイ コントローラーに指示します。 クラスターが不安定な場合、宣言型のデプロイでは、クラスターが自動的に目的の状態に戻ります。 たとえば、ノードがクラッシュする必要がある場合、デプロイ メカニズムは置換を再デプロイして目的の状態を実現します

宣言型構成を使用すると、アプリケーション コードと共にチェックインおよびバージョン管理できるコードとしてインフラストラクチャを表すことができます。 ビルドとデプロイ パイプラインを使用した継続的デプロイの変更制御とサポートの向上が提供されます。

コンテナーとオーケストレーターに最適なシナリオは何ですか?

次のシナリオは、コンテナーとオーケストレーターの使用に最適です。

高いアップタイムとスケーラビリティを必要とするアプリケーション

アップタイムとスケーラビリティの要件が高い個々のアプリケーションは、マイクロサービス、コンテナー、オーケストレーターを使用するクラウドネイティブ アーキテクチャの理想的な候補です。 これらはコンテナーで開発し、バージョン管理された環境全体でテストし、ダウンタイムを発生ささなければ運用環境にデプロイできます。 Kubernetes クラスターを使用することで、このようなアプリをオンデマンドでスケーリングし、ノード障害から自動的に復旧することもできます。

多数のアプリケーション

多数のアプリケーションをデプロイして維持する組織は、コンテナーとオーケストレーターの恩恵を受けます。 コンテナー化された環境と Kubernetes クラスターを設定する前の作業は、主に固定コストです。 個々のアプリケーションのデプロイ、保守、更新には、アプリケーションの数によって異なるコストがかかります。 いくつかのアプリケーションを超えて、カスタム アプリケーションを手動で管理する複雑さは、コンテナーとオーケストレーターを使用してソリューションを実装するコストを超えています。

コンテナーとオーケストレーターの使用を回避する必要がある場合

Twelve-Factor アプリの原則に従ってアプリケーションをビルドできない場合は、コンテナーとオーケストレーターを回避することを検討する必要があります。 このような場合は、VM ベースのホスティング プラットフォーム、または場合によってはハイブリッド システムを検討してください。 これを使用すると、特定の機能を個別のコンテナーまたはサーバーレス関数にいつでもスピンオフできます。

開発リソース

このセクションでは、次のアプリケーションでコンテナーとオーケストレーターの使用を開始するのに役立つ可能性がある開発リソースの簡単な一覧を示します。 クラウドネイティブマイクロサービス アーキテクチャ アプリの設計方法に関するガイダンスをお探しの場合は、この本のコンパニオン である .NET マイクロサービス: コンテナー化された .NET アプリケーションのアーキテクチャを参照してください。

ローカルなKubernetes開発

Kubernetes デプロイは運用環境で大きな価値を提供しますが、開発用コンピューターでローカルに実行することもできます。 個々のマイクロサービスを個別に操作することもできますが、運用環境にデプロイするときに実行されるのと同様に、システム全体をローカルで実行する必要がある場合があります。 Minikube と Docker Desktop に役立つツールがいくつかあります。 Visual Studio には、Docker 開発用のツールも用意されています。

Minikube

Minikube とは Minikube プロジェクトには、「Minikube は macOS、Linux、および Windows にローカル Kubernetes クラスターを実装します」と表示されます。その主な目標は、「ローカルの Kubernetes アプリケーション開発に最適なツールであり、適合するすべての Kubernetes 機能をサポートすること」です。Minikube のインストールは Docker とは別ですが、Minikube では Docker Desktop がサポートするハイパーバイザーとは異なるハイパーバイザーがサポートされています。 現在、Minikube では次の Kubernetes 機能がサポートされています。

  • DNS(ドメイン・ネーム・システム)
  • NodePorts
  • ConfigMaps とシークレット
  • ダッシュボード
  • コンテナー ランタイム: Docker、rkt、CRI-O、およびコンテナー化
  • コンテナー ネットワーク インターフェイス (CNI) の有効化
  • イングレス

Minikube をインストールしたら、イメージをダウンロードしてローカル Kubernetes クラスターを起動する minikube start コマンドを実行して、Minikube の使用をすぐに開始できます。 クラスターが起動したら、標準の Kubernetes kubectl コマンドを使用してクラスターを操作します。

Docker Desktop

Windows 上の Docker Desktop から直接 Kubernetes を操作することもできます。 Windows コンテナーを使用している場合は、このオプションが唯一の選択肢であり、Windows 以外のコンテナーにも最適です。 図 3-4 は、Docker Desktop の実行時にローカル Kubernetes のサポートを有効にする方法を示しています。

Docker Desktop での Kubernetes の構成

図 3-4. Docker Desktop での Kubernetes の構成。

Docker Desktop は、コンテナー化されたアプリをローカルで構成して実行するための最も一般的なツールです。 Docker Desktop を使用する場合は、運用環境にデプロイするのとまったく同じ Docker コンテナー イメージのセットに対してローカルで開発できます。 Docker Desktop は、コンテナー化されたアプリをローカルで "ビルド、テスト、出荷" するように設計されています。 Linux コンテナーと Windows コンテナーの両方がサポートされています。 Azure Container Registry や Docker Hub などのイメージ レジストリにイメージをプッシュすると、AKS はイメージをプルして運用環境にデプロイできます。

Visual Studio の Docker ツール

Visual Studio では、Web ベースのアプリケーションの Docker 開発がサポートされています。 新しい ASP.NET Core アプリケーションを作成するときは、図 3-5 に示すように、Docker サポートを使用して構成するオプションがあります。

Visual Studio での Docker サポートの有効化

図 3-5. Visual Studio での Docker サポートの有効化

このオプションを選択すると、プロジェクトはルートに Dockerfile を使用して作成されます。これを使用して、Docker コンテナーでアプリをビルドしてホストできます。 Dockerfile の例を図 3-6 に示します。

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["eShopWeb/eShopWeb.csproj", "eShopWeb/"]
RUN dotnet restore "eShopWeb/eShopWeb.csproj"
COPY . .
WORKDIR "/src/eShopWeb"
RUN dotnet build "eShopWeb.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "eShopWeb.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "eShopWeb.dll"]

図 3-6 Visual Studio で生成された Dockerfile

サポートが追加されたら、Visual Studio の Docker コンテナーでアプリケーションを実行できます。 図 3-7 は、Docker サポートを追加して作成された新しい ASP.NET Core プロジェクトから使用できるさまざまな実行オプションを示しています。

Visual Studio Docker の実行オプション

図 3-7 Visual Studio Docker の実行オプション

また、いつでも既存の ASP.NET Core アプリケーションに Docker サポートを追加できます。 図 3-8 に示すように、Visual Studio ソリューション エクスプローラーでプロジェクトを右クリックし、[ 追加>Docker サポート] を選択します。

Visual Studio での Docker サポートの追加

図 3-8 Visual Studio への Docker サポートの追加

Visual Studio Code Docker ツール群

Docker 開発をサポートする Visual Studio Code には、多くの拡張機能が用意されています。

Microsoft では、 Docker for Visual Studio Code 拡張機能を提供しています。 この拡張機能により、アプリケーションにコンテナーのサポートを追加するプロセスが簡略化されます。 必要なファイルをスキャフォールディングし、Docker イメージをビルドし、コンテナー内でアプリをデバッグできるようにします。 拡張機能には、開始、停止、検査、削除などのコンテナーとイメージに対するアクションを簡単に実行できるビジュアル エクスプローラーが備えています。 また、この拡張機能では Docker Compose もサポートされており、複数の実行中のコンテナーを 1 つのユニットとして管理できます。