Kubernetes 対 Docker – その違いとは?
ハードウェア仮想化は、ハイパーバイザーを用いて物理ハードウェアを仮想マシン(VM)と共有することで、スケーラビリティ、セキュリティ、分離性などの利点をもたらします。現在、仮想化の形態は仮想マシンだけにとどまらず、コンテナも広く普及しています。仮想マシンが基盤となるマシンの物理ハードウェアを共有するのに対し、コンテナは基盤となるオペレーティングシステムのカーネルを共有します。 コンテナは軽量な仮想マシンではなく、マイクロサービスベースのソフトウェアアーキテクチャを用いて開発されたアプリケーションを含め、アプリケーションを配信するために使用される標準化された実行可能パッケージであり、アプリケーションの実行に必要なすべてのコンポーネントを含んでいます。
Dockerエンジンは、コンテナを実行するための最も一般的なプラットフォームです。Kubernetesは、コンテナ化やクラウドコンピューティングの分野で、ますます頻繁に耳にするようになった用語です。しかし、DockerとKubernetesのどちらが優れているのでしょうか?これはよく議論されるテーマですが、このように問うことは技術的には正しくありません。例えば、"ホットとブルー、どちらが優れているか?"と問うことはできないのと同じです。
Dockerとは?
Dockerは、コンテナ化されたアプリケーションを実行するためのエンジンとして機能するオープンソースのスタンドアロンアプリケーションです。これはオペレーティングシステム(OS)上にインストールされ、できれば Linuxですが、Windows にもインストール可能です。 macOS、そしてそれは物理マシンまたは仮想マシン上で動作します。
コンテナ内で実行されるアプリケーションは、システムの他の部分や他のコンテナから隔離されていますが、あたかも独自のOSインスタンス上で実行されているかのような環境を提供します。 単一のオペレーティングシステム上で複数のDockerコンテナを同時に実行できます。これらのコンテナはDockerで管理でき、DockerはKubernetesなしでも動作します。コンテナを実行するためのホストが複数ある場合、手動での管理は困難になるため、一般的に集中管理ツールやオーケストレーションソリューションを選択する方が望ましいです。

Docker Compose は、複数のコンテナから構成される Docker アプリケーションを実行するために使用される基本的なコンテナオーケストレーションツールです。 コンテナごとに個別の Dockerfile を手動で設定する代わりに、1 つの YAML (yml) 形式の Docker Compose 設定ファイルを作成して、マルチコンテナアプリケーションを定義することができます。この単一の YAML ファイルを設定すれば、Linux コンソールで 1 つのコマンドを実行するだけで、必要なすべてのコンテナを起動できます。Docker Compose を使用することは Docker コンテナをオーケストレーションする 1 つの方法ですが、Docker Compose に代わる強力な選択肢として、Kubernetes があります。
Kubernetesとは何ですか?
Kubernetesは、コンテナ化されたソフトウェアやサービスを高度に自動化して管理するために使用されるオープンソースのコンテナオーケストレーションソリューションです。
Kubernetesは、コンテナ内で実行されるアプリケーションのデプロイ、スケーリング、可用性を自動化することを目的としたGoogleのプロジェクトです。コンテナを実行するホストの数を最大11台以上に増やすことができます。さらに、高可用性と負荷分散を確保するために、Kubernetesを使用してDockerコンテナのクラスターを作成することも可能です。
クラスターで使用されるホストはノードと呼ばれます。Kubernetesのアーキテクチャはマスター・スレーブ型であり、クラスターはマスターノードとワーキングノードで構成されます。Kubernetesに必要なノードの推奨最小数は4つです。1台のマシンでクラスターを構築することも可能ですが、すべての例やテストを実行するには、少なくとも4つのノードが必要です。 本番環境のトラフィックを処理するKubernetesクラスタには、少なくとも3つのワーキングノードが必要です。マスターノードを2台使用することで、1台のマスターノードが障害を起こした場合でもクラスタを保護できます。必要に応じて、2台以上のマスターノードを使用することも可能です。
Master nodesこれらは、クライアントからのリクエストの受け付け、コンテナによる操作のスケジューリング、制御ループの実行など、クラスタの状態を管理するために使用されます。のコピーは、 etcd データベース クラスタのすべてのデータを格納するこのプロセスは、各マスターノード上で実行する必要があります。マスターノードでは、以下の3つのプロセスが実行されます: kube-apiserver, kube-controller-manager そして kube-scheduler.Working nodesは、コンテナを実行してアプリケーションのワークロードを実行するために使用されます。以下の2つのKubernetesプロセスは、マスターノード以外のノード上で実行されます: kubelet (マスターノードとの通信用)および kube-proxy (各ノード上のKubernetesネットワークサービスを反映するため)。Replication Controllerこれは、指定された数のPodレプリカが、いつでも常に稼働している状態を維持するために使用されるコンポーネントです。これにより、必要な時にいつでもPodを利用できる状態を確保できます。
Kubernetesを使用する場合、サービス間の通信にはさまざまなCLIやAPIが利用されます。また、Kubernetesで構築されたクラスターを構成するRESTful APIのオブジェクトやリソースを命名する際には、特定の用語が用いられます。Podは、Kubernetesにおける基本的なスケジューリング単位です。これは、複数のコンテナが動作できるリソースのグループです。1つのPodに属するコンテナは、同じホスト上で実行され、同じリソースや同じローカルネットワークを使用します。Pod内のコンテナは相互に隔離されていますが、非常に容易に通信を行うことができます。したがって、Kubernetesでは一般的にPodが使用されますが、スタンドアロンのDockerアプリケーションを使用する場合は、コンテナプールしか利用できません。Serviceこれは、例えば多層アプリケーションの機能を実現するために連携して動作するコンテナの集合体です。Kubernetesは、抽象化を活用することで、Podの動的な命名とロードバランシングをサポートしています。このアプローチにより、名前によるサービス間の透過的な接続が保証され、各サービスの現在の状態を追跡することが可能になります。Labelsこれらは、Podやその他のオブジェクト、サービスに紐付けられたキー/値のペアであり、それらを簡単にグループ化したり、タスクを割り当てたりすることも可能です。Namespacesこれは、統合されたKubernetesクラスターを複数の仮想クラスターに論理的に分割できる手法です。各仮想クラスターは、クォータによって制限された仮想環境内で動作し、他の仮想クラスターに影響を与えることはありません。
KubernetesはDockerと併用できますが、Kubernetesが利用できるコンテナプラットフォームはDockerだけではありません。Kubernetesは、Windowsコンテナ、Linuxコンテナ、rktなどとも連携して動作します。なお、技術文書などで"K8s"という略称が使われることもあります。
Kubernetes 対 Docker:ネットワーク機能の比較
各ソリューションのネットワーク設定について確認してみましょう。
Docker コンテナ間のネットワーク通信のために、3つのネットワークモードを提供します。
Bridge. このモードはデフォルトで使用され、仮想レイヤ3ブリッジが作成されます。ホスト上のネットワーク名は docker0 このネットワークに対して。Dockerは、ネットワークアドレス変換(NAT)の原理を用いて、レイヤー3ネットワークブリッジを自動的に作成し、外部ネットワークインターフェースのマスカレードルールを設定します。これにより、コンテナ同士の通信や外部ネットワークへの接続が可能になります。 他のホストや外部ネットワークからコンテナに接続したい場合は、ホストマシンのネットワークインターフェースに対してポートフォワーディングを設定できます。これにより、ホストマシンの適切なポートに接続することで、Dockerコンテナの必要なポートに転送されます。必要に応じて、1つのDockerコンテナに対して複数のネットワークインターフェースを作成することも可能です。
Hostこのモードでは、ホストネットワークドライバによって、コンテナがDockerホストから切り離されないようにします。コンテナはホストのネットワークスタックを共有し、コンテナのホスト名はホストOSのホスト名と同じになります。TCPポート8080をリスニングするコンテナを実行した場合、そのコンテナアプリケーションはホストマシンのIPアドレスのTCPポート8080で利用可能になります。 ホストネットワークドライバは、Linuxマシンでのみ利用可能です。
None. 特定のコンテナのネットワークインターフェースには、ループバックインターフェース用の 127.0.0.1 アドレスを除き、IP アドレスは設定されていません。もし なし ネットワークモードが設定されています。

Multi-host networking for Docker containers. コンテナが異なるホスト上で実行されている場合、オーバーレイネットワークを設定すれば、コンテナ同士で通信できるようになります。有効なキーバリューストアサービス(領事, など、または ZooKeeper) はそのようなネットワークを作成するために設定する必要があります。
Kubernetes. スタンドアロンのDockerコンテナを使用する場合、各コンテナは、適切なネットワークインターフェースを使用してネットワーク経由で通信する基本単位と見なすことができます。Kubernetesを使用している場合、Podがコンテナクラスタの基本単位となります。各Podには独自のIPアドレスが割り当てられ、少なくとも1つのコンテナで構成されます。Podは、関連するタスクに使用される複数のコンテナで構成されることもあります。 同じPod内のコンテナは、同時に同じポートを開くことはできません。この種の制限が設けられているのは、複数のコンテナで構成されるPodであっても、IPアドレスは1つしか持たないためです。
さらに、Kubernetesは特別な コンテナを一時停止 各Podに対して。この特別なコンテナは、他のコンテナに対して(内部および外部通信用の)ネットワークインターフェースを提供することを目的としており、通常は一時停止状態(スリープモード)にあります。これらの一時停止コンテナは、Kubernetesが"SIGTERM"シグナルを送信すると起動します。

Flannel は通常、ネットワークオーバーレイの原理を用いて、Kubernetes内のコンテナを接続するためのネットワークファブリックとして使用されます。オーバーレイネットワークにより、クラスタ内の異なる物理ホスト(ノードと呼ばれる)間で論理ネットワークを介して通信を行い、コンテナを実行することが可能になります。オープンソースのキーバリューストアであるetcdは、コンテナが実行されているホストによってコンテナに割り当てられた実際のIPアドレスと、オーバーレイネットワーク内のIPアドレスとの対応関係を保存するために使用されます。

NSX Container Plugin を使用することで、Kubernetes のネットワーク機能を VMware NSX-T と統合できます。この統合により、Kubernetes の標準機能では利用できないマルチテナントのネットワークトポロジーを利用できるようになります。
Kubernetes のネットワークモデルには、以下の機能があります:
- すべてのコンテナは、NATを経由することなく、クラスタ内の他のコンテナと通信できます。
- すべてのクラスタノードは、NATを経由することなく、クラスタ内のすべてのコンテナと通信できます。逆に、すべてのコンテナも、すべてのクラスタノードと通信できます。
- コンテナは自身のIPアドレスを認識しており、そのIPアドレスはKubernetesの他のコンポーネントからも認識されます。
Ingress は、クラスタ内のサービスへの外部からのアクセス(主にHTTPおよびHTTPS)を管理するために使用されるKubernetesのAPIオブジェクトです。Ingressを設定することで、コンテナ化されたサービスへの外部アクセス、ロードバランシング、SSL終端、および名前ベースの仮想ホスティングを実現できます。Ingressルールが機能するためには、マスターノードにIngressコントローラーをデプロイする必要があります。

ユースケース
Dockerをスタンドアロンソフトウェアとして使用すると、開発者はアプリケーションを隔離された環境で実行できるため、アプリケーション開発に適しています。 さらに、テスターもDockerを使用して、サンドボックス環境でアプリケーションを実行できます。本番環境で多数のコンテナを実行するためにDockerを使用する場合、いくつかの問題に直面する可能性があります。例えば、一部のコンテナは簡単に過負荷になったり、障害が発生したりすることがあります。該当するマシン上でコンテナを手動で再起動することは可能ですが、手動での管理には貴重な時間と労力が多くかかってしまいます。
Kubernetesは、高可用性、ロードバランシング、コンテナオーケストレーションツールなどの主要な機能を提供することで、これらの問題を解決します。その結果、Kubernetesは、多数のDockerコンテナが存在する高負荷な本番環境に最も適しています。Kubernetesのデプロイは、スタンドアロンのDockerアプリケーションをインストールするよりも難しいため、開発やテストには必ずしもKubernetesが使用されるとは限りません。
Kubernetes 対 Docker Swarm
Docker Swarm Docker Swarmは、Dockerホストのグループを単一の仮想ホストとして機能させる、Docker専用のクラスタリングツールです。Docker SwarmはDocker Engineと完全に統合されており、標準のAPIやネットワーク処理を利用できます。これは、Dockerコンテナのデプロイ、管理、スケーリングを目的としています。
Swarmは、"ノード"と呼ばれるDockerホストのクラスタです。 KubernetesとDocker Swarmのクラスタ展開を比較する前に、Docker Swarmを使用する際のクラスタの主な構成要素について検討してみましょう。
Manager nodes これらは、制御のオーケストレーション、クラスタ管理、およびタスクの割り当てを行うために使用されます。
Worker nodes は、マネージャーノードからタスクを割り当てられたコンテナを実行するために使用されます。各ノードは、マネージャーノード、ワーカーノード、あるいはその両方の機能を果たすように設定できます。なお、ワーカーノードはSwarmサービスを実行することに注意してください。
Services. Docker Swarm のサービスは、コンテナ化された各サービスに必要な最適状態を定義します。サービスは、レプリカの数、利用可能なネットワークリソース、外部ネットワークからアクセス可能にする必要があるポートなどのパラメータを制御します。ネットワーク設定などのサービス設定は、コンテナを含むサービスを手動で再起動することなく、変更してコンテナに適用することができます。
Tasksタスクとは、単一のコンテナが実行されているスロットのことです。タスクは、Swarmサービスの構成要素です。

つまり、Docker SwarmとKubernetesは、同様の目的で使用される2つの異なるプラットフォームです。それでは、適切な分類に基づいてこれらを比較してみましょう。
クラスタ展開
Docker Swarm. 標準のDocker APIを利用すれば、標準のDocker CLI(コマンドラインインターフェース)を使用してSwarmクラスタをデプロイできます。これにより、特に初めて利用する場合でも、デプロイが容易になります。Kubernetesと比較してSwarmのデプロイが容易である理由は、単一のDockerマスターがサービスの配置方法を決定できる点にもあります。Docker SwarmではPodは使用されません。
Kubernetes 標準のDockerコマンドとは異なる、指定されたコマンドを使用する必要があります。Kubernetesでは特定のAPIが使用されるため、Docker管理用のコマンドを知っていても、Kubernetesのデプロイには別途ツールの使い方を学ぶ必要がある場合があります。Kubernetesクラスタ内ではノードを手動で定義する必要があります。具体的には、マスターノードの選択や、コントローラー、スケジューラーなどの定義を行う必要があります。
拡張性
Docker Swarm. Dockerが提供するシンプルなAPIのおかげで、大小さまざまなクラスターにおけるコンテナのデプロイやサービスの更新をより迅速に行うことができます。コマンドラインインターフェース(CLI)は非常にシンプルで理解しやすいものです。その結果、SwarmはKubernetesと比較して、よりスケーラブルなソリューションであると言えます。
Kubernetes 比較的統一されたAPIを提供する一方で、デプロイプロセスを遅延させがちな機能も数多く備えています。設定が必要なコンポーネントには、Pod、Deploy、Serviceの3種類があります。オートスケーリングに関しては、Kubernetesはサーバーの負荷を分析できるだけでなく、指定された要件に応じて自動的にスケールアップ・スケールダウンを行うことができるため、推奨されます。Kubernetesは、大規模な分散ネットワークや複雑なシステムにとって最適な選択肢です。
高可用性
これら2つのソリューション案は、いずれも同様のサービス複製および冗長化メカニズムを備えており、いずれの場合もシステムは自律的に調整されるため、障害が発生したノードがクラスタに復帰した後も、手動での再設定は不要です。
Docker Swarm. マネージャーノードは、ワーカーノードおよびクラスター全体のリソースを管理します。Swarmクラスターのノードは、サービスのレプリケーションに関与します。
Kubernetes. Kubernetesのロードバランシング機能により、正常に動作していないノードが検出されると、そのノードはクラスターから除外されます。すべてのPodはノード間で分散配置されるため、コンテナ化されたアプリケーションが実行されているノードに障害が発生した場合でも、高可用性が確保されます。
負荷分散
Docker Swarm. ロードバランシングは組み込み機能であり、内部のSwarmネットワークを利用して自動的に実行できます。クラスターへのすべてのリクエストは分散され、クラスターのノードにリダイレクトされます。どのノードも、どのコンテナにも接続可能です。Docker Swarmでは、DNS機能を利用して、サービス名への着信リクエストを分散しています。
Kubernetes. Podで定義されたポリシーは、Kubernetesにおけるロードバランシングに使用されます。この場合、コンテナPodはサービスとして定義する必要があります。ロードバランシングの設定は手動で行う必要がありますが、Ingressを利用してロードバランシングを行うことも可能です。
コンテナの作成と実行
Docker SwarmDocker Swarmの標準化されたAPIのおかげで、Docker CLIで利用可能なコマンドの大部分は、Docker Swarmを使用する際にも利用できます。Docker Composeでは、どのコンテナをグループ化するかを定義するだけでなく、ボリュームや使用するネットワークに関する設定も行えます。Docker Swarm向けのDocker Composeでは、レプリカの正確な数を設定することができます。
Kubernetes. Kubernetesには独自のAPIとクライアントがあり、設定にはYAMLファイルが必要です。これが大きな違いの一つであり、この場合、Docker ComposeやDocker CLIを使用してコンテナをデプロイすることはできません。 Kubernetesにおけるサービスの定義システムは、Docker Composeと同様の動作原理に従っていますが、より複雑です。Docker Composeの機能は、KubernetesではPod、Deployment、Serviceを使用して実現され、それぞれのレイヤーが特定の目的のために使用されます。 Podはコンテナ間の連携を担当し、Deploymentはクラスタ内の単一ノードに対する高可用性とネットワーク処理を担当します(Swarmを使用しないスタンドアロンのDockerアプリケーションにおけるDocker Composeに似ています)。一方、KubernetesのServiceは、クラスタ内でのサービス運用設定やフォールトトレランスなどを担当します。
ネットワーキング
Docker Swarmクラスター内のコンテナ間の通信用に、デフォルトで1つの内部ネットワークが用意されています。必要に応じて、このネットワークにさらにネットワークを追加することができます。ネットワークは生成されたTLS証明書によって保護されています。コンテナのデータ通信の暗号化には、手動での証明書生成がサポートされています。
Kubernetes. Kubernetesのネットワークモデルは大きく異なり、プラグインを使用して実装されています。その一つが、最も普及しているFlannelです。Podは相互に通信しますが、この通信はポリシーによって制限することができます。 etcdサービスによって管理される内部ネットワークが存在します。TLS暗号化も利用可能ですが、手動で設定する必要があります。Kubernetesのネットワークモデルでは、2つのCIDR(Classless Inter-Domain Routing、スーパーネットとも呼ばれる)を設定することが前提となっています。
監視
Docker Swarm. 監視やロギングのための組み込みツールはありませんが、サードパーティ製の監視ツールを手動で設定することは可能です。この目的には、ELKやReimannを利用できます。
Kubernetes. Kubernetesには、ロギングとモニタリングのための組み込みツールが用意されています。ElasticsearchとKibana(ELK)を使用すればクラスタ全体の状態を監視でき、Heapster、Grafana、Influxはコンテナサービスの監視に対応しています。
グラフィカル・ユーザー・インターフェース(GUI)
Docker Swarm. GUIは、使いやすいWebインターフェースを提供するPortainer.ioなどのサードパーティ製ツールを使用して有効化できます。あるいは、クラスタ管理用のグラフィカルインターフェースを備えたDocker Enterprise Editionを利用することも可能です。
Kubernetes. Kubernetesが提供するGUIは、Webインターフェース経由でアクセスできる信頼性の高いダッシュボードであり、これを使えばクラスターを簡単に管理できます。このGUIは、CLIを使ったKubernetesの管理経験がほとんどないユーザーにとって、非常に有用なツールとなります。
結論
Docker Swarmは、主にDocker APIとCLIを利用するDockerネイティブのソリューションです。一方、Kubernetesは、コンテナが実行されるクラスタを展開するために使用されるGoogleのプロジェクトです。
Docker SwarmとKubernetesはどちらも、高可用性、ロードバランシング、オーバーレイネットワーク、およびスケーラビリティ機能を提供します。 Docker Swarmは、機能設定の大部分が自動化されており、ハードウェアリソースの消費も少ないため、2つのうち展開が容易な方です。ただし、機能はDocker APIによって制限されており、ネイティブな監視ツールは備わっていません。
一方、Kubernetesは高い柔軟性を備えたモジュール式のソリューションであり、長年にわたり多くの大企業で採用されています。 Kubernetesには、サービスおよびクラスター全体の監視のための組み込みツールが用意されていますが、デプロイや設定がより困難であるため、運用にはより多くのリソースを要するソリューションとなります。KubernetesはDocker CLIやDocker Composeとは互換性がありません。高負荷のマルチコンテナアプリケーションが稼働している大規模な環境では、Kubernetesの使用が推奨されます。