Linux

2015年01月06日

このエントリーをはてなブックマークに追加

快適なOpenSSH作業環境を手に入れるまでの道のり

OpenSSHによるリモートログイン対象が多く、整理せざるを得ない状況に追い込まれた所から始まり、改善を重ね、今の所は快適な環境を手に入れた。これまでの記録を、ここにまとめておく。

主な特徴

  • keychainのような機能
    • ssh-agent多重起動防止
    • ssh-addによる複数の秘密鍵登録管理
    • SSH_AUTH_SOCKパス固定化(screen/tmux detach/reattach連携対応用途)
  • keychainよりも軽量
    • 軽量な理由は、keychainよりも処理してる内容が少ないから

背景・経緯

  1. 作業対象が数台だった頃、各サーバに秘密鍵を配置する運用でしのいで来た
    1. ログイン対象数が増え始める
    2. 管理対象キーペア数が増え始め、鍵管理が面倒臭くなる
    3. SSHクライアントとなる作業用ラップトップ数が増え始める
    4. ~/.ssh/をバージョン管理し、ssh_configと秘密鍵を管理
    5. ~/.ssh/をデプロイする所までは解決 (本エントリにおいては省略)
  2. ログイン時のパスフレーズ入力が面倒になり、ssh-agentについて調査・検証を開始
    1. ssh-agentが自動起動するように~/.bashrcを改良
    2. ssh-agent多重起動問題に遭遇
    3. mitchellh謹製bashrc と出会い、コードを拝借
    4. ssh-agent多重起動防止を実装
  3. 複数の秘密鍵を扱いたいが、mitchellh版ではssh-addのデフォルトパスしか扱ってなかった
    1. 複数の秘密鍵を扱えるように改良
  4. リモートログイン先にて新たなssh-agentが起動して来てしまう問題に遭遇
    1. 大元のSSHクライアント環境においては、単一ssh-agentプロセスのみ起動していて問題は無い
    2. しかし、リモートログインすると、リモートログイン先で新たにssh-agentが起動してしまう問題に遭遇
    3. リモートログイン状態かどうかを判定する仕組みを追加
  5. screenでdetachした後、reattachすると、UNIXソケットパスが切り替わってしまう問題に遭遇
    1. ssh-agentscreenの中から使う方法を発見・拝借し、SSH_AUTH_SOCKを固定化
    2. 更にtmux内からもSSH_AUTH_SOCKが固定化されてる事を確認
  6. リモートログイン先がMacOSの場合、SSH_AUTH_SOCK が固定されない問題に遭遇
    1. Yosemiteでの外部からログインしてssh-agentを正しく使う方法を発見・拝借し、SSH_AUTH_SOCK を固定化
  7. 快適なssh生活を手に入れた
  8. 実は、ここまでまとめ来た内容と似たツールとしてkeychainの存在を知る・・・
    1. keychainモードへの切り替えを試みる
    2. プロトタイプ版を作り、使ってみると、起動するまでが遅かった
    3. keychainモードへの切り替えを保留
    4. keychainの機能のうち、ホームディレクトリがNFSマウントされた環境を考慮した仕組みだけは拝借し、機能追加
  9. 2015/01/06現在、似非keychainで快適生活を過ごしている
  10. YosemiteへのSSHログイン後の鍵が期待通りではない事に気付く
    1. 手元の環境に置いてはYosemiteでの外部からログインしてssh-agentを正しく使う方法が不要だったので、修正・削除
  11. 2015/01/08現在、似非keychainで快適生活を過ごしている

対象環境

  • ログインシェルをbashに設定しているUNIXアカウント
  • ログインシェルをzshに設定しているUNIXアカウント

対象者?(自分が置かれた環境とも言う)

  • ログイン元環境が複数台存在する
  • ログイン先環境が複数台存在する
  • 1日にSSH接続する回数が恐らく多い方だ
  • keychainが遅いと感じている

動作確認済み環境

$ bash --version
$ ssh -V
  • Cygwin 1.7 / Windows 8.1
    • GNU bash, version 4.1.17(9)-release (i686-pc-cygwin)
    • OpenSSH_6.7p1, OpenSSL 1.0.1j 15 Oct 2014
  • MacOS 10.10 (Yosemite)
    • GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin14)
    • OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
  • Raspbian 7.6 (Wheezy)
    • GNU bash, version 4.2.37(1)-release (arm-unknown-linux-gnueabihf)
    • OpenSSH_6.0p1 Debian-4+deb7u2, OpenSSL 1.0.1e 11 Feb 2013
  • Fedora release 20 (Heisenbug)
    • GNU bash, version 4.2.53(1)-release
    • OpenSSH_6.4p1, OpenSSL 1.0.1e-fips 11 Feb 2013
  • CentOS-6.6
    • GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
    • OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013

使い方

  1. 【設定】 後述する作業対象ファイルを作成・修正・保存
  2. 【準備】 新規bashプロセスを作成し、ssh-agentssh-addを自動起動させる
  3. 【実行】 ssh -A <remotehost> にてリモートホストにSSH接続

作業対象ファイル

  1. ~/.bashrc or ~/.zshrc - 必須
    • 追記。無い場合は新規作成。
    • SSHクライアントおよび全SSH接続対象に反映
  2. ~/.ssh/agent_keys - 必要に応じて
    • 新規作成 +SSHクライアント環境のみ
~/.bashrc or ~/.zshrc- 必須

~/.zshrcにおいても動作を確認。bash前提で話を進めて行くので、zshの場合はbashzshで読み替えて頂きたい。

SSHクライアント環境および全SSH接続対象の~/.bashrcに追記・反映する必要がある。下記内容を、~/.bashrcに追記。追記場所は行末などで良い。

#-------------------------------------------------------------------------------
# SSH Agent
# + based on https://github.com/mitchellh/dotfiles/blob/master/bashrc#L181-L203
#-------------------------------------------------------------------------------

ssh_env=${HOME}/.ssh/environment.${HOSTNAME}

function start_ssh_agent() {
  # remote?
  [[ -z "${SSH_CLIENT}" ]] || return 0

  ssh-agent | sed 's/^echo/#echo/' > ${ssh_env}
  chmod 0600 ${ssh_env}
  . ${ssh_env} > /dev/null

  local ssh_agent_keys=${HOME}/.ssh/agent_keys

  if [[ -f "${ssh_agent_keys}" ]]; then
    local privkey=
    while read privkey; do
      # expand a file path using "~" or "${HOME}"
      eval privkey=${privkey}
      [[ -f "${privkey}" ]] || continue
      ssh-add ${privkey}
    done < ${ssh_agent_keys}
  else
    ssh-add
  fi
}

# Source SSH agent settings if it is already running, otherwise start
# up the agent proprely.

if [[ -f "${ssh_env}" ]]; then
  . ${ssh_env} > /dev/null
  ps -p ${SSH_AGENT_PID} > /dev/null || {
    start_ssh_agent
  }
else
  start_ssh_agent
fi

# static ssh agent sock path

ssh_agent_sock=${HOME}/.ssh/agent.sock.${HOSTNAME}

# based on http://www.gcd.org/blog/2006/09/100/
if ! [[ -L "${SSH_AUTH_SOCK}" ]] && [[ -S "${SSH_AUTH_SOCK}" ]]; then
  ln -fs ${SSH_AUTH_SOCK} ${ssh_agent_sock}
  export SSH_AUTH_SOCK=${ssh_agent_sock}
fi
~/.ssh/agent_keys - 必要に応じて作成

このファイルは作成しなくても良い。もしも使う場合、記述例は下記の通り。

~/.ssh/keys/github/hansode
~/.ssh/keys/wakame/deploy

この仕組みが威力を発揮する主な状況は、

  • 扱う秘密鍵が複数存在する時
  • 扱う秘密鍵は単数だが、ssh-addコマンドで追加させたい秘密鍵パスがデフォルト検索パスではなく、別の場所か複数指定したい時

なお、デフォルト検索パスはssh-addmanで述べられている。

man ssh-add より:

 DESCRIPTION
     ssh-add adds private key identities to the authentication agent,
    ssh-agent(1).  When run without arguments, it adds the files
    ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and
    ~/.ssh/identity.  After loading a private key, ssh-add will try to load
    corresponding certificate information from the filename obtained by
    appending -cert.pub to the name of the private key file.  Alternative
    file names can be given on the command line.

manに述べられている通り、引数無しssh-addコマンド実行の場合は、下記ファイルが追加対象となる。

  • ~/.ssh/id_rsa
  • ~/.ssh/id_dsa
  • ~/.ssh/id_ecdsa
  • ~/.ssh/id_ed25519
  • ~/.ssh/identity

これらに該当しないファイルパス、または複数ファイルを扱いたい場合、~/.ssh/agent_keysに記述しておくと、秘密鍵を容易に扱えるようになる。例え扱う秘密鍵が単一であり、しかもデフォルト検索対象であったとしても、明示的な宣言により、何を利用しているのかが見えやすいと言うメリットがある。それゆえ、個人的には積極的に利用している。

動作確認: ローカル環境編

前提条件
  • ローカル環境の~/.bashrc 修正が完了している事
確認項目
  1. ssh-agentが自動起動する
  2. ssh-addにより秘密鍵が登録される事
  3. ssh-agentが多重起動しない事
  4. SSH_AUTH_SOCKが固定化される事
確認作業: ssh-agent自動起動、ssh-addによる鍵登録、多重起動防止

bashを起動する。設定が正しければ、ssh-agent起動とssh-addによる複数鍵登録に成功し、下記のような出力が得られる。キーペアにパスフレーズが設定されている場合は、パスフレーズ入力待ちとなる。

localhost$ bash
Identity added: /home/hansode/.ssh/keys/github/hansode (dsa w/o comment)
Identity added: /home/hansode/.ssh/keys/wakame/deploy (rsa w/o comment)

次に、ssh-agentが多重起動しない事を確認する。新たなbash起動前のPIDを確認。

localhost$ echo $$
6796

PID6796である事が分かった。更にbashを起動。

localhost$ bash
localhost$ echo $$
2388

bash起動後、今度は何も出力されていない。そしてPID2388。これにより、別PIDである事が分かる。更にもう1つbashを起動してみる。

localhost$ bash
localhost$ echo $$
3916

PIDssh-agentの起動状況をまとめると、

  1. PID=6796 - ssh-agentが起動
  2. PID=2388 - ssh-agentは起動しない
  3. PID=3916 - ssh-agentは起動しない

整理すると、

  • ssh-agnetが起動してない場合は、ssh-agentを起動し、ssh-addで秘密鍵を登録
  • ssh-agentが起動している場合は、何もしない
  • ssh-agent多重起動を防止
確認作業: SSH_AUTH_SOCK固定化

SSHに関する環境変数を確認。

localhost$ env | sort | egrep ^SSH_
SSH_AGENT_PID=192
SSH_AUTH_SOCK=/home/hansode/.ssh/agent.sock.localhost

この結果から、SSH_AUTH_SOCK~/.ssh/agent.sock.${HOSTNAME}である事が分かる。ファイルパスに${HOSTNAME}を含めている理由は、ホームディレクトリがNFSマウントされた環境においても動作させる為。

~/.ssh/agent.sock.${HOSTNAME}のファイル情報を確認してみると、

localhost$ ls -l ~/.ssh/agent.sock.localhost
lrwxrwxrwx 1 hansode なし 32 Jan  3 21:39 /home/hansode/.ssh/agent.sock.localhost -> /tmp/ssh-3RRm1KL1FZ1A/agent.6700=

SSH_AUTH_SOCKに指定されているファイルは、シンボリックリンクである事が分かる。

シンボリックリンク先は/tmp/ssh-3RRm1KL1FZ1A/agent.6700である事も分かる。/tmp/ssh-3RRm1KL1FZ1A/agent.6700のファイル情報を確認してみると、実態となるUNIXソケットである事が分かる。

localhost$ ls -l /tmp/ssh-3RRm1KL1FZ1A/agent.6700
srw------- 1 hansode なし 0 Jan  3 21:29 /tmp/ssh-3RRm1KL1FZ1A/agent.6700=

整理すると、

  1. SSH_AUTH_SOCK~/.ssh/agent.sock.${HOSTNAME}
  2. ~/.ssh/agent.sock.${HOSTNAME}は、シンボリックリンク
  3. リンク先は/tmp/ssh-3RRm1KL1FZ1A/agent.6700

ssh-agentが改めて起動する場合は、シンボリックリンク情報だけが張り替わり、SSH_AUTH_SOCK=~/.ssh/agent.sock.${HOSTNAME}は固定化・定数化される。

動作確認: リモート環境編

前提条件
  • ローカル環境の~/.bashrc 修正が完了している事
    • ssh-agentが起動してる事
    • リモート環境用キーペアの秘密鍵がssh-addによる登録されてる事
  • リモート環境の~/.bashrc 修正が完了している事
    • リモート環境用キーペアの公開鍵が~/.ssh/authorized_keysに登録されてる事
確認項目
  1. SSH_AUTH_SOCKが固定化される事
確認作業: SSH_AUTH_SOCK固定化

参考までに、ForwardAgent noの場合は、SSH_AUTH_SOCKが存在しない。

localhost$ ssh remotehost
remotehost$ env | sort | egrep ^SSH_
SSH_CLIENT=192.0.2.68 39922 22
SSH_CONNECTION=192.0.2.68 39922 192.0.2.101 22
SSH_TTY=/dev/pts/0

ForwardAgent yes(-Aオプション付き)の場合は、SSH_AUTH_SOCKが設定される。そして、リモート環境においても~/.ssh/agent.sock.remotehostが設定されている事も分かる。

localhost$ ssh -A remotehost
remotehost$ env | sort | egrep ^SSH_
SSH_AUTH_SOCK=/home/hansode/.ssh/agent.sock.remotehost
SSH_CLIENT=121.114.159.68 39934 22
SSH_CONNECTION=192.0.2.68 39922 192.0.2.101 22
SSH_TTY=/dev/pts/0

ローカル環境と同じ様に、リモート環境も~/.ssh/agent.sock.remotehostは、実態ソケットファイルを参照するシンボリックリンクとなっている事が分かる。

remotehost$ ls -l ~/.ssh/agent.sock.remotehost
lrwxrwxrwx 1 hansode hansode 31 Jan  3 22:33 /home/hansode/.ssh/agent.sock.remotehost -> /tmp/ssh-2cwxr7qAo7/agent.30716

動作確認: リモート環境screen連携編

前提条件
  • ローカル環境の~/.bashrc 修正が完了している事
  • リモート環境の~/.bashrc 修正が完了している事
確認項目
  1. SSH_AUTH_SOCK
    1. screenの外から固定化されている事
    2. screenの中から固定化されている事
    3. detach/reattachしたscreenの中からも固定化されている事
確認作業: SSH_AUTH_SOCK固定化

ForwardAgent yes(-Aオプション付き)で対象サーバにSSHログイン。

localhost$ ssh -A remotehost

screen起動前のPIDと環境変数SSH_AUTH_SOCKを確認。

remotehost$ echo $$
27973
remotehost$ printenv SSH_AUTH_SOCK
/home/hansode/.ssh/agent.sock.remotehost

期待通り~/.ssh/agent.sock.${HOSTNAME}が指定されている。

この時のファイルパスが、ローカル環境におけるファイルパスとは違う事に注目したい。リモート環境はリモート環境特有ファイルパスが生成されいてる。

  • localhost: ~/.ssh/agent.sock.localhost
  • remotehost: ~/.ssh/agent.sock.remotehost

これはローカル環境と同様にNFSマウントされたホームディレクトリ環境を考慮した仕組みである。

次にscreenを起動。

remotehost$ screen

screen内のプロセスIDと環境変数SSH_AUTH_SOCKを確認。

remotehost:screen$ echo $$
28303
remotehost:screen$ printenv SSH_AUTH_SOCK
/home/hansode/.ssh/agent.sock.remotehost

期待通り~/.ssh/agent.sock.${HOSTNAME}が指定されている。

次に、detachしreattachする。

remotehost$ screen -r

再度screen内のプロセスIDと環境変数SSH_AUTH_SOCKを確認。

remotehost:screen$ echo $$
28303
remotehost:screen$ printenv SSH_AUTH_SOCK
/home/hansode/.ssh/agent.sock.remotehost

期待通り~/.ssh/agent.sockが指定されている。これにより、detachしたscreen内の作業を後日行う事が可能だ。

余談:Keychain化を試みたが・・・

ある程度の仕組みをまとめ終えてからkeychainの存在を知り、一度はkeychainに乗り換え作業をしてみた。結果は、keychainを使わない事を選択した。理由は、keychain起動速度が遅い事。多機能ゆえに速度が犠牲になっているのだろう。秘密鍵を常時5つ登録している状況においては、特に遅く感じられた。独自実装だけでも機能要件を満たしていたので、敢えてkeychain化を中断した。

個人利用の限りでは、似非keychainで問題は無い。仮に多人数を対象にした鍵管理フローを構築したい場合は、keychain仕様が良いのかも知れない。少なくとも誰か1人が不満を言うまでは。

現バージョンの課題

  • ssh-agent再起動を考慮してない
    • 解決策はssh-agent -kを手動実行し、bashを起動

あとがき

本エントリを書くきっかけとなったのは、身近なメンバーに対して自分のssh-agent・秘密鍵管理術の説明資料が無かった事。彼らに作業改善案を口頭で説明・提案するにしては、伝える量が多く、手頃な説明資料が欲しくなった。そして、今回の末年始休みを活用し、まとめ終えた。

エントリ初版は数時間で書き終えたが、どうしても関連するコードが気になり、整理を開始。そして再検証作業、文書修正・・・。最終的に書き終えるまでにかかったのは、合計6日間。関連物も含め、整理する良い期間となった。

とにかく、手頃な説明資料を手に入れた!喜ばしい。

関連成果物

参考文献

続きを読む


編集
@hansode at 10:30|PermalinkComments(0)TrackBack(0)

2014年02月13日

このエントリーをはてなブックマークに追加

イベント
Docker Meetup in Tokyo #1
日付
2014/02/12(水) 19:00〜21:00
場所
国立情報学研究所
天気
晴れ
概要
発表後記
  • 開始直後の会場アンケート、30人強のうち、ICCを知ってるのは、たった1人!マジか
  • ↑な状況で話を進めたので、何だか会場全体を置き去りにしてる感
  • しかし、この発表をきっかけにICCを使う人が増え、情報共有・検証報告が増えたら、それは成功と言える。
  • 身近な数人からは『むしろ突き抜けてて良かった。』との言葉を頂けた。
  • ICCに関わらず、Dockerのネットワーク周辺を触ってる人は少数派だと言う事を実感。



編集
@hansode at 14:00|PermalinkComments(0)TrackBack(0)

2014年01月31日

このエントリーをはてなブックマークに追加

次のマイナーバージョンがリリースされた事により、困った事は無いだろうか?

少し前の事だが、CentOSが6.5がリリースされた。何も気にせずにyum updateすると、6.5へ・・・・。検証等の理由あって手元の環境は6.4を維持しておきたい事がある。さて、この状況をどうやって回避するのか。その手段の1つが、/etc/yum/vars/releaseverファイルによる固定。

検証環境
  • CentOS 6.4
  • kernel-2.6.32-358.el6.x86_64
  • yum-3.2.29-40.el6.centos.noarch
手順は/etc/yum/vars/releaseverを作成するだけ
  1. /etc/yum/vars/releaseverを作成
  2. ファイルの中身は、固定化したいバージョン
例: 6.4 固定化
/etc/yum/vars/releasever を作成
$ sudo $SHELL -c "echo 6.4 > /etc/yum/vars/releasever"
中身を確認
$ cat /etc/yum/vars/releasever
6.4
考察

例えばCentOSであれば、/etc/yum.repos.d/CentOS-Base.repoを修正し、$releaseverを特定バージョンに固定化する手段がある。しかし、これはCentOSに限定される。/etc/yum/vars/releaseverファイルの場合、特定ディストリビューションに依存しせず、固定が可能である事。RHELであろうがCentOSだろうがScientificLinuxであろうが、幅広く利用可能である事。

あとがき

1つ前のリリースバージョンのパッケージが、ミラーサイトから徐々に消えて行くのは、どうしたものか。

参考文献



編集
@hansode at 13:00|PermalinkComments(0)TrackBack(0)

2013年12月21日

このエントリーをはてなブックマークに追加

devicemapper-backedは、動くけども、どうもオーバーヘッドが大きい

docker-top-logo

docker-0.7になってからメジャーLinuxディストリビューションで動くようになったのは、ご存知の通りで、CentOS6でも簡単にDockerホストを構築できるようになった。

確かに動きはするけども、しばらく使ってみると、もたついた動作へと変化して行く。『aufs-backedにしたら、どうなるのか?』と言う興味本位から、aufs-backed dockerホスト構築してみた。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
  • kernel-ml-aufs-3.10.5-3.el6.x86_64
devicemapper-backed docker info
$ sudo docker info
Containers: 0
Images: 0
Driver: devicemapper
 Pool Name: docker-253:1-2360151-pool
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 291.5 Mb
 Data Space Total: 102400.0 Mb
 Metadata Space Used: 0.7 Mb
 Metadata Space Total: 2048.0 Mb

Driver: devicemapper となっている。

セットアップ考察背景
  1. aufs入りkernelが必要か?
  2. https://github.com/sciurus/docker-rhel-rpm を発見。ただし、提供しているのはrpmspecファイル。rpmは提供してない
  3. 調べた結果kernel-ml-aufsを提供しているyumリポジトリに辿り着く。http://www.hop5.in/yum/el6/repoview/
  4. ここまで材料が揃うと、あとはインストールするだけ。
hop5 yum repo
repoファイルを配置
$ sudo curl -fsSkL -o /etc/yum.repos.d/hop5.repo http://www.hop5.in/yum/el6/hop5.repo
repoファイルの中身を確認
$ cat /etc/yum.repos.d/hop5.repo
[hop5]
name=www.hop5.in Centos Repository
baseurl=http://www.hop5.in/yum/el6/
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-HOP5
kernel-ml-aufsをインストール
$ sudo yum install -y kernel-ml-aufs
grub.confを確認
$ cat /boot/grub/grub.conf
default=1
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (3.10.5-3.el6.x86_64)
        root (hd0,0)
        kernel /boot/vmlinuz-3.10.5-3.el6.x86_64 ro root=LABEL=root rd_NO_LUKS rd_NO_LVM LANG=C rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM selinux=0
        initrd /boot/initramfs-3.10.5-3.el6.x86_64.img
title centos-6.5_x86_64 (2.6.32-431.el6.x86_64)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.32-431.el6.x86_64 ro root=LABEL=root rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM selinux=0
        initrd /boot/initramfs-2.6.32-431.el6.x86_64.img

default=1となっていて、kernel-ml-aufsがデフォルトではない。defaultを変更する必要がある。

grub設定変更

後で差分を確認する為に、既存confをバックアップ。

$ sudo cp -i /boot/grub/grub.conf{,.0}

default値を 1 から 0 へ変更

$ sudo sed -i 's,default=1,default=0,' /boot/grub/grub.conf
$ sudo diff /boot/grub/grub.conf{.0,}
1c1
< default=1
---
> default=0
kernel-ml-aufsで起動させる為、再起動
$ sudo reboot
docker infoを確認
$ sudo docker info
Containers: 0
Images: 0
Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 0
WARNING: No swap limit support

driverがaufsになってる事を確認。devicemapperとは違い、軽快なDockerホストが手に入った。

あとがき
  • 『何をしたいか』に着目すると、vanilla kernelにこだわる必要はない。システム要件次第か。
  • 純正RHELに拘る場合は、vanilla kernelである必要があるので、devicemapper-backedと言う選択肢しかない。
参考文献



編集
@hansode at 23:50|PermalinkComments(0)TrackBack(0)

2013年12月17日

このエントリーをはてなブックマークに追加

S3-backedで一歩先行く使い捨て生活

docker-top-logo

前回に続いてPrivate Docker Registry。前回やり残していた検証、

S3 Storage : 使い捨ての良き友

まだ動作検証してないけども、S3と連携させられる所までは分かっている。

この後の戦略・シナリオは、

  1. s3 config済みのカスタムregistryイメージを作成(Dockerfile経由で)
  2. カスタムregistryコンテナを起動
  3. カスタムregistryイメージをpush

ここまで済ませておけば、必要な時にプライベートregistryコンテナを起動すれば良い。カスタムregistryでさえも、気軽に使い捨てられる。この辺の検証は、また別のエントリで。

残り検証作業をしてみた。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
  • s3cmd-1.0.1-1.el6.noarch
事前準備:S3 bucket

新規作成でも既存バケットでも、どちらでも良い。s3cmdでバケットを新規作成する場合の例。

$ s3cmd mb s3://private-docker-registry
Bucket 's3://private-docker-registry' created

※本書用にでっち上げたバケット名

事前準備:Dockerイメージ用ファイル

イメージビルド用に必要なファイルを用意/配置しておく。

  1. Dockerfile
  2. config.xml
1: Dockerfile
$ cat Dockerfile
FROM stackbrew/registry

ADD config.yml /docker-registry/config.yml
2: config.xml(docker-registry用)

コンテナイメージに焼き込むdocker-registry用config.xml

# The common' part is automatically included (and possibly overriden by all
# other flavors)
common:
    # Bucket for storage
    boto_bucket: ***s3 bucket名***

    # Amazon S3 Storage Configuration
    s3_access_key: ***s3_access_key****
    s3_secret_key: ***s3_secret_key***
    s3_bucket: ***s3 bucket名***
    s3_encrypt: 1
    s3_secure: 1

    # Set a random string here
    secret_key: ***適切なパスフレーズ***

priv:
    storage: s3
    storage_path: /priv

privターゲットは、環境変数SETTINGS_FLAVOR用で、privでなくても良い。

イメージビルド
$ sudo docker build -t registry.private .
Uploading context 10240 bytes
Step 1 : FROM stackbrew/registry
 ---> 3321c2caa0cf
Step 2 : ADD config.yml /docker-registry/config.yml
 ---> ad03546fac66
Successfully built ad03546fac66
コンテナ作成

今回は -e=SETTINGS_FLAVOR=priv を指定して起動。これにより、private用途の設定内容を指定して起動可能となる。

$ sudo docker run -d -p 5000:5000 -e=SETTINGS_FLAVOR=priv registry.private
411732c40b673a7ef8bfde9c4a696a0446096d30c488b66e6bf790b0caf5b21b
接続テスト
$ curl -v http://localhost:5000/
* About to connect() to localhost port 5000 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:5000
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: gunicorn/18.0
< Date: Tue, 17 Dec 2013 11:22:17 GMT
< Connection: keep-alive
< Expires: -1
< Content-Type: application/json
< Pragma: no-cache
< Cache-Control: no-cache
< Content-Length: 31
< X-Docker-Registry-Version: 0.6.2
< X-Docker-Registry-Config: priv
<
* Connection #0 to host localhost left intact
* Closing connection #0
"docker-registry server (priv)"

"docker-registry server (priv)" となってる。これにより、SETTINGS_FLAVORがprivである事を確認出来る。

いよいよS3-backed Private Registryにpush

イメージ取得とtag打ちは、前回の作業により既に終わってるものとする。

sudo docker push 127.0.0.1:5000/ubuntu
The push refers to a repository [127.0.0.1:5000/ubuntu] (len: 1)
Sending image list
Pushing repository 127.0.0.1:5000/ubuntu (1 tags)
Pushing 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c

Pushing tags for rev [8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c] on {http://127.0.0.1:5000/v1/repositories/ubuntu/tags/latest}

clientサイドとしては、何か変化してるのかどうかすら、分からない。

S3バケットを覗いてみる
$ s3cmd ls s3://private-docker-registry/
                       DIR   s3://private-docker-registry/priv/

/priv/ ディレクトリが作成されている。これは "storage_path: /priv" と一致する。

$ s3cmd ls s3://private-docker-registry/priv/
                       DIR   s3://private-docker-registry/priv/images/
                       DIR   s3://private-docker-registry/priv/repositories/

その配下には、 /images/ と /repositories/ が作成されている。

$ s3cmd ls s3://private-docker-registry/priv/images/
                       DIR   s3://private-docker-registry/priv/images/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/

その先にはハッシュ値のディレクトリが存在。これの値は、push時にも出力されていたイメージID。

$ s3cmd ls s3://private-docker-registry/priv/images/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/
2013-12-17 11:24        78   s3://private-docker-registry/priv/images/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/_checksum
2013-12-17 11:23        68   s3://private-docker-registry/priv/images/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/ancestry
2013-12-17 11:23       437   s3://private-docker-registry/priv/images/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/json
2013-12-17 11:23  71488718   s3://private-docker-registry/priv/images/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/layer

遂に実態オブジェクトが現れた。pushの裏側でs3バケットにオブジェクトが正しく登録されていた事が分かる。

気軽に使い捨てる

これだけでは使い捨て感を得られないので、使い捨てしてみる。

  1. private registryコンテナを破棄
  2. 新private registryコンテナを作成
  3. ローカルからイメージを一度削除
  4. 新private registry経由でイメージをpull
private registryコンテナを破棄
$ sudo docker kill 411732c40b673a7ef8bfde9c4a696a0446096d30c488b66e6bf790b0caf5b21b
新private registryコンテナを作成
$ sudo docker run -d -p 5000:5000 -e=SETTINGS_FLAVOR=priv registry.private
febb22cad222594f2158bf240b199deda243bbc976bcf7b956c689b1c3cddffe
新private registryコンテナが起動してる事を確認
$ sudo docker ps
CONTAINER ID        IMAGE                                    COMMAND                CREATED             STATUS              PORTS                    NAMES
febb22cad222        127.0.0.1:5000/registry.private:latest   /bin/sh -c cd /docke   32 seconds ago      Up 31 seconds       0.0.0.0:5000->5000/tcp   evil_brown
イメージ削除前に存在有無確認
$ sudo docker images 127.0.0.1:5000/ubuntu
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
127.0.0.1:5000/ubuntu   latest              8dbd9e392a96        8 months ago        128 MB (virtual 128 MB)
ローカルからイメージを削除
$ sudo docker rmi 127.0.0.1:5000/ubuntu
Untagged: 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c
ローカルにイメージが無い事を確認
$ sudo docker images 127.0.0.1:5000/ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
pullしてイメージを取得
$ sudo docker pull 127.0.0.1:5000/ubuntu
Pulling repository 127.0.0.1:5000/ubuntu
8dbd9e392a96: Download complete
再びローカルにイメージが作成された事を確認
$ sudo docker images 127.0.0.1:5000/ubuntu
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
127.0.0.1:5000/ubuntu   latest              8dbd9e392a96        8 months ago        128 MB (virtual 128 MB)

無事、復活。

あとがき

private registry構築により、複数リポジトリを扱ってみると、DockerイメージがGitライクに操作出来てる事を再認識させられる。実によく出来てる。

  • 成果物としてDockerイメージリポジトリごと納品するケースも出て来るだろうか
  • S3-backedにしておけばオブジェクトが無くなる心配はほぼ皆無で、心配事を減らせるか

遊べそうな事ばかり増えて行く。

参考文献



編集
@hansode at 22:30|PermalinkComments(0)TrackBack(0)
このエントリーをはてなブックマークに追加

Public Registryには登録できないコンテナイメージの登録先

docker-top-logo

構築作業をしているとpublic registryに登録するまでもないイメージや、手元の環境に特化した設定を焼きこんでいるがゆえに、public registryには登録出来ないイメージが幾つか作成される。自分の場合は、Dockerホストごと再構築する事が多々あるので、イメージをどこかに保存しておきたい事がある。そう言った要件を満たすのが、プライベートDockerレジストリ。

Dockerがdocker-registryを開発・公開していてる。

更に、registryイメージがpublic registryに登録されている。

ここまで材料が揃っていると、あっと言う間にセットアップが完了する。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
事前準備としてマシンイメージをpull
$ sudo docker pull stackbrew/registry

$ sudo docker images stackbrew/registry
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
stackbrew/registry   0.6.0               982e72a4385c        5 days ago          596.8 MB (virtual 4.537 GB)
stackbrew/registry   0.5.9               ddba540fb44c        5 days ago          596.6 MB (virtual 4.536 GB)
stackbrew/registry   0.6.1               3321c2caa0cf        5 days ago          472.2 MB (virtual 3 GB)
stackbrew/registry   latest              3321c2caa0cf        5 days ago          472.2 MB (virtual 3 GB)

検証当時は、0.6.1が最新。

$ sudo docker history stackbrew/registry
IMAGE               CREATED             CREATED BY                                      SIZE
3321c2caa0cf        5 days ago          /bin/sh -c #(nop) CMD [/bin/sh -c cd /docker-   472.2 MB
709278331dd3        5 days ago          /bin/sh -c #(nop) EXPOSE [5000]                 472.2 MB
a2d8a28078d8        5 days ago          /bin/sh -c cp --no-clobber /docker-registry/c   472.2 MB
20dae6853028        5 days ago          /bin/sh -c cd /docker-registry && pip install   472.2 MB
b34b73dac452        5 days ago          /bin/sh -c #(nop) ADD . in /docker-registry     415.6 MB
0fa5f53aba34        5 days ago          /bin/sh -c apt-get install -y git-core python   415 MB
4f73ac94d99d        5 days ago          /bin/sh -c sed -i 's/main$/main universe/' /e   192.4 MB
9a776d8a79dd        4 weeks ago         /bin/sh -c #(nop) ADD raring.tar.xz in /        88.42 MB
adfd622eb223        4 weeks ago         /bin/sh -c #(nop) MAINTAINER Tianon Gravi <ad   0 B
511136ea3c5a        6 months ago                                                        0 B

Dockerfileの内容である事が分かる。

コンテナを起動
$ sudo docker run -d -p 5000:5000 stackbrew/registry
eb20a3b33092e44bd31ed12860adcfe39133d6e0b6dc88a964876c68d0789c4c

$ sudo docker ps
CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS              PORTS                    NAMES
eb20a3b33092        stackbrew/registry:0.6.1   /bin/sh -c cd /docke   4 seconds ago       Up 2 seconds        0.0.0.0:5000->5000/tcp   cocky_archimede

Dockerホストの 0.0.0.0:5000 から、コンテナ内の 5000/tcp へポートフォワードされる設定まで入った。

接続テスト
$ curl -v http://localhost:5000/
* About to connect() to localhost port 5000 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:5000
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: gunicorn/18.0
< Date: Tue, 17 Dec 2013 01:03:25 GMT
< Connection: keep-alive
< Expires: -1
< Content-Type: application/json
< Pragma: no-cache
< Cache-Control: no-cache
< Content-Length: 30
< X-Docker-Registry-Version: 0.6.2
< X-Docker-Registry-Config: dev
<
* Connection #0 to host localhost left intact
* Closing connection #0
"docker-registry server (dev)"

サービスしてる事を確認出来る。

登録用イメージを取得

イメージは何でも良い。ここでは ubuntu を使用。

$ sudo docker pull ubuntu
Pulling repository ubuntu
8dbd9e392a96: Download complete
b750fe79269d: Download complete
27cf78414709: Download complete

$ sudo docker images ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              12.04               8dbd9e392a96        8 months ago        128 MB (virtual 128 MB)
ubuntu              latest              8dbd9e392a96        8 months ago        128 MB (virtual 128 MB)
ubuntu              precise             8dbd9e392a96        8 months ago        128 MB (virtual 128 MB)
ubuntu              12.10               b750fe79269d        8 months ago        175.3 MB (virtual 350.6 MB)
ubuntu              quantal             b750fe79269d        8 months ago        175.3 MB (virtual 350.6 MB)

$ sudo docker images ubuntu | grep -w latest
ubuntu              latest              8dbd9e392a96        8 months ago        128 MB (virtual 128 MB)

イメージIDは、 8dbd9e392a96。メモっておく。

tag打ち

tagが、イメージ を どのendpointへ登録するのか が定まる。(どっか!ではない・・・)今回のendpointは、 localhost:5000 なので、下記の様にtag打ちする。

$ sudo docker tag 8dbd9e392a96 localhost:5000/ubuntu
プライベートレジストリ localhost:5000 へ登録してみる
$ sudo docker push localhost:5000/ubuntu
The push refers to a repository [localhost:5000/ubuntu] (len: 1)
Sending image list
Pushing repository localhost:5000/ubuntu (1 tags)
Pushing 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c

Pushing tags for rev [8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}

無事、成功。

S3 Storage : 使い捨ての良き友

まだ動作検証してないけども、S3と連携させられる所までは分かっている。

この後の戦略・シナリオは、

  1. s3 config済みのカスタムregistryイメージを作成(Dockerfile経由で)
  2. カスタムregistryコンテナを起動
  3. カスタムregistryイメージをpush

ここまで済ませておけば、必要な時にプライベートregistryコンテナを起動すれば良い。カスタムregistryでさえも、気軽に使い捨てられる。この辺の検証は、また別のエントリで。

あとがき

プライベートレジストリを使えば、プロジェクト特化したconfig入りイメージを気軽に登録できるので、コンテナベースデプロイを、一歩も二歩も進められそうか。

参考文献



編集
@hansode at 13:00|PermalinkComments(0)TrackBack(0)

2013年12月14日

このエントリーをはてなブックマークに追加

アップグレード検証はコンテナの得意分野の1つ

RHEL 7 Beta 1 が公開された。

気になったのでアップグレードを検証してみた。

  1. CentOS-6.5 minimal Dockerコンテナを作成
  2. RHEL-7.0 Beta 1へアップグレード
  3. build結果を観察

アップグレードは、期待通り失敗する。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
事前準備
  1. Dockerホスト構築
  2. Dockerfileを配置
  3. rhel-beta.repoを配置
Dockerfile
FROM hansode/centos-6-x86_64

RUN rpm --import http://ftp.redhat.com/redhat/rhel/beta/7/x86_64/os/RPM-GPG-KEY-redhat-beta
RUN rpm --import http://ftp.redhat.com/redhat/rhel/beta/7/x86_64/os/RPM-GPG-KEY-redhat-release

ADD rhel-beta.repo /etc/yum.repos.d/rhel-beta.repo

CMD yum update --enablerepo=rhel-beta -y

ベースイメージは拙作のhansode/centos-6-x86_64/を使用。

rhel-beta.repo
[rhel-beta]
name=Red Hat Enterprise Linux 7 Beta - $basearch
#baseurl=ftp://ftp.redhat.com/pub/redhat/rhel/beta/7/$basearch/os/
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=rhel-7-beta&arch=$basearch
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta
build検証
imageをbuild
$ sudo docker build -t centos6-to-rhel7beta .

Uploading context 266240 bytes
Step 1 : FROM hansode/centos-6-x86_64
 ---> cff199166afa
Step 2 : RUN rpm --import http://ftp.redhat.com/redhat/rhel/beta/7/x86_64/os/RPM-GPG-KEY-redhat-beta
 ---> Using cache
 ---> 29fe8e11a311
Step 3 : RUN rpm --import http://ftp.redhat.com/redhat/rhel/beta/7/x86_64/os/RPM-GPG-KEY-redhat-release
 ---> Using cache
 ---> 79d5818a221b
Step 4 : ADD rhel-beta.repo /etc/yum.repos.d/rhel-beta.repo
 ---> bae8fd8675fa
Step 5 : CMD yum update --enablerepo=rhel-beta -y
 ---> Running in f637d63aec99
 ---> 45b4fb3644ae
Successfully built 45b4fb3644ae
buildしたイメージを起動
$ sudo docker run -t centos6-to-rhel7beta

Transaction Check Error:
  file /etc/my.cnf from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/Index.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/armscii8.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/ascii.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/cp1250.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/cp852.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/hebrew.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/latin1.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/latin2.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/charsets/latin5.xml from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/czech/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/danish/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/dutch/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/english/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/estonian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/french/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/german/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/greek/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/hungarian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/italian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/japanese/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/korean/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/norwegian-ny/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/norwegian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/polish/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/portuguese/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/romanian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/russian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/serbian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/slovak/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/spanish/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/swedish/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /usr/share/mysql/ukrainian/errmsg.sys from install of mariadb-libs-1:5.5.33a-3.el7.x86_64 conflicts with file from package mysql-libs-5.1.71-1.el6.x86_64
  file /lib/firmware/ql2500_fw.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package ql2500-firmware-7.00.01-1.el6.noarch
  file /lib/firmware/ql2400_fw.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package ql2400-firmware-7.00.01-1.el6.noarch
  file /lib/firmware/radeon/ARUBA_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/BTC_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/CAYMAN_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/CEDAR_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/CYPRESS_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/JUNIPER_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/PITCAIRN_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/R700_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/REDWOOD_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/SUMO_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/TAHITI_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
  file /lib/firmware/radeon/VERDE_rlc.bin from install of linux-firmware-20131106-0.1.git7d0c7a8.el7.noarch conflicts with file from package xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch

Error Summary
-------------

minimal構成で、この結果。そうか、MariaDBになったんだっけ。

参考文献
あとがき

こう言った使い捨て検証は、コンテナの得意分野の1つで、実際に実施してみると、それを実感する。




編集
@hansode at 09:40|PermalinkComments(0)TrackBack(0)

2013年12月10日

このエントリーをはてなブックマークに追加

素のCentOS6でpipeworkを使うと、エラーに遭遇する

Dockerコンテナに狙ったIPアドレスを割り当てるpipeworkを使った。この時に触れてない無い事がある。それは、CentOSでpipeworkを使う為の事前準備作業。おそらくUbuntuの場合は、関係が無い話。

必要な事前準備作業は2つ

  1. pipeworkのipコマンドによる中のブリッジ操作箇所を計2箇所、brctlコマンドで置き換える
  2. 最低限netns対応のiprouteで置き換える

その手順を追っていく。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
  • iproute-2.6.32-130.el6ost.netns.2.x86_64
  • bridge-utils-1.2-10.el6.x86_64
1. pipework修正
pipework修正: brctlで書き換え対応1

修正しない場合に出るエラーメッセージ。

$ sudo pipework br1 $cid 192.168.1.10/24
Error: either "dev" is duplicate, or "master" is a garbage.

118行目をbrctlコマンドで書き換える。

-    ip link set $LOCAL_IFNAME master $IFNAME
+    brctl addif $IFNAME $LOCAL_IFNAME
pipework修正: brctlで書き換え対応2

修正しない場合に出るエラーメッセージ。

$ sudo pipework br1 $cid 192.168.1.10/24
Object "netns" is unknown, try "ip help".

109行目をbrctlコマンドで書き換える。

-    ip link add $IFNAME type bridge
+    brctl addbr $IFNAME
修正版pipeworkはforkしてメンテナンス中

上記修正対応済みコードは、forkして下記リポジトリにてメンテナンス予定。

本家はUbuntu向けであるはずなので、CentOS向けはforkリポジトリでメンテナンスするのが良いと考えてる。役目を終える時は、RHEL7/CentOS7がリリースされた時か。

2. iprouteを入れ替える

baseのiprouteパッケージはnetns機能不十分iprouteである為、netns周りを設定出来ないようだ。探してみると、同じように困ってる方が居た。なお、この方はDockerホスト環境で困っていた訳では無さそう。

残念なことにバージョン 6.4 ではまだ Linux Network Namespace (netns) が使えない。 どうやら Linux カーネルと iproute2 のバージョンが足りてないらしい。じゃあどうするかっていうと RedHat が出している OpenStack ディストリビューションの RDO を使う。

この戦略を拝借してiprouteを置き換える。

$ sudo yum install -y http://rdo.fedorapeople.org/openstack/openstack-havana/rdo-release-havana.rpm
$ sudo yum update --enablerepo=openstack-havana -y iproute

$ rpm -qa iproute
iproute-2.6.32-130.el6ost.netns.2.x86_64

※このバージョンのipコマンドでも、ブリッジ操作までは対応してなかったので、前半のbrctlコマンド仕様に書き換える必要性は残ったまま。

以上でpipeworkを使うための準備体操は終わり。快適なpipework生活を!




編集
@hansode at 00:20|PermalinkComments(0)TrackBack(0)

2013年12月07日

このエントリーをはてなブックマークに追加

固定IPアドレス指定のコンテナ作成

Dockerコンテナに狙ったIPアドレス割り当てした環境で検証をしたい場合がある。それを解決する手段の1つが、pipework。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
例として 192.168.1.10/24 をコンテナに割り当ててみる
コンテナを起動

今回は base を使用。どのマシンイメージを使っても良い。

$ sudo docker run -i -t base /bin/bash
root@9e6eb5df1d30:/# ip addr show
135: eth0: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 46:48:66:3b:64:ba brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.35/16 brd 172.17.255.255 scope global eth0
    inet6 fe80::4448:66ff:fe3b:64ba/64 scope link
       valid_lft forever preferred_lft forever
137: lo: <loopback,up,lower_up> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
</loopback,up,lower_up></broadcast,multicast,up,lower_up>

起動直後は、eth0 - 172.17.0.35 の組み合せで割り当てられている。

コンテナIDを確認

割り当て対象コンテナIDを知っておく必要がある。

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
9e6eb5df1d30        base:latest         /bin/bash           17 seconds ago      Up 17 seconds                           clever_mccarthy

作ったコンテナIDは、 9e6eb5df1d30。

pipeworkで狙ったIPアドレスを割り当てる
$ sudo pipework br1 9e6eb5df1d30 192.168.1.10/24

ブリッジは br1 でなくても良い。pipeworkのREADMEがbr1を使っていたので、br1を使用。

ブリッジ状態を確認
$ brctl show
bridge name     bridge id               STP enabled     interfaces
br1             8000.aa2ead359fe8       no              vethl17357
docker0         8000.fe1cbcd978e9       no              veth8D13Bz

pipeworkがホストに影響を与えた事

  1. br1追加(無い場合は自動的に追加される)
  2. veth8D13Bzがbr1に刺さる
コンテナ中のIPアドレスは?
root@9e6eb5df1d30:/# ip addr show
135: eth0: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 46:48:66:3b:64:ba brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.35/16 brd 172.17.255.255 scope global eth0
    inet6 fe80::4448:66ff:fe3b:64ba/64 scope link
       valid_lft forever preferred_lft forever
137: lo: <loopback,up,lower_up> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
138: eth1: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether b2:e6:66:26:d0:41 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 scope global eth1
    inet6 fe80::b0e6:66ff:fe26:d041/64 scope link
       valid_lft forever preferred_lft forever
</broadcast,multicast,up,lower_up></loopback,up,lower_up></broadcast,multicast,up,lower_up>

pipeworkがゲストに影響を与えた事

  1. eth1追加
  2. eth1に192.168.1.10/24割り当て
ホスト・ゲスト間通信してみる

狙ったIPアドレス割り当てする場合は、ホストからゲストへ通信したい場合である事が多い。おまけ作業としてホストからゲストへ通信するセットアップをしてみる。

  • ホスト 192.168.1.254/24
  • ゲスト 192.168.1.10/24
割り当て前のIPアドレス状態を確認
$ ip addr show br1
28: br1: <broadcast,multicast,up,lower_up> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether aa:2e:ad:35:9f:e8 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::f493:8bff:fed9:9566/64 scope link
       valid_lft forever preferred_lft forever
</broadcast,multicast,up,lower_up>

IPアドレス割り当てされてない事を確認。

ホストブリッジにIPアドレス割り当て
$ sudo ip addr add 192.168.1.254/24 dev br1

$ ip addr show br1
28: br1: <broadcast,multicast,up,lower_up> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether aa:2e:ad:35:9f:e8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.254/24 scope global br1
    inet6 fe80::f493:8bff:fed9:9566/64 scope link
       valid_lft forever preferred_lft forever
</broadcast,multicast,up,lower_up>

192.168.1.254/24 が割り当てされてる。

ゲストへ向けてping
$ ping -c 1 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.043 ms

--- 192.168.1.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.043/0.043/0.043/0.000 ms
ゲストから抜ける
root@9e6eb5df1d30:/# exit
コンテナ破棄後のブリッジ状態
$ brctl show
bridge name     bridge id               STP enabled     interfaces
br1             8000.000000000000       no
docker0         8000.000000000000       no

br1に刺さってたvethXが自動的に削除されている

あとがき

pipeworkの戦略は、eth0に割り当てる訳では無い。

  • 狙ったIPアドレス用veth追加し、
  • IPアドレス割り当てる

eth0を使いたい場合は、pipeworkの出番ではない。そのうちDockerが対応するのかな?




編集
@hansode at 19:00|PermalinkComments(0)TrackBack(0)
このエントリーをはてなブックマークに追加

EPELリポジトリにDockerパッケージが追加された

CentOS6にDockerホストを構築しようとすると大分面倒だったが、状況は一変した。EPELにパッケージが追加されたからだ。

検証環境
  • CentOS 6.5
  • kernel-2.6.32-431.el6.x86_64
  • docker-io-0.7.0-14.el6.x86_64
  • lxc-0.9.0-2.el6.x86_64
Dockerをインストール
$ sudo yum install -y http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo yum install -y docker-io

実に簡単。これだけ。

Dockerを起動
$ sudo /etc/init.d/docker start
Starting docker:                                           [  OK  ]
$ sudo /etc/init.d/docker status
docker (pid  1428) is running...
マシンイメージをダウンロード
$ sudo docker pull base
Pulling repository base
b750fe79269d: Download complete
27cf78414709: Download complete
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
base                latest              b750fe79269d        8 months ago        175.3 MB (virtual 350.6 MB)
base                ubuntu-12.10        b750fe79269d        8 months ago        175.3 MB (virtual 350.6 MB)
base                ubuntu-quantal      b750fe79269d        8 months ago        175.3 MB (virtual 350.6 MB)
base                ubuntu-quantl       b750fe79269d        8 months ago        175.3 MB (virtual 350.6 MB)
コンテナを起動
$ sudo docker run -i -t base /bin/bash
root@d004fa70a753:/# ip addr show
7: eth0: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether f2:df:e9:48:38:52 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
    inet6 fe80::f0df:e9ff:fe48:3852/64 scope link
       valid_lft forever preferred_lft forever
9: lo: <loopback,up,lower_up> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
root@d004fa70a753:/# uname -a
Linux d004fa70a753 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
root@d004fa70a753:/# exit
exit
</loopback,up,lower_up></broadcast,multicast,up,lower_up>
参考文献



編集
@hansode at 15:10|PermalinkComments(0)TrackBack(0)