コンテナ内のOpenSUSEなどのDebianホストでdockerを実行するにはどうすればよいですか?別々のモジュールで異なるカーネルを使用します。また、古いDebianバージョンは古いカーネルを使用しているため、カーネルバージョン3.10以降でどのように実行できますか?古いカーネルには古い組み込み関数しかありませんが、古いディストリビューションはどのようにして新機能を管理できますか?その「トリック」とは何ですか?
コンテナ内のOpenSUSEなどのDebianホストでdockerを実行する方法
カーネルは同じであり、すべてのコンテナイメージを実行するDockerエンジンをサポートするため:ホストカーネルは3.10以上である必要がありますが、その システムコールのリスト はかなり安定しています。
「 Architecting Containers:Why User Space vs.Kernel Space Matters 」を参照してください:
- アプリケーションにはビジネスロジックが含まれていますが、システムコールに依存しています。
- アプリケーションがコンパイルされると、アプリケーションが使用する(つまり依存する)システムコールのセットは、バイナリに埋め込まれます(高レベル言語では、これはインタープリターまたはJVMです)。
- コンテナは、ユーザー空間とカーネル空間がシステムコールの共通セットを共有する必要性を抽象化しません。
- コンテナ化された世界では、このユーザースペースは束ねられ、ラップトップから本番サーバーまでのさまざまなホストに出荷されます。
- 今後数年間で、これは課題を作成します。
時々、新しいシステムコールが追加され、古いシステムコールは廃止されます。これは、コンテナインフラストラクチャとその中で実行されるアプリケーションのライフサイクルについて考えるときに考慮する必要があります。
「 なぜカーネルバージョンがDockerコンテナのUbuntuバージョンと一致しないのですか? :
コンテナ内にカーネルはありません。カーネルをインストールしても、コンテナの起動時にカーネルはロードされません。コンテナのまさに目的は、新しいカーネルを実行することなくプロセスを分離することです。
Dockerは決して異なるカーネルを使用しません。カーネルは常にホストカーネルです。
ホストカーネルが、実行するコンテナ内のソフトウェアと「十分に互換性がある」場合、動作します。それ以外の場合はできません。
「コンテナ」は単なるプロセス構成です
理解しておくべき重要なことは、Dockerコンテナーはnot仮想マシンであることです。ソフトウェアを実行する新しい仮想コンピューターは作成されません。代わりに、Dockerは、コマンドラインからプロセスを開始するのと同じように、既存のOSでプロセスを実行するだけです。
コンテナ化されたプロセスと通常のプロセスの違いは、コンテナ化されたプロセスに課せられた制限と、その周囲の環境を見る方法の変更です。 (これらは、コンテナ化されたプロセスによって開始されたすべての子プロセスに渡されます。)典型的な制限と変更は次のとおりです。
/
(通常はコンテナのイメージで提供されるもの)に別のファイルシステムをマウントします。ホストファイルシステムの一部は、新しいプロセスのルートファイルシステムの下にマウントできます。 docker run -v /u/myprogram-data:/var/data/myprogram
を使用して、コンテナ化されたプロセスが/var/data/myprogram/file
を読み書きするときに、ホストファイルシステムで/u/myprogram-data/file
を読み書きします。ps
または同様のコマンドを使用して)表示できるが、ホストで実行中の他のプロセスは表示できないようにします。これらはすべて、カーネルに組み込まれた機能によって実行されます。適切なセットアップを行い、新しいプロセスを開始するときに適切なパラメーターを設定するプログラムを作成すれば、Dockerを使用せずに自分で行うことができます。
互換性
では、「互換性が十分」とはどういう意味ですか?それは、プログラムがカーネルに要求するもの(システムコール)と、カーネルがサポートすることを期待する機能に依存します。一部のプログラムは、物事を壊すような要求を行います。他の人はしません。たとえば、Ubuntu 18.04(カーネル4.19)または同様のホスト:
docker run centos:7 bash
は正常に動作します。docker run centos:6 bash
は終了コード139で失敗します。これは、セグメンテーション違反信号で終了したことを意味します。これは、4.19カーネルがbash
のビルドが実行しようとしたことをサポートしていないためです。docker run centos:6 ls
は正常に機能します。これは、bash
がそうであったように、カーネルが処理できない要求を行っていないためです。古いカーネル、たとえば4.9以前でdocker run centos:6 bash
を試すと、正常に動作することがわかります。 (少なくとも私がテストした限りでは。)