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)Docker 

2013年12月20日

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

Wakame Users Group Advent Calendar 2013 12/20担当 (6回目の登場)

Wakame2-logo-mini

「使ってみました/インストールしてみました」は他の方にお任せし、現場の風景をお届けします。

Wakame-vdcを読み解く

背景

困った時がドキュメントの書き時。今回は下記状況に陥って困った。

環境構成:

  • カナリア環境(しばらく稼働させてる環境)
  • ナイトリービルドによりスモークテスト実施

遭遇した状態:

  • どうやら断続的に node.state が !online状態(onlineではない状態の意味)のhvaが登場
    • 何故、断続的だと判断できるのは、一定時間経過したジョブを処理していたから
  • 何故 !online になっていたのか・・・を調査したいが、今の実装では state 変更をロギングする仕組みがないくて、ログだけでは調査出来ない
  • 今できる事は、state変更ロジックを確認しておく事

未理解な内部実装を理解する為、目出度く?!コードリーディングを開始したのであった。

パッケージバージョン
  • isono 0.2.19
  • wakame-vdc 13.08.0
家族構成

wakame-vdcは、複数agentによってクラスタが構成されていて、各agentはAMQPネットワークに参加している。この辺の詳細は、また後日、追い詰められた時に、書くのだと思う。触れる必要が中たっ為、今回は省略。

dcmgr-agent-cluster

今回の第一調査対象はhva。

役者: hva

hvaを覗いてみる。

wakame-vdc/dcmgr/bin/hva#L35

途中をざっくりと端折りつつ、読み解いて分かった事は、

  • NodeHeartbeatによって各agentがpingしているようだ
  • NodeHeartbeatの結果を集計しているのはNodeCollector
  • NodeCollectorモジュールを刺してるagentが誰か…
役者: collector

NodeCollectorモジュールを刺してるのは、collector。

wakame-vdc/dcmgr/bin/collector#L24

この先は、wakame-vdcではなく、Isono家の謎に迫る必要がある。さよなら、Wakameちゃん。

Isono家の謎 『状態遷移の条件』

状態遷移する条件を探していくと、

isono/node_modules/node_heartbeat.rb#L12-L19

      initialize_hook do
        @timer = EventMachine::PeriodicTimer.new(config_section.heartbeat_offset_time.to_f) {
          rpc = RpcChannel.new(node)
          rpc.request('node-collector', 'notify', manifest.node_id, node.boot_token) do |req|
            req.oneshot = true
          end
        }
      end

heartbeat_offset_time毎に、NodeCollector宛てにnotifyしてる事が分かる。

heartbeat_offset_timeは、何秒?

isono/node_modules/node_heartbeat.rb#L7-L10

      config_section do |c|
        desc "second(s) to wait until send the next heartbeat signal"
        heartbeat_offset_time 10
      end

明示設定が無い場合、 heartbeat_offset_time は 10 秒。

stateが !:online になる条件は?

少なくとも online ではない事までは分かっている。そうなると、!:onelineになる条件と、!:onlineとは、具体的に何かを探っていくと、node_stateモデルに辿り着く。

isono/models/node_state.rb#L23-L45

      def after_initialize
        self[:state] ||= :init
      end

      def process_event(ev, *args)
        case [ev, self.state.to_sym]
        when [:on_ping, :online], [:on_ping, :init], [:on_ping, :timeout]
          self.state = :online
          self.last_ping_at = Time.now
        when [:on_unmonitor, :online]
          self.state = :offline
        when [:on_unmonitor, :timeout]
          self.state = :offline
        when [:on_unmonitor, :init]
          self.state = :offline
        when [:on_timeout, :online], [:on_timeout, :timeout]
          self.state = :timeout
        when [:on_timeout, :init]
          # Do nothing
        else
          raise "Unknown state transition: #{ev}, #{self.state}"
        end
      end

onelineを含め、どんな状態になりえるのかが分かる。

  • init
  • oneline
  • timeout
  • offline

どの条件で、どうなるか・・・わけWakame(やっと使えた!)なので、直感的に分かりやすくしたくて図にしてみると、

isono-fsm

これで状態遷移を俯瞰しやすい。少なくとも普段コードを書かない自分にとっては最高に読みやすい。今回に限らず、今後の調査材料として役立つ。

前述の通りで、!onelineからonlineへ遷移してるのだから、その経路は絞られる。

!onlineからonlineへ遷移してるのだから・・・

online ⇒ timeout ⇒ online だった事が分かって来る。

isono/node_modules/node_collector.rb#L32-L49

            Models::NodeState.dataset.all.each { |row|
              next if row.state == :offline

              diff_time = Time.now - row[:last_ping_at]
              if row.state != :timeout && diff_time > config_section.timeout_sec
                row.process_event(:on_timeout)
                row.save_changes
                event.publish('node_collector/timedout', :args=>[row.values])
              end

              if diff_time > config_section.kill_sec
                row.process_event(:on_unmonitor)

                event.publish('node_collector/killed', :args=>[row.values])
                row.destroy
              end
            }
          }
  • 最終pingから何秒経過しているか
  • とある閾値を越えている場合、timeoutとして判定

と言う事が分かる。

閾値 config_section.timeout_sec は?

isono/node_modules/node_collector.rb#L8-L15

      config_section do
        desc "time in second to recognize if the agent is timed out"
        timeout_sec (10*2).to_f
        desc "the agent to be killed from the datasource after the time of second"
        kill_sec (10*2*2).to_f
        desc ""
        gc_period 20.0
      end
  • 明示指定が無い場合、 timeout_sec は (10*2).to_f => 20.0
Isono家の安否確認まとめ
  • 各agentは、一定時刻(10秒)毎に生存してる事を通知
  • NodeCollectorは、前回の確認時刻から一定時刻(20秒)以内に通知して来たかどうかを確認
    • 時間以内通知の場合は、online
      • 一定時間が経過してる場合は、timeout

Isono家は、20秒以内に返事しないagentを、timeout扱いする。

Isono家の安否確認を踏まえて、当時の状況を考察すると
  • 20秒以内に返事して無いhvaが居た

と言う事までが判明。しかし、何故返事してなかったのかは、謎のまま。Isono家とは違う次元の何かが起きていたようだ。調査は続くのであった。

あとがき

追い詰められた時の学習意欲。

参考文献



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

2013年12月19日

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

Wakame Users Group Advent Calendar 2013 12/19担当 (5回目の登場)

Wakame2-logo-mini

「使ってみました/インストールしてみました」は他の方にお任せし、現場の声をお届けします。

もうすぐRHEL7がリリースされる

先日、RHEL7betaがリリースされた。今後やるであろうRHEL7対応作業へ向けて、ここ数日で気になった3項目に関して頭の中を整理してみた。

  1. epel6 -> epel7
  2. msyql -> mariadb
  3. systemd対応
1. epel6 -> epel7
  • epel-release-7-x.rpmへ変更する程度で済むはず
  • それと、rpmbuildツールが少し頑張れば良い領域
2. mysql -> mariadb
  • DB初期化時に使用している管理コマンドmysqladmin等を切り替え
  • Rubyの依存パッケージの検証が必要。仮にMySQLのままだとしても、ある程度のバージョン差異が生じるため、検証が必要。
3. systemd対応

現在upstartを採用している理由はいくつあって、その1つは、以前、ubuntuがメインディストリビューションだった事。upstart system confであれば、ubuntuでもrhel互換でも、どちらでも使える。そう言った理由で採用した経緯がある。しかし、最近ではubuntu環境へのインストール要件は皆無に近い。

  • rhel7には、upstartのrpmパッケージが存在してないので、SysV initかsystemdへ変更する必要がある。
  • rhel7の標準initはsystemd
  • これらを踏まえると、systemd対応は必至
あとがき

12/08担当 @debilityさんのエントリ:

2年ほど前にWakame-vdcと大いにまみれさせていただいた

2年前はRHEL6.0対応し始めてから間もない頃で、RPM化するよりも半年以上も前の事。ご迷惑をおかけしつつも、苦しみを分かち合いながら一緒にお仕事した日々は、今では良き思い出。あれから2年、あっと言う間。

福岡出張へのお誘い、まだ来てません。そろそろですね?




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

2013年12月18日

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

Wakame Users Group Advent Calendar 2013 12/18担当 (4回目の登場)

Wakame2-logo-mini

今回に限り「使ってみました/インストールしてみました」をしてみます。

Dockerと連携させる

Wakame Users Group Advent Calendar 2013 12/02担当がOpenVNetインストールネタ。

手順が正しいのかどうかをDockerで確認してみた。(あれ?Wakame-vdcじゃないの?)

検証環境
  • CentOS 6.5 (OpenVNet推奨はCentOS 6.4らしいけども気にしない)
  • 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
  • wakame-vnet.noarch 20131108190022git48a1361.fpm0-1
何度も再現させるのはDockerの得意とする所

手戻りと作業切りわけを兼ねて、3つのイメージを作成する戦略にした。

  1. repoファイルセットアップまで実施
  2. RPMインストールまで実施
  3. DB初期化まで実施
1: openvnet.repo
openvnet.repo/Dockerfileを配置
FROM hansode/centos-6-x86_64

RUN curl -fsSkL -o /etc/yum.repos.d/openvnet.repo             https://raw.github.com/axsh/openvnet/master/openvnet.repo
RUN curl -fsSkL -o /etc/yum.repos.d/openvnet-third-party.repo https://raw.github.com/axsh/openvnet/master/openvnet-third-party.repo
RUN rpm -Uvh http://dlc.wakame.axsh.jp.s3-website-us-east-1.amazonaws.com/epel-release
イメージをビルド
$ sudo docker build -t openvnet.repo .
Uploading context 10240 bytes
Step 1 : FROM hansode/centos-6-x86_64
 ---> cff199166afa
Step 2 : RUN curl -fsSkL -o /etc/yum.repos.d/openvnet.repo             https://raw.github.com/axsh/openvnet/master/openvnet.repo
 ---> Running in 5907fffae0ed
 ---> 79cea9051987
Step 3 : RUN curl -fsSkL -o /etc/yum.repos.d/openvnet-third-party.repo https://raw.github.com/axsh/openvnet/master/openvnet-third-party.repo
 ---> Running in 0ec98e92ddac
 ---> 103fb501492e
Step 4 : RUN rpm -Uvh http://dlc.wakame.axsh.jp.s3-website-us-east-1.amazonaws.com/epel-release
 ---> Running in 57110506cb9b
warning: /var/tmp/rpm-tmp.epxeye: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Retrieving http://dlc.wakame.axsh.jp.s3-website-us-east-1.amazonaws.com/epel-release
Preparing...                ##################################################
epel-release                ##################################################
 ---> ceb9cf50ef7e
Successfully built ceb9cf50ef7e
ビルドされたイメージの内容を確認
$ sudo docker images openvnet.repo
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
openvnet.repo       latest              ceb9cf50ef7e        25 seconds ago      14.42 MB (virtual 586.8 MB)

ここまでに586.8 MB使用。

2: openvnet.common
openvnet.common/Dockerfileを配置
FROM openvnet.repo

RUN yum install --disablerepo=updates -y wakame-vnet
イメージをビルド
$ sudo docker build -t openvnet.common .
Uploading context 10240 bytes
Step 1 : FROM openvnet.repo
 ---> ceb9cf50ef7e
Step 2 : RUN yum install --disablerepo=updates -y wakame-vnet
 ---> Running in 8ab3ffbfd54f
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: ftp.iij.ad.jp
 * epel: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
Setting up Install Process
Resolving Dependencies
--> Running transaction check
...
Installed:
  wakame-vnet.noarch 0:20131108190022git48a1361.fpm0-1

Dependency Installed:
  dash.x86_64 0:0.5.5.1-4.el6
  dracut.noarch 0:004-335.el6
  dracut-kernel.noarch 0:004-335.el6
  file.x86_64 0:5.04-15.el6
  grubby.x86_64 0:7.0.15-5.el6
  kernel.x86_64 0:2.6.32-431.el6
  kmod-openvswitch.x86_64 0:1.10.0-1.el6
  libdrm.x86_64 0:2.4.45-2.el6
  libpcap.x86_64 14:1.4.0-1.20130826git2dbcaa1.el6
  libpcap-devel.x86_64 14:1.4.0-1.20130826git2dbcaa1.el6
  libpciaccess.x86_64 0:0.13.1-2.el6
  libxslt.x86_64 0:1.1.26-2.el6_3.1
  libyaml.x86_64 0:0.1.3-1.el6
  mysql.x86_64 0:5.1.71-1.el6
  mysql-server.x86_64 0:5.1.71-1.el6
  openpgm.x86_64 0:5.1.118-3.el6
  openvswitch.x86_64 0:1.10.0-1
  perl.x86_64 4:5.10.1-136.el6
  perl-DBD-MySQL.x86_64 0:4.013-3.el6
  perl-DBI.x86_64 0:1.609-4.el6
  perl-Module-Pluggable.x86_64 1:3.90-136.el6
  perl-Pod-Escapes.x86_64 1:1.04-136.el6
  perl-Pod-Simple.x86_64 1:3.13-136.el6
  perl-libs.x86_64 4:5.10.1-136.el6
  perl-version.x86_64 3:0.77-136.el6
  plymouth.x86_64 0:0.8.3-27.el6.centos
  plymouth-core-libs.x86_64 0:0.8.3-27.el6.centos
  plymouth-scripts.x86_64 0:0.8.3-27.el6.centos
  redis.x86_64 0:2.4.10-1.el6
  tar.x86_64 2:1.23-11.el6
  wakame-vnet-common.noarch 0:20131108190022git48a1361.fpm0-1
  wakame-vnet-ruby.x86_64 0:2.0.0.247.axsh0-1
  wakame-vnet-vna.noarch 0:20131108190022git48a1361.fpm0-1
  wakame-vnet-vnmgr.noarch 0:20131108190022git48a1361.fpm0-1
  wakame-vnet-webapi.noarch 0:20131108190022git48a1361.fpm0-1
  which.x86_64 0:2.19-6.el6
  zeromq.x86_64 0:2.2.0-4.el6
  zeromq-devel.x86_64 0:2.2.0-4.el6

Complete!
 ---> f4585f3b20de
Successfully built f4585f3b20de
ビルドされたイメージの内容を確認
$ sudo docker images openvnet.common
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
openvnet.common     latest              f4585f3b20de        About a minute ago   632.1 MB (virtual 1.219 GB)

ここまでに1.219 GB使用。

3: openvnet.smallci
openvnet.smallci/Dockerfileを配置
FROM openvnet.common

ADD ./initdb.sh /initdb.sh
CMD /initdb.sh
openvnet.smallci/init.shを配置
#!/bin/bash
#
# requires:
#  bash
#
set -e
set -x

[ -f /etc/sysconfig/network ] || : > /etc/sysconfig/network
/etc/init.d/mysqld start

until mysqladmin -uroot ping; do
  sleep 1
done
mysqladmin -uroot create vnet

cd /opt/axsh/wakame-vnet/vnet
PATH=/opt/axsh/wakame-vnet/ruby/bin:$PATH /opt/axsh/wakame-vnet/ruby/bin/bundle exec rake db:init

実行権限を付与。

$ chmod +x init.sh
イメージをビルド
$ sudo docker build -t openvnet.smallci .
Uploading context 10240 bytes
Step 1 : FROM openvnet.common
 ---> f4585f3b20de
Step 2 : CMD : > /etc/sysconfig/network
 ---> Running in 885a743efd17
 ---> ce5389ddeb69
Step 3 : CMD /etc/init.d/mysqld start
 ---> Running in e6049c2aeaeb
 ---> 6957beeae0cd
Step 4 : CMD export PATH=/opt/axsh/wakame-vnet/ruby/bin:$PATH
 ---> Running in 7743b6dd88f1
 ---> c78f8c15a74d
Step 5 : CMD printenv PATH
 ---> Running in e76ba9bc75bb
 ---> f412fdc6fa00
Step 6 : CMD mysqladmin -uroot create vnet
 ---> Running in 6a5fea2907ca
 ---> eeb6f5b51fac
Step 7 : CMD cd /opt/axsh/wakame-vnet/vnet && /opt/axsh/wakame-vnet/ruby/bin/bundle exec rake db:init
 ---> Running in c7415047c846
 ---> 7a7db5249aa5
Successfully built 7a7db5249aa5
ビルドされたイメージの内容を確認
$ sudo docker images openvnet.smallci
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
openvnet.smallci    latest              6f6e46b2dbb9        25 minutes ago      1.192 GB (virtual 2.411 GB)

ここまでに2.411 GB使用。パッケージインストールするだけで、ディスクサイズが2.5GB弱必要である事が分かった。インストールしましたエントリでは触れられてない事の1つ。

コンテナを起動
$ sudo docker run -t openvnet.smallci
+ '[' -f /etc/sysconfig/network ']'
+ :
+ /etc/init.d/mysqld start
Initializing MySQL database:  Installing MySQL system tables...
OK
Filling help tables...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h 02b537893292 password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &

You can test the MySQL daemon with mysql-test-run.pl
cd /usr/mysql-test ; perl mysql-test-run.pl

Please report any problems with the /usr/bin/mysqlbug script!

[  OK  ]
Starting mysqld:  [  OK  ]
+ mysqladmin -uroot ping
mysqld is alive
+ mysqladmin -uroot create vnet
+ cd /opt/axsh/wakame-vnet/vnet
+ PATH=/opt/axsh/wakame-vnet/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+ /opt/axsh/wakame-vnet/ruby/bin/bundle exec rake db:init

$ echo $?
0

DB初期化する所までは動作を確認できた。しかも、CentOS-6.5で!

まとめ
  • パッケージインストール程度ならばDockerで検証可能
  • OpenVNetはCentOS 6.5で動作しそう
  • DB初期化するまでとは言え、ディスクサイズは2.5GB弱使用する
あとがき

その先のOpen vSwitchやOpenFlowを使う構成になると、Dockerで検証できるかどうかは未知の世界。検証した結果、Dockerでは検証出来なかった。そんな結果になるかも知れない。そう言う時こそ、Wakame-vdcの出番。見事に繋がった?

参考文献



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

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)Docker 
このエントリーをはてなブックマークに追加

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)Docker 

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つで、実際に実施してみると、それを実感する。




編集

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生活を!




編集

2013年12月08日

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

Wakame Users Group Advent Calendar 2013 12/08担当 (3回目の登場)

Wakame2-logo-mini

「使ってみました/インストールしてみました」は他の方にお任せし、現場の悲鳴をお届けします。

全体が見えない

ここ1年は特に、自分がRubyコードをコミットするタイミングは、バグ修正がメイン。バグであるかどうかを確認する過程でモデルの関連を把握したくなる時がある。実装コードを読めば分かる訳だが、全体を俯瞰したい事が多い。実装者は狭い所を見ていれば良いみたいで、実装時のER図の需要は極めて低い。無くても実装されている事が、それを裏付けていると言えるのだろうか。

とある一部機能の実装を把握したくて実装コードを読み進めて行くと、途中で理解した内容を忘れてしまうほど、複雑怪奇(恐らく設計検討不足)になっていて・・・、俯瞰図が無いままでは効率が悪い。そこで、俯瞰図を書き始めた。

lib/dcmgr/models俯瞰図

俯瞰図作成後、調査効率は期待通りに向上した。

困った人が書く!

『ドキュメントがあれば・・・何故、書かないのか?』と思ってる時期はあったが、最近は、困った人が書けば良いと言う考え方へ切り替えた。と言うのは、誰向けに書かれてるのか分からないドキュメントを書く為の時間を割くよりは、実装に注力してもらった方が良い。そう思える事が多いからだ。

困った時が、ドキュメントの書き時

少なくともドキュメント対象は一人存在し、その人が欲するドキュメントが出来上がる。

コードを書かずに実装把握し、プロジェクトに貢献する事は十分可能。副産物として、実装を読み解くスキルは向上し、実装の理解度は高まる。この辺のドキュメント作成に興味のある方がいらっしゃいましたら、ご一報下さい。




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

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が対応するのかな?




編集