序文 Docker入門 Docker は、Docker が開発した軽量仮想化テクノロジーをベースにしたオープンソースのコンテナ エンジン プロジェクトです。プロジェクト全体は Go 言語に基づいて開発されており、Apache 2.0 プロトコルに準拠しています。現在、Docker はコンテナ内にアプリケーションを迅速かつ自動的にデプロイでき、カーネル仮想化テクノロジー (名前空間や cgroup など) を通じてコンテナのリソース分離とセキュリティ保護を提供できます。 Docker はオペレーティング システム層での仮想化によって分離を実現するため、Docker コンテナーは実行時に仮想マシン (VM) のような追加のオペレーティング システムのオーバーヘッドを必要とせず、リソースの使用率が向上し、IO などの面でパフォーマンスが向上します。 Docker は、その多くの斬新な機能とプロジェクト自体のオープン性により、Google、Microsoft、VMware などの業界リーダーを含む多くのメーカーから 2 年足らずで急速に支持を獲得しました。 Google は今年 6 月に Kubernetes をリリースし、Docker コンテナのスケジューリング サービスを提供しました。今年 8 月、Microsoft は Azure での Kubernetes のサポートを発表し、その後、従来の仮想化大手 VMware は Docker との強力なパートナーシップを発表しました。今年9月中旬、Dockerは分散アプリケーションの開発を促進するためにシリーズCの資金調達で4,000万ドルを調達した。 現状から判断すると、Docker には明るい未来があります。この連載記事では、ソースコードの観点からDockerのアーキテクチャ、Dockerの動作、Dockerの優れた機能について詳しく紹介します。この記事は、Docker ソース コード分析シリーズ「Docker アーキテクチャ」の第 1 回です。 Dockerバージョン この記事の Docker アーキテクチャの分析は、Docker ソース コードと、対応するバージョンの Docker (最新バージョンは 1.2) の実行結果に基づいています。 Docker アーキテクチャ分析コンテンツ ディレクトリ この記事の目的は、Docker ソースコードの理解に基づいて Docker アーキテクチャを分析することです。分析プロセスは主に次の 3 つのステップで実行されます。
Docker 全体アーキテクチャ図 Docker のソースコードを研究するのは退屈なプロセスではありません。代わりに、Docker アーキテクチャの設計原則を理解するのに役立ちます。 Docker はユーザー向けの C/S モデル アーキテクチャであり、Docker のバックエンドは非常に疎結合なアーキテクチャです。各モジュールは独自の機能を持ち、有機的に組み合わされて Docker の動作をサポートします。 ここで、まずは図に示すように、Dockerの全体的なアーキテクチャを添付します。 Docker 全体アーキテクチャ図 ユーザーが Docker クライアントを使用して Docker デーモンとの通信を確立し、後者にリクエストを送信することは容易に理解できます。 Docker アーキテクチャの主要部分として、Docker デーモンはまず Docker クライアントからの要求を受け入れるためのサーバー機能を提供します。次に、エンジンは Docker 内で一連のタスクを実行し、各タスクはジョブの形式で存在します。 ジョブの実行プロセス中にコンテナ イメージが必要になると、Docker レジストリからイメージがダウンロードされ、ダウンロードされたイメージはイメージ管理ドライバー graphdriver を通じてグラフの形式で保存されます。 Docker 用にネットワーク環境を作成する必要がある場合、ネットワーク管理ドライバー networkdriver を通じて Docker コンテナ ネットワーク環境が作成および構成されます。 Docker コンテナの実行リソースを制限したり、ユーザー指示を実行したりするなどの操作を execdriver を通じて完了する必要がある場合。 Libcontainer は独立したコンテナ管理パッケージです。 Networkdriver と execdriver はどちらも libcontainer を使用してコンテナに対する特定の操作を実装します。 コンテナを実行するコマンドが実行されると、実際の Docker コンテナは実行状態になります。コンテナには独立したファイルシステム、独立した安全な動作環境などが備わっています。 Dockerアーキテクチャにおける各モジュールの機能と実装の分析 次に、Docker アーキテクチャ全体の図から始めて、アーキテクチャ内のさまざまなモジュールを抽出し、各モジュールのより詳細なアーキテクチャ分析と機能説明を行います。主なモジュールは、Docker クライアント、Docker デーモン、Docker レジストリ、グラフ、ドライバー、libcontainer、および Docker コンテナです。 Dockerクライアント Docker クライアントは、Docker アーキテクチャのユーザーが Docker デーモンとの通信を確立するために使用するクライアントです。ユーザーが使用する実行ファイルは docker であり、コンテナを管理するための多くのリクエストは docker コマンドライン ツールを通じて開始できます。 Docker クライアントは、tcp://host:port、unix://path_to_socket、fd://socketfd の 3 つの方法で Docker デーモンとの通信を確立できます。簡潔にするために、この記事では最初の方法をプロトタイプとして使用し、2 つの間の通信を説明します。同時に、Docker デーモンとの接続を確立してリクエストを送信するときに、Docker クライアントはコマンドライン フラグ パラメータを設定することで、セキュア トランスポート層プロトコル (TLS) の関連パラメータを設定し、送信のセキュリティを確保できます。 Docker クライアントがコンテナ管理要求を送信すると、Docker デーモンがその要求を受信して処理します。 Docker クライアントが返されたリクエスト応答を受信して単純に処理すると、Docker クライアントのライフサイクル全体が終了します。コンテナ管理リクエストの送信を継続する必要がある場合は、docker 実行可能ファイルを使用して Docker クライアントを再度作成する必要があります。 Dockerデーモン Docker デーモンは、Docker アーキテクチャのバックグラウンドに常駐するシステム プロセスです。その機能は、Docker クライアントから送信されたリクエストを受け入れて処理することです。デーモンはバックグラウンドでサーバーを起動し、Docker クライアントから送信されたリクエストを受け入れる役割を担います。要求を受け入れた後、サーバーはルーティングと配布スケジュールを通じて要求を実行する対応するハンドラーを見つけます。 Docker デーモンを起動するために使用される実行可能ファイルも docker であり、これは Docker クライアントを起動するために使用される実行可能ファイル docker と同じです。 docker コマンドを実行すると、渡されるパラメータによって Docker デーモンと Docker クライアントが区別されます。 Docker デーモンのアーキテクチャは、大まかに Docker サーバー、エンジン、ジョブの 3 つの部分に分けられます。デーモンアーキテクチャ。 図 Dockerデーモンのアーキテクチャ図 Docker アーキテクチャでは、Docker サーバーは Docker クライアントに特化してサービスを提供するサーバーです。サーバーの機能は、Docker クライアントから送信されたリクエストを受け入れてディスパッチすることです。 Docker Server のアーキテクチャを図 4.2 に示します。 図4.2 Dockerサーバーのアーキテクチャ図 Docker の起動プロセス中に、パッケージ gorilla/mux を通じて mux.Router が作成され、リクエスト ルーティング機能が提供されます。 Golang では、gorilla/mux は強力な URL ルーターおよびディスパッチャーです。多くのルーティング項目が mux.Router に追加されました。各ルーティング項目は、HTTP 要求メソッド (PUT、POST、GET、または DELETE)、URL、およびハンドラーの 3 つの部分で構成されます。 Docker クライアントが HTTP 経由で Docker デーモンにアクセスする場合、mux.Router を作成した後、Docker はサーバーのリスニング アドレスと mux.Router をパラメーターとして受け取り、httpSrv=http.Server{} を作成し、最後に httpSrv.Serve() を実行して要求に応えます。 サーバー サービス プロセス中に、サーバーはリスナー上の Docker クライアントからのアクセス要求を受け入れ、要求を処理するための新しい goroutine を作成します。 goroutine では、まずリクエストの内容を読み取り、解析作業を行い、対応するルーティング項目を見つけ、対応するハンドラーを呼び出してリクエストを処理し、最後にハンドラーがリクエストを処理した後にリクエストに応答します。 なお、Docker 起動プロセス中の Docker Server の操作は、「serveapi」というジョブを実行することで完了します。原則として、Docker Server の運用は多くのジョブのうちの 1 つです。ただし、Docker Server の重要性と、後続のジョブを提供するという重要な機能を強調するために、「serveapi」ジョブを個別に抽出して分析し、Docker Server として理解します。 4.2.2 エンジン Engine は、Docker アーキテクチャ内で実行されるエンジンであり、Docker 操作のコア モジュールでもあります。 Docker コンテナの保管倉庫としての役割を担い、ジョブを実行することでこれらのコンテナを操作・管理します。 エンジン データ構造の設計と実装には、ハンドラー オブジェクトがあります。ハンドラー オブジェクトには、多くの特定のジョブに対するハンドラー処理アクセスに関する情報が格納されます。たとえば、Engine ハンドラー オブジェクトに {"create": daemon.ContainerCreate,} という項目がある場合、これは "create" という名前のジョブが実行中の場合、daemon.ContainerCreate のハンドラーが実行されることを意味します。 4.2.3 仕事 ジョブは、Docker アーキテクチャのエンジン内で最も基本的な作業実行単位と考えることができます。 Docker が実行できるすべてのタスクは、ジョブとして抽象化できます。たとえば、コンテナ内でプロセスを実行することはジョブです。新しいコンテナを作成するのは仕事です。インターネットから文書をダウンロードするのは仕事です。前述の Docker サーバーのセクションで説明した内容を含め、HTTP API を提供するサーバーを作成することも仕事です。 Job の設計者は、Job を Unix プロセスに似たものに設計しました。たとえば、ジョブには名前、パラメーター、環境変数、標準入力と出力、エラー処理、戻りステータスなどがあります。 4.3 Dockerレジストリ Docker Registry はコンテナイメージを保存するためのリポジトリです。コンテナ イメージは、コンテナの作成時にロードされ、コンテナのファイル構造とディレクトリが初期化されます。 Docker の動作中、Docker Daemon は Docker Registry と通信し、イメージの検索、イメージのダウンロード、イメージのアップロードという 3 つの機能を実装します。これら 3 つの機能に対応するジョブ名は、それぞれ「search」、「pull」、「push」です。 その中でも、Docker アーキテクチャでは、Docker はよく知られている Docker Hub であるパブリック Docker レジストリを使用できます。このように、Docker はコンテナ イメージ ファイルを取得するときに、インターネット経由で Docker Hub にアクセスする必要があります。同時に、Docker では、ユーザーがローカルのプライベート Docker レジストリを構築することも可能で、これにより、コンテナ イメージの取得がイントラネット上で完了することが保証されます。 4.4 グラフ Graph は、Docker アーキテクチャでダウンロードされたコンテナ イメージの管理者としての役割と、ダウンロードされたコンテナ イメージ間の関係を記録する役割を担います。 Graph は、一方ではバージョン情報を含むローカル ファイル システム イメージを保存し、他方では GraphDB を通じてすべてのファイル システム イメージ間の関係を記録します。 Graph のアーキテクチャを図 4.3 に示します。 図4.3 グラフアーキテクチャ図 その中で、GraphDB は SQLite 上に構築された小さなグラフ データベースであり、ノードの命名とノード間の関係の記録を実現します。これは、ほとんどのグラフ データベースが持つ機能のごく一部だけを実装していますが、ノード間の関係を表すためのシンプルなインターフェイスを提供します。 同時に、Graph のローカル ディレクトリには、各コンテナ イメージに関する特定の情報として、コンテナ イメージのメタデータ、コンテナ イメージのサイズ情報、コンテナ イメージによって表される特定の rootfs が保存されます。 4.5 ドライバー ドライバーは、Docker アーキテクチャのドライバー モジュールです。 Driver ドライバーを通じて、Docker は Docker コンテナ実行環境をカスタマイズできます。 Docker 操作のライフサイクル中、すべてのユーザー操作が Docker コンテナの管理のためであるとは限りません。また、Docker の動作情報の取得やグラフの保存・記録などに関する操作もあります。そこで、Docker コンテナの管理と Docker Daemon の内部ビジネスロジックを分離するために、これらの要求をすべて引き受ける Driver 層のドライバーが設計されています。 Docker ドライバーの実装では、graphdriver、networkdriver、execdriver の 3 種類のドライバーに分けられます。 Graphdriver は主に、保存や取得などコンテナ イメージの管理に使用されます。つまり、ユーザーが指定されたコンテナ イメージをダウンロードする必要がある場合、graphdriver は指定されたローカル ディレクトリにコンテナ イメージを保存します。同時に、ユーザーが指定されたコンテナ イメージを使用してコンテナの rootfs を作成する必要がある場合、graphdriver はローカル イメージ ストレージ ディレクトリから指定されたコンテナ イメージを取得します。 グラフドライバーが初期化される前に、aufs、btrfs、vfs、devmapper という 4 つのファイル システムまたはファイル システムがその中に登録されます。 Docker が初期化されると、システム環境変数「DOCKER_DRIVER」が取得され、使用されている指定されたタイプのドライバーが抽出されます。以降のすべてのグラフ操作はこのドライバーを使用して実行されます。 graphdriver のアーキテクチャを図 4.4 に示します。 図4.4 Graphdriverアーキテクチャ図 networkdriver の目的は、Docker の起動時に Docker 環境のブリッジを作成するなど、Docker コンテナ ネットワーク環境の構成を完了することです。 Docker コンテナの作成時に専用の仮想ネットワーク カード デバイスを作成します。 Docker コンテナに IP とポートを割り当て、ポートをホストにマッピングし、コンテナのファイアウォール ポリシーを設定するなどします。ネットワーク ドライバのアーキテクチャを図 4.5 に示します。 図4.5 ネットワークドライバのアーキテクチャ図 execdriver は、Docker コンテナの実行ドライバーとして、コンテナ実行名前空間の作成、コンテナ リソースの使用のカウントと制限、コンテナ内でのプロセスの実際の実行を担当します。 execdriver の実装プロセスでは、もともと LXC ドライバーは LXC インターフェイスを呼び出してコンテナの構成とライフサイクルを操作するために使用されていました。ただし、execdriver はデフォルトでネイティブ ドライバーを使用するようになり、LXC に依存しなくなりました。これは、デーモンの起動プロセス中に読み込まれる ExecDriverflag パラメータに具体的に反映され、構成ファイルで「native」に設定されています。これは、Docker バージョン 1.2 における大きな変更、または Docker のクロスプラットフォーム実装の先駆けと見なすことができます。 execdriver アーキテクチャを図 4.6 に示します。 図4.6 Execdriverアーキテクチャ図 4.6 ライブラリコンテナ libcontainer は、Docker アーキテクチャで Go 言語で設計および実装されたライブラリです。設計の本来の目的は、ライブラリが依存関係に依存せずにカーネル内のコンテナ関連 API に直接アクセスできるようにすることです。 libcontainer が存在するからこそ、Docker は libcontainer を直接呼び出して、最終的にコンテナの名前空間、cgroup、apparmor、ネットワーク デバイス、ファイアウォール ルールを操作できるのです。この一連の操作を完了するには、LXC や他のパッケージに依存する必要はありません。 libcontainer アーキテクチャを図 4.7 に示します。 libcontainer ダイアグラム さらに、libcontainer は、コンテナ管理の上位層の要件を満たすための完全な標準インターフェース セットを提供します。つまり、libcontainer は Docker の上位層によるコンテナの直接管理をブロックします。また、libcontainer は Go のようなクロスプラットフォーム言語を使用して開発および実装されており、さまざまな上位レベルのプログラミング言語からアクセスできるため、将来的に Docker が Linux と密接に結びつくかどうかはわかりません。同時に、Microsoft は有名なクラウド コンピューティング プラットフォーム Azure に Docker のサポートを追加しました。これは、Docker のオープン性と業界での人気を示しています。 Docker 以外にも、libcontainer の機能性とシステムとの疎結合性により、他のコンテナベースのプラットフォームにも登場する可能性が高く、クラウド コンピューティングの分野で新たなプロジェクトが生まれる可能性もあります。 4.7 Dockerコンテナ Docker コンテナは、Docker アーキテクチャにおけるサービス配信の究極の形式です。 Docker は、ユーザーのニーズと指示に応じて、対応する Docker コンテナをカスタマイズします。 コンテナイメージを指定することにより、ユーザーは Docker コンテナ内の rootfs やその他のファイルシステムをカスタマイズできます。 ユーザーはコンピューティング リソースの割り当てを指定して、Docker コンテナが指定されたコンピューティング リソースを使用できるようにします。 ユーザーは、ネットワークとそのセキュリティ ポリシーを構成して、Docker コンテナに独立した安全なネットワーク環境を提供します。 ユーザーは実行するコマンドを指定し、Docker コンテナに指定された作業を実行させます。 Docker コンテナの概略図を図 4.8 に示します。 図4.8 Dockerコンテナ図 5 Docker実行ケース分析 前の章では、Docker アーキテクチャの各部分の紹介に重点を置きました。この章では、Docker モジュールを順に簡単に分析します。分析のプロトタイプは、Docker の 2 つのコマンド docker pull と docker run です。 5.1 docker プル docker pull コマンドの目的は、指定されたコンテナ イメージを Docker レジストリからダウンロードし、それをローカル グラフに保存して、後で Docker コンテナを作成するときに使用できるようにすることです。 docker pull コマンドの実行プロセスを図 5.1 に示します。 図5.1 docker pullコマンド実行プロセスの概略図 図に示すように、図中の赤い矢印は、docker pull コマンドが開始された後に Docker によって実行される一連の操作を示しています。これらのステップを一つずつ分析してみましょう。 (1)Dockerクライアントはdocker pullコマンドを受信し、リクエストを解析してリクエストパラメータを収集し、DockerサーバーにHTTPリクエストを送信します。 HTTP リクエスト メソッドは POST で、リクエスト URL は "/images/create? "+"xxx"; です。 (2)Docker Serverは上記のHTTPリクエストを受け入れ、mux.Routerに渡します。 Mux.Router は、URL とリクエスト メソッドに基づいて、リクエストを実行する特定のハンドラーを決定します。 (3)mux.Routerはリクエストを対応するハンドラ、具体的にはPostImagesCreateにルーティングします。 (4)PostImageCreateハンドラで、「pull」という名前のジョブが作成され、実行が開始されます。 (5)「pull」というジョブの実行中に、pullRepository操作が実行され、つまり、Dockerレジストリから1つ以上の対応するイメージがダウンロードされます。 (6)「pull」というジョブはダウンロードしたイメージをグラフドライバーに渡します。 (7)グラフドライバーは、一方ではグラフオブジェクトを作成し、他方ではGraphDBに画像間の関係を記録することによって画像を保存する役割を担っています。 5.2 ドッカー実行 docker run コマンドは、新しい Docker コンテナ内で命令を実行します。 Docker がこのコマンドを実行するとき、その作業は 2 つの部分に分けられます。まず、Docker コンテナに必要な rootfs を作成します。 2 番目は、コンテナのネットワークやその他の動作環境を作成し、ユーザーの指示を実際に実行することです。したがって、実行プロセス全体において、Docker クライアントは Docker サーバーに 2 つの HTTP 要求を送信し、2 番目の要求の開始は最初の要求の戻りステータスに依存します。 Docker 実行コマンドの実行プロセスを図 5.2 に示します。 図5.2 docker runコマンド実行プロセスの概略図 図に示すように、図中の赤い矢印は、docker run コマンドが開始された後に Docker によって実行される一連の操作を示しています。これらのステップを一つずつ分析してみましょう。 (1)Dockerクライアントはdocker runコマンドを受信し、リクエストを解析してリクエストパラメータを収集し、DockerサーバーにHTTPリクエストを送信します。 HTTP リクエスト メソッドは POST で、リクエスト URL は "/containers/create? "+"xxx"; です。 (2)Docker Serverは上記のHTTPリクエストを受け入れ、mux.Routerに渡します。 Mux.Router は、URL とリクエスト メソッドに基づいて、リクエストを実行する特定のハンドラーを決定します。 (3)mux.Routerはリクエストルーティングを対応するハンドラ、具体的にはPostContainersCreateに配布します。 (4)PostImageCreateハンドラでは、「create」という名前のジョブが作成され、実行が開始されます。 (5)「create」というジョブの実行プロセス中に、Container.Create操作が実行されます。この操作では、Dockerコンテナのrootfsを作成するためにコンテナイメージを取得する必要があり、つまりグラフドライバーを呼び出します。 (6)graphdriverはGraphからDockerコンテナのrootfsを作成するために必要なすべてのイメージを取得します。 (7)graphdriverはrootfsのすべてのイメージをDockerコンテナで指定されたファイルディレクトリにロードしてインストールします。 (8)上記の操作がすべて正常に実行され、エラーや例外が返されなかった場合、DockerクライアントはDockerサーバーから返されたステータスを受け取った後、2番目のHTTPリクエストを開始します。リクエストメソッドは「POST」、リクエスト URL は「/containers/"+container_ID+"/start"」です。 (9)Docker Serverは上記のHTTPリクエストを受け入れ、mux.Routerに渡します。 Mux.Router は、URL とリクエスト メソッドに基づいて、リクエストを実行する特定のハンドラーを決定します。 (10)mux.Routerはリクエストルーティングを対応するハンドラ、具体的にはPostContainersStartに配布します。 (11)PostContainersStartハンドラでは、「start」という名前のジョブが作成され、実行が開始されます。 (12)「start」というジョブは初期設定作業を完了すると、ネットワーク環境の設定と作成を開始し、ネットワークドライバーを呼び出します。 (13)networkdriverは指定されたDockerコンテナのネットワークインターフェースデバイスを作成し、IPとポートを割り当て、ファイアウォールルールを設定する必要があります。対応する操作は、完了するために libcontainer 内の netlink パッケージに転送されます。 (14)netlinkはネットワーク環境の設定とDockerコンテナの作成を完了します。 (15)「start」という名前のジョブに戻ります。いくつかの補助操作を実行した後、ジョブはユーザー指示の実行を開始し、execdriver を呼び出します。 (16)execdriverは、名前空間、リソースの制御と分離、ユーザーコマンドの実行など、Dockerコンテナ内の動作環境を初期化するために呼び出されます。対応する操作は完了のために libcontainer に転送されます。 (17)libcontainerはDockerコンテナ内の動作環境の初期化を完了し、最後にユーザーが要求したコマンドを実行するために呼び出されます。 |
ケベルネテスシリーズ 1 ケベルネテス入門多くの同僚が Kubernetes を理解して研究するとき...
ウェブサイトの SEO は、細部にわたる最適化のプロセスです。SEO の最適化を実行すると、どんな小...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています多くの企業...
コダックのチーフ ブロガーであるジェニー シズニー氏は、同社の「1000 ワード ブログ」に投稿した...
ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスご存知のとおり、Weib...
外部リンク構築に関して、誰もがまず思い浮かべるのは友好的なリンク交換だと思います。リンク交換は、外部...
国美は自社製品を拼多多の店頭に並べた。ピンドゥオドゥオは4月19日、家電販売チェーンの国美小売が発行...
3月3日の早朝、一部のWeiboユーザーは、Alibaba Cloudでシステム障害が発生したようだ...
最近、Discuz! 公式サイトの「アプリケーション センター」セクションに、ウェブマスターがニーズ...
1. クラウドネイティブの技術的背景現在、デジタルトランスフォーメーションはあらゆる業界に徐々に浸透...
ウェブサイトが価値があるかどうかを判断することよりも、ウェブサイトの個々のページの価値を判断すること...
グループ購入ウェブサイトの出現により、Taobao、JD.com、Dangdang、Suning.c...
みなさんこんにちは。私は新しいウェブマスターのMemoryです。今日は、非常に現実的なテーマについて...
資金と交通量の不足という状況の中で、いくつかの独立した共同購入企業は、敵であり味方でもある Juhu...
[[387817]] Why's THE Design は、コンピュータ分野におけるプログラ...