Github: https://github.com/phusion/baseimage-docker
Dockerの使いやすさのために修正された最小限のUbuntuベースイメージ
Baseimage-dockerは8.3 MBのRAMしか消費せず、BusyboxやAlpineよりはるかに強力です。 以下の理由を参照してください。
Baseimage-dockerは、Dockerコンテナ内で正しく使用できるように設定された特別なDockerイメージです。 それはUbuntuです。
- ドッカーの親しみやすさのための変更。
- Dockerのコンテキストで特に便利な管理ツール。
- Dockerの哲学に違反することなく 、複数のプロセスを簡単に実行するためのメカニズム。
Dockerイメージのベースとして使用できます。
Baseimage-docker はDockerレジストリから引き出すことができます !
在庫のあるUbuntuベースイメージの問題は何ですか?
UbuntuはDocker内で動作するようには設計されていません。 そのinitシステムUpstartは、それが実際のハードウェアまたは仮想化されたハードウェア上で実行されていると仮定しますが、Dockerコンテナ内では実行されません。 しかし、コンテナ内では、完全なシステムを望んでいません。 最小限のシステムが必要です。 コンテナ内で使用するための最小限のシステムを設定することは、Unixシステムモデルに精通していない場合には困難に直面する多くの変なコーナーケースを伴います。 これは、多くの奇妙な問題を引き起こす可能性があります。
Baseimage-dockerはすべてのものを正しく取得します。 「目次」セクションには、変更されるすべてのものが記載されています。
なぜbaseimage-dockerを使うのですか?
あなたはあなたのDockerファイルから在庫ubuntu
イメージを自分で設定することができます。なぜ、baseimage-dockerを使用するのはなぜですか?
- Dockerの使いやすさのためにベースシステムを設定することは簡単な作業ではありません。 前述したように、多くのコーナーケースがあります。 すべての権利を得た時点で、あなたはベースイメージドッカーを再発明しました。 baseimage-dockerを使用すると、この作業を省くことができます。
- これは、正しいDockerfileを書くために必要な時間を短縮します。 基本システムについて心配する必要はなく、スタックとアプリケーションに集中することができます。
-
docker build
を実行するのに必要な時間が短縮され、Dockerファイルをより迅速に反復することができます。 - 再デプロイ時のダウンロード時間を短縮します。 Dockerは最初のデプロイ時にベースイメージを一度ダウンロードすればよい。 その後の各デプロイでは、ベースイメージの上に加えた変更だけがダウンロードされます。
関連リソース : ウェブサイト | Github | ドッカーレジストリ | ディスカッションフォーラム | Twitter | ブログ
目次
イメージの中身は何ですか?
概要
Ruby、Python、Node.js、Meteor Webアプリケーションに最適な、より完全なベースイメージを探していますか? 乗客ドッカーを見てください。
成分 | なぜそれが含まれていますか? / 備考 |
---|---|
Ubuntu 16.04 LTS | ベースシステム。 |
正しい initプロセス | 主な記事: ドッカーとPID 1ゾンビ刈り上げ問題 。
Unixプロセスモデルによると、 initプロセス (PID 1)はすべての孤立した子プロセスを継承し、 それらを刈り取る必要があります 。 ほとんどのDockerコンテナには、これを正しく行うinitプロセスがありません。 結果として、それらの容器は時間の経過とともにゾンビプロセスで満たされるようになる。 さらに、 Baseimage- |
DockerとAPTの非互換性を修正 | https://github.com/dotcloud/docker/issues/1024を参照してください 。 |
syslog-ng | カーネル自体を含む多くのサービスが/ var / log / syslogに正しくログできるようにsyslogデーモンが必要です。 syslogデーモンが実行されていない場合、多くの重要なメッセージが黙って呑み込まれます。
ローカルでのみ聞きます。 すべてのsyslogメッセージは「ドッカーログ」に転送されます。 なぜsyslog-ngですか? |
ログローテート | ログを定期的に回転して圧縮します。 |
SSHサーバー | コンテナに簡単にログインして、物を点検または管理することができます。
SSHはデフォルトでは無効になっており、この目的のためにbaseimage-dockerによって提供されるメソッドの1つに過ぎません。 他の方法はドッカーのエグゼクティブです。 パスワードとチャレンジ/レスポンス認証は、デフォルトで無効になっています。 キー認証のみが許可されます。 |
クロン | cronジョブが動作するには、cronデーモンが実行されていなければなりません。 |
それを実行します | UbuntuのUpstartを置き換えます。 サービスの監督と管理に使用されます。 SysV initよりも使いやすく、クラッシュ時にデーモンを再起動することができます。 Upstartよりもはるかに使いやすく軽量です。 |
setuser |
別のユーザーとしてコマンドを実行するためのツール。 su よりも使いやすく、 sudo より攻撃ベクトルが小さく、 chpst とは異なり、このツールは$HOME 正しく設定します。 /sbin/setuser として利用できます。 |
install_clean |
それ自身の後に自動的にクリーンアップするapt パッケージをインストールするためのツール。 すべての引数はapt-get -y install --no-install-recommends 渡され、インストール後にはaptキャッシュがクリアされます。 推奨パッケージを含めるには、 --install-recommends 追加します。 |
Baseimage-dockerは非常に軽量で、8.3 MBのメモリしか消費しません。
さて、私はDockerがコンテナ内で単一のプロセスを実行していると考えましたか?
Dockerの開発者は、コンテナごとに単一の論理サービスを実行するという理念を提唱しています。 論理サービスは、複数のOSプロセスで構成できます。
Baseimage-dockerは、単一のコンテナ内で複数のOSプロセスを実行することを推奨しています。 最低限、PID 1の問題と「syslogブラックホール」の問題を解決するため、これは理にかなっていると考えています。 複数のプロセスを実行することにより、最小のオーバーヘッドで、コンテナを複数の論理サービスに変えることなく、非常に実際のUnix OSレベルの問題を解決します。
論理サービスを複数のOSプロセスに分割することも、セキュリティの観点からは理にかなっています。 異なるユーザーとしてプロセスを実行することで、脆弱性の影響を制限できます。 Baseimage-dockerは、実行中のプロセスを異なるユーザ、例えばsetuser
ツールとして奨励するためのツールを提供します。
1つのコンテナ内で複数の論理サービスを実行することを推奨していますか? 必ずしもそうではありませんが、私たちはそれを禁止しません。 Dockerの開発者は、非常に意見があり、コンテナの構築方法について非常に堅実な考え方を持っていますが、Baseimage-dockerは完全に解読されていません。 私たちは自由を信じています。単一のコンテナで複数のサービスを実行するのが理にかなっていることもあります。 Docker開発者ではなく、何が理にかなっているかはあなた次第です。
Baseimage-dockerは「太った容器」や「容器をVMとして扱う」ことを主張していますか?
Baseimage-dockerは複数のプロセスの使用を主張しているため、Baseimage-dockerがコンテナをVMとして扱うことを主張すると考える人がいます。 したがって、Baseimage-dockerはDockerの哲学に従わないとも考えています。 これらの印象はどちらも真実ではありません。
Docker開発者は、単一のコンテナ内で単一の論理サービスを実行することを推奨しています。 しかし、我々はそれについて論争していない。 Baseimage-dockerは、単一のコンテナ内で複数のOSプロセスを実行することを主張し、単一の論理サービスは複数のOSプロセスで構成できます。
Baseimage-dockerは、Dockerの哲学を否定しません。 実際、私たちが紹介した変更の多くは明示的にDockerの哲学に沿ったものです。 たとえば、環境変数を使用してコンテナにパラメータを渡すことは、「Dockerのやり方」であり、さまざまなユーザーとして実行される複数のプロセスが存在する環境変数で簡単に処理するメカニズムを提供します。
baseimage-dockerの検査
画像を見渡すには、次のコマンドを実行します。
docker run --rm -t -i phusion/baseimage:<VERSION> /sbin/my_init -- bash -l
ここで、 <VERSION>
はbaseimage-dockerのバージョン番号の1つです 。
手動で何かをダウンロードする必要はありません。 上記のコマンドは、Dockerレジストリからbaseimage-dockerイメージを自動的に取得します。
baseimage-dockerをベースイメージとして使用する
入門
イメージはphusion/baseimage
と呼ばれ、Dockerレジストリで利用できます。
# Use phusion/baseimage as base image. To make your builds reproducible, make
# sure you lock down to a specific version, not to `latest`!
# See https://github.com/phusion/baseimage-docker/blob/master/Changelog.md for
# a list of version numbers.
FROM phusion/baseimage:<VERSION>
# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]
# ...put your own build instructions here...
# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
追加のデーモンの追加
あなたはrunitエントリを作成することによって、デーモン(例えば自分のアプリ)を画像に追加することができます。 あなたのデーモンを実行する小さなシェルスクリプトを書かなければなりません。そして、runitはあなたのために実行し続け、クラッシュ時に再起動します。
シェルスクリプトはrun
と呼ばれ、実行可能でなければならず、 /etc/service/<NAME>
ディレクトリに配置されなければなりません。
次に、memcachedサーバーのrunitエントリを作成する方法を示す例を示します。
memcached.sh
(このファイルがchmod + xであることを確認してください):
#!/bin/sh
# `/sbin/setuser memcache` runs the given command as the user `memcache`.
# If you omit that part, the command will be run as root.
exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
Dockerfile
:
RUN mkdir /etc/service/memcached
COPY memcached.sh /etc/service/memcached/run
RUN chmod +x /etc/service/memcached/run
シェルスクリプトは、デーモンをデーモン/フォークさせることなくデーモンを実行する必要があることに注意してください。 通常、デーモンはそのためにコマンドラインフラグまたは設定ファイルオプションを提供します。
コンテナの起動時にスクリプトを実行する
baseimage-docker initシステム/sbin/my_init
、起動時に次の順序で次のスクリプトを実行します。
-
/etc/my_init.d
(このディレクトリが存在する場合)内のすべての実行可能スクリプト。 スクリプトは辞書順に実行されます。 - このファイルが存在する場合、スクリプト
/etc/rc.local
。
すべてのスクリプトは、たとえば終了コード0で正しく終了する必要があります。終了コードが0以外のスクリプトが終了した場合、起動は失敗します。
重要:コンテナを対話モードで実行している場合(つまり、コンテナを-it
実行する場合)、デーモンモードではなく、stdoutを直接端末に送信しています( -i
対話型-t
端末)。 実行宣言で/sbin/my_init
ない場合は、 /sbin/my_init
は実行されないため、コンテナの起動時にはスクリプトは呼び出されません。
次の例は、起動スクリプトを追加する方法を示しています。 このスクリプトは、ブート時の時刻を単に/tmp/boottime.txtファイルに記録します。
logtime.sh
:
#!/bin/sh
date > /tmp/boottime.txt
Dockerfile
:
RUN mkdir -p /etc/my_init.d
COPY logtime.sh /etc/my_init.d/logtime.sh
RUN chmod +x /etc/my_init.d/logtime.sh
プロセスのシャットダウン
/sbin/my_init
は、シャットダウン時に子プロセスの終了を処理します。 SIGTERMを受信すると、正しいシャットダウンのためにシグナルを子プロセスに渡します。 プロセスがシェルスクリプトで開始されている場合は、実際のプロセスをexec
てください。そうでなければ、シェルはプロセスではなくシグナルを受け取ります。
/sbin/my_init
は5秒のタイムアウト後にプロセスを終了します。 これは環境変数を設定することで調整できます:
# Give children processes 5 minutes to timeout
ENV KILL_PROCESS_TIMEOUT=300
# Give all other processes (such as those which have been forked) 5 minutes to timeout
ENV KILL_ALL_PROCESSES_TIMEOUT=300
環境変数
メインコンテナコマンドとして/sbin/my_init
を使用すると、 docker run --env
またはdocker run --env
のENV
コマンドで設定された環境変数はすべて、my_initによって取得されmy_init
。 これらの変数は、/etc/my_init.d起動スクリプト、Runit管理サービス、Runit管理サービスなど、すべての子プロセスにも渡されます。 ただし、注意すべき注意点がいくつかあります。
- Unix上の環境変数は、プロセスごとに継承されます。 これは、一般に、子プロセスが他のプロセスの環境変数を変更することは不可能であることを意味します。
- 前述の点から、すべてのアプリケーションとサービスの環境変数を定義するための中心的な場所はありません。 Debianは
/etc/environment
ファイルを持っていますが、いくつかの状況でしか動作しません。 - いくつかのサービスは、子プロセスの環境変数を変更します。 Nginxはそのような例の1つです。環境変数を
env
設定オプションで保持するよう明示的に指示しない限り、すべての環境変数を削除します。 Nginx上でアプリケーションをホストしている場合(例えば、 乗客ドッカー画像を使用する、または自分の画像でPhusion Passengerを使用する場合)、Dockerが最初に渡した環境変数は表示されません。 - 私たちは、HOME、SHELL、USER、および他の環境変数を意図的に無視します。無視しないと 、マルチユーザコンテナが壊れるからです。 https://github.com/phusion/baseimage-docker/pull/86を参照してください
HOME
環境変数の設定の回避策は、RUN echo /root > /etc/container_environment/HOME
ます。 https://github.com/phusion/baseimage-docker/issues/119をご覧ください。
my_init
はこれらすべての警告の解決策を提供します。
独自の環境変数を集中的に定義する
起動時に、 起動スクリプトを実行する前に、 my_init
は/etc/container_environment
ディレクトリから環境変数をインポートします。 このディレクトリには、環境変数名の後に付けられたファイルが含まれています。 ファイルの内容には環境変数の値が含まれています。 したがって、このディレクトリは、すべての起動スクリプトとRunitサービスによって継承される独自の環境変数を一元的に定義するのに適しています。
たとえば、Dockerファイルから環境変数を定義する方法は次のとおりです。
RUN echo Apachai Hopachai > /etc/container_environment/MY_NAME
次のように動作することを確認できます。
$ docker run -t -i <YOUR_NAME_IMAGE> /sbin/my_init -- bash -l
...
*** Running bash -l...
# echo $MY_NAME
Apachai Hopachai
改行の処理
注意深く見たなら、 ‘echo’コマンドが実際に改行を出力することに気付くでしょう。 $ MY_NAMEに改行が含まれていないのはなぜですか? これは、 my_init
が末尾の改行をmy_init
ためmy_init
。 値を改行したい場合は、次のように別の改行を追加する必要があります:
RUN echo -e "Apachai Hopachai\n" > /etc/container_environment/MY_NAME
環境変数ダンプ
前述のメカニズムは環境変数を一元的に定義するのに適していますが、サービス自体(例えばNginx)が子プロセスから環境変数を変更したりリセットしたりするのを防ぐことはできません。 しかし、 my_init
メカニズムは、元の環境変数が何であるかを簡単に照会できるようにします。
起動時に、 /etc/container_environment
から環境変数をインポートした直後に、 my_init
はすべての環境変数(つまり、 container_environment
からインポートされたすべての変数と、 docker run --env
から取得したすべての変数)を次の場所にdocker run --env
ます次の形式で使用できます。
-
/etc/container_environment
-
/etc/container_environment.sh
– 環境変数をBash形式でダンプします。 このファイルはBashシェルスクリプトから直接ソースできます。 -
/etc/container_environment.json
– JSON形式の環境変数をダンプします。
複数の形式を使用すると、スクリプト/アプリケーションがどの言語で書かれていても、元の環境変数を簡単に照会することができます。
次に、ダンプの様子を示すシェルセッションの例を示します。
$ docker run -t -i \
--env FOO=bar --env HELLO='my beautiful world' \
phusion/baseimage:<VERSION> /sbin/my_init -- \
bash -l
...
*** Running bash -l...
# ls /etc/container_environment
FOO HELLO HOME HOSTNAME PATH TERM container
# cat /etc/container_environment/HELLO; echo
my beautiful world
# cat /etc/container_environment.json; echo
{"TERM": "xterm", "container": "lxc", "HOSTNAME": "f45449f06950", "HOME": "/root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "FOO": "bar", "HELLO": "my beautiful world"}
# source /etc/container_environment.sh
# echo $HELLO
my beautiful world
環境変数の変更
/etc/container_environment
内のファイルを変更することによって、 my_init
(したがって、その時点以降に生成されるすべての子プロセスの環境変数)の環境変数を変更することもできます。 my_init
が起動スクリプトを実行するたびに、自身の環境変数を/etc/container_environment
状態にリセットし、新しい環境変数をcontainer_environment.sh
およびcontainer_environment.json
再ダンプします。
ただし、
-
container_environment.sh
とcontainer_environment.json
を変更しても効果はありません。 - Runitサービスは、そのような環境を変更することはできません。
my_init
は、起動スクリプトの実行時にのみ/etc/container_environment
変更をアクティブにします。
セキュリティ
環境変数には機密情報が含まれている可能性があるため、 /etc/container_environment
とそのBashおよびJSONダンプはデフォルトでrootによって所有され、 docker_env
グループのみがアクセスできます。
環境変数に機密データが含まれていないことが確かな場合は、そのディレクトリとそのファイルの権限を世界的に読めるようにしてリリースすることもできます。
RUN chmod 755 /etc/container_environment
RUN chmod 644 /etc/container_environment.sh /etc/container_environment.json
システムロギング
Baseimage-dockerはsyslog-ngを使用して、コンテナにsyslog機能を提供します。 Syslog-ngはrunitサービスとして管理されません(下記参照)。 Syslogメッセージはコンソールに転送されます。
ログの起動/停止のシーケンス
すべてのアプリケーションログメッセージがsyslog-ngによって確実にキャプチャされるように、syslog-ngはrunitスーパーバイザプロセスの前に別々に起動され、runit終了後にシャットダウンされます。 これは、このイメージが提供する起動スクリプト機能を使用します。 これにより、syslog-ngがrunitサービスとして管理されていて、runitがsyslog-ngをコンテナの他のサービスと並行して終了させる場合に存在する競合状態が回避され、syslog-ngがログ中に終了すると正常終了時にログメッセージが破棄されるまだ他のサービスによって生産されています。
コンテナ内のオペレーティングシステムのアップグレード
Baseimage-dockerイメージには、Ubuntu 16.04オペレーティングシステムが含まれています。 このOSを随時更新したい場合があります。たとえば、最新のセキュリティアップデートを取得する場合などです。 OpenSSLは有名な例です。 OpenSSLの脆弱性は定期的に発見されるため、OpenSSLを可能な限り最新の状態に保つ必要があります。
最新のOSアップデートを含むBaseimage-dockerイメージを随時リリースしていますが、私たちに頼る必要はありません。 Baseimage-dockerイメージ内のOSを自分で更新することができます。それを待つのではなく、これを行うことをお勧めします。
イメージ内のOSをアップグレードするには、Dockerfileでこれを実行します。
RUN apt-get update && apt-get upgrade -y -o Dpkg::Options::="--force-confold"
コンテナ管理
Dockerの背後にあるアイデアの1つは、コンテナがステートレスで、簡単に再起動可能で、ブラックボックスのように動作することです。 ただし、開発、検査、デバッグの目的で、コンテナにログインしたり、コンテナ内でコマンドを実行したりする場合があります。 このセクションでは、これらの目的のためにコンテナを管理する方法について説明します。
新しいコンテナでワンショットコマンドを実行する
注:このセクションでは、insider-new-containerコマンドを実行する方法について説明します。 既存の実行中のコンテナ内でコマンドを実行するには、既存の実行中のコンテナでコマンドを実行するを参照してください。
通常、新しいコンテナを作成してその中で単一のコマンドを実行し、コマンドが終了した後すぐに終了する場合は、Dockerを次のように起動します。
docker run YOUR_IMAGE COMMAND ARGUMENTS...
しかし、このアプローチの欠点は、initシステムが起動していないことです。 つまり、 COMMAND
を呼び出すと、cronやsyslogなどの重要なデーモンは実行されません。 また、 COMMAND
はPID 1であるため、孤立した子プロセスは適切に収穫されません。
Baseimage-dockerは、上記の問題のすべてを解決しながら、単一のワンショットコマンドを実行する機能を提供します。 次のように1つのコマンドを実行します。
docker run YOUR_IMAGE /sbin/my_init -- COMMAND ARGUMENTS ...
これにより、以下が実行されます。
- /etc/my_init.d/*や/etc/rc.localなど、すべてのシステム起動ファイルを実行します。
- すべてのrunitサービスを開始します。
- 指定されたコマンドを実行します。
- 指定されたコマンドが終了すると、すべてのrunitサービスが停止します。
例えば:
$ docker run phusion/baseimage:<VERSION> /sbin/my_init -- ls
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 80
*** Running ls...
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
*** ls exited with exit code 0.
*** Shutting down runit daemon (PID 80)...
*** Killing all processes...
デフォルトの呼び出しがあまりにも騒々しいことがあります。 あるいは、スタートアップファイルを実行したくないかもしれません。 引数をmy_init
渡すことですべてをカスタマイズできます。 詳細については、 docker run YOUR_IMAGE /sbin/my_init --help
起動してdocker run YOUR_IMAGE /sbin/my_init --help
をdocker run YOUR_IMAGE /sbin/my_init --help
してください。
次の例では、すべてのrunitサービスを実行している間に、起動ファイルを実行せずにメッセージを少なくしてls
を実行します。
$ docker run phusion/baseimage:<VERSION> /sbin/my_init --skip-startup-files --quiet -- ls
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
既存の実行中のコンテナでコマンドを実行する
既存の実行中のコンテナ内でコマンドを実行するには、2つの方法があります。
-
docker exec
ツールを介して。 これはDocker 1.4以降で使用可能なDockerツールに組み込まれています。 内部的には、コンテナのコンテキスト内でコマンドを実行するために、Linuxカーネルシステムコールを使用します。docker exec
経由で、ログインをコンテナに追加するか、その中でコマンドを実行してください。 - SSHを介して。 この方法では、コンテナ内でSSHデーモンを実行する必要があり、SSHキーを設定する必要があります。 SSH経由で、ログインをコンテナに追加するか、その中でコマンドを実行してください。
どちらの方法もそれぞれの賛否両論があり、それぞれの小節で学ぶことができます。
docker exec
を使用して、コンテナにログインするか、内部でコマンドを実行する
DockerホストOS上のdocker docker exec
ツールを使用して、baseimage-dockerに基づく任意のコンテナにログインすることができます。 また、実行中のコンテナ内でコマンドを実行するために使用することもできます。 docker exec
は、Linuxカーネルシステムコールを使用して動作します。
SSHを使用してコンテナにログインするか、コンテナにコマンドを実行する方法と比較してみましょう 。
- 長所
- コンテナ内でSSHデーモンを実行する必要はありません。
- SSHキーを設定する必要はありません。
- ベースイメージドッカーをベースにしていないコンテナであっても、どのコンテナでも動作します。
- 短所
- ホスト上の
docker exec
プロセスがシグナル(kill
コマンドやCtrl-Cなど)によって終了した場合、docker exec
によって実行されたコマンドは強制終了されずクリーンアップされません 。 手動で行うか、-t -i
docker exec
を実行する必要があり-t -i
。 - Dockerデーモンにアクセスするには、Dockerホストに対する特権が必要です。 Dockerデーモンに効果的にアクセスできる人は、誰でもルートアクセス権を持っていることに注意してください。
- ユーザーがDockerホストにログインさせずにコンテナにログインできるようにすることはできません。
- ホスト上の
使用法
コンテナを開始する:
docker run YOUR_IMAGE
今実行したコンテナのIDを確認する:
docker ps
IDをdocker exec
ので、 docker exec
を使用してコンテナ内で任意のコマンドを実行することができます。 たとえば、 echo hello world
を実行するには:
docker exec YOUR-CONTAINER-ID echo hello world
コンテナ内でbashセッションを開くには、端末が利用できるように-t -i
渡す必要があります:
docker exec -t -i YOUR-CONTAINER-ID bash -l
SSH経由でコンテナにログインするか、その中でコマンドを実行する
SSHを使用して、baseimage-dockerに基づく任意のコンテナにログインすることができます。 また、実行中のコンテナ内でコマンドを実行するために使用することもできます。
docker exec
を使用してコンテナにログインする方法や、その内部でコマンドを実行する方法と比較してみdocker exec
う 。
- 長所
- Dockerホストにroot権限を必要としません。
- ユーザーがDockerホストにログインさせることなく、コンテナにログインできるようにします。 ただし、これはデフォルトでは有効になっていません。これは、baseimage-dockerがデフォルトで公開インターネットにSSHサーバーを公開しないためです。
- 短所
- SSHキーの設定が必要です。 しかし、ベースイメージドッカーは、あらかじめ生成された不安定なキーによって、これを多くの場合に容易にします。 詳細はこちらをお読みください。
SSHの有効化
Baseimage-dockerはデフォルトでSSHサーバーを無効にします。 Dockerファイルに以下を追加して有効にします。
RUN rm -f /etc/service/sshd/down
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
または、コンテナの単一のインスタンスに対してのみsshdを有効にするには、 起動スクリプトを含むフォルダを作成します。 その内容は
### In myfolder/enable_ssh.sh (make sure this file is chmod +x):
#!/bin/sh
rm -f /etc/service/sshd/down
ssh-keygen -P "" -t dsa -f /etc/ssh/ssh_host_dsa_key
その後、あなたはコンテナを始めることができます
docker run -d -v `pwd`/myfolder:/etc/my_init.d my/dockerimage
これは、コンテナのブート時にsshdを初期化します。 以下のように、安全でないキーを使用してアクセスしたり、セキュリティ保護されたキーを追加する方法を使用してアクセスできます。 さらに、ポートをマシンに-p 2222:22で公開すると、コンテナのIPアドレスを検索する代わりに、sshを127.0.0.1:2222にすることができます。
SSHキーについて
まず、適切なSSHキーがコンテナ内にインストールされていることを確認する必要があります。 デフォルトでは、キーはインストールされていないため、誰もログインできません。 便宜上、私たちは簡単に有効にすることができる、事前に生成された安全でない鍵 (PuTTY形式)を提供します。 ただし、このキーは便宜上のものです。 この鍵(公開鍵と秘密鍵の両方)は一般公開されているため、セキュリティは提供されません。 実稼働環境では、独自の鍵を使用する必要があります 。
1つのコンテナのみに安全でないキーを使用する
1つのコンテナに対してのみ非セキュアキーを一時的に有効にすることができます。 これは、安全でないキーがコンテナの起動時にインストールされることを意味します。 docker stop
とdocker start
がコンテナをdocker start
た場合、安全でないキーはそこに残っていますが、 docker run
を使用して新しいコンテナを起動すると、そのコンテナには安全でないキーが含まれません。
--enable-insecure-key
付けてコンテナを起動し--enable-insecure-key
:
docker run YOUR_IMAGE /sbin/my_init --enable-insecure-key
今実行したコンテナのIDを確認する:
docker ps
IDを取得したら、次のようにIPアドレスを探します。
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
IPアドレスを取得したので、SSHを使用してコンテナにログインしたり、コンテナ内のコマンドを実行したりすることができます。
# Download the insecure private key
curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/services/sshd/keys/insecure_key
chmod 600 insecure_key
# Login to the container
ssh -i insecure_key root@<IP address>
# Running a command inside the container
ssh -i insecure_key root@<IP address> echo hello world
安全でない鍵を永続的に有効にする
イメージ内の安全でないキーを永久に有効にすることもできます。 これはお勧めできませんが、セキュリティが重要でない一時的な開発環境やデモ環境に適しています。
Dockerfileを編集して、安全でない鍵を永続的にインストールしてください:
RUN /usr/sbin/enable_insecure_key
コンテナへのログイン手順は、 1つのコンテナにのみ安全でないキーを使うを参照してください。
独自のキーを使用する
Dockerfileを編集してSSH公開鍵をインストールします:
## Install an SSH of your choice.
COPY your_key.pub /tmp/your_key.pub
RUN cat /tmp/your_key.pub >> /root/.ssh/authorized_keys && rm -f /tmp/your_key.pub
その後、イメージを再構築します。 一度それを持って、そのイメージに基づいてコンテナを開始します:
docker run your-image-name
今実行したコンテナのIDを確認する:
docker ps
IDを取得したら、次のようにIPアドレスを探します。
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
IPアドレスを取得したので、SSHを使用してコンテナにログインしたり、コンテナ内のコマンドを実行したりすることができます。
# Login to the container
ssh -i /path-to/your_key root@<IP address>
# Running a command inside the container
ssh -i /path-to/your_key root@<IP address> echo hello world
docker-ssh
ツール
コンテナのIPを調べてSSHコマンドを実行すると、すぐに退屈になります。 幸運にも、このプロセスを自動化するdocker-ssh
ツールを提供しています。 このツールは、Dockerコンテナ内ではなく、 Dockerホスト上で実行されます。
まず、Dockerホストにツールをインストールします。
curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \
tar xzf master.tar.gz && \
sudo ./baseimage-docker-master/install-tools.sh
次に、次のようにツールを実行して、SSHを使用してコンテナにログインします。
docker-ssh YOUR-CONTAINER-ID
docker ps
実行すると、あなたのYOUR-CONTAINER-ID
参照することができます。
デフォルトでは、 docker-ssh
はBashセッションを開きdocker-ssh
。 コマンドを実行するように指示して終了することもできます。
docker-ssh YOUR-CONTAINER-ID echo hello world
自分でイメージを構築する
どんな理由であれ、Dockerレジストリからダウンロードするのではなく、自分でイメージを構築したい場合は、以下の手順に従ってください。
このリポジトリをクローン:
git clone https://github.com/phusion/baseimage-docker.git
cd baseimage-docker
Dockerで仮想マシンを起動します。 既に提供しているVagrantファイルを使用することができます。
vagrant up
vagrant ssh
cd /vagrant
イメージを構築する:
make build
結果のイメージを別のものにする場合は、NAME変数を次のように渡します。
make build NAME=joe/baseimage
オプションサービスの削除
デフォルトのbaseimage-dockerは、ビルドプロセス中にsyslog-ng
、 cron
、およびsshd
サービスをインストールします。
イメージにこれらのサービスの1つまたは複数が必要ない場合は、そのインストールを無効にすることができます。
次の例に示すように、イメージにsshd
がインストールされないようにするには、. ./image/buildconfig
ファイルのDISABLE_SSH
変数に1
を設定します。
### In ./image/buildconfig
# ...
# Default services
# Set 1 to the service you want to disable
export DISABLE_SYSLOG=0
export DISABLE_SSH=1
export DISABLE_CRON=0
その後、 make build
コマンドを進めることができます。
結論
- baseimage-dockerを使用していますか? 私たちについてのTweetやTwitterで私たちに従ってください 。
- 問題がありますか? 開発に参加したいですか? ディスカッションフォーラムにメッセージを投稿してください。
- Ruby、Python、Node.js、Meteor Webアプリケーションに最適な、より完全なベースイメージを探していますか? 乗客ドッカーを見てください。
Phusionの製品、baseimage-dockerをお楽しみください。 🙂