9
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

CentOS7 + systemd + Docker でインフラCIをやっていく

やっていけそうなので手順をメモします。

systemdが動くCentOS7ベースイメージを探す

  • 結論
FROM tukiyo3/centos7-ja-systemd

# 必要に応じ
RUN yum -y install systemd-libs-208-11.el7_0.4 systemd-sysv-208-11.el7_0.4
RUN echo 'exclude=systemd*' >> /etc/yum.conf
RUN yum -y update

# ... あとは自分のプロビジョン手順をやっていく

現状なら、こんな感じのDockerfileで行けると思う。

  • 背景

まず、 公式のCentOSイメージのとこに書いてある手順(Systemd integration のとこ) は、今のDockerのバージョンだと動かないみたいだな???

なので、成功する時代に作られた以下のイメージを使う。

だがしかし、このイメージ内部でナイーブに yum update をすると、systemdもアップデートされるのでその際にインストールが失敗する。

error: unpacking of archive failed on file /usr/bin/systemd-detect-virt: cpio: cap_set_file

こんなん言われる。したがって echo 'exclude=systemd*' >> /etc/yum.conf とでもしてアップデートを抑止しなければならない。

また、その抑止作業は systemd-libssystemd-sysv のインストールのあとで実行しなければならなく、そのバージョンはイメージに最初から入っている 208-11.el7_0.4 である。

その後

いつもの(いつもの?)DockerベースインフラCIな感じでよかった。Puppetの例。 /var/puppet 配下に Puppet のプロジェクトを ADD . してます。

docker build --rm -t $IMAGE_NAME .
docker run -h ${role}.develop.ci --name=$CONTAINER_NAME --privileged -d $IMAGE_NAME
docker exec $CONTAINER_NAME /bin/bash -c \
    'cd /var/puppet && \
     RUBYOPT=-Eutf-8:utf-8 puppet apply --test --environment=development \
     --modulepath=modules:roles manifests/site.pp'
ret=$?
test "$ret" -eq "0" -o "$ret" -eq "2"

docker exec $CONTAINER_NAME /bin/bash -c \
    "cd /var/puppet && \
     RUBYOPT=-Eutf-8:utf-8 FORCE_EXEC=1 bundle exec rake spec:ci:${role}"
ret=$?
test "$ret" -eq "0"

docker stop $CONTAINER_NAME
# なんかたまにrmが失敗するのでアドホックで || true してる...
# なお run の段階で --rm してないのは調査用にコンテナを残すため
docker rm $CONTAINER_NAME || true

特記することなど:

  • 以前書いた docker exec の 終了コードの件 はもう直ってるようだ。
  • --privileged じゃないとsystemdさんが立ち上がらないので大胆に行きましょう。CIだし... 細かく権限を与えても良いけど、調べるのが厳しい...。
  • RUBYOPT=-Eutf-8:utf-8 環境変数を渡してるのは、ServerspecやPuppetがRuby 2.0(みなさん、CentOS7ですよ!)で動作するのでおまじない的な意味で。
    • たぶんDockerfileに書いても良いはずなんだが、なんかうまく行かない時があって...要確認。

まとめ

やや強引(特にexcludeしたところが)なので、もっといい方法がある気がする...


追記

echo 'exclude=systemd*' >> /etc/yum.conf とでもしてアップデートを抑止しなければならない。

こう言っていたが、 yum-versionlock プラグインを使った方がスマートだろう。

Dockerfile は以下のようになる。

RUN yum -y install systemd-libs-208-11.el7_0.4 systemd-sysv-208-11.el7_0.4
RUN yum -y install yum-versionlock
RUN touch /etc/yum/pluginconf.d/versionlock.list && \
    echo 'systemd-208-11.el7_0.4'      >> /etc/yum/pluginconf.d/versionlock.list && \
    echo 'systemd-libs-208-11.el7_0.4' >> /etc/yum/pluginconf.d/versionlock.list && \
    echo 'systemd-sysv-208-11.el7_0.4' >> /etc/yum/pluginconf.d/versionlock.list
RUN yum -y update
# ...

更なる追記

aufs の場合だけsystemdのアップグレードができないらしい。。 doot2dockerなんかはデフォルトがaufsである。一時的にdevicemapperを使うとかすれば良いかもしれない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
9
Help us understand the problem. What are the problem?