Dockerでforward proxyサーバーを立てる with centos6.5 on virtualbox
-
[2014/05/08 追記] Dockerfile使って簡潔にまとめ直した版はこちら Dockerでforward proxyサーバー(squid)を立てる using Dockerfile - Qiita
-
centos6.5 on virtualboxな環境(dockerコンテナもcentos6.5)な環境で公式のチュートリアルを試してみた備忘
-
dockerとは何ぞやレベルの話は割愛。というか有用な情報が多く存在するのでいらんよね?という
やること
- virtualbox上にcentos6.5のVMを構築する
- 構築したVM上でdockerコンテナを動かす(同じくcentos)
- dockerのcentral repositryにあるcentosイメージはver 6.4なので、6.5にアップデート
- コンテナ上にsquidでプロキシサーバを立てて、数パターンのアクセス経路で通信を確認する
環境
- Virtualbox 4.3.8
- 作業PCはMac
- Vagrant 1.4.3
- Docker 0.8.0
作業ログ
Virtualbox上にベースとなるVMを作成
- vagrant1.4からprovisionerにdockerを指定できるようになったので、dockerのインストールはvagrantに任せる
- Docker - Provisioning - Vagrant Documentation
% vagrant box add centos65_86 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.1/centos65-x86_64-20131205.box
% vagrant init centos65_86
% vi Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "centos65_86"
config.vm.define :vmdocker1 do |vmdocker1|
vmdocker1.vm.hostname = "vmdocker1"
vmdocker1.vm.network :private_network, ip: "192.168.56.110"
# for VirtualBox
vmdocker1.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", 512]
end
# provisioner = docker
# pull_images でimageのダウンロード
vmdocker1.vm.provision :docker do |d|
d.pull_images "centos"
end
end
end
% vagrant up
% vagrant ssh
[vagrant@vmdocker1 ~]$ cat /etc/redhat-release
CentOS release 6.5 (Final)
dockerの確認
- vagrant経由でも現時点で最新のdocker 0.8.0がインストールされている
[vagrant@vmdocker1 ~]$ docker -v
Docker version 0.8.0, build cc3a8c8/0.8.0
- Driverがdevicemapperとなっているが、これはdockerのデフォルトドライバであるaufsにRHEL系ディストリビューションが対応していない為
- 参考 : Docker ストレージドライバによる RHEL/CentOS 対応について - Shin x blog
- ベースとなっているコピーオンライト・ストレージは lvm thin provisioning だが、centosでは6.4から対応している。dockerのcentral repositoryで公開されてるcentosは6.4なので対応状況としては問題なし
[vagrant@vmdocker1 ~]$ docker info
Containers: 0
Images: 1
Driver: devicemapper
Pool Name: docker-8:1-131916-pool
Data file: /var/lib/docker/devicemapper/devicemapper/data
Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 626.1 Mb
Data Space Total: 102400.0 Mb
Metadata Space Used: 0.9 Mb
Metadata Space Total: 2048.0 Mb
コンテナ起動確認
- docker runの際にsudoしてる例をよく見るが、vagrantなんでsudo不要
- 適当なコマンドを実行し、実行結果を確認してみる
[vagrant@vmdocker1 ~]$ docker run -t centos /bin/bash -c "echo hello; echo world;"
hello
world
- interactiveモード(-i)ではない場合、処理実行後にコンテナは停止するので、普通に
docker ps
しただけでは該当コンテナは表示されない。なので-a
オプションを付加する - 加えて、通常は情報を省略して表示するので省略を無効化する為に
--no-trunc
オプションを付加する - STATUS欄がコマンドの結果コードになる
[vagrant@vmdocker1 ~]$ docker ps -a --no-trunc 58a7ec06afa0
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58a7ec06afa04cbd28ca9536cc8ba651c227197ca2b1c24b750c3c154e514997 centos:6.4 /bin/bash -c echo hello; echo world; About a minute ago Exit 0 focused_brattain
- コンテナで実行した処理の結果は
docker logs
でも確認可能。 docker logsの出力は stdout/stderrのキャプチャ とイメージすればよいかと
[vagrant@vmdocker1 ~]$ docker logs 58a7ec06afa0
hello
world
コンテナのcentosを6.5にアップグレードする
- interactive-modeでシェルにログインし、centosのアップグレードを行う
- 普通に yum update するだけ
[vagrant@vmdocker1 ~]$ docker run -t -i centos /bin/bash
bash-4.1# cat /etc/redhat-release
CentOS release 6.4 (Final)
bash-4.1# yum -y update
: (なんだかんだupdateされる)
Complete!
bash-4.1# cat /etc/redhat-release
CentOS release 6.5 (Final) # <= 6.5になった
- この6.5にアップデートだけした時点で、一旦
docker commit
しておく - 業務で使用する場合とか、管理面を考慮してTAGとコミットコメントはちゃんと書いといた方が良さそうな気がした
[vagrant@vmdocker1 ~]$ docker commit -m 'upgrade 6.4 => 6.5' dabf3c7c0bcb centos:6.5
- 作成したイメージを
docker images
で確認。6.5にしただけでサイズが2倍...
[vagrant@vmdocker1 ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos 6.5 ccc8bfd8399d 51 seconds ago 600 MB
- 不要になった他のイメージは
docker rmi
して削除しておく- が、ここで 削除したのに容量が減らない という症状に出くわす...
- 参考 : Docker on CentOS 6.5 で詰んだのでメモ - sonots:blog
- 今後コミュニティが活発になるにつれdockerのcentral repositoryのストレージとかどんでもない容量に膨らむんじゃないかと推測されるので、その辺りどう解決していくのか注目
[vagrant@vmdocker1 ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 7.3G 2.3G 4.8G 32% /
tmpfs 246M 0 246M 0% /dev/shm
/vagrant 465G 94G 371G 21% /vagrant
[vagrant@vmdocker1 ~]$ docker rmi 539c0211cd76
Untagged: 539c0211cd76cdeaedbecf9f023ef774612e331137ce7ebe4ae1b61088e7edbe
Untagged: 539c0211cd76cdeaedbecf9f023ef774612e331137ce7ebe4ae1b61088e7edbe
[vagrant@vmdocker1 ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos 6.5 ccc8bfd8399d 5 minutes ago 600 MB
[vagrant@vmdocker1 ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 7.3G 2.3G 4.8G 32% / # <= 減っちゃいねぇ...
tmpfs 246M 0 246M 0% /dev/shm
/vagrant 465G 94G 371G 21% /vagrant
[root@vmdocker1 ~]# du -h /var/lib/docker --max-depth=1
32K /var/lib/docker/graph
576K /var/lib/docker/containers
4.0K /var/lib/docker/volumes
1.7G /var/lib/docker/devicemapper
6.5M /var/lib/docker/init
コンテナにsquidをインストール
- サービス開始時になんかスクリプトのエラーが出るけどスルー
- ポート=デフォルト=3128でサービス開始出来るところまで確認し、自動起動をonにしておく
[vagrant@vmdocker1 ~]$ docker run -t -i ccc8bfd8399d /bin/bash
bash-4.1# yum -y install squid
bash-4.1# /etc/init.d/squid start
/etc/init.d/squid: line 25: /etc/sysconfig/network: No such file or directory
/etc/init.d/squid: line 51: [: =: unary operator expected
Starting squid: . [ OK ]
bash-4.1# netstat -anp | grep squid
tcp 0 0 :::3128 :::* LISTEN 73/(squid)
udp 0 0 0.0.0.0:58841 0.0.0.0:* 73/(squid)
udp 0 0 :::37744 :::* 73/(squid)
bash-4.1# chkconfig squid on
bash-4.1# /etc/init.d/squid stop
/etc/init.d/squid: line 25: /etc/sysconfig/network: No such file or directory
Stopping squid: ................ [ OK ]
- centos6.5 + squid、まで完了したこの時点でもコミットしてイメージ作成しておく
- 業務でdockerを使うことになった場合も、おそらくこのようにコンテナ仕様に変更があれば適宜コミットしていくイメージ。
-
OSレベルで履歴を管理し、さらには任意の時点からの更新・派生・削除も行える。 という点をメリットと考えるなら、こうした適宜コミットがベターかと思ふ。
- 自分の場合普段の仕事でgitを使っている事もあってか、コミットがマメになる癖はあるかも
- centos65だと不要なイメージを削除しても容量が減らないという問題はありますがそのうち解決されると信じる
[vagrant@vmdocker1 ~]$ docker commit -m 'add squid' $(docker ps -q -a | head -1) centos:6.5-squid # docker ps -q -a | head -1 => 直近実行していたコンテナIDを取得
[vagrant@vmdocker1 ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos 6.5-squid 9a8172a27111 About a minute ago 660.3 MB
centos 6.5 ccc8bfd8399d 22 hours ago 600 MB
- ちなみにこのイメージを再度docker runしても、 __squidが自動起動されるわけではなかった("状態"を持ってるわけではない)。後述
ホストマシンとポートバインディングしてみる
- コンテナのsquid起動ポートをホストマシンにバインディングして、そのポートからsquidにアクセス出来るか確認する
[vagrant@vmdocker1 ~]$ docker run -p 13128:3128 -i -t 9a8172a27111 /bin/bash
bash-4.1#
- バインドに成功したかは docker ps とか docker port で確認可能
[vagrant@vmdocker1 network-scripts]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff60f536aaeb centos:6.5-squid /bin/bash 52 seconds ago Up 52 seconds 0.0.0.0:13128->3128/tcp high_ritchie
[vagrant@vmdocker1 network-scripts]$ docker port ff60f536aaeb 3128
0.0.0.0:13128
- コンテナのsquidを起動する
bash-4.1# /etc/init.d/squid start
/etc/init.d/squid: line 25: /etc/sysconfig/network: No such file or directory
/etc/init.d/squid: line 51: [: =: unary operator expected
Starting squid: . [ OK ]
- ホストマシンからバインドしたポートへのアクセスを試してみる。squidに / アクセスした際のエラーページが取得できてる
[vagrant@vmdocker1 ~]$ curl http://localhost:13128/ | head -10
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
101 3139 101 3139 0 0 1449k 0 --:--:-- --:--:-- --:--:-- 3065k
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ERROR: The requested URL could not be retrieved</title>
<style type="text/css"><!--
/*
Stylesheet for Squid Error pages
Adapted from design by Free CSS Templates
http://www.freecsstemplates.org
Released for free under a Creative Commons Attribution 2.5 License
- 折角プロキシとしてsquidを動かしているので、これを経由して外部(今回はapache1.3で稼働してるwebサーバを使用)にもアクセスしてみる。
[vagrant@vmdocker1 ~]$ curl -x localhost:13128 http://www.byaaaaaaaaaaaaaa.com/
(ズラズラと取得したコンテンツを表示)
- コンテナのsquidのaccess.logに該当アクセスが記録されている
bash-4.1# view /var/log/squid/access.log
1393929530.175 298 172.17.42.1 TCP_MISS/200 24888 GET http://www.byaaaaaaaaaaaaaa.com/ - DIRECT/10.0.yy.yy text/html
- アクセスしたサイトのaccess.logを確認、コンテナのIPアドレスが記録されている
172.17.42.1 - - [04/Mar/2014:19:39:58 +0900] "GET / HTTP/1.1" 200 24156 "-" "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" "-"
- 同様に、ホストVMを稼働させているローカルPC(Mac)からもコンテナのsquid経由で外部にアクセスしてみる
- ホストVMのIPアドレスを 192.168.56.110 とする
% curl -x 192.168.56.110:13128 http://www.byaaaaaaaaaaaaaa.com/
- コンテナのsquidで401で弾かれている
- アクセス元はvirtualboxのgatewayアドレス=192.168.56.1 になっている
bash-4.1# view /var/log/squid/access.log
1393929684.408 132 192.168.56.1 TCP_MISS/401 310 GET http://www.byaaaaaaaaaaaaaa.com/ - DIRECT/10.0.yy.yy text/html
- サイトのaccess.logも401で弾かれてる
192.168.56.1 - - [04/Mar/2014:19:42:32 +0900] "GET / HTTP/1.1" 401 5 "-" "curl/7.30.0" "-"
- ホストVMのVagrantfileにローカルPC => ホストVMのポートフォワード設定を追加してみる
- 最終的に ローカルPC(23128) => ホストVM(13128) => コンテナ(3128) というフォワード経路が完成
@@ -11,6 +11,8 @@
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vmdocker1.vm.hostname = "vmdocker1"
vmdocker1.vm.network :private_network, ip: "192.168.56.110"
+ vmdocker1.vm.network :forwarded_port, host: 23128, guest: 13128
+
- この状態で再度ローカルPCからチャレンジ
- ホストはlocalhost、ポートはフォワード設定した番号に変更している
% curl -x localhost:23128 http://www.byaaaaaaaaaaaaaa.com/
(ズラズラと取得したコンテンツを表示)
- コンテナのsquidのaccess.logに該当アクセスが記録されている
- アクセス元IPはローカルPCのもの
bash-4.1# view /var/log/squid/access.log
1393930836.500 276 10.0.xxx.xxx TCP_MISS/200 24888 GET http://www.byaaaaaaaaaaaaaa.com/ - DIRECT/10.0.yy.yy text/html
- アクセスしたサイトのaccess.logを確認、コンテナのIPアドレスが記録されている
- アクセス元IPは同じくローカルPCのもの
10.0.xxx.xxx - - [04/Mar/2014:20:00:37 +0900] "GET /welcome HTTP/1.1" 200 24156 "-" "curl/7.30.0" "-"
squid起動状態のコンテナをバックグラウンドで稼働させる
- squid起動状態でコンテナを終了し、コミットする
- このコミットにて作成されたイメージでコンテナを実行した際に、既にsquidが起動状態にあるかを確認する
[vagrant@vmdocker1 ~]$ docker commit -m 'update running squid' $(docker ps -q -a | head -1) centos:6.5-squid-running
[vagrant@vmdocker1 ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos 6.5-squid-running a2ca5119cdcf 19 seconds ago 660.3 MB
[vagrant@vmdocker1 ~]$ docker run -p 13128:3128 -i -t a2ca5119cdcf /bin/bash
[vagrant@vmdocker1 ~]$ docker run -p 13128:3128 -i -t a2ca5119cdcf /bin/bash
bash-4.1# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 11436 1596 ? S 23:27 0:00 /bin/bash
root 6 0.0 0.2 13364 1056 ? R+ 23:27 0:00 ps aux
- squidは停止状態でした。普通にdocker runしただけではdocker run時に同時にサービス起動する事は出来ないよう。
- イメージは状態を保持しているわけではない
- non-interactiveにdocker runしたコンテナでsquidサービスを起動(しっぱなし)にしておきたいが
- docker run時のコマンド引数で /etc/init.d/squid start しても、コンテナ内でバックグラウンドとして動くので、フォワグラウンドジョブが無い=すぐにコンテナが終了してしまう
[vagrant@vmdocker1 ~]$ docker run -p 13128:3128 -i -t a2ca5119cdcf /bin/bash -c '/etc/init.d/squid start'
/etc/init.d/squid: line 25: /etc/sysconfig/network: No such file or directory
/etc/init.d/squid: line 51: [: =: unary operator expected
Starting squid: [ OK ]
# ココでコンテナ終了
- これを解決するために、「コンテナ内ではフォアグラウンドに稼働し、docker runをバックグラウンドで実行」させてみる
- コンテナのsquidスクリプトにフォアグラウンドで稼働させるオプション
starti
を追加する
[vagrant@vmdocker1 ~]$ docker run -p 13128:3128 -i -t a2ca5119cdcf /bin/bash
bash-4.1# vi /etc/init.d/squid
99 starti() {
100 probe
101
102 SQUID_OPTS="-N"
103
104 parse=`$SQUID -k parse -f $SQUID_CONF 2>&1`
105 RETVAL=$?
106 if [ $RETVAL -ne 0 ]; then
107 echo -n $"Starting $prog: "
108 echo_failure
109 echo
110 echo "$parse"
111 return 1
112 fi
113 for adir in $CACHE_SWAP; do
114 if [ ! -d $adir/00 ]; then
115 echo -n "init_cache_dir $adir... "
116 $SQUID -z -F -f $SQUID_CONF >> /var/log/squid/squid.out 2>&1
117 fi
118 done
119 $SQUID $SQUID_OPTS -f $SQUID_CONF >> /var/log/squid/squid.out 2>&1
174 starti)
175 starti
176 ;;
- 追加したフォアグラウンド用オプションでsquidを起動し、動作確認してみる => OK
bash-4.1# /etc/init.d/squid starti
[vagrant@vmdocker1 ~]$ curl -x localhost:13128 http://www.byaaaaaaaaaaaaaa.com/
(OK!!)
- ここまでをコミットし、作成したイメージで デタッチモードで docker runする
[vagrant@vmdocker1 ~]$ docker commit -m 'add squid foreground start option' $(docker ps -q -a | head -1) centos:6.5-squid-running
170451d7b035ba10e96b798b5d83c9b99b67ed2a9cc586d3404ba4d3738a1739
[vagrant@vmdocker1 ~]$ docker run -p 13128:3128 -t -d 170451d7b035 /etc/init.d/squid starti
- squidが起動した状態でコンテナが実行されているので、アクセス確認してみる
- 実行中のコンテナは docker killで止める
[vagrant@vmdocker1 ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
210e3a97b2ab centos:6.5-squid-running /etc/init.d/squid st 4 seconds ago Up 4 seconds 0.0.0.0:13128->3128/tcp romantic_albattani
[vagrant@vmdocker1 ~]$ curl -x localhost:13128 http://www.byaaaaaaaaaaaaaa.com/
(OK!)
[vagrant@vmdocker1 ~]$ docker kill 210e3a97b2ab