Translate

2015年3月26日木曜日

CoreOSをVirtualBox上の仮想マシンへVagrantなしでインストールする

Docker ホストを構築する場合は
ホスト自体は最も軽い状態にしておきたい..

結局本格的に使用する場合は
現時点では CoreOS をつかうしかないのかな..?

そうなるといろいろ変なことして他の人に迷惑をかけない
VirtualBox上の仮想マシンでたてられるようにしておきたい。

ということでイチからやってみることにした。

将来的に物理マシンへインストールする練習にするためにVagrantを使わない方法でやってみました。

なお、以下の手順で作成したDockerホストはあくまで試行や学習用なのでローカルPC外部にサービス提供できません。

--------

前提


  • ターミナル接続ソフト(Poderosa, Tera Termなど)が導入済み
  • VirtualBoxが導入済み
  • 1GBメモリの仮想マシンが作成可能であること


CoreOSのダウンロード


  • ブラウザでhttps://coreos.com/を開く
  • Download CoreOS>ISO Image
  • Stable Channel>Download Stable ISO (Beta,Alphaの選択は後で変えられる)
  • ファイルを保存する
  • OKボタン
  • ※参考:私が試した際には約144MB


VirtualBox 上に仮想マシンを作成


  • VirtualBoxを起動
  • 新規(N)アイコン
  • 名前(N):適当な名前をつける
  • タイプ(T):「Linux
  • バージョン(V):「Other Linux (64-bit)
  • 次へ(N)ボタン
  • 必要なメモリサイズ:1GB

※注意:256MB512MBだと動作しません

  • 次へ(N)ボタン
  • 仮想ハードドライブを作成する(C)
  • 作成ボタン
  • VDI(VirtualBox Disk Image)
  • 次へ(N)ボタン
  • 可変サイズ(D)
  • 次へ(N)ボタン
  • 作成ボタン
  • 作成した仮想マシンを選択した状態で設定(S)アイコンを選択
  • ストレージ
  • コントローラ:IDE>空(DVDアイコン)を選択
  • 属性のCD/DVDドライブ(D)欄の右端のDVDアイコンを押す
  • 仮想DVD/CDディスクのファイルの選択...
  • ダウンロードしたCoreOS ISOイメージを選択
  • 開く(O)ボタン
  • ネットワーク
  • アダプター2タブ
  • ネットワークアダプタを有効化
  • ホストオンリーアダプター
※NIC1枚目がサービスLAN(ゲストコンテナを使う人用)、
 NIC2枚目が運用LAN(システムを管理する裏方用)想定です。
※キーバインドがUSになっていて使いづらいので
 SSHでターミナル接続して作業するため後で固定IPを割り付けています。

  • OKボタン
  • 作成した仮想マシンを選択した状態で起動(T)アイコンを選択
  • コンソールがあがるまで待機


CoreOS Live実行

  • core@localhost ~ $」が出るまで待機

注意: LiveCD/DVDを動かした状態であり、
この段階ではまだ仮想HDDへインストールされていません。
キーボードレイアウトがUSで固定され変えられません。
→このため手順ではターミナル接続ソフト上でなるべく編集作業しています。

  • ifconfig -a
  • ホストオンリー側のNIC(enp0s8)のIPアドレスとネットマスクをメモ
  • sudo passwd core
  • hogehoge coreのパスワード
  • hogehogecoreのパスワード(再度)

※注意:上記のような緩いパスワードだともう一度聞いてきます

  • sudo systemctl start sshd

※この段階でターミナル接続ソフトからログインできるようになります


CoreOSインストール


  • ターミナル接続ソフトウェアを起動
  • メモしたIPアドレス、ユーザを「core」、パスワードを「core」にしてSSH接続
  • sudo -s

※プロクシ環境下の場合以下の環境変数をセットします
 export http_proxy=http://<プロクシサーバFQDN>:<プロクシサーバポート>/
 export https_proxy=http://<プロクシサーバFQDN>:<プロクシサーバポート>/

※インストール後ログインするユーザを「core1」、
 パスワードを「fugafuga」、パスフレーズを「hogehoge」として手順を記述します。

  • openssl passwd -1 ("エル"ではなく"いち")
  • fugafuga ←corecoreのパスワード
  • fugafuga ←corecoreのパスワード
  • 出力した文字列をコピーしておく(passwdに使用)
  • ssh-keygen -t rsa
  • (Enter)
  • hogehoge ←パスフレーズ
  • hogehoge ←パスフレーズ
  • cat /root/.ssh/id_rsa.pub
  • 出力した文字列をコピーしておく(ssh-authorized-keysに使用)

 ※/root/.ssh/id_rsa.pubは再起動すると消えます

  • vi config.yml
  • 以下のリストを入力し保存する

#cloud-config

hostname: coreos1
coreos:
 units:
  - name: 10-static.network
    runtime: no
    content: |
      [Match]
      Name=enp0s8

      [Network]
      Address=192.168.XX.XXX/XX ←ホストオンリー側のIP
users:
 - name: core1
   passwd: $1$s... ..x1 ←opensslコマンドの文字列
   groups:
    - sudo
    - docker
   ssh-authorized-keys:
    - ssh-rsa AAA... ..71 root@localhost ←ssh-keygenコマンドの文字列

 ※注意:このファイル内でtabは使用できません
 ※注意:先頭の空白有無でもエラーになることがあります

  • coreos-install -d /dev/sda -C stable -c stable -c config.yml

 stablebetaもしくはalphaに変更可能
  実行するとたとえ自分自身がstableであっても再度ダウンロードするので
  時間がかかります。

  • Success! CoreOS stable XXX.X.X is installed on /dev/sda」と表示されるまで待機
  • shutdown -h now
  • Oracle VM VirtualBoxマネージャー画面の該当仮想マシンを選択した状態で設定(S)アイコンを選択
  • ストレージ
  • コントローラー:IDE>coreos_production_iso_image.isoを選択
  • 属性のCD/DVDドライブ(D):の右端のDVD/CDアイコンを選択
  • 仮想ドライブからディスクを除去
  • OKボタン

 ※注意:刺したままだと再度Live環境があがります


CoreOS起動


  • Oracle VM VirtualBoxマネージャー画面の該当仮想マシンを選択した状態で起動(T)アイコンを選択
  • ログインプロンプトが出るまで待機
  • core1
  • fugafuga core1のパスワード
  • sudo systemctl start sshd
  • vi /usr/share/oem/run
  • 以下の3行を記述し保存する

 #!/bin/bash
 systemctl set-environment HTTP_PROXY=http://<プロクシサーバFQDN>:<プロクシサーバポート>/
 systemctl set-environment HTTPS_PROXY=http://<プロクシサーバFQDN>:<プロクシサーバポート>/
 systemctl start sshd

※systemctl enable sshdが効かないためここに記述しています。
 プロクシ不要の環境は中2行削除してください。
  • sudo chmod a+x /usr/share/oem/run
  • reboot
  • ログインプロンプトが出るまで待機
  • ターミナル接続ソフトウェアを起動し、IPアドレス、ユーザ「core1」、パスワード「fugafuga」を指定してログイン
  • docker search centos
  • 以下の様にDocker Hub上の公式イメージなどが参照できていればOK


core1@coreos1 ~ $ docker search centos
NAME                                 DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
centos                               The official build of CentOS.                   890       [OK]
...

akroh/centos                         Centos 6 container that has been updated w...   0                    [OK]

------

インストールして気づいたが..
クラスタ型のDockerベアメタル環境を選択する場合、CoreOSは選択肢にならない。

CoreOSDockerは決別したらしいが、どうもその原因が投資で得たたくさんの資金で組み込んだ機能、クラスタリングやらDocker Machineやらが気に入らなかったらしい。

CoreOS公式サイトのインストール手順でも「Docker will not work out of the box(Dockerはボックス(仮想マシンor物理マシン)の外では動作しない)」という制限を最初に説明している。

このため、クラスタを将来的にやろうという人はCoreOSを選ばなくなるんじゃ..

でもDocker Machineもユーザガイド該当章先頭に「Note: Machine is currently in beta, so things are likely to change. We don't recommend you use it in production yet.(注意:Docker Machineは現在ベータ公開です、このため変更されることがあります。本番環境で使用しないことをおすすめします。)」ってかいてあるし..

通常のCentOS、Ubuntuや、Server版、LTS版でも、最小構成であったとしてもインストレーション時にそれなりのサイズのISOイメージを落とさにゃならんし..

RedHat のProject AtomicでだしてるCentOS AtomicHost版か、Sunappy Ubuntu Coreか、はたまたMesos?!

Docker Machineがさっさと使える状態になればこのへんも淘汰されるのか?!

..みんな、どれ使おうとしてるんだろ..

2015年3月20日金曜日

CoreOSをVirtualBox上でインストールしようとしたら、Failed to Switch Rootというエラーがでた

DockerをCentOSに入れて試そうとしたら
なぜかDNSが引けなくなってしまい
めんどくさくなったのでCoreOSを使ってみることにした。

で、CentOSをVirtualBox上でインストールしようとしたら

[FAILED] Failed to start Switch Root.

とでて、Enterを押すと「:/#」というプロンプト状態になってしまった。

でもこれはよくあることらしく
調べてみたらIssue13というかなり早い番号で見つかった。


Booting with iPXE wording is outdated/incorrect #13


簡単にいえば、メモリが1GB以上必要なのに
ケチって512MBにしていたから..

メモリ増やして、再度起動してみたら正常動作しました。


だって..PCおそくしたくないんだもん..


2015年3月17日火曜日

docker-compose.yml リファレンス を翻訳してみた


わざわざ翻訳しないといけないくらい難しい英語ではありませんが、
以下のページを翻訳してみました。

 docker-compose.yml リファレンス
 https://docs.docker.com/compose/yml/


複数のサービスをまとめてアプリケーションを提供する使い方が基本に成るはずなので、Dcocker Compose (もしくは代替ツール?) を使わざるを得ないはず。
なのでDockerfileだけでなくdocker-compose.ymlDocker活用には必修科目になるのだとおもいます。

以下、勝手翻訳文です。参照される方は at your own risk でお願いします。


参考迄:
Redmineコンテナを上げるためのdocker-compose.ymlを書いてみました。
docker-compose.ymlのサンプルになるかもしれないので
リンクをのこしておきます。



--------

docker-compose.yml リファレンス


docker-compose.yml に定義されたそれぞれのサービスは明確に1つのイメージもしくはビルドを指定しなくてはなりません。他のキーはオプションです、そしてそれらは「docker run」コマンドラインのオプションに類似しています。

docker run」同様、Dockerfile 内に指定されたオプション(例:CMD、EXPOSE、VOLUME、ENV)はデフォルトで尊重されています-再度docker-compose.yml に指定する必要はありません。

image


タグもしくはイメージIDの一部。ローカルもしくはリモートに存在するもの-Composeはローカルに存在しない場合pullを実行しようとします。

 image: ubuntu
 image: orchardup/postgresql
 image: a4bc65fd

build


Dockerfileのあるディレクトリへのパス。ディレクトリはDockerデーモンへ送信されるビルドコンテキストでもあります。

Composeはビルドし、生成した名前でタグ付けし、その後イメージを使用します。

 build: /path/to/build/dir

command


デフォルトコマンドをオーバライドします。

 command: bundle exec thin -p 3000

links


別のサービスコンテナへのリンク。サービス名とリンクエイリアス両方(SERVICE:ALIAS)か、サービス名だけ(エイリアスとしても使用される)を指定します。

 links:
  - db
  - db:database
  - redis


次のように、エイリアス名つきのエントリがこのサービスコンテナの /etc/hosts に作成されます:

 172.17.2.186  db
 172.17.2.186  database
 172.17.2.187  redis


開発環境もまた作成されます-詳細は開発環境リファレンスを参照のこと。

external_links


このdocker-compose.yml の外もしくは Compose の外で開始されたコンテナへのリンク、特に共有もしくは共通のサービスを提供するコンテナへのリンク。external_links はコンテナ名とリンクエイリアス両方を指定した場合(CONTAINER:ALIAS)リンクに近い意味をもちます。

 external_links:
  - redis_1
  - project_db_1:mysql
  - project_db_1:postgresql

ports


公開するポート。両方のポート(HOST:CONTAINER)かコンテナ側のポート(ホストポートはランダムに選択される)。

 注意:
 HOST:CONTAINER 形式でポートをマッピングする場合、
 60番より下のポートを使う誤りを経験するかもしれません、
 なぜならYMAL xx:yy 形式を60分数(時刻)の数字として解釈するためです。
 このため、ポートマッピングを指定する際常に文字列として明確に指定する
 ことを推奨します。

 ports:
  - "3000"
  - "8000:8000"
  - "49100:22"
  - "127.0.0.1:8001:8001"

expose


ホストマシンへ公開しないポートの露出-リンクされたサービスへのみアクセスします。内部ポートだけを指定します。

 expose:
  - "3000"
  - "8000"

volumes


ボリュームとしてのマウントするパス、オプションとしてホストマシン上のパスやアクセスモード(HOST:CONTAINER:ro)を指定します。

 volumes:
  - /var/lib/mysql
  - cache/:/tmp/cache
  - ~/configs:/etc/configs/:ro

volumes_from


別のサービスやコンテナからすべてのボリュームをマウントします。

 volumes_from:
  - service_name
  - container_name

environment


環境変数を追加します。配列もしくはディレクトリのどちらか使用可能です。

単一のキーの環境変数はCompose実行中のマシン上の値として解決されます、そしてそれは秘密裏にホスト特定値として有用です。

 environment:
   RACK_ENV: development
   SESSION_SECRET:
 
 environment:
   - RACK_ENV=development
   - SESSION_SECRET

env_file


ファイルから環境変数を追加します。単一値もしくはリストで記述します。

environmentで指定した環境変数はこれらの変数値でオーバライドします。

 env_file:
   - .env
 
 RACK_ENV: development

net


ネットワーキングモード。「docker client --net」パラメータとして同じ値を使ってください。

 net: "bridge"
 net: "none"
 net: "container:[name or id]"
 net: "host"


dns


カスタムDNSサーバ。単一値もしくはリストで記述します。

 dns: 8.8.8.8
 dns:
   - 8.8.8.8
   - 9.9.9.9

cap_add, cap_drop


コンテナ性能(capabilitities) を追加・削除します。すべてのリストは「man 7 capabilities」を参照してください。

 cap_add:
   - ALL
 
 cap_drop:
   - NET_ADMIN
   - SYS_ADMIN

dns_search


カスタムDNS検索ドメイン。単一値もしくはリストで記述可能です。

 dns_search: example.com
 dns_search:
   - dc1.example.com
   - dc2.example.com

working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged, restart, stdin_open, tty, cpu_shares


各々単一値(「docker run」に類似)を指定します。

 cpu_shares: 73
 
 working_dir: /code
 entrypoint: /code/entrypoint.sh
 user: postgresql
 
 hostname: foo
 domainname: foo.com
 
 mem_limit: 1000000000
 privileged: true
 
 restart: always
 
 stdin_open: true
 tty: true

Compose ドキュメンテーション


Composeのインストール
ユーザガイド
コマンドラインリファレンス
Compose 環境変数
Compose コマンドライン completion


2015年3月16日月曜日

The Docker User Guide: Docker Swarm を翻訳してみる


新たな機能として提供されたSwarmに関する以下のドキュメントを翻訳してみました。

 Docker Swarm
 https://docs.docker.com/swarm/


ユーザガイドだと概要レベルで、詳しい情報は殆ど外のリンクになってました。
概要レベルで知りたい方は読んでみてください。

なお参照される際は at your own risk でお願いします。

-------

Docker Swarm


Docker Swarm は、Dockerのネイティブクラスタリングを実現します。Docker Swarmは、複数のDockerホストのプールを単一の仮想的なホストに切り替えます。

Swarmは標準Docker APIを提供します、このためDockerデーモンとすでに通信可能などんなツールでもSwarmを使って複数のホスト群へ透過的にスケールさせることができます:Dokku、Compose、Krane、Flynn、Deis、DockerUI、Shipyard、Drone、Jenkins..そしてもちろんDockerクライアント自身も含みます。

ほかのDockerプロジェクトのように、Swarm"batteries included but removable"(取り外し可能な物以外を含むバッテリ)原則に従っています。Swarmはボックスの外部のバックエンドを単純にスケジューリングを取り付け、そして初期開発が落ち着いたら、プラグ挿入可能なバックエンドを有効にするためにAPIを開発します。

ゴールは単純な利用事例における独創的な経験を円滑に提供することです。そして、大規模製品開発のためのMesosのように、より強力なバックエンドとの交換を可能としています。

インストール


 注意:
 インストール前提は、Swarmノード群がすべて同一リリースのDockerデーモン
 (バージョン1.4.0以降が動作しており、それらがSwarmマネージャがアクセス可能な
 TCP ポートを listen する設定が実施されていることだけです。

公式Dockerイメージを使えば、Swarmを最も簡単に使いはじめることができます。

 docker pull swarm

ノードのセットアップ


Swarmノードでは、参照されるDockerデーモンが登録されたswarmノードエージェントを実行します。そして監視して、ディスカバリーバックエンドのステータスを更新します。

次の例は、Docker Hubベースのトークンディスカバリサービスを使用しています:


 # クラスタの作成
 $ docker run --rm swarm create
 6856663cdefdec325839a4b7e1de38e8 # <- cluster_id="" is="" this="" unique="" your="">

 # 各ノード上で、swarmエージェントを開始する。
 # はパブリックではないIP(例:192.168.0.X)を指定する。
 # (かつswarmマネジャがエージェントにアクセス可能な)
 $ docker run -d swarm join --addr= token://

 # 適当なマシンもしくはあなたのラップトップ上で
 # マネジャの開始
 $ docker run -d -p :2375 swarm manage token://

 # 通常のdocker クライアントを使用
 $ docker -H tcp:// info
 $ docker -H tcp:// run ...
 $ docker -H tcp:// ps
 $ docker -H tcp:// logs ...
 ...

 # クラスタ上のノードをリスト
 $ docker run --rm swarm list token://
 

 注意:
 Swarmマネジャが各ノード上のノードエージェントと通信可能にするために、
 共通のネットワークインターフェイスでlistenしなければなりません。
 これは「-H」フラグを使って開始することでアーカイブ可能です。
 (例: -H tcp:////0.0.0.0:2375)


TLS


SwarmCLISwarmとの間で、そしてSwarmDockerノードの間でさえもTLS認証をサポートしています。ただし、すべてのDockerデーモン認証とクライアントが認証は同一のCA認証書でサインされていなければなりません。

クライアント、サーバ両方でTLSを有効にするための、Dockerが指定されることが可能な同一のコマンドラインオプション:

 swarm manage --tlsverify --tlscacert= --tlscert= --tlskey= [...]

Docker上でのTLS認証のセットアップ方法および証明書の生成に関する詳細は、Dockerドキュメンテーションを参照してください。

 注意:
 「extendedKeyUsage = clientAuth,serverAuth」で
 Swarm証明書を生成しなくてはなりません。


ディスカバリサービス


詳細は、ディスカバリサービスドキュメントを参照してください。


高度なスケジューリング


高度なスケジューリングについての詳細を学習するにはフィルタ戦略を参照してください。


Swarm API


Docker Swarm APIはDockerリモートAPIと互換性があり、拡張して新たなエンドポイントが使えます。


The Docker User Guide: Docker Compose を翻訳してみた

もともと複数のアプリケーションを1つのサーバで動かすテンプレートを
Dockerでつくりたかったので、Composeに関する概要も必要かと思い

 Docker Compose
 https://docs.docker.com/compose/

を翻訳してみました。

複雑なアプリを一発で動かせるようにするには docker-compose.yml  ファイルを作る
必要がありそうなことはわかりました。


以下、勝手翻訳した内容です。
参照の際は at your own risk でお願いします。

--------

Docker Compose


ComposeはDockerを使って複雑なアプリケーションを定義、実行するためのツールです。Composeを使えば、複数コンテナを使用するアプリケーションを単一のファイルで定義することができ、単一のコマンドでアプリケーションを必要なだけ実行状態までスピンアップします。

Composeは開発環境、サーバ群の開始やCI(継続的インテグレーション)にとって素晴らしいツールです。我々は製品開発にComposeを使うことはまだ推奨しません。

Composeの使用は、基本的に3ステップです。

最初に、アプリケーション環境をDockerfileを使って定義します。Dockerfile化によりどこでも再現可能にすることができます:

 FROM python:2.7
 WORKDIR /code
 ADD requirements.txt /code/
 RUN pip install -r requirements.txt
 ADD . /code
 CMD python app.py

次に、アプリケーションのメイク方法をdocker-compose.yml上に定義して、分離した環境で動作できるようにします:

 web:
   build: .
   links:
    - db
   ports:
    - "8000:8000"
 db:
   image: postgres

最後に、「docker-compose up」を実行し、アプリケーション全体の開始および実行を構成(compose)します。

Composeはアプリケーションライフサイクル全体を管理するためのコマンドをもっています;
 

  • サービスの開始・終了・再ビルド
  • 実行中サービスのステータス参照
  • 実行中サービスのログアウトプットのストリーム
  • サービスに対するワンオフ(1回限りの)コマンド実行


Compose ドキュメンテーション




クイックスタート


Composeを使って簡単なPython Webアプリケーションの実行までの練習を使って始めてみましょう。Pyhonの知識が少し必要ですが、Pyhonをよく知らなくてもここでのデモンストレーションの概要は把握できるはずです。


インストールとセットアップ


最初に、DockerとComposeをインストールします。

次に、プロジェクトのためのディレクトリを作成します:

 $ mkdir composetest
 $ cd composetest

ディレクトリ内部で、app.pyを作成し、Flaskフレームワークを使ったRedisの値を足していく簡単な Web アプリケーションを構築します:

 from flask import Flask
 from redis import Redis
 import os
 app = Flask(__name__)
 redis = Redis(host='redis', port=6379)
 
 @app.route('/')
 def hello():
     redis.incr('hits')
     return 'Hello World! I have been seen %s times.' % redis.get('hits')
 
 if __name__ == "__main__":
     app.run(host="0.0.0.0", debug=True)

次に、Python依存関係を requirements.txt と呼ばれるファイルに定義します:

 flask
 redis


Dockerイメージの作成


すべてのアプリケーション依存するパッケージを含むDockerイメージを作成します。Dockerfile と呼ばれるファイルを使ってどうやってイメージをビルドするかを定義します:

 FROM python:2.7
 ADD . /code
 WORKDIR /code
 RUN pip install -r requirements.txt

これは Docker にPython、あなたのコード、そしてPython依存関係をDockerイメージに含める問い合わせをします。詳細はDocerユーザガイドDockerfileリファレンスを参照してください。


サービスの定義


次に、docker-compose.ymlを使ってサービスセットを定義します:

 web:
   build: .
   command: python app.py
   ports:
    - "5000:5000"
   volumes:
    - .:/code
   links:
    - redis
 redis:
   image: redis


このファイルでは2つのサービスを定義しています:

  • web」:カレントディレクトリ上のDockerfileからビルドされます。 ここでは、イメージ内で python app.py コマンドを実行し、コンテナ側5000番ポートをホスト上の5000番ポートに露出させ、redisサービスと通信し、そしてカレントをコンテナ内部へマウントしており、イメージのリビルド無しでコードを実行できます。
  • redis」:Docker Hubリポジトリから取得した公式イメージredisを使用します。


Composeを使ったアプリケーションのビルドおよび実行


ここで「docker-compose up」を実行すれば、ComposeがRedisイメージをpullし、アプリケーションコードのためのイメージをビルドし、開始します:


 $ docker-compose up
 Pulling image redis...
 Building web...
 Starting composetest_redis_1...
 Starting composetest_web_1...
 redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
 web_1   |  * Running on http://0.0.0.0:5000/

これで、Dockerデーモンホスト(もしBoot2dockerを使っているのであれば、「boot2docker ip」にてIPアドレスを問い合わせてください)のポート5000番でlistenしているアプリケーションを参照できます。

バックグラウンド実したいのであれば、「-d」フラグを「docker-compose up」コマンドに追加してください。「docker-compose ps」を使って何が現在実行中かを確認できます:

 $ docker-compose up -d
 Starting composetest_redis_1...
 Starting composetest_web_1...
 $ docker-compose ps
     Name                 Command            State       Ports
 -------------------------------------------------------------------
 composetest_redis_1   /usr/local/bin/run         Up
 composetest_web_1     /bin/sh -c python app.py   Up      5000->5000/tcp

docker-compose run」コマンドでサービスに対してワンオフコマンドを許可します。たとえば、どんな環境変数が「web」サービス上で有効かを確認するには:

 $ docker-compose run web env
docker-compose --help」で他の有効なコマンドを確認できます。

もし「docker-compose up -d」で開始したのであれば、サービスを停止したいのであれば、一度次のように実行して停止します:

 $ docker-compose stop

このセクションでは、Composeがいかにして動作するかに関する基本について確認しました。

続いて、DjangoRailsWordpressのクイックスタートを試しましょう
コマンド設定ファイル環境変数の詳細情報についてはリファレンスガイドを参照してください

The Docker User Guide: Working with Docker Hub を翻訳してみた



ユーザガイドの基礎的な使い方ではおそらく最後の章になる

 Working with Docker Hub
 https://docs.docker.com/userguide/dockerrepos/

を翻訳してみました。

参考にされる場合は、at your own riskでお願いします。


-------

Docker Hubの動作


これまでに、ローカルホスト上でDockerを実行するためのコマンドの使い方を学習してきました。そして、既存のイメージからコンテナをビルドするためのイメージの取得し、自分のイメージの作成する方法を学びました。

続いて、Docker Hubの簡単な使い方とDockerワークフローについて学習しましょう。

Docker Hub は Docker Incによって管理されている公式レジストリです。15,000を超えるイメージをダウンロードしてコンテナのビルドに使うことができます。また、認証、ワークグループ構造、webhooks やビルドトリガのようなワークフローツール、公に共有したくないイメージを保管するためのプライベートリポジトリのようなプライバシーツールも提供しています。

DockerコマンドとDocker Hub


Docker自身は docker search, pull, login, push コマンドを通じてDocker Hubへのアクセスを提供しています。このページではこれらのコマンドの使い方を学習します。

アカウントの作成とログイン


一般的には、Docker Hubのアカウント新規作成(まだ済んでいないのであれば)とログインからはじめます。Docker Hub上でアカウントディレクトリを作成するには次のように実行します:

 $ sudo docker login

このコマンドを実行すると、ユーザ名を要求するプロンプトが表示されます。ユーザ名はあなたの公式リポジトリの公式ネームスペースとなります。ユーザ名が有効であれば、Dockerはパスワードと電子メールアドレスを要求するプロンプトが表示されます。そして自動的にログインし、ローカルリポジトリからDocker Hubへのイメージのコミットやプッシュが可能になります。

 注意:
 認証情報はホームディレクトリ上の.dockercfg 認証ファイルへ格納されます。

イメージの検索


Webの検索インターフェイス経由もしくはコマンドラインインターフェイスを使ってDocker Hubリポジトリを検索することができます。イメージ名、ユーザ名、もしくは説明から検索したイメージを探すことができます:

 $ sudo docker search centos
 NAME           DESCRIPTION                                     STARS     OFFICIAL   TRUSTED
 centos         Official CentOS 6 Image as of 12 April 2014     88
 tianon/centos  CentOS 5 and 6, created using rinse instea...   21
 ...

上記では2つの結果サンプル(centosとtianon/centos)が確認できます。2番めの結果から、ユーザ名「tianon/」の公式リポジトリのもので、最初の結果のほうの「centos」は明確にリストされていません。これは信頼されたトップレベルのネームスペースだからです。

希望するイメージを発見したら、「docker pull 」を使って次のようにダウンロードします:

 $ sudo docker pull centos
 Pulling repository centos
 0b443ba03958: Download complete
 539c0211cd76: Download complete
 511136ea3c5a: Download complete
 7064731afe90: Download complete
 
 Status: Downloaded newer image for centos


これでイメージをダウンロードしたので、コンテナを起動できるようになりました。
 


Docker Hubへの貢献


誰もがDocker Hub レジストリから公式イメージをダウンロードできます。しかし、もしあなたが作成したイメージを共有したいのであれば、[[Docker Hub ユーザガイドの最初のセクション>Docker/UserGuide/UsingDockerHub]]にあるとおり、最初に登録しなければなりません。

 

レジストリからDocker Hubへのpush


リポジトリからpushするためには、イメージに名前をつけるか、ここで学習したようにコンテナから名前をつけたイメージへコミットします。

このリポジトリから名前もしくはタグでデザインされたレジストリへpushします。

 $ sudo docker push yourname/newimage

イメージがチームメイトや/もしくはコミュニティによりアップロードされます。

 

Docker Hubの機能


Docker Hubの機能についてより詳しく学習しましょう。
 

  • プライベートリポジトリ
  • 組織とチーム
  • 自動ビルド
  • Webhooks

プライベートリポジトリ


公式に誰にでも公開したくないイメージもあるとおもいます。Docker Hubはプライベートリポジトリも許可しています。ここのサイトからプランを選択してください。

 訳者注:
 翻訳時点で無料アカウントは1つのプライベートリポジトリしか持てません。


組織とチーム


プライベートリポジトリの利点の1つとして、組織もしくはチームのメンバ内だけで共有できることがあります。Docker Hub は、同僚と協業してプライベートリポジトリを管理するために、組織を作成させます。ここから組織の構築、管理方法を学習できます。

 

自動ビルド


自動ビルドはGitHubからBitBukketへ、Docker Hub上のディレクトリの、イメージのビルドや更新を自動化します。コミットをプッシュした時ビルド及び更新がトリガリングすることで、選択されたGitHubやBitBucketリポジトリへコミットフックを追加します。


自動ビルドのセットアップ
 

  1. Docker Hubにアカウントを新規作成しログイン
  2.  "Link Accounts"メニューからGitHub/BitBucketアカウントをリンク
  3. 自動ビルドの設定を実施
  4. ビルド対象のDockerfileを保持するGitHub/BitBucketプロジェクトをpick
  5. ビルド対象のブランチをpick(デフォルトはマスターブランチ)
  6. 自動ビルド名をつける
  7. ビルドへオプションのDockerタグを割り当て
  8. Dockerfile対象を特定(デフォルトでは/)


自動ビルドが設定されると、ビルドが自動的にトリガリングされ、数分後、 Docker Hub レジストリ上に新規自動ビルドを確認することができます。自動ビルドが無効化されるまで、GitHub/BitBucketリポジトリのsyncを待機します。

自動ビルドのステータをを確認したい場合、Docker Hubの自動ビルドページを開いてください。ビルドステータスとビルド履歴を確認することができます。

作成した自動ビルドは、無効化や削除することができます。ただし、「docker push」コマンドを使って自動ビルドのpushはできません。コードをGitHub/BitBucket リポジトリへコミットすることでのみ管理可能です。

リポジトリに対して複数の特定のDockerfileもしくはGitブランチを指定した自動ビルドを作成・設定できます。

 

ビルドトリガ


自動ビルドはDocker Hub上のURL経由でもトリガ実行可能です。これは必要に応じて自動ビルドイメージのリビルドを可能にしています。

 

Webhooks


Webhooks はリポジトリに紐付けられており、あるイメージもしくは更新イメージがリポジトリへpushされた時にイベントが実行(トリガ)されます。webhooksでターゲットのURLを指定でき、そしてイメージがpushされた時にJSONペイロードが配達されます。

webhooksについてのより詳しい情報は、Docker Hub ドキュメンテーションを参考にしてください。
 


次のステップ


では、Dockerを使ってみましょう!

2015年3月13日金曜日

The Docker User Guide: Linking Containers Together を翻訳してみた

今回は以下のサイトを翻訳してみました。

 Linking Containers Together
 https://docs.docker.com/userguide/dockerlinks/

ここまでDockerユーザガイドを翻訳すると、
例えば、DBを使ったWebアプリケーションなんかを動作させるには
単一のコンテナではダメ(ダメじゃないけど)だということがわかってきた。

とするとコンテナ間の通信が必要になり
動的にIPアドレスがふられているDocker内で
どうしても名前解決ってやつが必要になってくる。

しかもDockerは思想的に
各コンテナはIPアドレスやホスト名が動的につけられてもうごくよ
って感じでデザインするのがかっこいいとおもっているらしい..

で、必要になってくるのが今回翻訳した部分の知識だ。



あ、翻訳を参照される方は at your own riskでお願いします。


----------

コンテナのリンク


コンテナの動作セクションでは、ネットワークポート経由でDockerコンテナ内部で動作中のサービスとの通信方法について学習してきました。しかし、1つのポートでは、Dockerコンテナ内で操作中のサービスやアプリケーションでの相互接続はたった1つだけしかできません。このセクションでは、1つのネットワークポート経由の接続を短く再学習して、もう一つのアクセス方法であるコンテナリンキングについて紹介します。


ネットワークポートマッピングを使った接続


コンテナの動作セクションでは、Python Flaskアプリケーションが動作するコンテナを生成しました:


 $ sudo docker run -d -P training/webapp python app.py

 注意:
 (コンテナの動作セクションにて、docker inspectコマンドでコンテナのIPアドレスを
 確認したとおり)コンテナは1つの内部のネットワークと
 1つのIPアドレスを保有しています。
 Dockerは様々なネットワーク構成を持つことができます。
 Dockerネットワーキングにおけるより詳しい情報を以下のサイトで確認できます。

 Network Configuration
 https://docs.docker.com/articles/networking/

コンテナが生成された際に指定した「-P」フラグは自動的にコンテナ内部のネットワークポートをDockerホスト上のポート番号49153から65535までの範囲のランダムなポートにマップするために使用しています。docker ps を実行した際に、コンテナの5000番ポートが、ホストの49155番ポートへバインドされていることを確認しました。

 $ sudo docker ps nostalgic_morse
 CONTAINER ID  IMAGE                   COMMAND       CREATED        STATUS        PORTS                    NAMES
 bc533791f3f5  training/webapp:latest  python app.py 5 seconds ago  Up 2 seconds  0.0.0.0:49155->5000/tcp  nostalgic_morse

-p」フラグを用いてあるコンテナ側のポートを特定のポートへバインドする方法についても学習しました。

 $ sudo docker run -d -p 5000:5000 training/webapp python app.py


そして、1つだけのコンテナの特定ポートに縛られるためこの方法がそれほど良いアイディアではないことも学びました。

-p」フラグを使った設定方法は他にもいくつかります。デフォルトでは「-p」フラグは特定のポートをホスト上のすべてのインターフェイスへバインドします。しかし、例えばlocalhostへなどのように、特定のインターフェイスへバインドすることも可能です。

 $ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

この場合、コンテナ内部の5000番ポートからホストマシン上のlcalhostもしくは127.0.0.1インターフェイスの5000番ポートへバインドしています。

または、コンテナの5000番ポートをあるダイナミックポートへバインドしますが、ローカルホスト上のみ可能です。

 $ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py

/udp」を追加することでUDPポートをバインドすることも可能です。例えば:

 $ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

カレントのポートバインディングを確認した際に便利なdocker ポートのショートカットについても学習しました。これは、特定のポート設定を確認する際にも便利です。例えば、ホストマシンでコンテナポートをのlocalhostへバインドすると、dockerポートのアウトプットに反映されます。

 $ sudo docker port nostalgic_morse 5000
 127.0.0.1:49155

 注意:
 複数ポートを設定するために、「-p」フラグを複数使用することができます。

リンクによる通信


ネットワークポートマッピングは、Dockerコンテナが別のコンテナと通信する唯一の方法ではありません。Dockerにも、複数のコンテナをリンクし次から次へと接続情報を送信するリンクがあります。コンテナがリンクされると、送信元コンテナについての情報は受信先コンテナへ送信できます。送信元コンテナの状況を説明している選択されたデータを参照することができます。


名前をつけることの重要性


Dockerはコンテナ名を頼りにリンクを確立します。これまで学習してきたとおり、生成したそれぞれのコンテナは自動的に名前が作成されます;このガイドをとおして、旧友 nostalgic_morse を本当によくしっているとおもいます。コンテナに名前をつけることもできます。この名前をつけることは2つの役に立つ機能を提供します:
 

  1. 例えば、Webアプリケーションを含むコンテナの名前を「web」にするなど、特定の機能を実行するコンテナに名前をつければ、より覚えやすくなり便利です。
  2. 例えば、「web」コンテナに「db」コンテナへリンクする設定が可能になるなど、Dockerに対して他のコンテナに参照させるリファレンスポイントを提供します。

--name」フラグでコンテナに名前をつけることができます。例えば:

 $ sudo docker run -d -P --name web training/webapp python app.py

上記は、新規コンテナを起動し、「--name」フラグを使って「web」と名付けています。「docker ps」コマンドを使うとコンテナ名を参照できます。

 $ sudo docker ps -l
 CONTAINER ID  IMAGE                  COMMAND        CREATED       STATUS       PORTS                    NAMES
 aed84ee21bde  training/webapp:latest python app.py  12 hours ago  Up 2 seconds 0.0.0.0:49154->5000/tcp  web

「docker inspect」コマンドもコンテナ名を返却します。

 $ sudo docker inspect -f "{{ .Name }}" aed84ee21bde
 /web

 注意:
 コンテナ名は一意でなくてはなりません。
 これは「web」と呼ぶのは1つのコンテナだけであることを意味しています。
 もしコンテナ名を再利用したいのであれば、同じな目の新規コンテナを生成する前に、
 (docker rm で)古いコンテナ削除しなくてはなりません。
 他の方法として、docker runコマンドに「--rm」フラグを使うことができます。
 このフラグを使うと、停止した直後に対象のコンテナは削除されます。


リンクをまたがった通信


リンクはコンテナに対してお互いを見つけ、一方から他方へ情報をセキュアに伝達することを許可します。リンクをセットアップした時に、送信元コンテナと受信先コンテナとの間にパイプを構築します。受信側は送信元についての選択された情報へアクセスすることができます。リンクを作成するために、「--link」フラグを使います。最初に新規コンテナを生成します、この場合は新規コンテナにデータベースが含まれています。

 $ sudo docker run -d --name db training/postgres

上記の場合、「db」と呼ばれる新規コンテナを「training/postgres」イメージから生成しています。そしてそのコンテナはPostgreSQL データベースを含んでいます。

ここで前に作成した「web」コンテナを削除してリンクのあるコンテナを置き換える必要があります:


 $ sudo docker rm -f web

新規「web」コンテナを生成し「db」コンテナにリンクします。

 $ sudo docker run -d -P --name web --link db:db training/webapp python app.py

これは新規の「web」コンテナを、以前に作成した「db」コンテナにリンクしています。「--link」フラグの書式は次のとおり:

 --link :alias

nameはリンク先コンテナの名前で、aliasはリンク名のエイリアスです。aliasがどのように使用されるかについては後述します。

次に、「docker inspect」を使ってリンクされたコンテナを確認します:

 $ sudo docker inspect -f "{{ .HostConfig.Links }}" web
 [/db:/web/db]

web/db」から「web」コンテナが「db」コンテナにリンクされていることがわかります。そして「db」コンテナについての情報へのアクセスを許可しています。

では、リンクは実際にコンテナに何をするのでしょうか?

さきほどの例では、受信側である「web」は送信元である「db」についての情報へアクセスできます。これを実現するには、Dockerはコンテナ間にセキュアなトンネルを構築するので、コンテナのポートを外部に露出させる必要がありません;「db」コンテナを開始した際に、「-P」や「-p」を使わなかったことに注意してください。これはリンクを使う大きな利点です:送信元コンテナ、ここではPostgreSQLデータベース、をネットワークへ公開させる必要がありません。

Dockerは送信元コンテナから受信先コンテナへ2つの方法で連結情報を公開します:
 

  • 環境変数
  • /etc/hosts ファイルの更新


環境変数


コンテナへリンクした時、Dockerはいくつかの環境変数を生成します。Dockerは。「--link」パラメータを元にしてターゲットとなるコンテナ内に自動的に環境変数を生成します。Dockerから生成したすべての環境変数もまた送信元コンテナから公開します:
 

  • 送信元コンテナのDockerfile
  • 送信元コンテナ開始時における docker run コマンドの「-e」、「--env」、「--env-file」オプション

これらの環境変数は、ターゲットコンテナ内部のプログラムから送信元コンテナに関連する情報の発見を可能にします。

 警告:
 Dockerが生成しているコンテナ内部のすべての環境変数が
 リンク先に対して利用可能にしていることを理解することは重要です。
 もし機密データがリンク先に保管されているならば、
 これはセキュリティに対する深刻な影響をあたえることがあります

Dockerは、「--link」パラメータにリストされた各ターゲットコンテナへ _NAME 環境変数をセットします。例えば、もし「web」と呼ばれる新規コンテナが「--link db:webdb」を指定して「db」とよばれるデータベースコンテナにリンクされているならば、Dockerは「web」コンテナ上に「WEBDB_NAME=/web/webdb」を生成します。

Dockerはまた、送信元コンテナによって公開された各ポートの環境変数群をセットします。次の形式のような一意な prefix のついた環境変数となります:

 _PORT__

このprefixのコンポーネントは:

  • --link」パラメータ内で指定したエイリアス (例:webdb)
  • 公開されている 番号
  • TCPUDPかのどちらかである


Dockerはこのprefix形式をつかって3つの個別の環境変数を定義します:

  • prefix_ADDR」:URLから取得したIPアドレス(例:WEBDB_PORT_8080_TCP_ADDR=172.17.0.82)
  • prefix_PORT」:URLから取得したポート番号(例:WEBDB_PORT_8080_TCP_PORT=8080)
  • prefix_PROTO」:URLから取得したプロトコル(例:WEBDB_PORT_8080_TCP_PROTO=tcp)

もしコンテナが複数ポートを公開するのであれば、環境変数はそれぞれに定義されます。これは、例えば、もしコンテナが4ポート公開するならば、各ポート3つづなので、Dockerは12個の環境変数を生成します。

それらにくわえて、Dockerは「_PORT」と呼ばれる環境変数を生成します。値には送信元コンテナの最初に公開したポートのURLが含まれます。"最初"のポートは最も低い番号を公開ポートとして定義します。たとえば、WEBDB_PORT=tcp://172.17.0.82:8080 のようになります。もしポートがtcp、udp ともに使用されるのであれば、tcp が指定されます。

最後に、Dockerはターゲット側の環境変数としてそれぞれのDockerが生成する環境変数を送信元コンテナから公開します。それぞれの環境変数は、Dockerがターゲットコンテナ上に変数「_ENV_ 」を生成します。変数値は送信元コンテナ開始時にDockerによって使用された値がセットされます。

データベースの例に戻ると、特定のコンテナの環境変数をリストする「env」コマンドを実行することができます。

 $ sudo docker run --rm --name web2 --link db:db training/webapp env
 ...
 DB_NAME=/web2/db
 DB_PORT=tcp://172.17.0.5:5432
 DB_PORT_5432_TCP=tcp://172.17.0.5:5432
 DB_PORT_5432_TCP_PROTO=tcp
 DB_PORT_5432_TCP_PORT=5432
 DB_PORT_5432_TCP_ADDR=172.17.0.5
 ...

Dockerが送信元である「db」コンテナに関する便利な情報の一連の環境変数を構築したことがわかります。「DB_」から始まる各変数、これらは先ほど指定したエイリアスから書き込まれています。もしエイリアスが「db1」であれば、環境変数の先頭は「DB1_」から始まります。それらの環境変数は「db」コンテナ上のデータベースと接続するアプリケーションを設定するために使うことができます。通信はセキュアでプライベートです;リンクされた「web」コンテナにだけ「db」コンテナと通信することができます。


Docker 環境変数の重要な注意


/etc/hosts ファイルのホストエントリとは異なり、送信元コンテナが再実行されると、環境変数に格納されたIPアドレスは自動的に更新されません。リンクされたコンテナのIPアドレスの解決には/etc/hostsのホストエントリを使用することを推奨します

これらの環境変数はコンテナの最初のプロセスでのみセットされます。sshd のような、いくつかのデーモンは、接続のためのシェルを実行する際に環境変数をこすりだします。

/etc/hosts ファイルの更新


環境変数に加えて、Dockerは送信元コンテナのためにホストエントリを/etc/hostsファイルへ追加します。ここでは「web」コンテナのエントリを見てみましょう:

 $ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash
 root@aed84ee21bde:/opt/webapp# cat /etc/hosts
 172.17.0.7  aed84ee21bde
 ...
 172.17.0.5  db

2つの関連するホストエントリを見ることができます。最初の1つは、ホスト名としてコンテナIDを使用している「web」コンテナのエントリです。もう一つのエントリはリンクエイリアスを使って「db」コンテナのIPアドレスを参照しています。

 root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
 root@aed84ee21bde:/opt/webapp# ping db
 PING db (172.17.0.5): 48 data bytes
 56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
 56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
 56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms

 注意:
 この例では、初期のコンテナには含まれていなかったため、
 pingをインストールする必要がありました。

ここでは、pingコマンドでホストエントリを使って、172.17.0.5としてresolveして、「db」コンテナへのpingを実行しました。ホストエントリを使ってアプリケーションにdbコンテナの利用を設定することができます。

 注意:
 単一の送信元コンテナから複数の受信先コンテナにリンクすることができます。
 例として、「db」コンテナに接続された複数の web
 (実際には異なる名前が付けられている)コンテナを持つ事ができました。

もし送信元コンテナを再起動したら、リンクされたコンテナの /etc/hosts ファイル群は新しい送信元コンテナのIPアドレスに自動更新され、リンクされた通信を継続させます。

 $ sudo docker restart db
 db
 $ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash
 root@aed84ee21bde:/opt/webapp# cat /etc/hosts
 172.17.0.7  aed84ee21bde
 ...
 172.17.0.9  db


次のステップ


このセクションでは複数のDockerのリンクについて学習したので、次のステップではデータ、ボリューム、コンテナ内部におけるマウントの方法について学習します。

コンテナにおけるデータ管理へ進む。

----------

dockerコマンドで、いかに露出させるホスト名やポートを減らし、
内部の通信で済ませてしまうようにDockerfileを書くには
=イメージをどうつくるか
には、ある程度デザインに対するパターン言語が必要なんでないのかな。

まあ、英語ではあるんだろうなあ..
ベストプラクティス云々の単語がちらほらしているし..

このあたりを日本語で華麗に書籍化とかしたら
ヒーローになれるんだろうけど..

超..めんどくさそうだ..

既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ

既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。   1. The Twelve Factors (日本語訳からの転記) コードベース   バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 ...