CentOS7上のDockerでコンテナを固定IP化して幸せになりたい

  • 13
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

CentOS7上のDockerでコンテナを固定IP化して幸せになりたい

背景

普段、開発環境としてWindows+VirtualBox+Vagrantを利用しているのですが、VMはリソースの消費が大きいことに日々悩んでいます。そこで、リソースが節約できそうなDockerでコンテナを固定IP化してVagrant的に利用できたら幸せになれる!という思惑から設定を考えてみました。(Docker的にはアンチパターンかもしれませんが。。。)

ゴール

  • VirtualBoxのホストオンリーアダプタまたはブリッジアダプタのネットワーク上で指定した固定IPアドレスを持つコンテナを稼働させる。

私はWindows上のエディタ/IDEで開発するためにVMに固定IPを割り当ててSambaを稼働させてます。その兼ね合いでコンテナにも個別に固定IPアドレスを割り当てたいので上記のゴールを設定しています。

実は以前に似たような目的でpipeworkを使った下記の記事を投稿しましたが、pipeworkの手間が煩わしく使わなくなってしまいました。するとDockerが似たような機能を取り込んで手間が減ったので、今回あらためて記事にまとめてみました。

前提

  • VirtualBox+Vagrant上に構築します。
  • CentOS7のVagrantのBoxは作成済みとします。
      ※ CentOS公式のVagrantのBoxはファイルシステムがxfsではなくext4になっています。
      ※ 私はDockerのストレージエンジンにoverlayを使いたかったためxfsベースのBoxを自作しました。
  • ホストオンリーアダプタのネットワークは192.168.77.0/24とします。
      ※ VirtualBoxのホストオンリーアダプタの設定と一致させます。
  • ブリッジアダプタのネットワークは10.0.0.0/24とします。
      ※ ホストPCが参加しているネットワークと一致させます。

参考記事

下記の記事を参考にさせていただきました。

構築手順

1. VagrantでCentOS7のVMを起動

Vagrantfileを用意してvagrant upします。

ホストオンリーアダプタの場合は以下の内容でVagrantfileを用意します。Box名は適切なものに置換してください。

Vagrant.configure("2") do |config|
  config.vm.box = "(Box名)"

  config.vm.provider "virtualbox" do |v|
    v.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all']
  end

  config.vm.network "private_network", ip: "192.168.77.10", auto_config: false
end

ブリッジアダプタの場合は以下の内容でVagrantfileを用意します。

Vagrant.configure("2") do |config|
  config.vm.box = "(Box名)"

  config.vm.provider "virtualbox" do |v|
    v.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all']
  end

  config.vm.network "public_network", auto_config: false
end

Vagrantfileが用意できたらvagrant upします。

$ vagrant up

2. Dockerのインストール

VMが起動したらVMのCentOS7上でDockerの設定を行います。ここではrootで作業する前提で話を進めます。

(オプション)私はストレージエンジンにoverlayを使いたかったため、以下の設定を行ってvagrant reloadして再起動しています。

# tee /etc/modules-load.d/overlay.conf <<-'EOF'
overlay
EOF

Dockerのリポジトリを設定します。

# tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

(オプション)ストレージエンジンにoverlayを使う場合は以下の追加設定を行います。

# mkdir -p /etc/systemd/system/docker.service.d
# tee /etc/systemd/system/docker.service.d/override.conf <<-'EOF'
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --storage-driver=overlay
EOF

Dockerをインストールして起動させます。

# yum -y install docker-engine
# systemctl enable docker.service
# systemctl start docker.service

Dockerが動作しているか確認します。

# docker info

(オプション)ストレージエンジンにoverlayを使う場合はdocker infoで設定されているか確認できます。

3. ブリッジの設定

CentOS7上にブリッジを作成していきます。

# yum -y install bridge-utils
# ip addr flush dev eth1

ホストオンリーアダプタの場合は以下のようにします。

# docker network create --driver bridge --subnet=192.168.77.0/24 --gateway=192.168.77.10 --opt "com.docker.network.bridge.name"="docker1" my_bridge

ブリッジアダプタの場合は以下のようにします。

# docker network create --driver bridge --subnet=10.0.0.0/24 --gateway=10.0.0.10 --opt "com.docker.network.bridge.name"="docker1" my_bridge

なお、「--gateway=」で設定するIPアドレスが作成されるブリッジのIPアドレスとして利用されますので、他で利用されていないIPアドレスを指定する必要があります。

その後、以下の設定を行います。

# mkdir -p /etc/systemd/system/docker.service.d
# tee /etc/systemd/system/docker.service.d/override2.conf <<-'EOF'
[Service]
ExecStartPost=/bin/sh -c "/usr/bin/sleep 1s; /usr/sbin/ip addr flush dev eth1; /usr/sbin/brctl addif docker1 eth1"
ExecStopPost=/bin/sh -c "/usr/sbin/brctl delif docker1 eth1"
EOF
# systemctl daemon-reload

設定が完了したらvagrant reloadして設定に問題ないか確認します。以下のようにdocker1にeth1が関連付けられていたらOKです。

# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.02426630bacc       no
docker1         8000.0242cdcc83a0       no              eth1

コンテナイメージの作成

今回構築した環境用にCentOS6とCentOS7のイメージを作成します。

作成するイメージのゴール

  • ログインID/パスワードがdocker/dockerのユーザを作成します。
  • dockerユーザにsudo権限を与えます。
  • sshdを稼働させます。(Docker的にはアンチパターンかもしれませんが。。。)

CentOS6のイメージ作成

以下の内容のDockerfileを作成します。

FROM centos:6.8
ENV container docker
RUN yum -y update && yum clean all
RUN yum -y install openssh-server openssh-clients passwd sudo && yum clean all && chkconfig sshd on
RUN groupadd docker && useradd -g docker docker && (echo "docker" | passwd docker --stdin) && sed -i 's/Defaults.*requiretty/#Defaults requiretty/g' /etc/sudoers && ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key && ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key && sed -ri 's/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g' /etc/pam.d/sshd && (echo "docker ALL=(ALL) NOPASSWD: ALL" >/etc/sudoers.d/docker)
CMD ["/sbin/init"]

ビルドします。

# docker build --rm -t local/c6 .

CentOS7のイメージ作成

FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
RUN yum -y update && yum clean all
RUN yum -y install openssh-server openssh-clients passwd sudo && yum clean all && systemctl enable sshd.service
RUN groupadd docker && useradd -g docker docker && (echo "docker" | passwd docker --stdin) && sed -i '/^session.*pam_loginuid.so/s/^session/# session/' /etc/pam.d/sshd && sed -i 's/Defaults.*requiretty/#Defaults requiretty/g' /etc/sudoers && rm /usr/lib/tmpfiles.d/systemd-nologin.conf && /usr/bin/ssh-keygen -A -v && (echo "docker ALL=(ALL) NOPASSWD: ALL" >/etc/sudoers.d/docker)
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

ビルドします。

docker build --rm -t local/c7-systemd .

コンテナの起動

固定IPを指定して起動します。ここではホストオンリーアダプタのネットワーク上のIPアドレスの例になっていますが、ブリッジアダプタの場合は「--ip=192.168.77.11」の代わりに「--ip=10.0.0.11」などを指定することになります。指定した固定IPに対してsshなどが可能です。

CentOS6

# docker run --name container1 --network=my_bridge --ip=192.168.77.11 -d local/c6

CentOS7

# docker run --privileged --name container1 --network=my_bridge --ip=192.168.77.11 -v /sys/fs/cgroup:/sys/fs/cgroup:ro --stop-signal=$(kill -l RTMIN+3) -d local/c7-systemd

コンテナの停止と再稼働

通常通りのdocker stop/docker startで行います。

停止

# docker stop container1

再稼働

# docker start container1