fbpx

「Kubernetesで初めてのアプリを作ろう」パート2: プロセスの設定 #docker #kubernetes #k8s

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

このブログシリーズのパート1では、Kubernetesでの初めてのアプリ構築の基本をご紹介しました。今回の記事では、アプリケーションを管理するための拡張可能なプロセスを作るために、PodやControllerをどのように使うべきかをご説明します。

KubernetesにおけるPodとControllerとしてのプロセス

いかなるアプリケーションもその核となるのは実行プロセスです。そしてKubernetesでは基本的に Pod としてプロセスを作成します。Podは個々のコンテナに比べて、少し手が込んでいます。すなわち、コンテナの一群としてまとめてスケジュールでき、単一ホストにまとめて配置できます。これが最初の判断ポイントとなります:

判断ポイント その1: プロセスはどのようにPodにまとめるべきか?

Podの背景にある元の考え方は、VMのように 論理ホスト をエミュレートすることでした。Pod内のコンテナは常に同じKubernetesノード上にスケジュールされ、localhostを通じてお互いに通信可能となります。これによりPodは、互いに密接に動作する必要のあるプロセスの集合をうまく表現することができます。

ここで考慮すべき重要な点があります: 1つのPod内にある個々のコンテナを別々にスケールすることは不可能ではありません。 アプリケーションのスケールアップが必要な場合、Podを追加しなければなりません。それにはPodが有する各コンテナの複製が伴います。どのアプリケーションコンポーネントが同様の割合でスケーリングするのか、また反対に同様の割合でスケーリングしないコンポーネントはどれか、あるいはどのコンポーネントが同じホストに同居すべきなのか、といった要因によって、プロセスをどのようにPodにまとめるべきかが決まります。

私たちのウェブアプリで考えてみます。おそらく私たちは、フロントエンドのコンテナのみを有するPodを作成することから始めるでしょう。このフロントエンド用コンテナを、残りのアプリケーションから独立してスケーリングできるようにしたければ、フロントエンド用コンテナのみがPod内に存在するはずです。

一方で、データベース用のコンテナとAPI用のコンテナを一緒に有するもう1つのPodを設計するかもしれません。この方法では、同じ物理ホスト上でAPIがデータベースに通信できることを保証でき、APIとデータベース間のネットワークレイテンシを除外し、最大効率化が可能です。前述の通り、これは独立したスケーリングを犠牲にしてしまいます。APIコンテナとデータベースコンテナを同じPodとしてスケジュールする場合、データベースコンテナの新しいインスタンスが欲しいときは毎回、APIコンテナの新しいインスタンスも一緒に増えてしまいます。

この選択が正しいか間違っているかは、それぞれの場合で議論となるでしょう: APIとデータベース間のレイテンシは本当に主要なボトルネックなのでしょうか?APIとデータベースを別々にスケーリングすることの方がより重要である可能性はないでしょうか?最終的な判断はユーザによって異なるでしょう。しかし同じ判断ポイントが多くのアプリケーションに一般的に適用可能です。

さあ、Podについては計画を練りました(フロントエンドに1つのPod、APIとデータべースの組み合わせに1つのPod)。次は、これらのPodをどのように管理するかについて決めます。実質的には、Podを直接的にスケジュールすることは望ましくありません(これを「ベア・ポッド(Bare Pod)」と呼びます)。ここでは Kubernetes controllers の利点を活かします。障害を起こしたPodを自動で再スケジュールしてくれます。また、Podをどこでどのようにスケジュールするか簡単に作用できるようにし、それらのPodをどのように更新・維持するための機能もあります。 ここでは、少なくとも2つの主要な種類のControllerの中から選択します:

判断ポイント その2: それぞれのPodにどのよう種類のControllerを使うべきか: DeploymentかDaemonSetか?

Deployment

もっとも一般的な種類のControllerです。リソースが利用可能な場所ならどこでもスケジュールが可能であるステートレスなPodにとって、最も典型的で最適な選択です。

DaemonSet

1つのホストに対して1つ 実行するためのPodに最適です。これらは一般的に、Kubernetesクラスタ内のすべてのホストそれぞれにぴったり1つずつ存在することに適している、ログアグリゲータ、ファイルシステム管理、システムモニターなど、デーモンのようなプロセスに使われます。

すべてではありませんが、ほとんどの場合Podはこの2つのControllerで最適にスケジュールできます。なかでもDeploymentが主力です。私たちのウェブアプリコンポーネントのどちらも、クラスタ全体のデーモンでは理に適わないため、私たちは両者をDeploymentでスケジュールします。のちにロギングまたはモニタリングのアプライアンスをデプロイしたい場合は、クラスタ内の各ノードで実行できるdaemonSetが一般的な方法でしょう。

これまでに、コンテナをどのようにPodにまとめるかと、Controllerを使用してPodをどのように管理するかについて判断してきました。では次に、これらのオブジェクトを作成するためのKubernetes yamlをいくつか書いてみましょう。Kubernetesドキュメントや、Dockerのトレーニングマテリアルで、手順や例が紹介されています。

命令的なkubectlコマンド ではなく 、Kubernetes yaml定義を用いて、 アプリケーションを定義することを 強く お勧めします。最初の記事でお伝えしたように、コンテナ化したアプリケーションのオーケストレーションにおいて最も重要な側面の1つは、共有性です。バージョン管理システムにチェックイン・配布できるyamlファイルはとても簡単に共有できるのです。一連のCLIコマンドでは、すぐに読み込みや追跡が困難となってしまいます。

チェックポイント その2: Kubernetes yamlで、ControllerとPodを記述しよう。

yamlを掌中に収めたら、Deploymentを作成し、すべてが期待どおりに動くことを確実にするよいタイミングです: Pod内の個々のコンテナはクラッシュせずに実行され、同じPod内のコンテナはlocalhost上でお互いに通信可能となっているはずです。

高度なトピックス

前述のPod、Deployment、DaemonSetsをマスターしたら、あなたのKubernetesアプリケーションをさらに高めるためのトピックスがあります:

StatefulSet

ステートフルなPodの管理に適切な種類のControllerです。これにはKubernetesのサービスとストレージについての理解が必要です(次で紹介します)。

スケジューリングアフィニティルール

Podをクラスタ内のどこにスケジュールするかに影響を与え制御することができます。これは、より大きなクラスタでの洗練された運用に役立ちます。

ヘルスチェック

livenessProbeはPodとコンテナにとって重要なメンテナンス機能で、Kubernetesにコンテナの状態をどのように自動でモニタリングするかを伝え、状態が悪くなった際に対応するものです。

PodSecurityPolicy

この定義は、クラスタ管理者が誰がどのようにPodをスケジュールするかを制御するもので、一般的に、高い権限やroot権限でPodが作られることを防ぎます。

Kubernetesベースのアプリケーションのためのネットワーキングについては、パート3でご紹介します。

KubernetesのPodやControllerについてもっと学びたい人は、ドキュメントをご参照ください:

Docker社によるPlay with Kubernetesもご覧ください。

2020年はじめには、Kubernetesトレーニングも開始する予定です。 トレーニングでは、より詳細な事例とハンズオン演習を提供します。トレーニングについてお知らせを受け取るには、こちらにサインアップしてください: トレーニングについてお知らせを受け取る


原文: Designing Your First App in Kubernetes, Part 2: Setting up Processes

新規CTA