VagrantとLXCコンテナで仮想空間増築（Windows7編）

## Windowsの話
WindownsはMacと違いUnixライクな環境がないので、
プログラムが絡んだコンテンツ等の動作検証を、ローカル側から容易に行えません。
ですが、Vagrantという仮想環境構築ツールを用いると、
WindowsマシンでもLinuxな環境の構築が可能となります。

そういえばCygwinといったWindows上で動作するUnixライクなものもありますが、
今回はVagrantにてubuntu等のOSをインストールをし、
LXCでCentOSのコンテナを複数立ち上げるをやってみようと思います。

Dockerがありますやん。とか思われる方が多々おられるかと思いますが、
コンテナにOSを入れて、ガッツリ使用するという主旨と、その際にブリッジを使ったネットワーク設定等を自分で行いたかったので、地道に構築していこうと思った次第です。

## Vagrantの環境構築
Windows環境下におけるVagrantの構築は特に難しくないし、色んな方達が解説されているので、そちらを参照して頂くとして、いきなりubuntu14.04を使用するところから始めます。

* Windowsのコマンドプロンプトを用い、設置したいディレクトリにて下記を実行。

```console
vagrant box add ubuntu14.04 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
```
※長いけど1行です。

* addしたbox名ubuntu14.04を指定して初期化


```console
vagrant init ubuntu14.04
```

* ubuntuの起動


```console
vagrant up
```

default: 22 => 2222 (adapter 1)
default: SSH address:127.0.0.1:2222
vagrant起動時に上記内容が出力されるかと思いますが、
ssh接続ポートが22から2222へと変換されるといった内容になります。

127.0.0.1:2222にてローカル端末のVagrant@ubuntu14.04へのSSH接続が可能となります。
※接続時に要求されるパスワードは[vagrant]です。
vagrantを介して設置したubuntu14.04へSSH接続が出来たましたら、
LXC環境の構築開始となります。

## Lxcのインストールと設定

* LXCと必要になる物をインストール<p>※下記はvagrant下のubuntu14.04内での作業となります。</p>

```sh
$ sudo aptitude -y install lxc yum rpm
```

* 念の為、使用するOSテンプレートがあるかの確認

```sh
$ sudo ls /usr/share/lxc/templates/ 

lxc-alpine  lxc-busybox  lxc-debian  lxc-gentoo  lxc-oracle  lxc-ubuntu　lxc-altlinux   lxc-centos   lxc-download  lxc-openmandriva  lxc-plamo  lxc-ubuntu-cloud　lxc-archlinux  lxc-cirros   lxc-fedora    lxc-opensuse  lxc-sshd
```
* CentOSのlxcコンテナ作成<p>※コンテナ用にLVM使用したいけどwindowsなので省略。</p>

```sh
$ sudo lxc-create -t centos -n cent01
```

+ 対話式でrootのパス変更

```sh
$ sudo chroot /var/lib/lxc/cent01/rootfs passwd
```
コンテナの設定ファイル/var/lib/lxc/cent01/configは、
初期設定のままで使用可能ですが、ネットワーク構成などが異なる場合、
都度変更が必要となります。

## ネットワークの話
デフォルトの状態においては、コンテナの(eth0)は、ブリッジインターフェース(lxcbr0) とブリッジ接続します。外部とコンテナが直接通信を行う為には、ブリッジインターフェースの(lxcbr0)を、ホスト側の物理インターフェース(eth0)をブリッジに参加させ、(lxcbr0)とコンテナ側の(eth0)をブリッジ接続します。あぁめんどい。

Vagrantはデフォルトでホスト側の(eth0)が10.0.2.15でIPが割り当てられるので、
他のインターフェースに固定IPを割り当てたい場合、OSを設置したディレクトリ内の「Vagrantfile」ファイルにて「private_network」と「public_network」の項目を設定すると、IPの固定化が可能となります。
テキストエディタにて
config.vm.network "private_network", ip: "192.168.33.10"
といった内容で「Vagrantfile」を編集し、Windowsのコマンドプロンプトで

```console
vagrant reload
```
を実行してVMの再読み込みすると、下記内容がvagrantにより
/etc/network/interfacesへ記載されます。

```sh:/etc/network/interfaces
$ sudo cat /etc/network/interfaces
----------------------------------
# The loopback network interface
auto lo
iface lo inet loopback

#VAGRANT-BEGIN
# The contents below are automatically generated by Vagrant. Do not modify.
auto eth1
iface eth1 inet static
      address 192.168.33.10
      netmask 255.255.255.0
#VAGRANT-END
----------------------------------
```

+ ここまで来たら作ったコンテナをログ付きで起動。

```sh
$ sudo lxc-start -n cent01-d -o cent01.log
```
+ アタッチしてコンテナに入る。

```sh
$ sudo lxc-attach -n cent01
```
アタッチしたコンテナ内での作業となりますが、ネットワークの設定とルーティングの編集が必要になります。(lxcbr0)に割り振られている10.0.3.1/24のレンジを使用します。

```sh:/etc/sysconfig/network-scripts/ifcfg-eth0
vim /etc/sysconfig/network-scripts/ifcfg-eth0
----------------------------------
DEVICE=eth0
#BOOTPROTO=dhcp
BOOTPROTO=static
ONBOOT=yes
HOSTNAME=cent01
NM_CONTROLLED=no
TYPE=Ethernet
MTU=
IPADDR=10.0.3.10
NETMASK=255.255.255.0
GATEWAY=10.0.3.1
----------------------------------
```
## Apacheの設定
特に編集箇所は無いのですが、ホスト側のポートと衝突を避けるため、
ポートを80から8081へ変更します。

```sh:/etc/httpd/conf/httpd.conf
vim /etc/httpd/conf/httpd.conf
----------------------------------
ServerName 10.0.3.10:8081
----------------------------------

service httpd start
chkconfig httpd on
```
続けてApacheの起動と自動起動の設定。
上記が済んだら一旦コンテナから抜けて、コンテナの再起動を。

## IPフォワーディングとか

再度コンテナにアタッチし、Ping等でネットワークが接続されているか確認を。
ネットワークに接続されてない場合、デフォルトゲートウェイの設定をする必要があったりします。

```sh
ip r
----------------------------------
10.0.3.0/24 dev eth0  proto kernel  scope link  src 10.0.3.10
169.254.0.0/16 dev eth0  scope link  metric 1006
----------------------------------
無いので下記コマンドを実行
ip r a default via 10.0.3.1 dev eth0
```
```sh
再確認
ip r
----------------------------------
default via 10.0.3.1 dev eth0
10.0.3.0/24 dev eth0  proto kernel  scope link  src 10.0.3.10
169.254.0.0/16 dev eth0  scope link  metric 1006
----------------------------------
設定完了
```

+ フォワーディングが有効になっているかチェック

```sh
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
```
が返って来たらOK。0の場合は、

```sh:/etc/sysctl.conf
vim /etc/sysctl.conf
----------------------------------
net.ipv4.ip_forward = 0 → 1
----------------------------------
sysctl -p
```
で反映

コンテナ(cent01)10.0.3.10は、vagarantのプライベートアドレス項目にて設定されている192.168.33.10という知らないサブネットから受信することになり、戻りのパケットは自分のデフォルトゲートウェイの(lxcbr0)10.0.3.1へ送りつけるので問題なさげだけど、念のためNATしたパケットの送信元アドレスを(lxcbr0)の10.0.3.1にする。
「192.168.33.10:80宛のパケットは10.0.3.1というアドレスに付け替えてから送信する」というルールをコンテナ(cent01)で設定する。

```sh
iptables -t nat -A POSTROUTING -m tcp -p tcp --dst 10.0.3.10 --dport 8081 -j SNAT --to-source 10.0.3.1
```

下記をホスト側で行う。

```sh
iptables -t nat -A PREROUTING -m tcp -p tcp --dst 192.168.33.10 --dport 80 -j DNAT --to-destination 10.0.3.184:8081
```
これにてローカルPCからコンテナのApacheへの接続が可能になるかと思います。その他使用するデーモンについては、都度記述箇所を変える事で対応可能かと思われます。MySQLやPostgreSQLをコンテナ毎に分けて使用する事も可能ですし、夢は広がりますね！

## 最後に一言
Lxcは軽くて良いし、ディレクトリ構成が分かり易いので大好きなのですが、
設定とかがやっぱ面倒な感じ。この辺は好き嫌いが出るかもですね。
というか「Windowsでこんな変態構成する必要ないやん」というツッコミはナシで。