機械学習技術 人工知能技術 自然言語処理技術 セマンティックウェブ技術 オントロジー技術 検索技術 データベース技術 アルゴリズム デジタルトランスフォーメーション技術 Visualization & UX ワークフロー&サービス ITインフラ技術 DevOpsについて 本ブログのナビ
サマリー
Docker実践ガイドより。今回はDockerの概要について述べる。
イントロダクション
Dockerは、従来のハイパーバイザー型の仮想化基盤では手動で行なっていたOSのインストールといった複雑な人間の手作業をできるだけ省力化し、すぐにアプリケーションをコンテナとして稼働させる仕組みを提供している。また、アプリケーション構築の自動構築化、複数コンテナの強調動作、ソフトウェアコンポーネントの破棄、開発、本番環境構築の時間短縮など、従来の仮想化基盤と比較にならないレベルで高効率化を実現できる点などの特徴を持つ。
このように2013年に始まった、いわゆる「コンテナ革命」は、今や欧米において「ポスト仮想化」の大きな波に乗り、さまざまな先進的なベンダーが、Dockerをベースとした周辺ソフトウェアの開発とサービスの提供にしのぎを削っている。
Dockerによるコンテナ基盤は、人工知能、IoT、ビッグデータなどのソフトウェア開発力がキーとなる分野に必須の要素技術となる。世界の開発競争に打ち勝つには「柔軟性とスピードで確信をもたらす先進技術」の採用が不可欠であり、欧米のオープソースコミュニティや先進企業では、Dockerのような確信的なITを駆使し、自社の利益を生み出す努力を日々重ねている。彼らは、今までと同じ技術を使っていては、自分たちのビジネスの成長はあり得ないということを十分理解している。
Dockerとは
Dockerは、ソフトウェア開発者やIT部門の管理者をターゲットとした、アプリケーションやOSの開発・配置を行うための”コンテナ”を利用した基盤ソフトウェアとなる。コンテナとは、ホストOS上で独立したプロセスとして実行されるアプリケーション環境であり、OSの基本コマンドやアプリケーションの実行バイナリ、ライブラリなどの実行環境全体をパッケージ化し、それらをOSの分離された空間で実行する技術となる。DockerはdotCloud社(現Docker Inc.)によって開発され、2013年にリリースされ、その後オープンソースソフトウェアとしてして公開され、その使い風っての良さから、瞬く間に多くの開発者、IT部門の管理者に広まり、世界中のIT基盤で採用されているものとなる。
Dockerは、コンテナ技術の採用により、ハイパーバイザー型の仮想ソフトウェアに比べ、極めて集約度の高い(ハードウェア資源の消費や性能劣化の小さい)ITシステムを実現できる。しかし、Dockerが注目される理由は、仮想環境における性能面の優位性だけではなく、昨今の急速なビジネス変化に対応する道具として、IT技術者にその有用性が認められたからだと言える。
Dockerを利用することによるのソフトウェア開発でのメリット
ソフトウェア開発の観点で見た場合、インターネットで提供されるサービスの迅速な開発や柔軟な対応を行うには、ソフトウェア開発の本質的な部分に注力する必要がある。ソフトウェア開発が、ハードウェア環境の確保や開発環境のインストールといった煩わしい作業から解放され、アプリケーション開発に集中できれば、作業工数が削減され、開発した成果物の単価を引き下げ、さらにはソフトウェアの価格競争力を高めることも可能となる。
このようなアプリケーション開発者の要望を実現するには、アプリケーション単位での分離、開発環境の作成と廃棄を容易に行える仕組みが必要となる。そのためには、アプリケーションのメンテナンスの簡素化をよりいっそう推し進める必要がある。もちろん、従来のKVMなどによるハイパーバイザー型の仮想環境やパブリッククラウドのサービスでも、ソフトウェア開発者への効率向上の手段を提供しているが、Docker独自のパッケージングやリポジトリの機能により、更に利便性の高い開発環境をもたらす。
運用管理上のメリット
ITシステムが支える企業のビジネス(顧客ニーズ)が、グローバル化と共に多様化し、その対応を迫られるIT管理者にとって、仮想ソフトウェアの普及やクラウドサービスにおけるIaasやPaaSをはじめとする多様なサービスの登場は、メリットの非常に大きなものとなる。それがDockerの登場により、さらに推し進められようとしている。ITインフラの現場では、Dockerの運用により、アプリケーションの開発と実環境への素早い展開と運用の両立が可能となり、「DeveOps環境」や「イミュータブル・インフラストラクチャ」の実現に大きく貢献することとなる。ソフトウェア開発者やIT部門の管理者にとって、ハードウェア資源を意識せずに、運用、廃棄などを迅速に行える環境が、Dockerによって手に入れることができる。
Dockerのもたらす環境 – 開発環境と実行環境のパッケージ化
ネットワークを通じた、IT部門が用意した環境をすぐ利用できる環境といえば、クラウドコンピューティングにおけるIaaS(Infrastracture as a Service)やPaaSがある。しかし、パブリッククラウドが迅速にサービスを利用者に提供したとしても、それらの基盤上で動くアプリケーションの開発環境や実行環境の使い勝手が良く、カスタマイズの自由度が高くないと、ITシステム全体としてあまり意味がない。Dockerが注目される理由の一つは、この「アプリケーションの開発環境と実行環境をパッケージ化」し、迅速な配置や廃棄が可能である点が挙げられる。
例えば、開発者が複数のLinux OS上で稼働する、複数バージョンの開発環境をゼロから用意するとなれば、開発環境の入手、構築、利用、破棄といった作業は無視できない工数になる。それがDockerでは、先に述べた「アプリケーション環境と実行環境をパッケージ化」した「Dockerイメージ」を利用することで、多様な開発環境を容易に構築できる。
Dockerイメージとは、Dockerコンテナの生成に必要なファイルシステムであり、イメージ内には、実行ファイル、ライブラリ、Dockerコンテナの実行に際に起動させたいコマンドなどが含まれる。Dcokerイメージを元にして、コンテナが起動すると、内蔵されているアプリケーションの手記設定が自動的に行われ、基本機能をすぐに利用できる状態になるものも少ないくない。このようにDockerイメージさえ入手すれば、すぐにアプリケーションを利用できる仕組みが、開発者の工数を大幅に低減できる。
Dockerのもたらす環境 – 異種OS環境の実現
IaaSのようなクラウド基盤を構築できなくても、異種OSを手軽に作れる点は、Dockerの大きな魅力の一つとなる。アプリケーションの開発と異種OSの実行環境を、クラウドソフトウェアに依存せずに簡単に配備できれば、初期投資が限られたITシステムに関わる開発者と管理者の双方にとって大きなメリットがある。ここでとう「異種OS」とは、Linux環境であれば、異なるLinuxディストリビューションを意味し、例えばCentOSのDockerイメージ、UbuntuのDockerイメージ、SUSEベ-スのDockerイメージ、さらには、DebianベースのWebアプリケーション入りのDockerイメージなど、さまざまな種類のDockerイメージが存在する。
レジストリの提供/成果物の活用
Dockerは、高性能なアプリケーションの開発・実行環境の提供だけでなく、それらのOSやアプリケーション(Dockerイメージ)を世界中で共有し、ITシステムが目的を達成するために必要な工程を自動化するWebサービスを提供している。このWebサービスは、Docker Hubと呼ばれるクラウド上のDockerイメージレジストリ(保管庫)サービスとなる。アプリケーションやサービスコンテナの構築と配信を行う、いわゆるDockerイメージのパブリッククラウドサービスとなる。
新たなITインフラへの移行のためのイミュータブル・インフラストラクチャ
現在、Dockerのシステム開発の中で注目を浴びているものが、サービスプロバイダなどで導入されているイミュータブル・インフラストラクチャ(Immutable Infrastructure)と呼ばれるIT基盤のアーキテクチャとなる。これは本番用のシステムには一切手を加えず「不変の状態」であるということから”イミュータブル”と呼ばれている。
イミュータブル・インフラストラクチャは、下図に示したように、本番システムと開発システムの合計2系統のシステムを持つ。
開発用のシステム上でソフトウェアを開発した後、負荷分散総力旧システムを切り離し、開発システムを負荷分散装置と接続し、新たな本番環境として運用する。イミュータブルインフラストラクチャでは、開発系システムに対して、新しい要件が加わるなどの理由により、サービスやアプリケーションが新たに必要になった場合は、サーバーを新規に作成し、不要となった既存の旧システム(旧サーバー)を廃棄する。この廃棄される旧システムのことを、イミュータブル・インフラストラクチャではディスポーザブル・コンポーネント(廃棄可能な部品、構成要素)と呼ぶ。例えば、アプリケーションの動作テストを繰り返す旅に新しいサーバーほ作成し、すべてのテストが終了したら、途中で作ったサーバーは廃棄するといった方法が取られる。
従来の個別最適されたシステムの場合、導入当初は安定的に稼働していたものであっても、バッチの運用や機能追加を施すと、そのシステムは、大量のバッチが適用された状態になってしまう。管理者が厳密に大量のバッチ適用や変更履歴を追跡できたとして、システムが正常に稼働できるかどうかの判断もあやふやになり、誰もそのシステムの挙動を正確に把握できなくなにる恐れがある。そこで、バッチの適用状況の把握といったサーバー環境の現在の状態管理者が非常に煩雑になるならば「サーバーの状態を管理しない運用方法」を採ることで、開発者も管理者も煩雑なシステム管理から解放されるべきであるというのが、このイミュータブル・インフラストラクチャの考え方となる。
Dockerに向くシステム、向かないシステム
Dockerの向かないシステムとしては、ある業務目的を達成するために、要件定義を厳密に行うミッションクリティカルシステム(銀行のオンラインシステム、量販店の通販システム、通信インフラ、原子力発電所などの制御システム等の絶対に停止しては困るようなシステム)がある。このようなシステムは、構成を少しでも変更すると、業務に多大な影響があると考えられるため、ビジネスの変化が多少あるとしても、ITシステム自体を大きく変更することはないものとなる。
逆にDockerに向く環境は、サービスプロバイダ、ホスティングなどのITサービスが日々変化するようなシステムで、このような場合は軽量のコンテナ上でアプリケーションの開発が頻繁に行われ、革新的なサービスが次々と提供されるようなものとなる。
Dockerの課題
Dockerは、いまだ進化の途上であり利用上の課題もある。それらをいかに示す。
- 管理工数の軽減
Dockerはさまざまな企業で利用されているが、多くのユーザーは大量のDockerコンテナの管理工数の低減を課題に挙げている。Dcokerはシンプルなこの万度ラインを提供しているが、GUI管理ツールや、Dockerコンテナの自動配備、資源管理などのツールも提供されている。すなわち、Docker単体だけでシステムがすべて完結することはなく、効率化のための周辺ソフトウェアの整備をある程度視野におかなければならない。
コンテナにどのようなアプリケーションを幾つ配置するべきかの指針についても課題となっている。一つのコンテナに搭載するアプリケーションの数をあまり多くすると可搬性が損なわれ、逆に一つのコンテナに一つのアプリケーションのみを搭載するとコンテナの数が指数関数的に増加して管理が複雑なる。利用目的を考えてコンテナの用途を設計する必要がある。
Dockerの運用において、複数のコンテナが連携するためのKubernetes等のオーケストレーションソフトウェアが注目されている。このオーケストレーションできるソフトウェアは、主にオープンソースソフトウェアが軸になっているため、ベンダーによるサポート範囲を明確に理解する必要がある。
- ミッションクリティカル領域での利用
Docker自体が機能追加や仕様変更などを短時間に頻繁に繰り返している場合には、これらのオーケストレーションソフトウェアとDockerの組み合わせをビジネスの本番システムに採用するかは、慎重に検討する必要がある。またミッションクリティカルなビジネス系システムでは必須となるHAクラスタソフトウェアとDockerの連携についても、ベンダーが適用する商用のHAクラスタソフトウェアが、Dockerコンテナを正式にサポートしていない状況を考慮すると、ミッションクリティカルな領域でのDockerの採用は控えるべきである。
- ライブマイグレーションのサポート
仮想環境をすでに導入しているシステムでは、日常のメンテナンスを無停止で行うためにゲストOSのライブマイグレーションが行われることが少なくないが、Dockerでは現時点でライブマイグレーションを正式にはサポートしていない。もし、現行の業務が稼働している仮想基盤におけるゲストOSのライブマイグレーション要件(ゲストOSを別の物理サーバーに無停止で移動さらせる)が必須である場合には、無停止型サーバー(通称FTサーバーと呼ばれる)やハイパーバイザー方の仮想化ソフトウェアを使い続けるかOpenVX等の商用製品の採用を検討すべきものとなる。
- 稼働OSの制約
DockerのホストOSがLinuxの場合は、その上で稼働するコンテナもLinuxに限定される。これはホストOSがLinuxの場合は、LinuxコンテナとWindowsコンテナを混在させることができないことを意味する。Windowsアプリケーションを業務で使用しており、それをコンテナで稼働させるには、Windows Serverで搭載される「WIndows Server Container」を導入する必要がある。
Dockerコンテナのアーキテクチャ
ITシステムにおいて、開発面や運用面の変化に迅速に対応する解決策の一つとして、従来は仮想ソフトウェアの採用があった。仮想ソフトウェアは、複数のOS環境とアプリケーションを一つのファイルとして扱い、非常に可搬性の高い基盤を提供する。しかし、Dockerと比較すると、複数のOSを集約した場合性能劣化や、OSとアプリケーションの仲立ちをする仮想ソフトウェアの介在による障害発生時の問題切り分けの複雑さが問題かされていた。
一方Dockerでは、従来のハイパーバイザー型の仮想化とは異なり、一つのOS環境に、コンテナと呼ばれる分離された空間を即生死、その分離された空間ごとに異なるOS環境を実現できる。コンテナによって複数の異種Linux OS環境を実現することができるため、複数のOSバージョンを必要とするITシステムを一つのOS環境に集約できるというメリットがある。
コンテナはアプリケーションの分離された空間を提供できる。アプリケーションの分離された空間を実現することで、一つのOSでありながら、プロセスを分離することができるため、複数の異種Linux OS環境を実現できる。例えば、CentOS7のホストOS上でDockerを稼働させ、CentOS6のDockerコンテナや、Ubuntu server 14.04LTSのDockerコンテナを複数同時に花道さらることができる。
コンテナ自体は、Dockerが登場する以前から存在し、古くから使われている。これらは、いずれも単一OS上で複数の分離された空間を提供するという特徴を持ち、ハイパーバイザー型の仮想化ソフトウェアではない。
一般にハイパーバイザー型の仮想化ソフトウェアは、ハイパーバイザーと呼ばれるソフトウェアが、仮想的なハードウェアである「仮想マシン」を提供する。その仮想マシンが提供する仮想的なBIOS、仮想CPU、仮想メモリ、仮想ディスク、仮想NICなどをゲストOSに見せることで、ゲストOSからは、あたかも物理的なマシンで稼働しているかのように見えるのである。
このため、ゲストOSとしては、通常のOSの起動、停止となんら変わらない運用が必要となる。例えば、ゲストOSでは、自身の仮想ディスクのマスターブートレコード領域に対してブートローダーをインストールしなければ、当然ゲストOSは正常には動作しない。またOSの終了時に正常なシャットダウン手続きを行わなければ、仮想ディスクにインストールされたゲストOSは、物理サーバーで稼働するOSのときと同様に、OS自体が破損する可能性もある。
一方、コンテナ環境では、ゲストOSに相当する分離された空間において、そもそも「マスターブートレコードに応じたカーネルを稼働する」や「カーネルをロードした後にドライバルイを含んだ初期RAMDISKをロードする」といった、いわゆる物理マシン上での一般的な「OSブート手順」がない。このため、コンテナ環境は、ハイパーバイザー型の仮想化基盤のゲストOSに比べて、オーバーヘッドが少ないため、コンテナの起動・停止が非常に高速であるという特徴を持つ。
また、ハイパーバイザー型のソフトウェアは、ハードウェアをエミュレートしているのに対し、コンテナ環境は、名前空間(namespace)とcgroupsと呼ばれる資源管理の仕組みを使うことで、単一のOS内で複数のコンテナがプロセスとして稼働するだけであるため、分離された空間に必要と去れるOS環境(コンテナ)のコンポーネントや資源も少なくて済むといった特徴もある。したがって、Linuxコンテナは、ハイパーバイザー型の仮想技術に比べて、CPU、メモリ、ストレージ、ネットワークなどのハードウェア資源の消費や、オーバーヘッドが小さいため、集積率を劇的に向上させることが可能となる。また、性能においても、コンテナ環境では、アプリケーションのプロセスがコンテナごとに分離されるが、ホストOSから直接実行されるため、コンテナ上のCPU利用は、ホストOSと同等の性能を発揮できる(下図)
Dockerにおける名前空間とは
単一のOS環境において、Dockerは複数の分離された空間を作成できるが、その分離された空間を実現しているのが名前空間(namespace)となる。この名前空間は、プロセスの分離を実現することができるため、例えばある分離された空間Aのプロセスは、別の分離された空間Bには見えないといった制御も実現する。Dockerコンテナを作成する際に、以下に挙げた名前空間が作成される。
- ipc 名前空間: Inter-Process Communication名前空間と呼ばれる。内部的なプロセス間通信を分離する。
- mnt 名前空間 : プロセスから見えるファイルシステムのマウント情報を分離し、chrootコマンドに近い働きをする。
- net 名前空間 : ネットワークの制御を行う名前空間となる。net名前空間ごとにネットワークインターフェースを持つことができるため、複数のコンテナとホスト間でネットワーク通信を行うことができる。
- pid名前空間 : プロセスの分離に用いる。カーネルが制御しており、親PIDによる子PIDの制御などに使われる。
- user名前空間 : ユーザーIDとグループIDを分離する。user名前空間ごとに個別のユーザーIDとグループIDを保持できる。
- uts名前空間 : UTS(Unix Time-Sharing System)名前空間と呼ばれる。ホスト名やNISドメイン名などの分離に利用する。
これらの機能を使って、プロセスやファイルシステム、ユーザーIDなどが分離された空間を複数作ることで、コンテナを実現している。
pid名前空間の分離
名前空間を使用すると、ファイルシステムやネットワーキングなど、各コンテナのシステムリソースを分離できる。ユーザーがDockerコンテナを実行すると、Dockerエンジンは、そのコンテナに対する名前空間を作成する。各コンテナは、別々の名前空間で動作し、アクセスは、その名前空間に限定される。Dockerエンジンが稼働するホストOSから見ると、複数の名前空間に所属するプロセスが一様に動いているように見えるが、個々の名前空間(すなわちコンテナ内)の中では、その名前空間に所属するアプリケーションのプロセスしか見えない(下図)。
例えば、Dockerエンジンが稼働するホストOSによって、Webサーバーのhttpdサービスが稼働するコンテナとFTPサーバーのvsftpdサービスが稼働するコンテナの2つが起動し、ホストOSは、httpdデーモンにプロセスID(PID)として100番を割り当て、vsftpdデーモンに、PIDとして2000万を割り当てたとする。ホストOSからは、httpdとvsftpdの両方がプロセスとして稼働している。しかし、httpdサービスが稼働するコンテナ内では、httpdにPIDの1万が割り当てられ、一方、vsftpdサービスが稼働するコンテナ内では、vsftpdにPIDの1万が割り当てられる、httpdとvsftpdに同じPIDの1万が割り当てられているが、httpdが稼働するコンテナとfsftpdが稼働するコンテナは別々のPID名前空間であるため、httpdが稼働するコンテナ内ではvsftpdは見えず、vsftpdが稼働するコンテナからもhttpdは見えない。名前空間に閉じた形でプロセスIDが割り当てられるため、ホストOSのプロセス空間をアプリケーションのプロセス空間で分離できたことになる。
ファイルシステムの分離
コンテナ(プロセス)として分離されるのはプロセスIDだけではなく、ファイルシステムの名前空間も同様となる。Dockerエンジンが稼働するコンテナ基盤では、コンテナごとに別々のファイルシステムの名前空間を持つことが可能となる。コンテナ内のファイルシステムは、別のコンテナのファイルシステムを見ることができない。例えば、CentOSベースのコンテナ内でtest1.htmlというファイルをコンテナ内の/dataディレクトリに作成し、Ubuntuベースのコンテナ内でtest2.htmlというファイルをコンテナ内の/dataディレクトリに作成したとする。このとき、Dockerエンジンが稼働するホストOSから見ると、ホストOS上の/var/lib/dockerディレクトリ配下に、test.htmlファイルとtest2.htmlファイルが見える(下図)。
ホストOS上のファイルシステムの名前空間は単一なので、両方のファイルが見えるが、CentOSのコンテナ内ではtest1.htmlファイルのみが見え、test2.htmlファイルは見えない。一方Ubuntuのコンテナではtest2.htmlファイルのみが見え、test1.htmlファイルは見えない。このように、名前空間に閉じた形でファイルシステムが割り当てられるため、ホストOSのファイルシステム空間をコンテナごとのファイルシステム空間で分離できたことになる。
cgroups(Control Group)
一つのホスト上で複数の分離空間として稼働するコンテナが稼働する環境において、限られたハードウェア資源の利用制限は非常に重要となる。特定のユーザーが使用するコンテナがホストマシンのハードウェア資源を食い潰すようなことがあると、他のユーザーの利用に支障をきたす。Docker環境において、デフォルトでは、コンテナがハードウェア資源を使い果たそうとする。一つのコンテナがハードウェア資源を使い果たすのを防ぐには、コンテナごとに使用できるハードウェア資源を制限しなければならない。これを実現するのがcgroups(Control Group)となる(下図)。
cgroupsは、Linuxのカーネルに実装されている資源制御の仕組みとなる。cgroupsは、各コンテナが使用するCPUやメモリなどのハードウェア資源の使用量を制限し、分離された名前空間ごとに設定したハードウェア資源を割り当てる。CPUメモリ、ネットワーク通信の帯域幅などのコンピュータ資源を組み合わせ、ユーザーが定義したタスクのグループに割り当て、このグループに対して資源利用の制限や解放を設定することが可能となる。
cgroupsは、Docker登場以前からLinuxサーバーシステムにおいて古くから利用されており、決め細かくハードウェア資源の割り当て制御ができるため、非常に強力な資源管理ツールとして有名なものとなる。Linuxに実装されているcgroupsは、アプリケーションのプロセスに対して、主にCPU、メモリ、ブロックI/Oなどの各種物理デバイスの使用量を制限する。
cgroupsは、仮想的なファイルシステム(具体的には、ホストOS上の/sys/fs/cgroupsディレクトリ配下)を提供しており、このファイルシステム上で提供されるパラメータを変更することで、各種リソースの制御が可能となる。この設定は、システムが稼働中に行うことができ、ホストOSの再起動を行うことなく資源の割り当てを動的に行うことが可能となる。cgroupsのファイルシステムで管理される主な統計情報を下記に示す。
- bkkio : ブロックデバイスの入出力統計情報の表示、I/O制御
- cpuacct : 消費しているCPU時間のレポートを生成
- cpuset : プロセスが稼働するCPUコア、メモリの割り当て配置の設定
- devices : デバイスへのアクセス制御の設定
- freezer : タスク(プロセス)の一時停止、再開
- hugetb : サイズの大きい仮想メモリページを利用可能とする
- memory : タスクが消費するメモリソースのレポート作成、使用メモリの上限設定
- pref_event : prefツールで閲覧可能とする
コメント