LoginSignup
17
16

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-09-06

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 
17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16