Kubernetesを使用してサーバー間でDockerコンテナをスケールする方法
Dockerは、アプリケーションをスタンドアロンのコンテナとしてパッケージ化できる、開発者向けのコンテナ化プラットフォームです。互換性のあるコンテナランタイムが利用できる場所であれば、どこでも実行されます。
Dockerの人気はほぼコンテナと同義にされるほどですが、それがすべてのユースケースにとって完璧な技術というわけではありません。そのままDockerを使用すると、CLIは個々のコンテナを管理するためのものであるため、プロダクション環境での課題が生じます。
Kubernetesは、コンテナのスタックを管理し、複数のサーバー間でスケーリングするオーケストレーションプラットフォームです。物理マシンのクラスター全体にデプロイでき、サービスの冗長性と耐障害性を向上させます。ここでは、自分の「Docker」コンテナをスケーリングするためのクラスターを開始する方法を説明します。
Kubernetesの基本
いくつかの重要なKubernetes用語を理解することで、Dockerとの違いを把握しやすくなります。Kubernetesの辞書には、クラスタに追加できる多数のリソースが説明されています。この記事に関連するのは、コンテナのスケジューリングを制御するコンポーネントのみです。
高いレベルで言えば、Kubernetesのインストールは「ノード」のクラスタです。ノードは、ワークロードをホストする独立した物理マシンです。単一の「マスターノード」は、クラスタの操作を「スケジューリング」して最も適切なワーカーノードに新しいコンテナを配置することで、クラスタの運営を調整(「オーケストレーション」)する責任を負っています。
ここにいくつかの重要な用語があります:
- マスター - マスターノードはクラスターを操作します。これはKubernetesをインストールするマシンです。制御プレーンを実行し、コンテナ化されたアプリのホスティングをワーカーノードに委任します。
- コントロールプレーン - コントロールプレーンはマスターノードのソフトウェアコンポーネントです。APIサーバー、設定ストア、コンテナスケジューラーなど、いくつかのサービスを含んでいます。
- ノード - ノードとは、コンテナをホストするマシンのことです。各ワーカーは、Kubeletと呼ばれるKubernetesコンポーネントを実行します。これにより、制御プレーンと連絡を取り合い、新しいコンテナをプロビジョニングするためのスケジューリング指示を受け取ります。
- ポッド - ポッドはKubernetesクラスターにおける最小の計算単位であり、コンテナインスタンスのグループを表します。ポッドの抽象化により、複数の実行中のコンテナを一括で操作することができます。
- レプリカセット - レプリカセットは、指定された数のレプリカが利用可能であることを保証するために、ポッドをスケーリングする役割を担っています。ポッドのレプリカを3つ要求した場合、レプリカセットは可用性の制約が満たされることを保証します。ポッドが失敗した場合は自動的に置き換えられ、サーバー間でのコンテナの複製を自動化することができます。
スケーラブルなクラスターを作成するには、マスターノード、少なくとも2つのワーカーノード、および複数のレプリカを提供するデプロイメントが必要です。Kubernetesは、利用可能なすべてのノードにわたってポッドをスケジュールできるため、1つのノードが障害を起こした場合でも耐障害性を提供します。
クラスターを作成する
Kubernetesは、ほとんどの主要なクラウドプロバイダーから管理されたオファリングとして利用可能です。これにより、制御プレーンを作成し、可変数のワーカーノードを追加するためのワンクリックの方法が提供されます。
自分のハードウェア上で、MicroK8sのような自己完結型のKubernetesディストリビューションを使用してクラスターを実行できます。冗長スケジューリングのサポートを希望する場合は、少なくとも2台の孤立した物理的または仮想マシンが必要です。
両方のマシンにMicroK8sをインストールします。一つのノードをマスターとして指定し、使用します。
add-nodeノード登録プロセスを開始するためのコマンド:
microk8s add-nodeこれにより、microk8s joinコマンドが出力されます。セカンダリノードに切り替えて、そのコマンドを実行してください。それにより、最初のクラスターに新しいワーカーとして参加します。これで、両方のマシンがコンテナ化されたワークロードをホストする準備が整いました。
水平スケーリングデプロイメントの定義
複数のサーバーで動作するアプリケーションは「水平スケール」として説明されます。それは、複数の異なる環境に広がっているということです。システムの垂直スケーリングは、既存の環境にリソースを追加することを含みます。
Kubernetesのワークロードを定義する最も簡単な方法は、Deploymentを使用することです。このリソースタイプは、コンテナイメージからPodを作成し、サービスを介して公開ネットワーキングルートを設定します。Deploymentはデフォルトで単一のPodインスタンスを持ちますが、複数のレプリカで構成することもできます。
こちらがシンプルなデプロイメントマニフェストです:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Kubectlを使用して、マニフェストをクラスターに適用します:
microk8s kubectl apply -f ./manifest.yamlKubernetesは3つのPodを作成し、それぞれがnginx:latestイメージから作成したNGINXウェブサーバーをホストします。ポート80はコンテナポートとして公開され、外部からのトラフィックを可能にします。
ポッドは自動的にクラスターのノードに分散されます。ノードは十分なリソースを提供できる場合、ポッドをホストする資格があります。
任意の時点でレプリカの数を更新できます。マニフェストのreplicasフィールドを変更し、それをクラスターに再適用してください。Kubernetesスケジューラーは、新しいPodをプロビジョニングしたり、古いPodを必要に応じて終了したりする措置をとります。replicasを0にスケールダウンすると、デプロイメントやその関連リソースを実際に削除することなく、アプリケーションをオフラインにできます。
動的にノードを追加する
レプリカ数を更新することで、クラスター内の既存リソースを活用できます。最終的には、ノードの総容量を使い果たしてしまい、新しいPodがスケジュールされるのを妨げる可能性があります。Kubernetesは、ノードを作成および削除できるクラスターのオートスケーリング機能を提供しており、スケジュール可能なPodの数を効果的に変更します。
オートスケーリングの設定は比較的複雑です。正確な手順はクラスターのホスティング環境によって異なります。需要の変化を検出するためにホストにフックできるクラスターオートスケーラーとの統合が必要です。Google Cloudの公式ドキュメントが利用可能で、Amazon EKSやMicrosoft AKSからもソリューションが提供されています。
オートスケーリングは、クラスターの容量不足のためにスケジュールできないポッドを常にチェックすることで機能します。また、正常にスケジュールされたポッドが減少したノード数と共存できるかどうかも評価します。その後、オートスケーラーはクラウドプロバイダーのAPIを利用してコンピューティングインスタンスを追加および削除し、クラスターのリソースを動的に調整します。新しいインスタンスを作成することは通常は課金対象の操作であるため、請求書に影響を与える可能性があります。
要約
Kubernetesは、複数のサーバーにわたってコンテナインスタンスを分散させるのを簡単にします。マシンをノードとして登録するか、マネージドクラウドクラスターを使用し、その後、replicasフィールドが設定されたDeploymentを作成します。必要なレプリカ数を更新することで、ワークロードをスケールさせることができます。
需要に大きな変化が予想される場合は、オートスケーリングを使用して動的に容量を拡張してください。この機能を利用することで、新しいノードを即座に作成し、追加リソースを加えることでレプリカ数を増やし続けることができます。
ポッドをスケーリングする際は、インバウンドトラフィックの分配が必要であることを忘れないでください。ポート80を公開する場合、Kubernetesはリクエストをどのノードのポート80にマッピングできる必要があります。これは、デプロイメントとサービスとともに自動的に機能します。Kubernetesはロードバランサーを作成し、ポッドを継続的に監視してトラフィックをどこに向けることができるかを調べます。

