導入
Kubernetesは、Googleが初めに開発し、Cloud Native Computing Foundation(CNCF)がサポートする強力なオープンソースシステムであり、クラスタ化された環境でコンテナ化されたアプリケーションを管理するためのものです。これは、関連する分散コンポーネントやサービスをさまざまなインフラストラクチャにわたって管理するためのより良い方法を提供することを目指しています。Kubernetesについて詳しく学びたい場合は、以下のガイドをご覧ください。マネージドKubernetesホスティングサービスをお探しの場合は、成長のために構築されたシンプルでマネージドされたKubernetesサービスをご覧ください。
このガイドでは、Kubernetesとは何か、Kubernetesの基本的な概念について説明します。システムのアーキテクチャ、解決する問題、およびコンテナ化された展開とスケーリングを処理するために使用するモデルについて説明します。
Kubernetesとは?
Kubernetesは、基本的なレベルでは、クラスター内のマシンでコンテナ化されたアプリケーションを実行し、調整するためのシステムです。これは、予測可能性、スケーラビリティ、高可用性を提供する方法を使用して、コンテナ化されたアプリケーションとサービスのライフサイクルを完全に管理するためのプラットフォームです。
Kubernetesのユーザーとして、アプリケーションの実行方法や他のアプリケーションや外部世界とのやり取り方法を定義できます。サービスをスケーリングアップまたはダウンし、優雅なローリングアップデートを実行し、アプリケーションの異なるバージョン間でトラフィックを切り替えて機能をテストしたり、問題のある展開をロールバックしたりできます。Kubernetesは、高い柔軟性、パワー、信頼性でアプリケーションを定義および管理できるようにするインターフェースと組み合わせ可能なプラットフォームのプリミティブを提供します。
Kubernetesアーキテクチャ
これらの機能を提供する方法を理解するには、Kubernetesが高いレベルでどのように設計および組織化されているかを把握するのが役立ちます。Kubernetesは、各上位レイヤーが下位レベルで見られる複雑さを抽象化するように構築されたシステムとして視覚化できます。
基本的に、Kubernetesは個々の物理的または仮想マシンを共有ネットワークを使用してクラスターにまとめ、再び物理的または仮想マシンであるかどうかに関係なく、各サーバー間で通信します。このKubernetesクラスターは、すべてのKubernetesコンポーネント、機能、およびワークロードが構成される物理プラットフォームです。
Kubernetesクラスタ内のマシンは、それぞれKubernetesエコシステム内で役割が与えられます。1台のサーバー(または高可用性展開の場合は小規模なグループ)がマスターサーバーとして機能します。このサーバーは、ユーザーやクライアントに対してKubernetes APIを公開し、他のサーバーのヘルスチェックを行い、作業を適切に分割して割り当てる方法を決定(「スケジューリング」と呼ばれる)し、他のコンポーネント間の通信を調整(コンテナオーケストレーションとしても言及されることがあります)。マスターサーバーは、クラスタとの主要な接点として機能し、Kubernetesが提供するほとんどの集中ロジックに責任を負います。
クラスタ内の他のマシンは、ノードとして指定されます:ローカルおよび外部リソースを使用してワークロードを受け入れて実行するサーバー。隔離、管理、柔軟性をサポートするために、Kubernetesはアプリケーションとサービスをコンテナで実行しますので、各ノードにはコンテナランタイム(Dockerやrktなど)を搭載する必要があります。ノードはマスターサーバーから作業指示を受け取り、適切にトラフィックをルーティングおよび転送するためにネットワークルールを調整しながら、コンテナを作成または破棄します。
上記のように、アプリケーションとサービス自体はコンテナ内のクラスタで実行されます。基盤となるコンポーネントは、アプリケーションの望ましい状態がクラスタの実際の状態と一致するようにします。ユーザーは、メインのKubernetes APIサーバーと直接またはクライアントやライブラリを介して通信することでクラスタとやり取りします。アプリケーションやサービスを起動するには、JSONまたはYAMLで定義された宣言的な計画が提出されます。この計画では、何を作成するか、どのように管理するかが定義されています。その後、マスターサーバーは計画を受け取り、要件やシステムの現在の状態を調査して、インフラ上で実行する方法を検討します。指定された計画に従って実行されるユーザー定義のアプリケーションのグループは、Kubernetesの最終層を表します。
マスターサーバーコンポーネント
前述のように、マスターサーバーはKubernetesクラスタの主要なコントロールプレーンとして機能します。管理者やユーザーとの主要な接点となり、比較的複雑でないワーカーノード向けにクラスタ全体のシステムを提供します。全体として、マスターサーバー上のコンポーネントは、ユーザーのリクエストを受け入れ、ワークロードコンテナをスケジュールする最適な方法を決定し、クライアントとノードを認証し、クラスタ全体のネットワークを調整し、スケーリングとヘルスチェックの責任を管理します。
これらのコンポーネントは、単一のマシンにインストールするか、複数のサーバーに分散して配置することができます。このセクションでは、Kubernetesクラスターのマスターサーバーに関連する各個々のコンポーネントを見ていきます。
etcd
Kubernetesが機能するために必要な基本的なコンポーネントの1つは、グローバルに利用可能な構成ストアです。CoreOS(オペレーティングシステム)チームによって開発されたetcdプロジェクトは、軽量で分散型のキーバリューストアであり、複数のノードに跨るように構成することができます。
Kubernetesはetcd
を使用して、クラスター内の各ノードがアクセスできる構成データを保存します。これはサービスの検出に使用でき、コンポーネントが最新の情報に従って自身を構成または再構成するのに役立ちます。また、リーダー選出や分散ロックなどの機能によって、クラスターの状態を維持します。シンプルなHTTP/JSON APIを提供することで、値の設定や取得のインターフェースが非常に直感的です。
制御プレーンのほとんどの他のコンポーネントと同様に、etcd
は単一のマスターサーバーに設定するか、本番環境では複数のマシンに分散して配置することができます。唯一の要件は、それがKubernetesマシンの各々からネットワークアクセス可能であることです。
kube-apiserver
最も重要なマスターサービスの1つはAPIサーバーです。これは、ユーザーがKubernetesのワークロードや組織単位を構成できるようにするための主要な管理ポイントです。また、デプロイされたコンテナのetcdストアとサービスの詳細が一致していることを確認する責任もあります。さまざまなコンポーネント間のブリッジとして機能し、クラスタの健全性を維持し、情報やコマンドを伝達します。
APIサーバーはRESTfulインターフェースを実装しており、さまざまなツールやライブラリが簡単に通信できます。ローカルコンピューターからKubernetesクラスターとやり取りするデフォルトの方法として、kubectlというクライアントが利用可能です。
kube-controller-manager
コントローラーマネージャーは、多くの責任を持つ一般的なサービスです。主に、クラスターの状態を管理し、ワークロードのライフサイクルを管理し、定期的なタスクを実行するさまざまなコントローラーを管理します。たとえば、レプリケーションコントローラーは、ポッドに定義されたレプリカ(同一のコピー)の数がクラスターに現在展開されている数と一致することを保証します。これらの操作の詳細はetcdに書き込まれ、コントローラーマネージャーはAPIサーバーを介して変更を監視します。
変更が見られると、コントローラーは新しい情報を読み取り、望ましい状態を満たす手順を実行します。これには、アプリケーションのスケーリングアップやダウン、エンドポイントの調整などが含まれる場合があります。
kube-scheduler
クラスター内の特定のノードにワークロードを割り当てる実際のプロセスは、スケジューラーです。このサービスは、ワークロードの動作要件を読み込み、現在のインフラ環境を分析し、作業を受け入れ可能なノードまたはノードに配置します。
スケジューラーは、各ホストの利用可能な容量を追跡し、利用可能なリソースの範囲内でワークロードがスケジュールされないようにします。スケジューラーは、各サーバー上の既存のワークロードに割り当てられたリソースと合わせて、合計容量を把握する必要があります。
cloud-controller-manager
Kubernetesはさまざまな環境で展開でき、クラスター内のリソースの状態を理解し管理するためにさまざまなインフラストラクチャプロバイダとやり取りできます。Kubernetesはアタッチ可能なストレージやロードバランサなどのリソースの一般的な表現と連携しますが、非均質なクラウドプロバイダによって提供される実際のリソースとこれらをマッピングする方法が必要です。
クラウドコントローラーマネージャーは、異なる機能、特徴、およびAPIを持つプロバイダーとのやり取りを可能にする接着剤として機能し、内部的に比較的一般的な構築を維持します。これにより、Kubernetesはクラウドプロバイダーから収集した情報に基づいて状態情報を更新し、システムで必要な変更に応じてクラウドリソースを調整し、クラスターに提出された作業要件を満たすための追加のクラウドサービスを作成して利用できます。
ノードサーバーコンポーネント
Kubernetesでは、コンテナを実行して作業を行うサーバーをノードと呼びます。ノードサーバーには、マスターコンポーネントとの通信、コンテナネットワークの構成、および割り当てられた実際のワークロードを実行するために必要ないくつかの要件があります。
A Container Runtime
各ノードに必要な最初のコンポーネントは、コンテナランタイムです。通常、この要件はDockerをインストールして実行することで満たされますが、rktやruncなどの代替品も利用可能です。
コンテナランタイムは、比較的に隔離された軽量なオペレーティング環境にカプセル化されたアプリケーション、つまりコンテナを開始および管理する責任があります。クラスタ上の各作業ユニットは、基本レベルでは1つ以上のコンテナとして実装され、展開される必要があります。各ノード上のコンテナランタイムは、クラスタに提出されたワークロードで定義されたコンテナを最終的に実行するコンポーネントです。
kubelet
クラスタグループとの各ノードの主な接点は、kubeletと呼ばれる小さなサービスです。このサービスは、コントロールプレーンサービスとの間で情報を中継し、etcd
ストアとやり取りして構成の詳細を読み取ったり新しい値を書き込んだりする責任があります。
kubelet
サービスは、クラスタに認証し、コマンドや作業を受け取るためにマスターコンポーネントと通信します。作業は、ワークロードと操作パラメータを定義するマニフェストの形で受け取ります。その後、kubelet
プロセスは、ノードサーバー上の作業の状態を維持する責任を負います。必要に応じてコンテナランタイムを制御してコンテナを起動または破棄します。
kube-proxy
個々のホストのサブネット化を管理し、他のコンポーネントにサービスを利用可能にするために、kube-proxyという小さなプロキシサービスが各ノードサーバーで実行されます。このプロセスはリクエストを適切なコンテナに転送し、プリミティブなロードバランシングを行い、ネットワーキング環境が予測可能でアクセス可能になるように責任を持ちますが、適切な場所では隔離されます。
Kubernetesオブジェクトとワークロード
コンテナはコンテナ化されたアプリケーションを展開するために使用される基本的なメカニズムですが、Kubernetesはコンテナインターフェイスの上に追加の抽象化レイヤーを使用してスケーリング、耐障害性、およびライフサイクル管理機能を提供します。ユーザーは、コンテナを直接管理する代わりに、Kubernetesオブジェクトモデルによって提供されるさまざまなプリミティブで構成されるインスタンスを定義し、それらと対話します。以下では、これらのワークロードを定義するために使用できるさまざまなタイプのオブジェクトについて説明します。
ポッド
A pod is the most basic unit that Kubernetes deals with. Containers themselves are not assigned to hosts. Instead, one or more tightly coupled containers are encapsulated in an object called a pod.
A pod generally represents containers that should be controlled as a single application. Pods consist of containers that operate closely together, share a life cycle, and should always be scheduled on the same node. They are managed entirely as a unit and share their environment, volumes, and IP space. In spite of their containerized implementation, you should generally think of pods as a single, monolithic application to best conceptualize how the cluster will manage the pod’s resources and scheduling.
通常、ポッドは、ワークロードの一般的な目的を満たすメインコンテナと、オプションで、密接に関連するタスクを容易にするいくつかのヘルパーコンテナで構成されます。これらは、独自のコンテナで実行および管理されることから利益を得るプログラムですが、メインアプリケーションに密接に結びついています。たとえば、ポッドには、主要なアプリケーションサーバーを実行する1つのコンテナと、外部リポジトリで変更が検出されたときに共有ファイルシステムにファイルをダウンロードするヘルパーコンテナがある場合があります。通常、ポッドレベルでの水平スケーリングは推奨されません。なぜなら、そのようなタスクにはより適した上位レベルのオブジェクトがあるからです。
一般的に、ユーザーはポッドを自分で管理すべきではありません。なぜなら、アプリケーションに通常必要ないくつかの機能(複雑なライフサイクル管理やスケーリングなど)を提供しないからです。代わりに、ユーザーは、ポッドやポッドテンプレートをベースコンポーネントとして使用するが、追加の機能を実装した上位レベルのオブジェクトと協力することが推奨されています。
レプリケーションコントローラとレプリケーションセット
しばしば、Kubernetesを使用する際には、単一のポッドではなく、同一の複製されたポッドのグループを管理します。これらはポッドテンプレートから作成され、レプリケーションコントローラやレプリケーションセットと呼ばれるコントローラによって水平にスケーリングできます。
A replication controller is an object that defines a pod template and control parameters to scale identical replicas of a pod horizontally by increasing or decreasing the number of running copies. This is an easy way to distribute load and increase availability natively within Kubernetes. The replication controller knows how to create new pods as needed because a template that closely resembles a pod definition is embedded within the replication controller configuration.
レプリケーションコントローラーは、クラスターに展開されたポッドの数がその構成内のポッドの数と一致するようにする責任があります。ポッドまたは基礎となるホストが失敗した場合、コントローラーは新しいポッドを起動して補償します。コントローラーの構成内のレプリカの数が変更されると、コントローラーは希望する数に合わせてコンテナを起動または終了します。レプリケーションコントローラーは、アプリケーションの可用性に対する影響を最小限に抑えながら、一連のポッドを新しいバージョンに一つずつ切り替えるローリング更新も実行できます。
レプリケーションセットは、コントローラーが管理するポッドを識別する方法においてより柔軟性のあるレプリケーションコントローラーデザインの繰り返しです。レプリケーションセットは、レプリケーションコントローラーのようにバックエンドを新しいバージョンにサイクルさせるローリング更新を行うことはできませんが、より多くのレプリカ選択機能を備えているため、レプリケーションコントローラーを置き換えることが始まっています。代わりに、レプリケーションセットは、その機能を提供する追加の上位ユニットの内部で使用することを意図しています。
ポッドと同様に、レプリケーションコントローラーとレプリケーションセットの両方とも、直接操作するユニットではありません。水平スケーリングと信頼性の保証を追加するためにポッドデザインを基にして構築されていますが、より複雑なオブジェクトに見られる細かいライフサイクル管理機能には欠けています。
展開
展開は、直接作成および管理される最も一般的なワークロードの1つです。 展開は複製セットをビルディングブロックとして使用し、柔軟なライフサイクル管理機能を追加します。
複製セットで構築された展開は、複製コントローラーが提供する機能を複製しているように見えるかもしれませんが、展開はローリングアップデートの実装に存在した多くの問題を解決します。 複製コントローラーを使用してアプリケーションを更新する場合、ユーザーは現在のコントローラーを置換する新しい複製コントローラーの計画を提出する必要があります。 複製コントローラーを使用すると、履歴の追跡、アップデート中のネットワーク障害からの回復、および悪い変更のロールバックなどのタスクは、難しいか、またはユーザーの責任として残されています。
展開は、複製されたポッドのライフサイクル管理を容易にする高レベルのオブジェクトです。 展開は、構成を変更するだけで簡単に変更でき、Kubernetesは複製セットを調整し、異なるアプリケーションバージョン間の遷移を管理し、必要に応じてイベント履歴と元に戻す機能を自動的に維持します。 これらの機能のため、展開はおそらく最も頻繁に作業するKubernetesオブジェクトのタイプになるでしょう。
Stateful Sets
Stateful setsは、順序付けと一意性の保証を提供する特殊なポッドコントローラーです。主に、展開の順序、永続的なデータ、または安定したネットワーキングに関連する特別な要件がある場合に、より細かい制御を持つために使用されます。たとえば、stateful setsは、データ志向のアプリケーション(データベースなど)に関連付けられることがよくあります。これらのアプリケーションは、新しいノードに再スケジュールされても同じボリュームにアクセスする必要があります。
Stateful setsは、各ポッドに対して一意の数値ベースの名前を作成することで、安定したネットワーキング識別子を提供します。この名前は、ポッドが別のノードに移動する必要がある場合でも永続化されます。同様に、再スケジュールが必要な場合には、永続ストレージボリュームをポッドと共に転送できます。ボリュームは、ポッドが削除された後も永続化され、意図しないデータ損失を防ぎます。
展開やスケールの調整時には、stateful setsは名前の番号識別子に従って操作を実行します。これにより、実行の順序に対する予測可能性と制御が向上し、一部のケースで役立ちます。
デーモンセット
デーモンセットは、クラスタ内の各ノード(または指定された場合はそのサブセット)でポッドのコピーを実行するもう一つの特殊な形式のポッドコントローラーです。これは、Kubernetesノード自体のメンテナンスを支援し、サービスを提供するポッドを展開する際に最もよく使用されます。
例えば、ログの収集と転送、メトリクスの集約、およびノード自体の機能を拡張するサービスの実行は、デーモンセットの人気のある候補です。デーモンセットはしばしば基本的なサービスを提供し、フリート全体で必要とされるため、他のコントローラーが特定のホストにポッドを割り当てるのを防ぐポッドスケジューリングの制限をバイパスできます。例えば、ノードの役割がユニークであるため、マスターサーバーは通常のポッドスケジューリングで利用できないように設定されていますが、デーモンセットはポッドごとに制限をオーバーライドして必要なサービスが実行されていることを確認できます。
ジョブとクーロンジョブ
これまでに説明したワークロードはすべて、長期間実行されるサービスのようなライフサイクルを想定しています。 Kubernetesは、実行中のコンテナが作業を完了した後に成功裏に終了することが期待される、よりタスクベースのワークフローを提供するジョブというワークロードを使用します。ジョブは、継続的なサービスの実行ではなく、一回限りの処理やバッチ処理を実行する必要がある場合に便利です。
ジョブの構築はcron jobsに基づいています。LinuxやUnix-likeシステムの従来のcron
デーモンがスケジュールに応じてスクリプトを実行するのと同様に、Kubernetesのcron jobsはスケジューリングコンポーネントを備えたジョブを実行するためのインターフェースを提供します。Cron jobsは、将来の実行または定期的な繰り返しの基盤としてジョブをスケジュールするために使用できます。Kubernetesのcron jobsは、単一のオペレーティングシステムではなくクラスタをプラットフォームとして使用する古典的なcronの動作の再実装です。
その他のKubernetesコンポーネント
クラスタで実行できるワークロードを超えて、Kubernetesはアプリケーションの管理、ネットワーキングの制御、および永続性の有効化を支援するいくつかの他の抽象化を提供しています。ここでは、より一般的な例についていくつか説明します。
Kubernetesサービス
これまで、我々は「サービス」という用語を従来のUnixのような意味で使用してきました:長期間実行され、しばしばネットワークに接続され、リクエストに応答できるプロセスを示すために。しかし、Kubernetesでは、serviceはポッドのための基本的な内部ロードバランサーおよびアンバサダーとして機能するコンポーネントです。サービスは、同じ機能を実行する論理的なポッドの集合をグループ化して、それらを単一のエンティティとして表示します。
これにより、特定のタイプのすべてのバックエンドコンテナを追跡およびルーティングできるサービスをデプロイできます。内部の利用者は、サービスが提供する安定したエンドポイントについてのみ知る必要があります。一方、サービスの抽象化により、必要に応じてバックエンドのワークユニットをスケーリングアウトまたは置換できます。サービスのIPアドレスは、そのポッドへの変更に関係なく安定しています。サービスをデプロイすることで、簡単に発見性を得ることができ、コンテナの設計を簡素化できます。
他のアプリケーションまたは外部の消費者に1つ以上のポッドへのアクセスを提供する必要がある場合は、いつでもサービスを構成する必要があります。たとえば、インターネットからアクセスできる必要がある一連のWebサーバーを実行しているポッドがある場合、サービスが必要な抽象化を提供します。同様に、Webサーバーがデータの格納と取得を行う必要がある場合は、内部サービスを構成してデータベースポッドへのアクセスを提供したいと考えるでしょう。
デフォルトでは、サービスは内部のルーティング可能なIPアドレスを使用してのみ利用可能ですが、いくつかの戦略のうちの1つを選択することで、クラスターの外部で利用可能にすることができます。 NodePort構成は、各ノードの外部ネットワーキングインターフェイスに静的ポートを開くことによって機能します。外部ポートへのトラフィックは、内部クラスターIPサービスを使用して適切なポッドに自動的にルーティングされます。
また、LoadBalancerサービスタイプは、クラウドプロバイダのKubernetesロードバランサー統合を使用してサービスにルーティングする外部ロードバランサーを作成します。クラウドコントローラーマネージャーは、内部サービスアドレスを使用して適切なリソースを作成し、構成します。
ボリュームと永続的ボリューム
コンテナ化された環境では、データを信頼性を持って共有し、コンテナの再起動間もデータの可用性を保証することは多くの場合課題です。コンテナランタイムは、通常、コンテナのライフサイクルを超えて持続するストレージをコンテナにアタッチするためのメカニズムを提供しますが、実装は通常、柔軟性に欠けています。
これを解決するために、Kubernetes は独自のボリューム抽象化を使用し、ポッド内のすべてのコンテナでデータを共有し、ポッドが終了するまでデータを利用できるようにします。これにより、密に結合されたポッドは、複雑な外部メカニズムなしでファイルを簡単に共有できます。ポッド内のコンテナの障害は共有ファイルへのアクセスに影響しません。ポッドが終了すると、共有ボリュームが破棄されるため、本当に永続的なデータのための良い解決策ではありません。
永続ボリュームは、ポッドのライフサイクルに結びついていない、より堅牢なストレージを抽象化するメカニズムです。代わりに、管理者は、ユーザーが実行しているポッドに対して要求してクレームできるストレージリソースをクラスターに構成することができます。ポッドが永続ボリュームを使用し終わると、ボリュームの再利用ポリシーによって、ボリュームが手動で削除されるか、データと一緒に直ちに削除されるかが決まります。永続的データは、ノードベースの障害に対処し、ローカルで利用可能なストレージよりも大きな量のストレージを割り当てるために使用できます。
ラベルと注釈
A Kubernetes organizational abstraction related to, but outside of the other concepts, is labeling. A label in Kubernetes is a semantic tag that can be attached to Kubernetes objects to mark them as a part of a group. These can then be selected for when targeting different instances for management or routing. For instance, each of the controller-based objects use labels to identify the pods that they should operate on. Services use labels to understand the backend pods they should route requests to.
ラベルは単純なキーと値のペアとして与えられます。各ユニットには複数のラベルが付けられる場合がありますが、各ユニットには各キーに対して1つのエントリしか持てません。通常、一般的な目的の識別子として “name” キーが使用されますが、開発段階、公開可能性、アプリケーションバージョンなどの他の基準でオブジェクトを分類することもできます。
注釈は、オブジェクトに任意のキーと値の情報を添付するための類似のメカニズムです。ラベルはポッドを選択基準と一致させるのに役立つ意味情報に使用されるべきですが、注釈はより自由形式で、構造化されていないデータを含むことができます。一般的に、注釈は選択目的には役立たないオブジェクトに豊富なメタデータを追加する方法です。
結論
Kubernetesは、ユーザーが高度に抽象化されたプラットフォーム上でスケーラブルで高可用性なコンテナ化されたワークロードを実行できるようにするエキサイティングなプロジェクトです。Kubernetesのアーキテクチャと内部コンポーネントのセットは最初は daunting に見えるかもしれませんが、そのパワー、柔軟性、堅牢な機能セットはオープンソースの世界やクラウドネイティブ開発において類を見ないものです。基本的なビルディングブロックがどのように組み合わさるかを理解することで、プラットフォームの機能を十分に活用してワークロードをスケールできるシステムを設計し、驚くべきクラウドネイティブアプリケーションを構築することができます。
Source:
https://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes