仮想マシン
 Computer >> コンピューター >  >> ソフトウェア >> 仮想マシン

Docker コンテナの完全な導入ガイド

大きな約束から始めましょう。あなたは今日、この記事を絶対に気に入るはずです。それは長く、詳細で、非常に役立つものになるでしょう。 GRUB、GRUB2 を考えてみてください。ここでも同じです。 Linux Containers (LXC) テクノロジーをシンプルで便利な方法でラップする優れたディストリビューション プラットフォームである Docker に取り組むだけです。

開始方法を説明し、SSH と Apache を使用して独自のコンテナーを作成し、Dockerfile の使用方法を学び、サービス ポートを公開し、通常は公開フォーラムでは対処されない膨大な数の小さなバグや問題を解決します。 .遠慮なくフォローしてください。


目次


  1. はじめに
  2. Docker の実装
  3. はじめに
  4. Docker コマンド
  5. プル画像
  6. Docker コンテナを開始する
  7. Apache と SSH をインストールする <オール>
  8. サービス開始
  9. アパッチ サービス
  10. SSH サービス
  • Web サーバーが起動しているかどうかを確認する <オール>
  • 受信ポートを公開する
  • IP アドレスを確認する
  • 新しい構成のテスト
  • SSH が機能するかどうかを確認する <オール>
  • ちょっと待って、root パスワードは何ですか?
  • イメージをコミットする
  • Dockerfile <オール>
  • ビルド イメージ
  • テスト画像
  • 代替ビルド <オール>
  • COPY 命令
  • コンテナの利点
  • 発生する可能性のある問題とトラブルシューティング
  • 追加コマンド <オール>
  • exec と attach の違い
  • 開始と実行の違い
  • ビルドと作成の違い
  • これはほんの始まりに過ぎません ...
  • 続きを読む
  • 結論

  • はじめに

    昨年のどこかで Gizmo's Freeware の記事でこの技術の概要を簡単に説明しました。それでは、Docker の使用に真剣に取り組みます。まず、このフレームワークを使用すると、細かいことを気にすることなく、便利な方法で LXC を使用できることを覚えておくことが重要です。これはこの世界の次のステップであり、OpenStack が仮想化の世界における次の進化のステップであるのと同じです。歴史と類推をいくつか紹介しましょう。

    仮想化は、ハードウェアを抽象化できるソフトウェアから始まりました。次に、物事を高速化するために、仮想化プログラムはハードウェア アクセラレーションを使用し始め、その後、準仮想化も実現しました。最終的には、ハイパーバイザーが雨上がりのきのこのように出現し始め、すべてをプロビジョニングして管理することがやや難しくなりました。これが、統一された API の下にさまざまなプラットフォームを隠す OpenStack のような概念の主な理由です。

    コンテナも同様の方法で進み始めました。まず、chroot がありましたが、jailed 環境内で実行されているプロセスは同じ名前空間を共有し、同じリソースを求めて戦いました。次に、kexec システム コールを取得しました。これにより、BIOS を介さずに別のカーネルのコンテキストで起動できます。その後、制御グループが登場し、CPU、メモリなどのシステム リソースをサブグループに分割できるようになりました。これにより、システム上で実行されているプロセスをより適切に制御できるようになり、その名前が付けられました。

    その後、Linux カーネルは、基本的なパーティション分割メカニズムとして cgroup を使用して、リソースの完全な分離を提供し始めました。技術的には、これはシステム レベルの仮想化テクノロジであり、自己完結型環境内の制御ホスト上で実行中のカーネルの複数のインスタンスを実行できますが、パフォーマンスのペナルティとオーバーヘッドがほとんどないという追加のボーナスがあります。

    OpenVZ など、いくつかの競合するテクノロジが同様のソリューションを提供しようとしましたが、コミュニティは最終的にその焦点をメインライン カーネル内のネイティブな有効化に絞り込みました。これが将来の方向性であると思われます。それでも、コンテナを実行するにはかなりの量の技術的知識とスクリプト作成が必要なため、LXC の使用はやや難しいままです。

    これがDockerの出番です。ざらざらした部分を取り除いて、インフラストラクチャ バックエンドを気にせずに新しいコンテナ インスタンスを生成する簡単な方法を提供しようとします。よくほとんど。しかし、難易度ははるかに低いです。

    Docker のもう 1 つの強力な利点は、広くコミュニティに受け入れられていることと、クラウド サービスとの統合が重視されていることです。これは、AWS、Hadoop、Azure、Jenkins などの大企業の名前を挙げていることを意味します。次に、Platform as a Service (Paas) についても話します。これが今後数年間でどれだけのお金と焦点を獲得するか想像できます。技術的な状況は巨大で混乱を招き、Docker の上に構築される概念とラッパー テクノロジがますます増えて、変化と進化を続けることは間違いありません。

    しかし、私たちは技術面に集中したいと考えています。基本を習得したら、ゆっくりと拡張し、強力な統合機能とソリューションの柔軟性を活用し始め、クラウド エコシステムの専門知識を多様化、自動化、および純粋なラッドにすることに取り組みます。それは今すぐには実現しませんが、最初の数マイル、または数キロメートルという泥だらけのスタートアップの水域をナビゲートする手助けをしたいので、賢明で効率的な方法で Docker を使い始めることができます。これは新しい技術であるため、そこにはワイルド ウェストがあり、ほとんどのオンライン ドキュメント、ヒント、チュートリアルなどは時代遅れであり、誰の役にも立たないコピー アンド ペースト バージョンであり、ほとんどが不完全です。今日はそれを直したい。

    Docker の実装

    クールなことをする前に、もう少し退屈なことをしましょう。とにかく、Docker は主に LXC に関するものですが、それだけではありません。拡張できるように設計されており、libvirt および systemd とも連携できます。将来の成長の可能性があり、追加のモジュールが追加されると、Xen や KVM などの従来のハイパーバイザーや、libvirt とその仲間を使用するものを効果的に置き換えることができるため、ある意味では、これはほとんどハイパー ハイパーバイザーのようになります。

    あなたが疑問に思った場合、これはパブリックドメインの画像です.

    はじめに

    CentOS 7 を使用してデモを行います。Ubuntu ではありません。ほとんどのオンラインのものは Ubuntu に焦点を当てていますが、Linux のできるだけエンタープライズに近いフレーバーを使用してそれがどのように行われるかをお見せしたいと思います。まず、docker をインストールします:

    yum install docker-io

    ソフトウェアをインストールしたら、使用を開始できます。ただし、docker コマンドを初めて実行しようとすると、次の 2 つの問題が発生する場合があります。

    docker <任意のコマンド>
    FATA[0000] https:///var/run/docker.sock/v1.18/images/json を取得:unix にダイヤル /var/run/docker.sock:そのようなファイルやディレクトリはありません。 TLS なしで TLS が有効なデーモンに接続しようとしていますか?

    そして、他のエラーは次のとおりです:

    docker <任意のコマンド>
    FATA[0000] https:///var/run/docker.sock/v1.18/containers/json を取得:unix にダイヤル /var/run/docker.sock:権限が拒否されました。 TLS なしで TLS が有効なデーモンに接続しようとしていますか?

    その理由は、最初に Docker サービスを開始する必要があるからです。さらに、Docker はシステムのかなり機密性の高い部分にアクセスし、カーネルとやり取りする必要があるため、テクノロジーをルートとして実行する必要があります。それがどのように機能するかです。

    systemctl 起動ドッカー

    これで夢中になって Docker を使い始めることができます。

    Docker コマンド

    基本的なことは、 docker help を実行して、使用可能なコマンドのリストを取得することです。すべてのオプションを実行するわけではありません。進めていくうちに、それらについてさらに学びます。一般に、疑問がある場合は、かなりまともなオンライン ドキュメントを参照してください。完全な CLI リファレンスも素晴らしいです。また、GitHub には優れたチート シートもあります。しかし、最初のミッションは、新しい Docker イメージをダウンロードしてから、最初のインスタンスを実行することです。

    プル画像

    利用可能な画像がたくさんあります。 CentOSで練習したいです。これは良い出発点です。公式リポジトリが利用可能で、サポートされているすべてのイメージとタグがリストされています。実際、この時点で、Docker イメージがどのようにラベル付けされているかを理解する必要があります。

    命名規則は、たとえば centos:latest のように、repository:tag です。つまり、最新の CentOS イメージが必要です。ただし、必要なイメージは centos:6.6 である可能性もあります。よし、やろう。

    次に、docker images コマンドを実行してイメージを一覧表示しましょう:

    Docker コンテナーを開始する

    元のチュートリアルで見たように、最も簡単な例はシェルを実行することです:

    docker run -ti centos:centos7 /bin/bash

    では、ここには何がありますか? CentOS 7 イメージから、BASH シェルを使用して、独自の TTY (-t) と STDIN (-i) を持つ新しいコンテナー インスタンスを実行しています。数秒で、コンテナ内に新しいシェルができます。現在、これは非常に基本的な、非常に簡素化されたオペレーティング システムですが、その中で何かを構築することができます。

    Apache と SSH のインストール

    SSH アクセスもできる Web サーバーをセットアップしましょう。この目的のために、かなり基本的なインストールを行う必要があります。 Apache (httpd) と SSHD (openssh-server) を入手して設定します。これは Docker 自体とは何の関係もありませんが、役に立つ演習です。

    コンテナー内で SSH を使用する必要はありません。セキュリティ上のリスクがあり、その他のことも含まれます。まあ、おそらく、必要なものとコンテナの使用目的に応じて、はいまたはいいえです。ただし、セキュリティに関する考慮事項は脇に置いておきます。この演習の目的は、任意のサービスをセットアップして実行する方法を学習することです。

    サービス開始

    init スクリプトまたは systemd コマンドを使用して Apache を起動することをお勧めします。これではうまくいきません。具体的には CentOS の場合、systemd が付属していますが、さらに重要なことに、コンテナーには独自の systemd がありません。試行すると、コマンドは失敗します。

    systemctl start httpd
    D-Bus 接続の取得に失敗しました:サービス マネージャーへの接続がありません。

    この問題にはハックがあり、今後のチュートリアルでこれらのいくつかについて学びます。しかし、一般に、コンテナーの軽量で単純な性質を考えると、プロセスを実行するために本格的なスタートアップ サービスは必要ありません。これにより、複雑さが増します。

    アパッチ サービス

    Apache (HTTPD) を実行するには、/usr/sbin/httpd を実行するか、ディストリビューションで同等のコマンドを実行します。ほとんどの場合、httpd.conf で ServerName ディレクティブを構成していないという警告が表示されます。これを行う方法は、私のかなり広範な Apache ガイドで学びました。

    /usr/sbin/httpd
    AH00558:httpd:172.17.0.4 を使用して、サーバーの完全修飾ドメイン名を確実に判別できませんでした。このメッセージを抑制するには、'ServerName' ディレクティブをグローバルに設定してください

    SSH サービス

    SSHD では、/usr/sbin/sshd を実行します。

    /usr/sbin/sshd -f /etc/ssh/sshd_config
    ホスト キーを読み込めませんでした:/etc/ssh/ssh_host_rsa_key
    ホスト キーを読み込めませんでした:/etc/ssh/ssh_host_dsa_key
    ホスト キーを読み込めませんでした:/etc/ssh/ssh_host_ecdsa_key
    ホスト キーを読み込めませんでした:/etc/ssh/ssh_host_ed25519_key

    すべてのキーを持っていないため、失敗することもあります。通常、起動スクリプトがこれを取得するため、サービスが正しく起動する前に ssh-keygen コマンドを 1 回実行する必要があります。 2 つのコマンドのいずれかが機能します:

    /usr/bin/ssh-keygen -t rsa -f <ファイルへのパス>

    /usr/bin/ssh-keygen -A
    ssh-keygen:新しいホスト キーの生成:RSA1 RSA DSA ECDSA ED25519

    Web サーバーが起動しているかどうかを確認します

    これで、コンテナー内で Apache が実際に実行されていることがわかります。

    ps -ef|grep Apache
    アパッチ 87 86 0 10:47 ? 00:00:00 /usr/sbin/httpd
    アパッチ 88 86 0 10:47 ? 00:00:00 /usr/sbin/httpd
    アパッチ 89 86 0 10:47 ? 00:00:00 /usr/sbin/httpd
    アパッチ 90 86 0 10:47 ? 00:00:00 /usr/sbin/httpd
    アパッチ 91 86 0 10:47 ? 00:00:00 /usr/sbin/httpd

    しかし、外部接続を確認したい場合はどうすればよいでしょうか?この時点で、いくつかの問題が発生しています。 1 つ目は、いわば、開いているポートをセットアップしていません。 2 つ目は、コンテナの IP アドレスがわからないことです。ここで、BASH シェル内で ifconfig を実行しようとしても、基本的なネットワーク コマンドを含む必要なパッケージがインストールされていないため、何もできません。コンテナがスリムで安全になるので、良いです。

    受信ポートを公開する

    他の Web サーバーと同様に、着信接続を許可する必要があります。デフォルトのポート 80 を使用します。これは、ルーターのポート転送と同じであり、ファイアウォール ポリシーなどを許可します。 Docker を使用すると、目的の結果を得る方法がいくつかあります。

    run コマンドで新しいコンテナーを開始する場合、 -p オプションを使用して、開くポートを指定できます。単一のポートまたはポートの範囲を選択できます。また、ホスト ポート (hostPort) とコンテナー ポート (containerPort) の両方をマップすることもできます。例:

    • -p 80 は、コンテナー ポート 80 を公開します。これは、ホスト上のランダムなポートに自動的にマップされます。正しいポートを識別する方法については、後で学習します。
    • -p 80:80 は、コンテナー ポートをホスト ポート 80 にマップします。これは、コンテナーの内部 IP アドレスを知る必要がないことを意味します。内部 NAT の要素が関係しており、Docker 仮想インターフェイスを通過します。これについてはすぐに説明します。また、この方法を使用すると、ポート 80 にバインドできるコンテナーは 1 つだけになります。IP アドレスが異なる複数の Web サーバーを使用する場合は、それぞれを異なるポートに設定する必要があります。

    docker run -ti -p 22:22 -p 80:80 image-1:latest
    FATA[0000] デーモンからのエラー応答:コンテナーを開始できません 64bd520e2d95a699156f5d40331d1aba972039c3c201a97268d61c6ed17e1619:0.0.0.0:80 のバインドに失敗しました:ポートは既に割り当てられています

    他にも多くの考慮事項があります。 IP 転送、ブリッジ ネットワーク、パブリック ネットワークとプライベート ネットワーク、サブネット範囲、ファイアウォール ルール、負荷分散など。現時点では、これらについて心配する必要はありません。

    ポートを公開する追加の方法もありますが、後で新しいイメージを構築するためのテンプレートである Dockerfiles のトピックに触れるときに説明します。今のところ、-p オプションを使用してイメージを実行することを忘れないでください。

    IP アドレスの確認

    ホスト ポートを解放したい場合は、hostPort 部分を省略できます。その場合、コンテナの IP アドレスと Web サーバー ポートを使用して、コンテナに直接接続できます。そのためには、コンテナの詳細を把握する必要があります:

    docker inspect <コンテナ名またはID>

    これは、KVM XML 構成によく似た非常に長い詳細リストを提供しますが、これは JSON で記述されています。これは、データの別の最新の醜い形式です。読みやすいが非常に醜い。

    docker inspect の気晴らし_euclid
    [{
    "AppArmorProfile":"",
    "引数":[],
    "構成":{
    "AttachStderr":真,
    "AttachStdin":真,
    "AttachStdout":真,
    "コマンド":[
    「/ビン/バッシュ」
    ]、
    "CPUシェア":0,
    "CPUset":"",
    "ドメイン名":"",
    "エントリポイント":null,
    "環境":[
    ...
    "ExposedPorts":{
    "80/tcp":{}
    }、
    "ホスト名":"43b179c5aec7",
    "画像":"centos:centos7",
    "ラベル":{},
    "Macアドレス": ""、
    ...

    IP アドレスだけに絞り込むことができます。

    docker inspect <コンテナ名または ID> | grep -i "ipaddr"
    "IPアドレス":"172.17.0.20",

    新しい構成のテスト

    新たに始めましょう。新しいインスタンスを起動し、Apache をセットアップして起動します。 Web ブラウザーを開いてテストします。動作する場合は、Web サーバーが正しく構成されています。まさに私たちが望んでいたものです。

    docker run -it -p 80:80 centos:centos7 /bin/bash

    実行中のコンテナーを確認すると、ポート マッピングが表示されます。出力は簡潔にするために複数行に分割されています。通常、すべて大文字のタイトルは行ヘッダーとして表示され、その後、残りのすべてが下に出力され、1 行に 1 つのコンテナーが表示されます。

    # docker ps
    コンテナ ID 画像 コマンド
    43b179c5aec7 centos:centos7 "/bin/bash"

    作成済み ステータス ポート
    2 時間前 2 時間前 0.0.0.0:80->80/tcp

    名前 気晴らし_euclid

    ブラウザには次のように表示されます:

    オプション:これで、内部 IP アドレス範囲はホスト上でのみアクセス可能になります。他のマシンからアクセスできるようにしたい場合は、NAT と IP 転送が必要になります。名前を使用する場合は、/etc/hosts と DNS を適切に構成する必要があります。コンテナーの場合、これは新しいインスタンスの実行時に --add-host="host:IP" ディレクティブを使用して実行できます。

    別の注意点:他のチュートリアルで見たように、VirtualBox や KVM と同様に、Docker には独自の内部ネットワークがあることを思い出してください。これはかなり大規模な /16 ネットワークであるため、非常に多くの自由があります。ホスト上:

    # /sbin/ifconfig
    docker0:flags=4163 mtu 1500
    inet 172.17.42.1 ネットマスク 255.255.0.0 ブロードキャスト 0.0.0.0
    inet6 fe80::5484:7aff:fefe:9799 prefixlen 64 scopeid 0x20<リンク>
    イーサ 56:84:7a:fe:97:99 txqueuelen 0 (イーサネット)
    RX パケット 6199 バイト 333408 (325.5 KiB)
    RX エラー 0 ドロップ 0 オーバーラン 0 フレーム 0
    TX パケット 11037 バイト 32736299 (31.2 MiB)
    TX エラー 0 ドロップ 0 オーバーラン 0 キャリア 0 コリジョン 0

    SSH が機能しているかどうかを確認します

    SSH で同じ演習を行う必要があります。繰り返しますが、これはポート 22 を公開することを意味し、いくつかのオプションを利用できます。さらに面白くするために、ランダムなポート割り当てを試してみましょう:

    docker run -ti -p 20 -p 80 centos:centos7 /bin/bash

    特にポートについて、docker ps で確認すると:

    0.0.0.0:49176->22/tcp、0.0.0.0:49177->80/tcp Boring_mcclintock

    これは、docker0 IP アドレス、docker ps コマンド出力で指定されたポートに接続できることを意味します。これは、サービス ポートでコンテナー IP に実際に直接接続することと同等です。これは、コンテナーが使用する内部 IP アドレスを気にする必要がなく、転送を簡素化できるため、便利です。では、接続してみましょう。ホスト ポートを使用することも、コンテナ IP を直接使用することもできます。

    ssh 172.17.42.1 -p 49117

    どちらの方法でも、必要なものは得られます。たとえば、次のようになります。

    ssh 172.17.0.5
    ホスト '172.17.0.5 (172.17.0.5)' の信頼性を確立できません。 ECDSA キー フィンガープリントは 00:4b:de:91:60:e5:22:cc:f7:89:01:19:3e:61:cb:ea です。
    接続を続行しますか (はい/いいえ)?はい
    警告:既知のホストのリストに '172.17.0.5' (ECDSA) が永久に追加されました。
    root@172.17.0.5 のパスワード:

    ちょっと待って、root パスワードは何ですか?

    root パスワードがないため失敗します。今から何をする?繰り返しますが、いくつかのオプションがあります。まず、passwd コマンドを使用してコンテナー内のルート パスワードを変更してみます。しかし、passwd ユーティリティがインストールされていないため、これは機能しません。次に、必要な RPM を取得して、コンテナー内にセットアップします。ホストで、依存関係を確認します:

    rpm -q --whatprovides /etc/passwd
    セットアップ-2.8.71-5.el7.noarch

    しかし、これはセキュリティ上の脆弱性です。私たちはコンテナをスリムにしたいと考えています。したがって、パスワード ハッシュをホストの /etc/shadow からコンテナにコピーするだけです。後で、より効率的な方法について学習します。

    非常に明確に印象的なもう1つのことは、私たちがすべての行動を繰り返しているということです.これは効率的ではないため、コンテナに加えた変更を保持する必要があります。次のセクションでそれを扱います。

    イメージをコミット

    コンテナーに変更を加えた後、それをコミットすることができます。つまり、後で新しいコンテナーを開始するときに、すべての手順を最初から繰り返す必要はなく、既存の作業を再利用して時間と帯域幅を節約できます。 ID またはエイリアスに基づいてイメージをコミットできます:

    docker commit <コンテナ名またはID> <新しいイメージ>

    たとえば、次のようになります:

    docker コミット 43b179c5aec7 myapache3
    1ee373ea750434354faeb1cb70b0177b463c51c96c9816dcdf5562b4730dac54

    画像のリストをもう一度確認してください:

    Dockerfile

    A more streamlined way of creating your images is to use Dockerfiles. In a way, it's like using Makefile for compilation, only in Docker format. Or an RPM specfile if you will. Basically, in any one "build" directory, create a Dockerfile. We will learn what things we can put inside one, and why we want it for our Apache + SSH exercise. Then, we will build a new image from it. We can combine it with our committed images to preserve changes already done inside the container, like the installation of software, to make it faster and save network utilization.

    Before we go any further, let's take a look at a Dockerfile that we will be using for our exercise. At the moment, the commands may not make much sense, but they soon will.

    FROM myhttptest2:latest

    EXPOSE 22

    CMD ["/usr/sbin/sshd", "-D"]

    EXPOSE 80

    RUN mkdir -p /run/httpd
    CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

    What do we have here?

    • The FROM directory tells us what repo:tag to use as the baseline. In our case, it's one of the committed images that already contains the httpd and sshd binaries, SSH keys, and a bit more.
    • EXPOSE 22 - This line exposes port 22 inside the container. We can map it further using the -p option at runtime. The same is true for EXPOSE 80, which is relevant for the Web server.
    • CMD ["/usr/sbin/sshd", "-D"] - This instructions runs an executable, with optional arguments.それはそれと同じくらい簡単です。
    • RUN mkdir -p /run/httpd - This instruction runs a command in a new layer on top of the base image - and COMMITS the results. This is very important to remember, as we will soon discuss what happens if you don't use the RUN mkdir thingie with Apache.
    • CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"] - We run the server, in the foreground. The last bit is optional, but for the time being, you can start Apache this way. Good enough.

    As you can see, Dockerfiles aren't that complex or difficult to write, but they are highly useful. You can pretty much add anything you want. Using these templates form a basis for automation, and with conditional logic, you can create all sorts of scenarios and spawn containers that match your requirements.

    Build image

    Once you have a Dockerfile in place, it's time to build a new image. Dockerfiles must follow a strict convention, just like Makefiles. It's best to keep different image builds in separate sub-directories.例:

    docker build -t test5 .
    Sending build context to Docker daemon 41.47 kB
    Sending build context to Docker daemon
    Step 0 :FROM myapache4:latest
     ---> 7505c70235e6
    Step 1 :EXPOSE 22 80
     ---> Using cache
     ---> 58f11217c3e3
    Step 2 :CMD /usr/sbin/sshd -D
     ---> Using cache
     ---> 628c3d6b5399
    Step 3 :RUN mkdir -p /run/httpd
     ---> Using cache
     ---> 5fc118f61a4d
    Step 4 :CMD /usr/sbin/httpd -D FOREGROUND
     ---> Using cache
     ---> d892acd86198
    Successfully built d892acd86198

    The command tells us the following:-t repository name from a Dockerfile stored in the current directory (.).それで全部です。 Very simple and elegant.

    Test image

    Run a new container from the created image. If everything went smoothly, you should have both SSH connectivity, as well as a running Web server in place. Again, all the usual network related rules apply.

    Alternative build

    Once you have the knowledge how do it on your own, you can try one of the official Apache builds. Indeed, the Docker repository contains a lot of good stuff, so you should definitely invest time checking available templates. For Apache, you only need the following in your Dockerfile - the second like is optional.

    FROM httpd:2.4
    COPY ./public-html/ /usr/local/apache2/htdocs/

    COPY instruction

    What do we have above? Basically, in the Dockerfile, we have the declaration what template to use. And then, we have a COPY instructions, which will look for a public-html directory in the current folder and copy it into the container during the build. In the same manner, you can also copy your httpd.conf file. Depending on your distribution, the paths and filenames might differ. Finally, after building the image and running the container:

    docker run -ti -p 22 -p 80 image-1:latest
    AH00558:httpd:Could not reliably determine the server's fully qualified domain name, using 172.17.0.17. Set the 'ServerName' directive globally to suppress this message
    [Thu Apr 16 21:08:35.967670 2015] [mpm_event:notice] [pid 1:tid 140302870259584] AH00489:Apache/2.4.12 (Unix) configured -- resuming normal operations
    [Thu Apr 16 21:08:35.976879 2015] [core:notice] [pid 1:tid 140302870259584] AH00094:Command line:'httpd -D FOREGROUND'


    Advantages of containers

    There are many good reasons why you want to use this technology. But let's just briefly focus on what we gain by running these tiny, isolated instances. Sure, there's a lot happening under the hood, in the kernel, but in general, the memory footprint of spawned containers is fairly small. In our case, the SSH + Apache containers use a tiny fraction of extra memory. Compare this to any virtualization technology.

    Problems you may encounter &troubleshooting

    Let's go back to the Apache example, and now you will also learn why so many online tutorials sin the sin of copy &pasting information without checking, and why most of the advice is not correct, unfortunately. It has to do with, what do you do if your Apache server seems to die within a second or two after launching the container? Indeed, if this happens, you want to step into the container and troubleshoot. To that end, you can use the docker exec command to attach a shell to the instance.

    docker exec -ti boring_mcclintock /bin/bash

    Then, it comes down to reading logs and trying to figure out what might have gone wrong. If your httpd.conf is configured correctly, you will have access and error logs under /var/log/httpd:

    [auth_digest:error] [pid 25] (2)No such file or directory:AH01762:Failed to create shared memory segment on file /run/httpd/authdigest_shm.25

    A typical problem is that you may be a missing /run/httpd directory. If this one does not exist in your container, httpd will start and die. Sounds so simple, but few if any reference mentions this.

    While initially playing with containers, I did encounter this issue. Reading online, I found several suggestions, none of which really helped. But I do want to elaborate on them, and how you can make progress in your problem solving, even if intermediate steps aren't really useful.

    Suggestion 1:You must use -D FOREGROUND to run Apache, and you must also use ENTRYPOINT rather than CMD. The difference between the two instructions is very subtle. And it does not solve our problem in any way.

    ENTRYPOINT ["/usr/sbin/httpd"]
    CMD ["-D", "FOREGROUND"]

    Suggestion 2:Use a separate startup script, which could work around any issues with the starting or restarting of the httpd service. In other words, the Dockerfile becomes something like this:

    ...
    EXPOSE 80
    COPY ./run-httpd.sh /run-httpd.sh
    RUN chmod -v +x /run-httpd.sh
    CMD ["/run-httpd.sh"]

    And the contents of the run-httpd.sh script are along the lines of:

    #!/bin/bash

    rm -rf /run/httpd/*

    exec /usr/sbin/apachectl -D FOREGROUND

    Almost there. Remove any old leftover PID files, but these are normally not stored under /run/httpd. Instead, you will find them under /var/run/httpd. Moreover, we are not certain that this directory exists.

    Finally, the idea is to work around any problems with the execution of a separation shell inside which the httpd thread is spawned. While it does provide us with additional, useful lessons on how to manage the container, with COPY and RUN instructions, it's not what we need to fix the issue.

    Step 3 :EXPOSE 80
     ---> Using cache
     ---> 108785c8e507
    Step 4 :COPY ./run-httpd.sh /run-httpd.sh
     ---> 582d795d59d4
    Removing intermediate container 7ff5b58b40bf
    Step 5 :RUN chmod -v +x /run-httpd.sh
     ---> Running in 56fadf4dd2d4
    mode of '/run-httpd.sh' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)
     ---> 928640f680cf
    Removing intermediate container 56fadf4dd2d4
    Step 6 :CMD /run-httpd.sh
     ---> Running in f9c6b30795e2
     ---> b2dcc2818a27
    Removing intermediate container f9c6b30795e2
    Successfully built b2dcc2818a27

    This won't work, because apachectl is an unsupported command for managing httpd, plus we have seen problems using startup scripts and utilities earlier, and we will work on fixing this in a separate tutorial.

    docker run -ti -p 80 image-2:latest
    Passing arguments to httpd using apachectl is no longer supported. You can only start/stop/restart httpd using this script. If you want to pass extra arguments to httpd, edit the /etc/sysconfig/httpd config file.

    But it is useful to try these different things, to get the hang of it. Unfortunately, it also highlights the lack of maturity and the somewhat inadequate documentation for this technology out there.

    Additional commands

    There are many ways you can interact with your container. If you do not want to attach a new shell to a running instance, you can use a subset of docker commands directly against the container ID or name:

    docker

    For instance, to get the top output from the container:

    docker top boring_stallman

    If you have too many images, some of which have just been used for testing, then you can remove them to free up some of your disk space. This can be done using the docker rmi command.

    # docker rmi -f test7
    Untagged:test7:latest
    Deleted: d0505b88466a97b73d083434b2dd0e7b59b9a5e8d0438b1bf8c6c
    Deleted:5fc118f61bf856f6f3d90e0e71076b737fa7cc58cd56785ea7904
    Deleted:628c3d6b53992521c9c1fdda4148693347c3d10b1d130f7e091e7
    Deleted:58f11217c3e31206b4e41d07100a797cd4d17e4569b0fdb8b7a18
    Deleted:7505c70235e638c54028ea5b63eba2b691de6bee67c2cb5e2861a
    ...

    Then, you can also run your containers in the background. Using the -d flag will do exactly that, and you will get the shell prompt back. This is also useful if you do not mask signals, so if you accidentally break in your shell, you might kill the container when it's running in the foreground.

    docker run -d -ti -p 80 image-3:latest

    You can also check events, examine changes inside a container's filesystem as well as check history, so you basically have a version control in place, export or import tarred images to and from remote locations, including over the Web, and more.

    Differences between exec and attach

    If you read through the documentation, you will notice you can connect to a running container using either exec or attach commands. So what's the difference, you may ask? If we look at the official documentation, then:

    The docker exec command runs a new command in a running container. The command started using docker exec only runs while the container's primary process (PID 1) is running, and it is not restarted if the container is restarted.

    On the other hand, attach gives you the following:

    The docker attach command allows you to attach to a running container using the container's ID or name, either to view its ongoing output or to control it interactively. You can attach to the same contained process multiple times simultaneously, screen sharing style, or quickly view the progress of your daemonized process. You can detach from the container (and leave it running) with CTRL-p CTRL-q (for a quiet exit) or CTRL-c which will send a SIGKILL to the container. When you are attached to a container, and exit its main process, the process's exit code will be returned to the client.

    In other words, with attach, you will get a shell, and be able to do whatever you need. With exec, you can issue commands that do not require any interaction, but with you use a shell in combination with exec, you will achieve the same result as if you used attach.

    Differences between start and run

    Start is used to resume the execution of a stopped container. It is not used to start a fresh instance. For that, you have the run command. The choice of words could have been better.

    Differences between build and create

    The first command is used to create a new image from a Dockerfile. On the other hand, the latter is used to create a new container using command line options and arguments. Create lets you specify container settings, too, like network configurations, resource limitations and other settings, which affect the container from the outside, whereas the changes implemented by the build command will be reflected inside it, once you start an instance. And by start, I mean run.それを得る?

    This is just a beginning ...

    There are a million more things we can do: using systemd enabled containers, policies, security, resource constraints, proxying, signals, other networking and storage options including the super-critical question of how to mount data volumes inside containers so that data does not get destroyed when containers die, additional pure LXC commands, and more. We've barely scratched the surface. But now, we know what to do. And we'll get there. Slowly but surely.

    続きを読む

    I recommend you allocate a few hours and then spend some honest time reading all of the below, in detail. Then practice. This is the only way you will really fully understand and embrace the concepts.

    My entire virtualization section

    Dockerizing an SSH Deamon Service

    Differences between save and export in Docker

    Docker Explained:Using Dockerfiles to Automate Building of Images

    結論

    We're done with this tutorial for today. Hopefully, you've found it useful. In a nutshell, it does explain quite a few things, including how to get started with Docker, how to pull new images, run basic containers, add services like SSH and Apache, commit changes to a file, expose incoming ports, build new images with Dockerfiles, lots of troubleshooting of problems, additional commands, and more. Eventful and colorful, I'd dare say.

    In the future, we will expand significantly on what we learned here, and focus on various helper technologies like supervisord for instance, we will learn how to mount filesystems, work on administration and orchestration, and many other cool things. Docker is a very nice concept, and if used correctly, it can make your virtual world easier and more elegant. The initial few steps are rough, but with some luck, this guide will have provided you with the right dose of karma to get happily and confidently underway. Ping me if you have any requests or desires. Technology related, of course.終わったね。

    追記If you like this article, then you'd better give some love back to Dedoimedo!

    乾杯。


    1. XenServer + XenCenter のレビュー

      この記事は非常に珍しいものでありながら楽しいものであることがわかると思います。まず、以前に Citrix XenServer について、つまりインストールと構成の方法について書きました。全体として、XenServer は同様の機能を備えた無料の XCP の基盤であるため、操作は非常に簡単でした。ただし、最初のセットアップを超えて長居することはありませんでした。 今日は、XenServer をラップトップにインストールする方法をもう一度紹介しますが、ラップトップはベアメタル ハイパーバイザーの典型的なハードウェアとして意図されたものではないことを十分に認識しています。さらに、SSH と、VM

    2. Windows BSOD 分析 - 完全な使用ガイド

      Windows ブルー スクリーン オブ デス (BSOD) は、特定のスクリーン セーバーまたはテスト ソフトウェアを使用していない限り、コンピューター モニターに表示したくないものです。しかし、時折、Windows ユーザーは最終的なソフトウェア障害、つまりカーネル自体の障害に遭遇し、システムが完全にフリーズし、最終的にクラッシュすることがあります。 Linux では、この種の状況はカーネル パニックとして知られています。 Windows では、BSOD と呼ばれます。しかし、それは同じことです。つまり、システムのコア、カーネル、および付随するドライバーにおける重大で回復不能な例外です