カテゴリー

アクセスカウンター


since 1996/06/14

Count per Day

  • 11今日の訪問者数:
  • 48昨日の訪問者数:
  • 1266月別訪問者数:
  • 0現在オンライン中の人数:

docker環境作成memo

概要

dockerでLXC環境を作ったメモです。CentOS7.2の最小構成インストールから作業開始です。

# cat /etc/redhat-release
 CentOS Linux release 7.2.1511 (Core)
 # uname -r
 3.10.0-327.22.2.el7.x86_64

docker/Linuxコンテナ(LXC)とは何なのか

私もこれから運用を考えようといろいろ試行錯誤している段階なので、偉そうなことは言えませんがわかる範囲で。

Linuxコンテナは仮想化サーバの技術の一種です。概念的には古い時代から存在してました。有名どころではSolarisコンテナとかですかね。Jailという技術もこの一種だと聞いてます。リソースの少ない時代の賜物ですから、vmwareやLinux/KVMなどに比べると少ないリソースで運用できるのがポイントですね。当然、vmwareなどの仮想化技術に比べるとメリット・デメリットはあります。
なお、ここではvmware等の仮想化のことをHW仮想化。コンテナはコンテナと称します。

  • HW仮想化はHWやOS含めて一つの環境をソフト的に作り出す技術である一方で、コンテナはプロセス(psコマンドで出てくるやつ)をグループ化してそこに制限を与える技術です。仮想化はゲストOSが完全に隔離されますが、コンテナはホストOSからpsコマンドを叩けばコンテナ内のプロセスもある程度見れたりします。
  • HW仮想化は機械自体を仮想化するので、Linux仮想サーバ上でWindowsを動かすことも容易ですが、コンテナはそこまでは難しいみたいです。ただ、CentOS7上のコンテナでCentOS5や6、あるいはDebianなどは容易に動かせます。
  • HW仮想化はゲストOSを作成すると、それを1つのゲストとして起動・停止させる運用をしますが、LXCは「イメージ」を用意しておき、それからいくつでもコンテナインスタンスを生成できます。たとえばCentOS6のコンテナイメージから、10個のCentOS6のコンテナインスタンスを生成することも可能です。
  • HW仮想化はゲストOSを起動すると、ホストOSで有ろうとも「別サーバ」としてしかアクセスできませんが(それなりに便利にアクセスするツールはありますが)、ゲストOSにホストOSのディレクトリをマウントしたりなど、リソース共有が比較的容易にできます。
  • コンテナはオーバヘッドが少ないです。たとえば制限をきつくしない限りは、起動した分しかホストのメモリを消費しません。逆にコンテナ毎に上限も設定できます。
  • HW仮想化は一般的にゲストOSを起動後にOSをインストールし環境を整えますが、Linuxコンテナはイメージから生成できます。このコンテナイメージは自作も可能ですが、一般的にはダウンロードしてきます。
    dockerの場合は標準のリポジトリとして、docker hubを使います。(https://hub.docker.com/explore/)
  • コンテナはメリットばかりに見えますが、仮想化に比べると隔離されているレベルが低いので、安全性を考えると仮想化よりもレベルが低いかも。

コンテナの特徴はこんな感じです。ちなみにLXC(Linuxコンテナ)は技術の総称で、それを実現するツール(ソフトウェア)の一つがdockerですね。LXC自体はdocker以外でも実現できた気がします。最近、活発になってきているのはカーネルレベルでのコンテナ支援機能が充実してきたからだと思います。

あと、概要はだいたいこの通りなのですが、docker自体の使い方は以下のような想定をしている気がしています。この辺も理解してないと、扱いにとても疑問が沸いてきます。

  • HW仮想化系のサーバは、ゲストOS作成後は基本的には起動したままで、再起動は希にする利用していきます。dockerもそれはできますが、どちらかというとコンテナイメージを先に作っておき、「使う」時にコンテナを起動、使い終わったら止める(止まる)使い方が基本みたいです。当然ながらデーモン系の機能を有するコンテナは起動したままになります。
  • コンテナは、コンテナイメージのインスタンスとして起動しますが、コンテナ(インスタンス)からコンテナイメージを作るのも容易です。これを活用して、コンテナイメージを変更管理に乗せる運用を想定しているようです。
    つまりは、サーバ基盤の構成変更(たとえばapacheのバージョンアップ)をした場合は、新たにコンテナイメージを作成する感じです。コンテナイメージを上書きしなければ、バージョンアップに伴う障害が発生した場合は、いつでも古いコンテナに戻れることを意味しています。
    企業などでは、これをCI(継続的インテグレーション)に乗せることで、システム基盤の品質改善につなげることができたりするんじゃないでしょうか。

なんでこんなことを書くかというと、コンテナインスタンスは起動後の設定変更がとても難しいというかほとんどできません。たとえばポート追加とかもコンテナを消さないとできないみたいです。(できるけどとても面倒)
だから、データもコンテナの外に置いて、コンテナインスタンスの中にはデータを置かないという運用になります。

また、標準的なコンテナにはsyslogdやinit(ランレベルの概念)が存在しないので、ログは取れてないし、ランレベルを切り替えて運用というのもあり得ません。デーモンも都度serviceコマンド等で起動します。初めは何でこんな仕組みなんだ?と思うかもしれませんが、上記の理由が背景にありますし、リソースの有効活用という意味では不要な物は徹底的に間引いてるんだと思います。

dockerセットアップ

CentOS7.2の場合は、標準のyumリポジトリからインストールがいけます。

# yum install docker

セットアップ後はデータディレクトリは作成されますが、まだ空です。

# ls -lad /var/lib/docker/
drwx------ 2 root root 6 6月 24 21:10 /var/lib/docker/
# ls -l /var/lib/docker
合計 0

個人的にdockerディレクトリを/dataへ集約したいので、起動(ファイル作成)前に修正。シンボリックリンクはあまり宜しくないという記述をどこかで見た気もしますが、、、

# mkdir /data/docker
# rmdir /var/lib/docker
# ln -s /data/docker /var/lib/docker
# ls -l /var/lib/docker
lrwxrwxrwx 1 root root 12 7月 17 18:02 /var/lib/docker -> /data/docker

やはりシンボリックリンクはよくないようなので、mountに変更しました。確かにデバイス系ファイルを扱う機能なので、こっちの方がいいでしょう。

# mkdir /data/docker
# mount -o bind /data/docker /var/lib/docker
# df -ha /var/lib/docker
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/vdb 76G 3.2G 73G 5% /var/lib/docker
# vi /etc/fstab
/data/docker /var/lib/docker none bind 0 0  ←追記
※念のため再起動して自動mountされることを確認

firewalldを止めます。

# systemctl stop firewalld.service
# systemctl disable firewalld.service

firewalldを止めるのに違和感を感じる人も居ると思いますが、dockerはCentOS6をサポートしなくなった割にiptableをごりごり使います。また、後続のshipyardのインストールではfirewalldが有効になっていると先に進まなくなる問題もあります。
どっちにしろちゃんと設定すればいいだけの話なので、ここではfirewalldを止めてiptablesをちゃんと設定すればいいだけの話になります。
※しかもコンテナに関するiptablesの設定はdockerが勝手にやってくれるので、その方が手間が掛からないかもですね。

そして起動

# systemctl enable docker
# systemctl start docker
# ls /var/lib/docker/
containers devicemapper image network tmp trust volumes
# docker version
Client:
Version: 1.10.3
API version: 1.22
Package version: docker-common-1.10.3-44.el7.centos.x86_64
Go version: go1.4.2
Git commit: 9419b24-unsupported
Built: Fri Jun 24 12:09:49 2016
OS/Arch: linux/amd64
Server:
Version: 1.10.3
API version: 1.22
Package version: docker-common-1.10.3-44.el7.centos.x86_64
Go version: go1.4.2
Git commit: 9419b24-unsupported
Built: Fri Jun 24 12:09:49 2016
OS/Arch: linux/amd64
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE

初期のデバイス状況はこんな感じです。

# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 253:0 0 15G 0 disk
├─vda1 253:1 0 512M 0 part /boot
├─vda2 253:2 0 5.5G 0 part /
├─vda3 253:3 0 5G 0 part /var
├─vda4 253:4 0 1K 0 part
└─vda5 253:5 0 4G 0 part [SWAP]
vdb 253:16 0 75.5G 0 disk /data
vdc 253:32 0 78.5G 0 disk /***
loop0 7:0 0 100G 0 loop
└─docker-253:16-268635791-pool 252:0 0 100G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-253:16-268635791-pool 252:0 0 100G 0 dm

ちなみにこれまでは無かったのですが、dockerを起動するとdocker-storage-setup.serviceというサービスが異常ステータスになります。原因はよくわかりませんが、一応貼り付けておきます

# systemctl status docker-storage-setup.service
 docker-storage-setup.service - Docker Storage Setup
Loaded: loaded (/usr/lib/systemd/system/docker-storage-setup.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 月 2016-07-18 11:01:35 JST; 1min 12s ago
Process: 9459 ExecStart=/usr/bin/docker-storage-setup (code=exited, status=1/FAILURE)
Main PID: 9459 (code=exited, status=1/FAILURE)
7月 18 11:01:35 ***.d77.jp systemd[1]: Starting Docker Storage Setup...
7月 18 11:01:35 ***.d77.jp docker-storage-setup[9459]: INFO: Volume group backing root filesystem could not be determined
7月 18 11:01:35 ***.d77.jp docker-storage-setup[9459]: ERROR: No valid volume group found. Exiting.
7月 18 11:01:35 ***.d77.jp systemd[1]: docker-storage-setup.service: main process exited, code=exited, status=1/FAILURE
7月 18 11:01:35 ***.d77.jp systemd[1]: Failed to start Docker Storage Setup.
7月 18 11:01:35 ***.d77.jp systemd[1]: Unit docker-storage-setup.service entered failed state.
7月 18 11:01:35 ***.d77.jp systemd[1]: docker-storage-setup.service failed.

いろいろいじりたい人は、パラメータはこの辺にあります。この辺も個人的にはdockerのバージョンによって設定値が変わってわかりづらかったし、デフォでもさほど困らないのでそのままで行ってます。恐らくコンテナの初期サイズが最大10GBなので、それで足りない場合は修正が必要ですが、まぁデータはmountした別ディレクトリを使うべきだと思うので、その辺も手を付けません。

# ls -l /etc/sysconfig/docker*
-rw-r--r-- 1 root root 1737 6月 24 09:02 /etc/sysconfig/docker
-rw-r--r-- 1 root root 56 6月 24 09:01 /etc/sysconfig/docker-network
-rw-r--r-- 1 root root 415 6月 24 09:01 /etc/sysconfig/docker-storage
-rw-r--r-- 1 root root 179 5月 10 23:45 /etc/sysconfig/docker-storage-setup

まだ何も動いてないですが、このあとHelloWorldコンテナとか作って動作確認とかするといいんでしょう。個人的には散々作ったので、省略。

WebGUI”shipyard”

無くてもいいんだけど、有ると便利なのでWebGUIを構築します。dockerのWebGUIはいくつかあり、おおよそdocker imageで配布されてるのでそれを活用します。いろいろ検証はしましたけど、これを執筆時点ではshipyardが一番扱いやすく動作が安定してました。docker s

http://shipyard-project.com/

セットアップ方法はこの辺に書いてあります。

https://github.com/shipyard/shipyard

Docker Swarmというクラスタ環境を作ってセットアップされるそうなので構築後は複数のコンテナが登場します。セットアップにもソコソコ時間を要しますね。

# curl -s https://shipyard-project.com/deploy | bash -s
Unable to find image 'alpine:latest' locally
Trying to pull repository docker.io/library/alpine ...
latest: Pulling from docker.io/library/alpine
~略~
Status: Downloaded newer image for docker.io/shipyard/shipyard:latest
Waiting for Shipyard on 192.168.1.●●●:8080
.
Shipyard available at http://192.168.1.●●●:8080
Username: admin Password: ●●●

セットアップ後にアクセス用URLとパスワードが出てきますので、そこからアクセスできます。ちなみにこの段階でコンテナイメージど稼働中のコンテナは以下のようになります。

# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/alpine latest ************ 3 weeks ago 4.795 MB
docker.io/swarm latest ************ 5 weeks ago 19.34 MB
docker.io/rethinkdb latest ************ 5 weeks ago 184.2 MB
docker.io/shipyard/shipyard latest ************ 6 weeks ago 58.89 MB
docker.io/shipyard/docker-proxy latest ************ 6 months ago 9.464 MB
docker.io/ehazlett/curl latest ************ 10 months ago 8.727 MB
docker.io/microbox/etcd latest ************ 11 months ago 17.86 MB
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
************ shipyard/shipyard:latest "/bin/controller --de" 33 minutes ago Up 33 minutes 0.0.0.0:8080->8080/tcp shipyard-controller
************ swarm:latest "/swarm j --addr 192." 33 minutes ago Up 33 minutes 2375/tcp shipyard-swarm-agent
************ swarm:latest "/swarm m --replicati" 33 minutes ago Up 33 minutes 2375/tcp shipyard-swarm-manager
************ shipyard/docker-proxy:latest "/usr/local/bin/run" 33 minutes ago Up 33 minutes 0.0.0.0:2375->2375/tcp shipyard-proxy
************ alpine "sh" 33 minutes ago Up 33 minutes shipyard-certs
************ microbox/etcd:latest "/bin/etcd -addr 192." 33 minutes ago Up 33 minutes 0.0.0.0:4001->4001/tcp, 0.0.0.0:7001->7001/tcp shipyard-discovery
************ rethinkdb "rethinkdb --bind all" 34 minutes ago Up 34 minutes 8080/tcp, 28015/tcp, 29015/tcp shipyard-rethinkdb

で、インストールしたshipyardからアクセスするとこんな感じ。

ログイン画面

docker_shipyard_1

コンテナ(起動中のコンテナインスタンス)一覧

docker_shipyard_2

コンテナイメージ一覧

docker_shipyard_3

コマンドの実行結果に比べればきれいで見やすいのは一目瞭然ですし、メニューからコンテナの起動・停止・削除等もできます。あと、リモートログインできなくなった場合用に、Web画面上からbashを呼び出してコンソールアクセスみたいなこともできて便利です。
当然、WebGUIからできないこともあるし、CUIの方がやりやすいところもありますが、コンテナが増えてくると管理が煩雑になるし、コンテナのグルーピングなんて機能はdockerには無いので、こういうのはいずれ必須になると思います。

ちなみにshipyardはホストOS再起動時に自動起動します。

運用上の注意点とか気にしておくこととか

気になってて、使ってて解決したこととかを書き殴っておきます。

  • Linux/KVM運用中のサーバに、突然の思いつきでdockerを入れない方がいい。
    いろいろ機能がバッティングします。ネットのブリッジ設定とか。
  • shipyardなどの管理機能は先に入れておく。
  • Linux/KVMなどの仮想サーバ上にdockerを入れても難なく動きます。
    ※そもそもハードの仮想化支援機能(Intel VTとか)って使われてるか疑問ですが。
  • サイジングには気をつける。
    当然と言えば当然ですが、dockerの場合は「/var/lib/docker」に1コンテナ最大で10GBのコンテナファイル(動的拡張なので実際には小さいですが)が作成されます。気にしておかないと/var領域[*]を食いつぶしてホストOSが大変なことになります。
  • デーモンを停止せずにコンテナを停止すると、デーモンはkillされます。stopじゃなくkillであることに注意が必要です。データベースなどはこうなると再起動時にリカバリが走りますし、最悪は壊れます。
    ちなみに「コンテナ停止時にデーモンを停止してから安全にコンテナを止める」方法は無くは無いですが難しいです。

 

[*]/var領域を食いつぶすと、、、
経験がある人にはわかると思いますが、/varの使用率が100%になるとログが出力できなくなって障害が起きても原因がわからなくなります。それだけでなく、pidファイルもあるので、デーモン起動時にpidが作成できなくて起動しないということも起きます。
要するに、こうなるとOSが起動しなくなり、CDブートなどでの復旧を余儀なくされます。

コンテナの作成

とりあえず、CentOSを突っ込みます。まずは、コンテナイメージの取得。これは標準のリポジトリにあるものを活用します。

# docker pull centos:7.2.1511
Trying to pull repository docker.io/library/centos ...
7.2.1511: Pulling from docker.io/library/centos
f19ed9d73b3e: Pull complete
Digest: sha256:12c9336412cd76165d7e42906ab9a7234cecd7c4247ed92958ab4ad49644b531
Status: Downloaded newer image for docker.io/centos:7.2.1511
# docker images | grep -i centos
docker.io/centos 7.2.1511 ************ 2 weeks ago 194.6 MB

shipyardを入れてるのに、早速CUIか!って感じですが、イメージの取得は時間が掛かることがあるので、CUIの方がわかりやすいのと、あまり回線がプアなら時間がかかるのでバックエンドで実行などできるので、コンテナの作成についてはCUIでやった方がいいかなと思います。

ちなみにイメージ名は必ず「コンテナイメージ名:Tag」という名称になっており、だいたいTagの部分がバージョンになってますので、これを変更すれば別のバージョンのイメージを取得できます。「latest」というTagにすれば最新版が取得できたりもしますね。管理上わかりづらいので個人的には「latest」は使ってませんが。

次にコンテナの起動です。

# docker run -i -t centos:7.2.1511 /bin/bash
[root@************ /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 12:29 ? 00:00:00 /bin/bash
root 14 1 0 12:30 ? 00:00:00 ps -ef
[root@************ /]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-***:**-***-*** 10G 238M 9.8G 3% /
tmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/vdb 76G 721M 75G 1% /etc/hosts
shm 64M 0 64M 0% /dev/shm

こんな感じです。ホスト名は無作為に作成されたコンテナIDになります。これは変更できません。psの実行結果も乗せてありますが、見ての通りほとんど何も常駐してないです。syslogdも無いのでログも無いですね。initも無いのでランレベルの概念もありません。ランレベルが無いということはシャットダウンもできません。
ログアウトもそもそもログインしてないできないのですが、抜けるにはexitです。

# exit
exit
# docker ps | grep 'centos'
~何も出ない~

、、、という感じで、コンテナから抜けるとコンテナ自体が停止します。ちなみに一応コンテナは停止状態で残ってます。

# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
************ centos:7.2.1511 "/bin/bash" 37 minutes ago Exited (0) 2 minutes ago modest_mahavira

コンテナを再起動して再接続するには以下のような感じです。

# docker start コンテナID
# docker attach コンテナID
[root@************ /]#

exitすると停止しちゃうので、exitしないでデタッチすることもできます。デタッチは「CTRL+q、CTRL+q」

[root@************ /]# ←「CTRL+q、CTRL+q」
# ←ホストOS
# docker attach コンテナID
[root@************ /]# ←コンテナ内

停止したコンテナは以下の通り削除できます。

# docker rm コンテナID
コンテナID

リモートログインできるコンテナイメージを作成する

dockerの運用はコンテナイメージを作成できないとほぼ無意味です。ここではちゃんとリモートログインできるCentOS7のコンテナを作成してみます。

まずは、コンテナを作ります。コンテナは「コンテナID」というランダムな文字が付与されますが、わかりづらいので今回は名前「custom_cnt」を付けました。コンテナIDは相変わらずですが、「docker ps」で一番後ろに表示される「NAMES」に出てきます。
名前を付けた方が何かと管理しやすいので、必ず付けておきましょう。

# docker run --name custom_cnt -i -t centos:7.2.1511 /bin/bash
[root@************ /]#

リモートログインと言っても具体的には以下のことができるようにします。

  • コンテナ起動時にsshdが動くこと。
  • できればログも取りたい。
  • うっかりexitしても止まらない。

ただし、残念ならがコンテナ停止時に常駐しているプロセスはすべてkillされるので、それはしょうが無い。先ずyumでインストール済みプログラムの最新化と、sshd、rsyslogdの導入をします。なんとyumは入ってるので何事もなくできます。

[root@************ /]# yum update
Loaded plugins: fastestmirror
~略~
Complete!
[root@************ /]# yum install openssh.x86_64 openssh-server.x86_64 openssh-clients.x86_64
~略~
Complete!
[root@************ /]# yum install rsyslog.x86_64

次に「コンテナ起動時にデーモンを起動」ですが、docker runのオプションに「/bin/bash」と書かれていますが、これがコンテナ内の最上位の親プロセス(pid=1)として起動します。だから、exitするとbashが停止してコンテナも落ちるという仕組みです。
なので、/bin/bashでは無く別のシェルプログラムを起動させることでいろいろと実現ができます。

先ずは、こんなシェルを書きます。「/start.sh」とかいう名前で保存してもいいでしょう。これを「/bin/bash」の代わりに起動させてやれば、デーモンが起動した上でbashが起動しますし、誤ってbashをexitしても、bashが再起動してくれます。

#!/bin/bash
#起動するプログラムをここに書く
while true ; do
/bin/bash
done

問題は、rsyslogやsshdをどうやって起動するかで、CentOS7のコンテナはserviceコマンドもsystemctlコマンドも使えません。なので、直接デーモンを起動させるしか無いですが、通常どのように起動しているか調べてみましょう。コンテナでは無いCentOS7の環境を使います。

[root@************ /]# systemctl status rsyslog
● rsyslog.service - System Logging Service
Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since 土 2016-07-02 07:09:29 JST; 2 weeks 1 days ago
Main PID: 1470 (rsyslogd)
~略~
[root@************ /]# more /usr/lib/systemd/system/rsyslog.service
~略~
EnvironmentFile=-/etc/sysconfig/rsyslog
ExecStart=/usr/sbin/rsyslogd -n $SYSLOGD_OPTIONS
[root@************ /]# more /etc/sysconfig/rsyslog
~略~
SYSLOGD_OPTIONS=""
[root@************ /]# /usr/sbin/rsyslogd -n &
[root@************ /]#  cat /var/log/messages
Jul 17 13:59:13 ************ rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="259" x-info="http://www.rsyslog.com"] start

雰囲気的には「/usr/sbin/rsyslogd -n 」の後ろに$SYSLOGD_OPTIONSを付けて起動してるようでしたが、SYSLOGD_OPTIONSは空だったので付けず、&を付けてバックグランドで起動すれば動くみたいです。同じ感じでsshdも調べて先ほどのシェルを完成させたのがこちら。

[root@************ /]# chmod 755 /start.sh
[root@************ /]# ls -l /start.sh
-rwxr-xr-x 1 root root 94 Jul 17 14:05 /start.sh
[root@************ /]#  cat /start.sh
[root@************ /]# !/bin/bash
if [ ! -f /etc/ssh/ssh_host_rsa_key -o ! -f /etc/ssh/ssh_host_ecdsa_key -o ! -f /etc/ssh/ssh_host_ed25519_key ]; then
/usr/bin/ssh-keygen -A
fi
/usr/sbin/rsyslogd -n &
/usr/sbin/sshd -D &
while true ; do
/bin/bash
done
[root@************ /]# passwd root

ちょっと面倒な内容になっていますが、CentOS7ではsshdが起動する前に、ssh-keygenというサービスが起動して、「/etc/ssh/ssh_host_云々」というファイルを生成してます。sshdがこのファイルへアクセスできないと「Read from socket failed: Connection reset by peer」というメッセージと共に通信拒否されてしまうので、無ければ作るという処理が追加されてます。
あと、コンテナはrootで処理をされていますが、標準でパスワードが設定されておらずリモートログインできませんのでパスワードを設定します。(rootで直接ログインするのも何ですが、ここでは割愛します)

さて、あとはコンテナ起動時に/bin/bashの代わりに/start.shを起動するように設定すればOKですが、これがちょっと難解です。あと、このコンテナへリモートから接続するにはホストOSを経由しないとならないので、ポートフォワードも必要です。
なので、この辺を踏まえてコンテナを再作成します。

まずは、作成したコンテナをイメージ化します。イメージ化は数MBのファイルがコピーされるので少し重いです。
今回コンテナのイメージ名は「d77.jp/centos_sv:7.2.1511」にしましたがこの辺は何でもいいです。面倒なら「hoge」とかでも被らなければ大丈夫だと思います。

[root@************ /]# exit
exit
# docker ps -a -f 'id=コンテナID'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
************ centos:7.2.1511 "/bin/bash" 43 minutes ago Exited (0) About a minute ago custom_cnt
# docker commit custom_cnt d77.jp/centos_sv:7.2.1511
sha256:~略~
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
d77.jp/centos_sv 7.2.1511 ************ 4 seconds ago 494.9 MB
docker.io/centos 7.2.1511 ************ 2 weeks ago 194.6 MB
~略~

そして、このイメージからコンテナを起動します。

# docker run --name custom_cnt2 -d -p 8022:22 -t d77.jp/centos_sv:7.2.1511 /start.sh

docker_shipyard_4
注意としては、「-p 8022:22」というオプションですね。これはホストOSの8022番ポートをコンテナの22番ポートへポートフォワードしているという意味です。コンテナは内部的に「172.17.0.0/16[*]」というIPのLANが生成されます。ですから、外部からのアクセスはホストOSを通じてフォワードされなければなりません。また、22/tcpはホスト側のsshが使っているので使えません。dockerは便利なことに「-p 8022:22」というオプションを付けるだけでこのポートフォワードとポート変換を同時に設定してくれます。
docker_port_1

これで、「ホストOSのIP:8022」というアドレスへ外部からsshをすればログインが可能となります。

[*]「172.17.0.0/16」がデフォルトのサブネットかどうかはわかりません。もしかしたら私の環境は別ネットで「172.16.0.0/16」を使ってたので、スライドしてくれたのかも・・・

ネットワークを構成する

dockerは前述の通り、内部に独自のLANを持っていてコンテナを作ると自動的にIPを割り当ててくれます。DHCPなのかどうなのかは知りませんが、とりあえずコンテナに固定IPを割り当てたかったので、ちょっと調べてみました。なお、dockerの外のIPを割り当てるのはちょっと面倒だったので、あくまで内部LANでの固定IPです。

ネットワーク構成を調べる

あまり関係ないですが、初期状態のネットを調べてみました。

# docker network ls
NETWORK ID NAME DRIVER
************ none null
************ host host
************ bridge bridge

「docker network inspect ネットワークID」で詳細を確認できますが、意味は以下の通りのようです。

  • none/null →謎
  • host →謎
  • bridge →内部サブネットと、各コンテナへ割り当てられたIPの設定ぽい

サブネットとIPの設定

既存のサブネット上で固定IPの設定はできないそうなので、サブネットを追加します。

# docker network create --subnet=172.18.0.0/16 docker_net
# docker network ls
NETWORK ID NAME DRIVER
************ none null
************ host host
************ docker_net bridge ←追加された
************ bridge bridge
# docker network inspect ネットワークID
[
{
"Name": "docker_net",
"Id": "************",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16"
}
]
},
"Containers": {},
"Options": {}
}
]

で、このサブネットの固定IPを設定したコンテナを作成します。

# docker run --name nettest -d --net=docker_net --ip=172.18.0.2 -p 10222:22 -t d77.jp/mcsv:20160718 /start.sh
# docker exec -it nettest ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 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
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
36: eth0@if37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 ****::**:****:****:**/64 scope link
valid_lft forever preferred_lft forever

前の「172.17.***.***」と差し替わってます。ちなみに、これでもポートフォワードも正常動きます。他のコンテナとサブネットが違うので、172.17.***.***へのpingは通りませんでした。

コンテナで使えないコマンドのインストール

コンテナは最小構成なので、使えないコマンドが沢山あります。IPを調べたくてもipコマンドがありませんみたいな。無ければyumでinstallすればいいだけの話ですが、コマンドが細かすぎてどのパッケージに入ってるかわからないことも多いのでメモしておきます。

  • ipコマンド
    # yum install iproute
  • whichコマンド
    # yum install which
  • mpstat、vmstatなど
    # yum install sysstat
  • bannerコマンド
    # yum install figlet
    →「figlet -f banner コメント」でbannerコマンドとほぼ同じ動作
  • nmctl
    yum install NetworkManager

その他私的なメモ

  • 本格的にCIをやるなら、Dockerfileベースでコンテナを作り、Dockerfileをソース管理するといい?
  • コンテナを作るベースイメージは、CentOSなどの一般的なディストリより、Alpine Linuxがいいらしい。イニシャルサイズが1/10くらいになるとのこと。
  • 個人的にソースコード管理には(制限付きで無料の)BitBucketを使ってた。GitHubは有料なので使ってない。私的な環境なので、できれば自前で管理したいので探したところ、GitLabやGitBucketというのがいいらしい?
    https://hub.docker.com/r/sameersbn/gitlab/

 

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

Time limit is exhausted. Please reload CAPTCHA.