Dockerコンテナ内でシェルが動く理屈がわかりません


[Dockerコンテナのシェルの中に入る -
Qiita](https://qiita.com/__cooper/items/4740c24666299c366044)

`docker exec` にシェルを指定することでコンテナ内でシェルを操作できます。  
このシェルはホストのものではなくコンテナのものだと思うのですが、シェルというのはOSのカーネルと対話するものですよね。たとえば`httpd`のイメージ等はWebサーバー用のイメージですからOSというものは内蔵されていないと思うのですが、なぜシェルが動くのでしょうか？

シェルが持つ代表的なコマンドが動くような最小限のOSがコンテナに内蔵されているのでしょうか？




("OSの`カーネル`と対話するものですよね" 辺りの文章の意図するところを理解できていませんが、タイトルの疑問に関しては)

単に`シェル`と呼ばれるプログラムがあらかじめコンテナイメージにインストールされているから動く、というだけです。

> `httpd`のイメージ

というのは

  * <https://hub.docker.com/_/httpd>

のことだと思いますが、 このページからリンクされている[GitHub上のリポジトリ](https://github.com/docker-
library/httpd/)に登録されている`Dockerfile`を見ると、ベースは[Debian](https://github.com/docker-
library/httpd/blob/6c8e82e20ecefc94c616439f15d14c4bb215b200/2.4/Dockerfile#L1)か[Alpine](https://github.com/docker-
library/httpd/blob/f5ef4cc849a4ea7ed56e797b86ad06ccf9f93a9a/2.4/alpine/Dockerfile#L1)であることがわかります。  
Debianであれば[`dash`](https://ja.wikipedia.org/wiki/Debian_Almquist_shell)が、Alpine
Linuxであれば([busybox](https://wiki.alpinelinux.org/wiki/How_to_get_regular_stuff_working#Shell_.40_commandline)の)[`ash`](https://ja.wikipedia.org/wiki/Almquist_Shell)が、
`/bin/sh` として入っています。

(ちなみに[`alpine`イメージ](https://hub.docker.com/_/alpine)の`Dockerfile`は[これ](https://github.com/alpinelinux/docker-
alpine/blob/v3.9/x86_64/Dockerfile)ですね。[`debian`](https://hub.docker.com/_/debian)は[スクリプトから生成している](https://github.com/debuerreotype/docker-
debian-artifacts)っぽく、`Dockerfile`そのものはバージョン管理対象ではなさそうでした)

* * *

例えばAlpineのイメージで`bash`を使いたい場合、素の状態ではインストールされていないので利用できませんが、[こちらのイメージ](https://hub.docker.com/_/bash)のように[別途インストール](https://github.com/tianon/docker-
bash/blob/master/5.0/Dockerfile)すれば利用できるようになる、というそれだけのことです。

使いたいプログラムが`シェル`と呼ばれるカテゴリに属しているかどうかは特に影響しない話かと思います。

* * *

> `シェル`が持つ代表的なコマンドが動くような最小限のOSがコンテナに内蔵されているのでしょうか？

`シェル`そのものが内蔵されています、というのが回答になります。




Docker のイメージにはユーザー空間向けのファイルやデータしか含まれません。カーネルイメージ (`/boot/vmlinuz*`)
に相当するものは含まれません。コンテナ内のカーネルサービスはホスト OS 環境が提供するものを利用します。

コンテナとはホスト OS の各種リソース (プロセス ID、ファイルシステム、ネットワークなど) を分離してコンテナ専用の OS
環境を用意するものです。コンテナ内には OS のサービスとしてユーザー空間もカーネル空間は存在するし、当然どちらも利用できます。

`docker exec ...` すると Docker はコンテナを作成しますが、それはそのコンテナ用の名前空間 (`namespaces`(7))
を作成して隔離された OS 環境一式を作成し、その中で指定のコマンド (シェルなど) を起動しているに過ぎません。

コンテナ内でシェルが利用できるかどうかはコンテナイメージ内のファイル構成に依ります。シェルそのもの (`/bin/sh` など)
のほか、シェルの実行に必要な共有ライブラリ等が存在すれば利用できるでしょう。それらを含めないコンテナイメージも作成可能です。

