基礎から分かるコンテナのネットワーク接続性:Dockerとネットワーク
Dockerでコンテナを作成するのは容易だが、それらがマイクロサービスとして機能するためには、さまざまな要素を考慮したネットワーク接続性が不可欠だ。基本的なところから復習しよう。
企業アプリの開発は、従来型のウオーターフォールモデルからよりアジャイルなアプローチである「DevOps」に変わりつつある。そのDevOpsと密接に関連する重要な技術がコンテナだ。少なくともDockerのコンテナが重要な役割を果たしているのは確かだ。
関連記事
- いまさら聞けないコンテナ&マイクロサービス
- コンテナ/マイクロサービスが機能する鍵は「DNS」
- クラウドネイティブアプリを支えるコンテナ技術群
- コンテナとDevOpsに求められるセキュリティ
- Dockerで永続ストレージを実現する4つの方法
コンテナはサンドボックス実行環境で、コンテナそれぞれに独自のリソース制限がある。アプリケーションを個々のコンポーネントに分解すれば、導入と保守も別個に行うことが可能になる。さらに、状況に応じて個別にスケールアップすることもできる。こうしたアプローチをマイクロサービスという。
ネットワーク接続性
ただしマイクロサービスアーキテクチャの成功の鍵を主に握るのは、各コンポーネントが相互に通信する方法と、データベースやストレージサービスなどの共有リソースと通信する方法だ。DevOpsアプローチでは、コンテナとそのワークロードが連続的に実行され、その上廃棄後も何らかの時点で実行される場合がある。そのため各コンテナがネットワーク接続性を備えることが大きな課題になる。
コンテナは、物理サーバのクラスタで実行される仮想マシン(VM)のインスタンスでホストされる可能性がある。どのホストも独自にネットワークに接続でき、そのネットワーク接続をホスト内の各コンテナにマッピングできなければならない。これは、コンテナの無数のインスタンスをロックダウンするために、IPアドレスの割り当てとセキュリティポリシーの適用を実行することを意味する。
Dockerは自社のコンテナプラットフォームに
- Bridge
- Host
- Container
- ネットワークなし
の4つのネットワークサポートモードを用意した。
デフォルトモードのBridgeは仮想ネットワークを作成して、ホスト内の全てのコンテナとホストの外部ネットワークポートをリンクする。Hostモードはコンテナをホストのネットワークスタックにリンクして、ホスト内の全ネットワークインタフェースからコンテナにアクセスできるようにする。Containerモードは既存のコンテナのネットワーク名前空間を再利用する。ネットワークなしのモードは、各コンテナに独自のネットワークスタックを用意するがインタフェースは構成せず、ユーザーが独自にカスタム構成をセットアップできる。
Dockerはコンテナを相互接続するために仮想イーサネットブリッジを実装しているため、ユーザーはシンプルなソフトウェア定義ネットワーク(SDN)を扱っていることになる。このサポートは、スタンドアロンのワークロードが実行されている場合、または全てのコンテナが一つのホストだけで実行されている場合は問題ない。だが、さまざまなスケールで実行されるワークロードについては、コンテナがサーバのクラスタで実行されていることをアプリケーションが求める可能性が高い。こうしたコンテナの多くは、別のホストで実行されているコンテナと通信しなければならない。
KubernetesとCNI
ここからが複雑になる。他のホストで実行されているコンテナにアクセスするには、コンテナがポートとIPアドレスを把握する必要がある。ITエンジニアはこれを手動で構成することもできる。だが、DevOps環境では時間のかかる複雑な作業になる。従って、コンテナを作成して導入する際のネットワークインタフェース構成を自動化する何らかのメカニズムが必要だ。
この種の自動化をオーケストレーションと呼ぶ。従って、コンテナの実際の導入に何らかのオーケストレーションツールが使用されるのは驚くことではない。コンテナオーケストレーションの標準になっているのが「Kubernetes」だ。これはGoogleを起源とするが、現在はオープンソースプロジェクトとしてCloud Native Computing Foundation(CNCF)が監督している。オーケストレーションツールには他にもDockerの「Docker Swarm」や「Apache Mesos」がある。
Kubernetesによる市場独占の副産物の一つは、同時に「Container Network Interface」(CNI)も普及したことだ。CNIはネットワーク層を構成する標準APIで、Kubernetesのおかげで他のプラットフォームにも導入されることになった。実のところCNIを開発したのはコンテナランタイム「rkt」の開発元であるCoreOSだ。Dockerは独自に「Container Network Model」(CNM)を開発しているが、CNIもサポートする。
CNIは基本的に、IPアドレス管理(IPAM)などのタスクを処理するネットワークサービスに接続する手段だ。Kubernetesの場合、CNIはコンテナのグループが相互に通信する方法を管理するよう定義されているネットワークポリシーを適用する。
VMwareNSX&その他のツール
CNIをサポートするプラットフォームの一つに「VMware NSX」がある。NSXは、既存の物理イーサネットに複数の仮想ネットワークを作成して管理できるSDNシステムで、基本的には仮想ネットワークトラフィックを転送するためのパケット転送バックプレーンとしてそのインフラを使用する。これらの仮想ネットワークは、それぞれが独自のIPアドレス範囲やその他の特性を保持することができる。
実際のNSXには2つのバージョンがある。一つは「NSX-V」とも呼ばれ、「VMware vSphere」と密接に統合されている。もう一つのバージョン「NSX-T」は「KVM」などの他のハイパーバイザーと連動するように開発されていて、これは「Linux」や「OpenStack」をサポートするために重要になる。
どちらのバージョンも、同じノードで実行されているVMやコンテナ間のトラフィックに直接対処する仮想スイッチとして機能する。対象が別のノードで実行されているVMやコンテナの場合、仮想ネットワークパケットは標準のイーサネットパケットにカプセル化されて、そのノードで実行されている仮想スイッチに送信される。
この他にも同様の機能を備えるプラットフォームがある。Microsoftは「Windows Server 2016」からSDN機能を組み込んでいて、例えば各ノードで実行される「Hyper-Vネットワーク仮想化」や、3つのHyper-V VMのクラスタで実行される一元的な管理サービス「ネットワークコントローラー」がある。
OpenStackは「Neutron」というネットワークサービスにより、ユーザーがネットワーク接続性を設定、定義することを可能にするAPIを提供する。このサービスはNeutronサーバと、サーバノードで実行されるエージェントで構成される。また「Open vSwitch」、Midokuraの「ミドネット」、Juniper Networksの「OpenContrail」、Cisco Systemsの「NX-OS」、NSXなどのネットワークプラットフォームとNeutronが連動できるプラグインも備える。OpenStackはKubernetesの他にも「Magnum」サービスを通じて別のコンテナオーケストレーションツールもサポートする。ただし、NeutronもCNIに準拠している。
セキュリティもコンテナの導入における重要な要素の一つで、さまざまなスケールで実行される場合は特に重要になる。物理ネットワークと同様、あの手この手でインフラに侵入しようとする攻撃からアプリケーションを保護するため、ファイアウォールやその他のセキュリティポリシーを実装する必要がある。だがコンテナ間のトラフィックが全く保護されていないことがよくある。
コンテナを相互接続する仮想ネットワークは複雑なので、コンテナネットワークトラフィック内で起きる事象を監視するのにオーケストレーション層やSDN層が最適になる。
SDNベンダーはセキュリティも考慮に入れている。例えばVMwareは、ネットワークの仮想化と同様にインフラ保護の点でもNSXを売り込んでいる。各コンピューティングノードで実行される分散ファイアウォールを効果的に提供するNSXは、外部からのパケットと同じくらい容易にインフラ内のトラフィックをフィルタリングできる。
軽量なコンポーネント
マイクロサービスに話を戻す。このアーキテクチャの主な特徴は、コンポーネントが軽量で、通常は単一の機能を実装することだ。こうしたコンポーネントが相互にリンクされて完全なアプリケーション機能を提供する。つまりコンテナ内のコードは、他のサービスを検出してそのサービスが仮想ネットワークのどこに存在するかを特定できなければならない。
そのための方法は多数あるが、DNSを使ってIPアドレスではなく名前でサービスを検索するのが一般的な方法の一つだ。これによりIPアドレスの変更が可能になる。IPアドレスはコンテナインスタンスが稼働/廃棄されるときに変更される。事実、Docker 1.10以降およびKubernetes 1.11以降は、この目的のためだけにEmbedded DNS Serverが実装されている。
他に負荷分散という要素もある。マイクロサービスアーキテクチャの目的は、特定機能の別のインスタンスを生み出してアプリケーションを拡張できるようにすることだ。その後インフラは、トラフィックを各インスタンスに確実にルーティングしなければならない。Kubernetesは、負荷分散を行うために同一のサービスのコピーにラウンドロビン方式でパケット転送する「kube-proxy」モジュールを使用する。だがこれだけでは確実に十分といえず、「HAProxy」「nginx」「Istio」などの他ソフトウェアのツールを使って負荷分散を実装しなくてはならない場合がある。
厄介ごと
コンテナのネットワークサポートは少々厄介だ。コンテナベースのDevOps導入が大掛かりになるにつれてその複雑さは増す。従って多くの企業が、コンテナベースのインフラを稼働させるために必要なほとんどの機能、または全ての機能を統合する既製のプラットフォームを利用している。
「Red Hat OpenShift」などのコンテナをサポートするPaaSからPivotal Softwareの「Pivotal Container Service」(PKS)といったプラットフォームまで、その選択肢は多岐にわたる。PKSにはNSX-TやKubernetes、そしてプラットフォーム全体の監視とライフサイクル管理を実行する「BOSH」というツールが含まれている。ただしコンテナの運用に特化しているため、開発者向けの機能は充実していない。一方、OpenShiftは最初からDevOps向けの継続的な統合サポートを提供している。
自身で統合するか、複雑な作業のほとんどをプラットフォームに任せるかは自由だ。いずれにしても、あらゆるコンテナとマイクロサービス戦略では、ソフトウェア制御下で構成/再構成できるネットワークが不可欠になっていくだろう。
Copyright © ITmedia, Inc. All Rights Reserved.