ククログ

株式会社クリアコード > ククログ > LXCコンテナに名前でアクセスする方法

LXCコンテナに名前でアクセスする方法

LXCコンテナを複数作って、開発に使用しているとIPアドレスではなく名前で各コンテナにアクセスしたくなります。 もちろんlxc-consoleを使えば名前でアクセスできるのですがlxc-consoleではC-aが取られてしまって不便です。

そこで、SSHを使って名前で各コンテナにアクセスできるととても便利です。

dnsmasqを使うと簡単にそのような環境を構築することができるので、その手順を紹介します。 なお、環境はDebian sidを想定しています。

Ubuntuだとlxcを入れるだけでやってくれる内容なのでUbuntu12.04でやっていることを調べてDebian向けにアレンジしています。

必要なパッケージをインストールする

$ sudo apt-get install -y lxc dnsmasq-base bridge-utils

lxcbr0を作成する

$ sudo brctl addbr lxcbr0

lxcbr0が自動起動するように設定する

/etc/network/interfaces:

...
auto lxcbr0
  iface lxcbr0 inet static
  address 192.168.30.1
  netmask 255.255.255.0
  pre-up  /path/to/lxcbr0-pre-up
  post-up /path/to/lxcbr0-post-up
  post-down /path/to/lxcbr0-post-down

pre-up, post-up, post-downでそれぞれスクリプトを指定して必要な処理を実行しています。

lxcbr0-pre-up:

#! /bin/bash

brctl show | grep -q lxcbr0
if test $? -ne 0; then
  brctl addbr lxcbr0
fi

lxcbr0が存在しなかったら作成するスクリプトです。

lxcbr0-post-up:

#!/bin/sh
# This is the address we assigned to our bridge in /etc/network/interfaces
braddr=192.168.30.1
# ip address range for containers
brrange=192.168.30.2,192.168.30.254
iptables -A FORWARD -i lxcbr0 -s ${braddr}/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE 
dnsmasq --bind-interfaces --conf-file= \
        --bogus-priv \
        --domain-needed \
        --expand-hosts \
        --domain=lxc.localdomain \
        --listen-address $braddr \
        --except-interface lo \
        --dhcp-range $brrange \
        --dhcp-lease-max=253 \
        --dhcp-no-override \
        --pid-file=/tmp/dnsmasq-lxcbr0.pid

このスクリプトが今回の最も重要な部分です。 iptablesでNATの設定をしてからdnsmasqを起動してDHCPサーバとDNSサーバの機能を有効にしています。

同等の設定をデーモンとして起動するdnsmasqに行っても同じことができます。 ただし、その場合iptablesの設定は別の方法で実行する必要があります。

lxcbr0-post-down:

#!/bin/bash
kill $(cat /tmp/dnsmasq-lxcbr0.pid)
rm -f /tmp/dnsmasq-lxcbr0.pid

lxcbr0-post-upで作ったPIDファイルを見てdnsmasqを終了させるだけのスクリプトです。

lxcbr0を起動する

$ sudo ifup lxcbr0

dnsmasqが起動していることを確認します。

$ ps aux | grep dnsmasq
nobody   13187  0.0  0.0  35104  1216 ?        S    15:05   0:00 dnsmasq --bind-interfaces --conf-file= --bogus-priv --domain-needed --expand-hosts --domain=lxc.localdomain --listen-address 192.168.30.1 --except-interface lo --dhcp-range 192.168.30.2,192.168.30.254 --dhcp-lease-max=253 --dhcp-no-override

コンテナを作成する

$ sudo lxc-create -t ubuntu -n ubuntu1204 -- --release precise --bind $USER

名前解決の確認をする

$ dig @192.168.30.1 ubuntu1204
; <<>> DiG 9.9.5-3-Debian <<>> @192.168.30.1 ubuntu1204
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56257
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ubuntu1204.                    IN      A

;; ANSWER SECTION:
ubuntu1204.             0       IN      A       192.168.30.201

;; Query time: 0 msec
;; SERVER: 192.168.30.1#53(192.168.30.1)
;; WHEN: Mon Apr 28 15:57:44 JST 2014
;; MSG SIZE  rcvd: 55

/etc/resolve.confにnameserverを追加する

このままだとSSHなどを使えないので/etc/resolve.confにnameserverを追加します。

NetworkManagerを使用していない場合は単純に追加しても問題ありませんが、NetworkManagerを使用している場合はNetworkManagerが自動的に/etc/resolve.confを書き換えてしまうのでnamesererの設定が消えてしまうことがあります。 /etc/dhcp/dhclient.confに以下の内容を追加してNetworkManagerを再起動すると、自動的に/etc/resolv.confに反映されます。

/etc/dhcp/dhclient.conf:

...
prepend domain-name-servers 192.168.30.1;
...

SSHでコンテナにアクセスする

$ ssh ubuntu1204

まとめ

LXCコンテナに名前でアクセスする方法を紹介しました。