GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

phusion

baseimage-docker – ドッカーの使いやすさのために修正された最小限のUbuntuベースイメージ

投稿日:

ドッカーの使いやすさのために修正された最小限のUbuntuベースイメージ http://phusion.github.io/baseimage-do…

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プロセスがありません。 結果として、それらの容器は時間の経過とともにゾンビプロセスで満たされるようになる。

さらに、 docker stop SIGTERMをinitプロセスに送信し、initプロセスはすべてのサービスを停止します。 残念ながら、ほとんどのinitシステムはDocker内で正しく動作しません。なぜなら、Dockerはハードウェアシャットダウンのために構築されているからです。 これにより、SIGKILLを使用してプロセスを強制終了させることができます.SIGKILLは、正しく初期化解除する機会を与えません。 これにより、ファイルが破損する可能性があります。

Baseimage- /sbin/my_initには、これらのタスクを正しく実行するinitプロセス/sbin/my_initが付属しています。

DockerとAPTの非互換性を修正 https://github.com/dotcloud/docker/issues/1024を参照してください
syslog-ng カーネル自体を含む多くのサービスが/ var / log / syslogに正しくログできるようにsyslogデーモンが必要です。 syslogデーモンが実行されていない場合、多くの重要なメッセージが黙って呑み込まれます。

ローカルでのみ聞きます。 すべてのsyslogメッセージは「ドッカーログ」に転送されます。

なぜsyslog-ngですか?
私はrsyslogについて悪い経験をしています。 私は定期的にrsyslogのバグに遭遇し、しばらくの間、何もできない100%CPUループに入ることでログホストをダウンさせます。 Syslog-ngははるかに安定しているようです。

ログローテート ログを定期的に回転して圧縮します。
SSHサーバー コンテナに簡単にログインして、物を点検または管理することができます。

SSHはデフォルトで無効になっており、この目的のためにbaseimage-dockerによって提供されるメソッドの1つに過ぎません。 他の方法はドッカーのエグゼクティブです。 docker execはいくつかの注意点があるため、SSHは代替手段としても提供されています。

パスワードとチャレンジ/レスポンス認証は、デフォルトで無効になっています。 キー認証のみが許可されます。

クロン 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 --envENVコマンドで設定された環境変数はすべて、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.shcontainer_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 --helpdocker 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ホスト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 stopdocker 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-ngcron 、および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コマンドを進めることができます。

結論

Phusionの製品、baseimage-dockerをお楽しみください。 🙂







-phusion

執筆者: