GNU/Linux >> Linux の 問題 >  >> Panels >> Docker

Dockerとは何ですか?それはどのように機能しますか?

この包括的なガイドでは、Dockerとは何か、その進化、基盤となるコアLinuxの概念、およびその仕組みについて説明しました。

Dockerは、コンテナーベースの実装に関してはデファクトスタンダードになっています。 Dockerは、小規模な実装から大規模なエンタープライズアプリケーションまでのコンテナーベースのオーケストレーションの基盤です。

Dockerは、移植性のために開発され、最新のマイクロサービスアーキテクチャ向けに設計されているため、DevOpsコミュニティで急速に人気と採用を獲得しました。

このブログでは、学習します

  1. Dockerとは何ですか?
  2. Dockerについて学び、Dockerが他のコンテナーテクノロジーとは異なり、有益である理由を確認してください。
  3. Dockerコアアーキテクチャとその主要コンポーネント
  4. コンテナの進化とLinuxコンテナの基本的な概念
  5. コンテナとは何ですか?また、どのLinux機能がコンテナを機能させますか?
  6. プロセス、コンテナ、VMの違い

ここでの考え方は、Dockerが実際に何であり、どのように機能するかを理解するための基本を正しく理解することです。

Dockerとは何ですか?

Dockerは、goで記述され、Dotcloud(A PaaS Company)によって開発された人気のあるオープンソースプロジェクトです。

これは、Linuxカーネル機能を使用するコンテナエンジンです。 オペレーティングシステム上にコンテナを作成するためのネームスペースやコントロールグループのようなものです。したがって、これをOSレベルの仮想化と呼ぶことができます。

Dockerは当初、 Linuxコンテナー(LXC)の上に構築されていました 。その後、DockerはLXCをコンテナーランタイムlibcontainer(現在はruncの一部)に置き換えました。記事の最後に、LXCとコンテナーのコアコンセプトについて説明しました。

すべての概念と実装が似ているので、DockerがLinux Container(LXC)とどのように違うのか疑問に思われるかもしれません。

Dockerには、単なるコンテナーテクノロジーであるだけでなく、アプリケーションのパッケージ化を容易にする明確に定義されたラッパーコンポーネントがあります。 。 Dockerの前は、コンテナーを実行するのは簡単ではありませんでした。つまり、すべてのアプリケーションシステム要件をコンテナにパックすることで、アプリケーションをインフラストラクチャから切り離すためのすべての作業を実行します。

たとえば、Java jarファイルがある場合は、Javaがインストールされている任意のサーバーで実行できます。同様に、Dockerを使用して必要なアプリケーションを含むコンテナーをパッケージ化すると、Dockerがインストールされている他のホストで実行できます。

いくつかのDockerコマンドとパラメーターを実行することで、コンテナーを稼働させます。

Dockerとコンテナの違い

Dockerは、コンテナーを効率的に管理するために開発されたテクノロジーまたはツールです。

では、Dockerなしでコンテナを実行できますか?

はい!もちろん。 LXCテクノロジーを使用して、Linuxサーバーでコンテナーを実行できます。さらに、Podmanのような最新のツールは、Dockerのような同様のワークフローを提供します。

Dockerについて知っておくべきこと:

  1. DockerはLXCではありません
  2. Dockerは仮想マシンソリューションではありません。
  3. Dockerは構成管理システムではなく、Chef、Puppet、Ansibleなどの代わりにはなりません。
  4. Dockerはサービステクノロジーとしてのプラットフォームではありません。
  5. Dockerはコンテナではありません。

Dockerの優れた点は何ですか?

Dockerには、アプリケーションを開発者のラップトップからテスト環境、そして本番環境に移動するための効率的なワークフローがあります。アプリケーションをDockerイメージにパッケージ化する実際の例を見ると、それについてさらに理解できます。

Dockerコンテナの起動に1秒もかからないことをご存知ですか? ?

信じられないほど高速で、互換性のあるLinuxカーネルを備えた任意のホストで実行できます。 (Windowsもサポート)

注: WindowsのLinuxカーネルサポートがないため、LinuxホストでWindowsコンテナを実行することはできません。ここからWindowsコンテナについて読むことができます

Dockerは、イメージストレージにコピーオンライトユニオンファイルシステムを使用します。したがって、コンテナに変更が加えられると、書き込みモデルのコピーを使用して変更のみがディスクに書き込まれます。

コピーオンライトを使用すると、すべてのコンテナの共有ストレージレイヤーが最適化されます。

Docker採用統計

これがDockerのGoogleトレンドデータです。過去5年間、爆発的な話題になっていることがわかります。

これは、Dockerの採用が増加していることを示すDatadogの調査結果です。

Dockerコアアーキテクチャ

次のセクションでは、Dockerアーキテクチャとそれに関連するコンポーネントについて説明します。また、Dockerを機能させるために各コンポーネントがどのように連携するかについても見ていきます。

Dockerアーキテクチャは、その開始以来、数回変更されています。この記事の最初のバージョンを公開したとき、DockerはLXCの上に構築されていました

Dockerで発生した注目すべきアーキテクチャの変更は次のとおりです

  1. Dockerは2014年にLXCからlibcontainerに移行しました
  2. runc –すべてのOCI仕様に従うコンテナーをスピンアップするためのCLI。
  3. containerd – Dockerは、2016年にコンテナー管理コンポーネントをcontainerdに分離しました

OCI:Open Container Initiativeは、コンテナーの実行時間と仕様に関するオープンな業界標準です。

Dockerが最初に起動されたとき、それはモノリシックアーキテクチャを持っていました。現在、次の3つの異なるコンポーネントに分けられています。

  1. Docker Engine(dockerd)
  2. docker-containerd(containerd)
  3. docker-runc(runc)

Dockerやその他の大規模な組織は、標準のコンテナーランタイムおよび管理レイヤーに貢献しました。したがって、containerd およびrunc 現在、すべての組織からの貢献者とともにCloudNativeFoundationの一部になっています。

注: Dockerをインストールすると、これらすべてのコンポーネントがインストールされます。個別にインストールする必要はありません。説明のために、さまざまなコンポーネントとして示しています。

それでは、各Dockerコンポーネントを見てみましょう。

Dockerエンジン

Dockerエンジンは、Dockerデーモン、APIインターフェース、およびDockerCLIで構成されます。 Dockerデーモン(dockerd)は、dockerdとして継続的に実行されます systemdサービス。 Dockerイメージの構築を担当します。

イメージを管理してコンテナを実行するには、dockerd docker-containerdを呼び出します API。

docker-containerd(containerd)

containerd Dockerイメージをダウンロードしてコンテナーとして実行するのとは別のシステムデーモンサービスです。 dockerdから命令を受け取るためにAPIを公開します サービス

docker-runc

runc は、コンテナに必要な名前名とcgroupの作成を担当するコンテナランタイムです。次に、それらの名前空間内でコンテナコマンドを実行します。 runcランタイムは、OCI仕様に従って実装されます。

コンテナランタイムの詳細については、この優れた3部構成のブログ投稿シリーズをお読みください。

Dockerはどのように機能しますか?

Dockerのコアビルディングブロックを見てきました。

それでは、Dockerコンポーネントを使用したDockerワークフローを理解しましょう。

Dockerコンポーネント

次の公式の高レベルのDockerアーキテクチャ 図は、一般的なDockerワークフローを示しています。

Dockerエコシステムは、次の4つのコンポーネントで構成されています

  1. Docker Daemon(dockerd)
  2. Dockerクライアント
  3. Docker画像
  4. Dockerレジストリ
  5. Dockerコンテナ

Dockerデーモンとは何ですか?

Dockerにはクライアントサーバーアーキテクチャがあります。 Dockerデーモン(dockerd )またはサーバーは、コンテナに関連するすべてのアクションを担当します。

デーモンは、CLIまたはRESTAPIを介してDockerクライアントからコマンドを受け取ります。 Dockerクライアントは、デーモンと同じホスト上にある場合も、他のホスト上に存在する場合もあります。

デフォルトでは、dockerデーモンはdocker.sockをリッスンします UNIXソケット。 Docker APIにリモートでアクセスするユースケースがある場合は、ホストポートを介して公開する必要があります。そのようなユースケースの1つは、DockerをJenkinsエージェントとして実行することです。

Docker内でDockerを実行する場合は、docker.sockを使用できます。 ホストマシンから。

Dockerイメージとは何ですか?

イメージはDockerの基本的な構成要素です。これには、OSライブラリ、依存関係、およびアプリケーションを実行するためのツールが含まれています。

コンテナーを作成するためのアプリケーションの依存関係を使用して、イメージを事前に構築できます。たとえば、Nginx WebサーバーをUbuntuコンテナーとして実行する場合は、NginxバイナリとNginxの実行に必要なすべてのOSライブラリを使用してDockerイメージを作成する必要があります。

Dockerfileとは何ですか?

DockerにはDockerfileの概念があります これは、イメージの構築に使用されます。 Dockerfileは、1行に1つのコマンド(命令)を含むテキストファイルです。

これがDockerfileの例です。

Dockerイメージは、レイヤー化された方法で編成されます。 Dockerfileのすべての命令 画像にレイヤーが追加されます。画像の最上位の書き込み可能なレイヤーはコンテナです。

すべての画像はベース画像から作成されます。

たとえば、Ubuntuのベースイメージを使用して、Nginxアプリケーションで別のイメージを作成できる場合です。ベースイメージは、親イメージまたは親イメージから構築されたイメージにすることができます。詳細については、彼のDockerの記事をご覧ください。

このベースイメージ(親イメージ)はどこから来たのかと疑問に思うかもしれません。初期の親ベースイメージを作成するためのDockerユーティリティがあります。必要なOSライブラリを取得し、それらをベースイメージに焼き付けます。 Linuxディストリビューションの公式ベースイメージを取得するため、これを行う必要はありません。

画像の最上層は書き込み可能であり、実行中のコンテナーによって使用されます。画像内の他のレイヤーは読み取り専用です。

Dockerレジストリとは何ですか?

Dockerイメージのリポジトリ(ストレージ)です。

レジストリはパブリックまたはプライベートにすることができます。たとえば、Docker Incは、DockerHubと呼ばれるホストされたレジストリサービスを提供します。中央の場所から画像をアップロードおよびダウンロードできます。

注: デフォルトでは、dockerをインストールすると、Docker設定でカスタムレジストリを指定しない限り、パブリックDockerハブからイメージが検索されます。

リポジトリが公開されている場合、他のDockerハブユーザーはすべてのイメージにアクセスできます。 DockerHubでプライベートレジストリを作成することもできます。

Dockerハブはgitのように機能し、ラップトップ上でローカルにイメージをビルドしてコミットし、Dockerハブにプッシュできます。

ヒント: エンタープライズネットワーク/プロジェクトでDockerを使用する場合は、パブリックDockerハブを使用する代わりに、独自のDockerレジストリを設定してください。すべてのクラウドプロバイダーには、独自のコンテナーレジストリサービスがあります。

Dockerコンテナとは何ですか?

Dockerコンテナーは、既存のイメージから作成されます。これは、画像の書き込み可能なレイヤーです。

画像レイヤーとコンテナを関連付けようとすると、ubuntuベースの画像がどのように検索されるかを次に示します。

アプリケーションをコンテナーにパッケージ化してコミットし、それをゴールデンイメージにして、そこからさらにコンテナーを構築することができます。

コンテナは、開始、停止、コミット、および終了できます。コンテナをコミットせずに終了すると、コンテナの変更はすべて失われます。

理想的には、コンテナーは不変オブジェクトとして扱われ、実行中のコンテナーに変更を加えることはお勧めしません。代わりに、テスト目的でのみ実行中のコンテナに変更を加えてください。

2つ以上のコンテナをリンクして、階層型アプリケーションアーキテクチャを形成できます。ただし、kubernetesなどのコンテナオーケストレーションツールの登場により、Dockerを使用したスケーラブルなアプリケーションのホスティングが容易になりました。

コンテナの進化

コンテナ化が新しいテクノロジーだと思うなら、そうではありません。 Googleは、インフラストラクチャでコンテナテクノロジーを何年も使用しています。

コンテナの概念は2000年代に始まりました。実際、ルートは、プロセスのルートディレクトリを変更するという概念であるchrootがあった1979年にさかのぼります。

これは2000年に開始されたコンテナベースのプロジェクトのリストです。

テクノロジー
2000 FreeBSDjailsはコンテナの概念を導入しました。
2003 OSレベルの仮想化の概念でリリースされたLinux-Vサーバープロジェクト
2005 Solarisゾーン–OSレベルの仮想化プロジェクトが導入されました
2007 GoogleはGenericProcessContainersに関する論文をリリースしました
2008 LXCコンテナーの初期リリース
2011 cloudfoundryが監視員を発表
2013 lcmcty–Googleがオープンソース
2013 DockerプロジェクトはDotCloudによって発表されました
2014 ロケット。 (rkt)CoreOSが発表
2016 WindowsServer2016の一部としてリリースされたWindowsコンテナープレビュー

Linuxコンテナ(LXC)とは何ですか?

では、Linuxコンテナとは何かを理解しましょう。

一般的な仮想化環境では、1つ以上の仮想マシンがXen、Hyper-Vなどのハイパーバイザーを使用して物理サーバー上で実行されます。

一方、コンテナはオペレーティングシステムのカーネル上で実行されます。これは、OSレベルの仮想化と呼ぶことができます。基礎となるコンテナの概念に入る前に、2つの主要なLinuxの概念を理解する必要があります。

  1. ユーザースペース: ユーザープログラム(アプリケーション、プロセス)を実行するために必要なすべてのコードは、ユーザースペースと呼ばれます。たとえば、ファイルを作成するためにプログラムアクションを開始すると、ユーザースペースのプロセスがKernalスペースへのシステムコールを行います。
  2. カーネルスペース :これはオペレーティングシステムの心臓部であり、システムハードウェアやストレージなどと相互作用するカーネルコードがあります。

コンテナはプロセスです。

Nginx Webサーバーなどのアプリケーションを起動すると、プロセスが開始されます。プロセス自体は、分離が制限された自己完結型の命令です。

実行と操作に必要なファイルと構成のみでプロセスを分離できるとしたらどうでしょうか。それがコンテナの役割です。

コンテナはプロセスです 個別のオペレーティングシステムの感覚を与えるために、ユーザースペースコンポーネントを十分に分離します。

親コンテナプロセスには子プロセスが含まれる場合があります。つまり、コンテナはプロセスのグループでもあると言えます。 。

たとえば、Nginxサービスを開始すると、親Nginxプロセスが開始されます。親プロセスは、キャッシュマネージャー、キャッシュローダー、ワーカーなどの子プロセスにまたがっています。

したがって、Nginxコンテナーを開始すると、分離された環境でマスターNginxプロセスが開始されます。

これについては、以下のセクションで実際に説明します。

各コンテナーには分離されたユーザースペースがあり、単一のホストで複数のコンテナーを実行できます。

これは、コンテナにOS全体があるという意味ですか ?

いいえ。カーネルを備えたVMとは異なり、コンテナには特定のディストリビューションに関連する必要なファイルが含まれ、共有ホストカーネルを使用します。

さらに興味深いことに、単一のホストでさまざまなLinuxディストリビューションベースのコンテナを実行できます 同じカーネル空間を共有します。

たとえば、UbuntuサーバーでRHEL、CentOS、SUSEベースのコンテナーを実行できます。すべてのLinuxディストリビューションでユーザースペースのみが異なり、カーネルスペースは同じであるため、これが可能です。

Linuxコンテナの基本概念

次の画像は、Linuxの大陸を視覚的に表したものです。

コンテナは、ネームスペースとコントロールグループと呼ばれる2つのLinuxカーネル機能を使用して分離されています。

実際の例えは、アパートの建物です。単一の大きな建物ですが、各コンドミニアム/フラットは、計量された水、ガス、電気で独自のアイデンティティを持つ個々の世帯のために隔離されています。この隔離を確立するために、コンクリート、鉄骨構造、およびその他の建設資材を使用します。許可されない限り、他の家を見ることができません。

同様に、これを複数のコンテナを含む単一のホストに関連付けることができます。コンテナをCPU、メモリ、IPアドレス、マウントポイント、プロセスで分離するには、2つのLinuxカーネル機能が必要です。 名前名とコントロールグループと呼ばれます。

Linux名前空間

コンテナーとは、サービス(プロセス)を実行するための十分に分離された環境を持つことです。このレベルの分離を実現するには、コンテナにファイルシステム、IPアドレス、マウントポイント、プロセスIDなどが必要です。これはLinux名前空間を使用して実現できます。

名前空間は、コンテナのマウントポイント、ユーザー、IPアドレス、プロセス管理などを担当します。したがって、基本的に、名前空間はコンテナの境界を設定します。

Linuxの主な名前名は次のとおりです

  1. pid名前空間 :プロセスの分離を担当します(PID:プロセスID)。
  2. ネット名前空間 :ネットワークインターフェイスを管理します(NET:ネットワーク)。
  3. ipc名前空間 :IPCリソースへのアクセスを管理します(IPC:プロセス間通信)。
  4. mnt名前空間 :ファイルシステムのマウントポイントの管理を担当します(MNT:マウント)。
  5. uts名前空間 :カーネルとバージョンの識別子を分離します。 (UTS:Unixタイムシェアリングシステム)。
  6. usr名前空間: ユーザーIDを分離します。簡単に言うと、ホストとコンテナの間でユーザーIDを分離します。
  7. Cgroup名前空間: コントロールグループ情報をコンテナプロセスから分離します

上記の名前空間を使用すると、コンテナはネットワークインターフェイス、IPアドレスなどを持つことができます。各コンテナには名前空間があり、その名前空間内で実行されているプロセスには、その名前空間外の特権はありません。

興味深いことに、lsnsを使用して、Linuxマシンの名前名を一覧表示できます。 コマンド。

Linuxコントロールグループ

サービスを開始するときに、メモリやCPUの制限は指定しません。代わりに、サービスのリソースに優先順位を付けて割り当てるために、カーネルに任せます。

ただし、CGroupsと呼ばれるLinuxカーネル機能を使用して、サービスのCPUメモリ制限を明示的に設定できます。 。これは単純なアプローチではありません。それを機能させるには、いくつかの追加の構成と微調整を行う必要があります。

ホスト内で複数のコンテナを実行できるため、リソースの使用やデバイスへのアクセスなどを制限するメカニズムが必要です。ここで、コントロールグループが重要になります。

Linuxコントロールグループは、コンテナーによって使用されるリソースを管理します。コンテナLinuxコントロールグループのCPU、メモリ、ネットワーク、およびIOリソースを制限できます。

では、コンテナのCPUとメモリのリソースを制限しないとどうなりますか?

1つのコンテナがすべてのホストリソースを使用し、リソースが利用できないために他のコンテナがクラッシュする可能性があります。

Dockerのようなツールは、すべての複雑なバックエンド構成を抽象化し、単純なパラメーターでこれらのリソース制限を指定できるようにします。

コンテナがVMより優れているのはなぜですか?

コンテナには、VMに比べていくつかの重要な利点があります。それらを見てみましょう。

リソースの使用率とコスト

  1. VMを使用して、アプリケーションを個別に実行できます。つまり、VMごとに1つのサービスを実行できます。しかし、それでも十分に活用されていない可能性があります。また、VMのサイズ変更は、実稼働アプリケーションにとって簡単な作業ではありません。
  2. 一方、コンテナは最小限のCPUとメモリの要件で実行できます。また、アプリケーションを分離するために、VM内で複数のコンテナーを実行することもできます。さらに、コンテナのサイズ変更には数秒かかります。

プロビジョニングと展開

  1. 関連するワークフローによっては、VMのプロビジョニングとVMへのアプリケーションのデプロイに数分から数時間かかる場合があります。ロールバックでも時間がかかります。
  2. ただし、コンテナを数秒でデプロイし、数秒でロールバックすることもできます。

ドリフト管理

  1. VMでのドリフト管理は簡単ではありません。すべての環境が類似していることを確認するには、本格的な自動化とプロセスが必要です。不変のデプロイメントモデルに従うことで、VM環境のドリフトを回避できます。
  2. イメージがバックアップされると、コンテナのすべての環境で同じになります。したがって、変更を加える場合は、dev envで変更を開始し、コンテナイメージを再ベイクする必要があります。
ドッカーに関するよくある質問

containeredとruncの違いは何ですか?

containerdはコンテナーの管理を担当し、runcはcontainerdからの入力を使用してコンテナーを実行する(コンテナー内で名前空間、cgroupを作成し、コマンドを実行する)責任があります

DockerエンジンとDockerデーモンの違いは何ですか?

Dockerエンジンは、Dockerデーモン、RESTインターフェース、およびDockerCLIで構成されています。 Dockerデーモンは、dockerイメージを構築し、docker命令をcontainerdランタイムに送信するsystemddockerdサービスです。


Docker
  1. Webサーバーとは何ですか?Webサーバーはどのように機能しますか?

  2. コンテナ化とは何ですか?DockerとKubernetesとはどのように関連していますか?

  3. Dockerコンテナに静的IPを割り当てる方法

  1. Makefileとは何ですか?どのように機能しますか?

  2. NGINXとは何ですか?それはどのように機能しますか?

  3. DNSとは何ですか?どのように機能しますか?

  1. DockerコンテナでMySQLを実行する方法

  2. DockerコンテナにSSHで接続する方法

  3. DockerコンテナにVimをインストールする方法