前回はlxcで仮想ubuntuを立ち上げてみるところまでやってみた。IPアドレスもdnsmasqで名前解決できるようになった。
そこで思い立ったのが、ホストの環境を汚さずに、デスクトップ環境のためのコンテナを作って、そこへ外部からVNC接続してみようかなと。飽きたらポイっとまるごと捨てればいいし。
lxcクローン
$ lxc-clone master ubu01
なにか構築したいなって時にすぐ始められるように、予め必要最低限のことを終わらせてあるubuntuコンテナをmasterとして作っておいて、lxc-cloneする。
起動
$ lxc-start -n ubu01 -d
sshログイン
$ ssh ubuntu@ubu01
lxdeインストール
$ sudo apt-get install lxde
ubuntu-desktopじゃなくてlxde。メモリもディスクも少ないShuttleではlxdeの方が小さくてよい。
それでも500MB位は消費してしまうが。
vncserver インストール
$ sudo apt-get install vnc4server
他にも色々VNCサーバーはあるようだけれど、扱いが簡単なvnc4server。
~/.vnc/xstartup作成 (っていうか、デフォルトをリンクしておくだけ)
$ mkdir ~/.vnc
$ ln -s /etc/X11/Xsession ~/.vnc/xstartup
vncserver起動(vncserverでもvnc4serverでもいっしょ)
$ vncserver :0
最初の起動時には、xauthのパスワード設定を要求してきます。適当に設定。
vncが 5900 で待ち受け状態になりました。
ホストの5900ポートを ubu01:5900 へルーティングする
(ホスト側で)
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 5900 -j DNAT --to ubu01:5900
ホストとコンテナ間でのプライベートネットワークへ外部からアクセスできるようにするのに
一番お手軽な方法。
そしたら、外からホストの5900へVNC接続するとubu01:5900へルーティングされて、
めでたくlxdeのデスクトップへ到達します。
日本語化!
忘れてました。いつも端末ばっかりだったので、GUIには日本語化ってのがありました。
そもそも lxc で作った ubuntuコンテナってロケールがen_US.UTF-8だし・・・そこからか。
日本語フォント インストール(IPA入れとけばいいっしょ)
$ sudo apt-get install fonts-ipafont
とりあえずフォントさえ入れれば、lxdeで日本語が表示されます。
日本語パッケージインストール
$ sudo apt-get install language-pack-ja
ロケール設定
$ sudo update-locale LANG=ja_JP.UTF-8
/etc/default/localeに書き込まれる。が、今のシェルの環境変数はen_US.UTF-8のままです。
インプットメソッド
$ sudo apt-get install ibus-anthy
mozcの方が評判いいらしいが、自分にはぴんとこなかった。
ibusじゃなくてfcitxか?とも思って入れてみたけど、??な感じ。ibus-anthyで十分っす。
タイムゾーン変更(日本語化というより日本時間でってだけだけど)
$ sudo dpkg-reconfigure tzdata
CUIメニュー操作でAsiaからTokyo選ぶ
ここまでやったら、一度コンテナを再起動したほうが良い。環境変数とか変わるんで。
(ホストでリブート)
$ lxc-stop -n ubu01 -r
そしたら改めてコンテナ上で vncserver を起動して、そとからVNC接続すると lxdeデスクトップ自体も日本語表示になって、IMもibusで動いている状態に。
後処理
$ sudo iptables -t nat -D PREROUTING 1
遊び終わったら、DNAT設定を消しておこう。
コンテナも終わらせるか、vncserverを $ vncserver -kill :0 しておこう。
油断していると外から潜り込まれちゃうのでね。
2015/08/15
2015/08/14
lxcのdnsmasqでコンテナのIPアドレス管理
lxc楽しくて、調子に乗って何個も作るとコンテナのIPアドレスでアクセスするのが面倒になってくる。
コンテナ側で固定IP設定するのもいいけど、lxc-cloneして使う場合、外側で管理しないと辛い。
ということで、コンテナ内はデフォルトのDHCP設定のままで、ホスト側で制御したい。
一番本家っぽいところを読む・・・
https://help.ubuntu.com/lts/serverguide/lxc.html#lxc-network
やっぱり、ありますね。方法が。
/etc/default/lxc-net ファイルの以下の記述があるんで、コメント外す
LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
LXC_DOMAIN="lxc" ←必要かなぁ。dnsmasqが使うかな。
DNS in Ubuntu + LXC が参考になりました。
/etc/resolvconf/resolv.conf.d/head とか /etc/network/interface当たりに
nameserver 10.0.3.1を加えればいいだけだった。
$ sudo resolveconf -u
更新して
$ ping ubu01
$ ping ubu01.lxc
が出来るようになった。これで、dhcp-hostでIP指定してなくても名前解決が出来るんで
更に楽ちん。
https://github.com/jeremiahsnapp/dev-lxc
これも面白そう。高度すぎ?
コンテナ側で固定IP設定するのもいいけど、lxc-cloneして使う場合、外側で管理しないと辛い。
ということで、コンテナ内はデフォルトのDHCP設定のままで、ホスト側で制御したい。
一番本家っぽいところを読む・・・
https://help.ubuntu.com/lts/serverguide/lxc.html#lxc-network
やっぱり、ありますね。方法が。
/etc/default/lxc-net ファイルの以下の記述があるんで、コメント外す
LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
LXC_DOMAIN="lxc" ←必要かなぁ。dnsmasqが使うかな。
/etc/lxc/dnsmasq.conf を作成して以下のように記述
dhcp-host=ubu01,10.0.3.11
dhcp-host=ubu02,10.0.3.12
dhcp-host=ubu03,10.0.3.13
もしくは
dhcp-hostsfile=/etc/lxc/dnsmasq-hosts.conf
と書いて、別ファイルにまとめることも出来るそうな。
$ sudo service lxc-net stop
$ sudo service lxc-net start
とかじゃなくてホスト再起動のほうがいいかも。
その後、コンテナを起動すると、指定アドレスになった。DHCP側で管理できるってことだね。
楽ちん。
楽ちん。
ホスト側から名前でアクセスしたい
IP管理するんだったら全部 hosts ファイルに書くっていう手もあるが、それすら面倒くさい。
本家のドキュメントを読むと
server=/lxc/10.0.3.1 を /etc/dnsmasq.conf に書き加えろとか書いてあるんだけど、効果なし。
あちこちの記事でも書き加える場所とか説明がまちまちで、よくわからん。DNS in Ubuntu + LXC が参考になりました。
/etc/resolvconf/resolv.conf.d/head とか /etc/network/interface当たりに
nameserver 10.0.3.1を加えればいいだけだった。
$ sudo resolveconf -u
更新して
$ ping ubu01
$ ping ubu01.lxc
が出来るようになった。これで、dhcp-hostでIP指定してなくても名前解決が出来るんで
更に楽ちん。
https://github.com/jeremiahsnapp/dev-lxc
これも面白そう。高度すぎ?
2015/08/13
lxcを入れてVM構築
LinuxContainers.org Infrastructure for container projects というLinuxカーネルのコンテナ技術を使って軽量VM環境を構築できるらしいものを最近知りました。
VMWare、Xen、KVM、もっと大きなのでは AWS とかが、VMの世界だと思っておりましたが、それら全部が openstack (cloud softwre) ファミリーだったのね。
ということで、軽量でメモリもディスクもあまり使わなそうな lxc でVMっぽいものをやってみた。
lxcの先には Docker とかいうものが控えているようだけれど、まずは基礎から。
lxcの勉強には LXCで学ぶコンテナ入門 を参考にさせてもらいました。
lxcインストール
$ sudo apt-get install lxc
すると
/etc/lxc/ 設定
/usr/share/lxc/ ディストーション設定やテンプレート
/var/lib/lxc/ ルート権限のコンテナ格納場所
/etc/init/lxc-**.conf 自動起動やらネットワーク設定やら
が作られて
upstart-file-bridge
upstart-socket-bridge
upstart-udev-bridge
cgmanager
dnsmasq
がデーモンで動き始めました。
ifconfig すると、lxcbr0 っていうコンテナのネットワークをブリッジするインターフェースが追加されているのを確認。
root権限でコンテナ作って動かしてみる
$ sudo lxc-create -t ubuntu -n uc01
/var/lib/lxc/uc01にuc01という名前のubuntuが作られた。
起動!
$ sudo lxc-start -n uc01
動いた~。デフォルトのubuntuユーザでログインしてみた。ふむふむ。sshが出来る状態なのね。
えーと、コンソールから抜けるのは??? Ctrol+a qだそうな。やってみたけど抜けられぬ。。
停止(ホスト側で)
$ sudo lxc-stop -n uc01
コンソールから抜けられなかったので、外から殺しました。
デーモン起動して
$ sudo lxc-start -n uc01 -d
コンソール起動
$ sudo lxc-console -n uc01
おぉ? 今度は Ctrl+a q で抜けられた!まあいいか。次へ進む。
どうやらlxc-startをフォアグラウンドで起動した時のコンソールではダメで、lxc-consoleで起動したコンソールならば抜けられるようだ。
ネットワークタイプをmacvlanへ変更
デフォルトだと、仮想ネットワークが構築されて、それがホストに作られたブリッジインターフェース経由で外に出られるようになっていて、ホストから ssh 接続ができる状態。
これだと、外から uc01 へsshしたりは出来ない。
/var/lib/lxc/uc01/configを以下のように変更
lxc.network.type = veth
lxc.network.link = lxcbr0
↓
lxc.network.type = macvlan
lxc.network.link = em1 ← 普通はeth0とかになるところ。自分のShuttleではem1なのだ。
ホストの物理インターフェースに接続される。dhcpもいつものルータが担う。
ホストと同じように固定IP設定も普通にできる。
再起動
$ sudo lxc-stop -r -n uc01
確認
$ sudo lxc-ls -f
ふむ。IPアドレスが 192.168.1.31 とかになった。
コンテナから外に出れる。外部から コンテナ(uc01)へssh出来る。
ただし! ホストからはsshもpingも出来ない。
macvlanモード設定でコンテナ同士でのアクセスは出来るようになる。が、ホストはダメです。
コンテナ削除
$ sudo lxc-destroy -n uc01
なくなりました。
ここまでは全然何の問題もないっすね。あっけない。けど、裏ではものすごい技術の集合体です。
----
ユーザ権限でコンテナ作成
いくつかホスト側で設定が必要らしいが、ubuntu 14.04 だとそのほとんどは済んでいて、簡単な設定ファイルを用意するだけでよいようだ。
ユーザホームディレクトリ
$ mkdir .config/lxc
$ cp /etc/lxc/default.conf .config/lxc
$ echo "lxc.id_map = u 0 100000 65536" >> .conifig/lxc/default.conf
$ echo "lxc.id_map = g 0 100000 65536" >> .conifig/lxc/default.conf
VMWare、Xen、KVM、もっと大きなのでは AWS とかが、VMの世界だと思っておりましたが、それら全部が openstack (cloud softwre) ファミリーだったのね。
ということで、軽量でメモリもディスクもあまり使わなそうな lxc でVMっぽいものをやってみた。
lxcの先には Docker とかいうものが控えているようだけれど、まずは基礎から。
lxcの勉強には LXCで学ぶコンテナ入門 を参考にさせてもらいました。
$ sudo apt-get install lxc
すると
/etc/lxc/ 設定
/usr/share/lxc/ ディストーション設定やテンプレート
/var/lib/lxc/ ルート権限のコンテナ格納場所
/etc/init/lxc-**.conf 自動起動やらネットワーク設定やら
が作られて
upstart-file-bridge
upstart-socket-bridge
upstart-udev-bridge
cgmanager
dnsmasq
がデーモンで動き始めました。
ifconfig すると、lxcbr0 っていうコンテナのネットワークをブリッジするインターフェースが追加されているのを確認。
root権限でコンテナ作って動かしてみる
$ sudo lxc-create -t ubuntu -n uc01
/var/lib/lxc/uc01にuc01という名前のubuntuが作られた。
起動!
$ sudo lxc-start -n uc01
動いた~。デフォルトのubuntuユーザでログインしてみた。ふむふむ。sshが出来る状態なのね。
えーと、コンソールから抜けるのは??? Ctrol+a qだそうな。やってみたけど抜けられぬ。。
停止(ホスト側で)
$ sudo lxc-stop -n uc01
コンソールから抜けられなかったので、外から殺しました。
デーモン起動して
$ sudo lxc-start -n uc01 -d
コンソール起動
$ sudo lxc-console -n uc01
おぉ? 今度は Ctrl+a q で抜けられた!まあいいか。次へ進む。
どうやらlxc-startをフォアグラウンドで起動した時のコンソールではダメで、lxc-consoleで起動したコンソールならば抜けられるようだ。
ネットワークタイプをmacvlanへ変更
デフォルトだと、仮想ネットワークが構築されて、それがホストに作られたブリッジインターフェース経由で外に出られるようになっていて、ホストから ssh 接続ができる状態。
これだと、外から uc01 へsshしたりは出来ない。
/var/lib/lxc/uc01/configを以下のように変更
lxc.network.type = veth
lxc.network.link = lxcbr0
↓
lxc.network.type = macvlan
lxc.network.link = em1 ← 普通はeth0とかになるところ。自分のShuttleではem1なのだ。
ホストの物理インターフェースに接続される。dhcpもいつものルータが担う。
ホストと同じように固定IP設定も普通にできる。
再起動
$ sudo lxc-stop -r -n uc01
確認
$ sudo lxc-ls -f
ふむ。IPアドレスが 192.168.1.31 とかになった。
コンテナから外に出れる。外部から コンテナ(uc01)へssh出来る。
ただし! ホストからはsshもpingも出来ない。
macvlanモード設定でコンテナ同士でのアクセスは出来るようになる。が、ホストはダメです。
コンテナ削除
$ sudo lxc-destroy -n uc01
なくなりました。
ここまでは全然何の問題もないっすね。あっけない。けど、裏ではものすごい技術の集合体です。
----
ユーザ権限でコンテナ作成
いくつかホスト側で設定が必要らしいが、ubuntu 14.04 だとそのほとんどは済んでいて、簡単な設定ファイルを用意するだけでよいようだ。
ユーザホームディレクトリ
$ mkdir .config/lxc
$ cp /etc/lxc/default.conf .config/lxc
$ echo "lxc.id_map = u 0 100000 65536" >> .conifig/lxc/default.conf
$ echo "lxc.id_map = g 0 100000 65536" >> .conifig/lxc/default.conf
lxc.id_mapへは、/etc/subuid と /etc/subgid に書かれているユーザのサブIDを設定する。
このsubuidとかはubuntuでは普通にユーザを作成すると作られている情報。
/etc/lxc/lxc-usernet ファイルに追記
$ sudo echo "user veth lxcbr0 10" >> /etc/lxc/lxc-usernet
"user"にvethでlxcbr0を使うコンテナを10個作れる。という特権を与える設定。
vethしかダメらしい。
作成(ユーザコンテナの場合、テンプレートには download しか選べない)
$ lxc-create -n ubu01 -t download
すると、どのディストリビューション入れる?って対話で聞いてくるので、それにそって入れても良いし、分かっているなら以下のようにオプション指定してもいい。
$ lxc-create -n ubu01 -t download -d ubuntu -r trusty -a amd64
ってな感じ。
ダウンロードイメージは毎日ビルドされているものをwgetで取得してくるようだ。
起動
$ lxc-start -n ubu01 -d
$ ps aux でプロセスを見てみると、UIDが100000位上のプロセスが10数個立つ。これがユーザコンテナのプロセスだろう。lxcはホストのカーネルプロセスの一部として動くので混ざるわけだ。
実はこの時ちゃんと起動しなくて、cgmanagerがエラーを出してクラッシュした。
何か設定が悪いのか?と調べてみたところ、lxcかcgmanagerのちょっとしたバグ?なのだろうか
ホストを再起動したら、直った。
起動してもログイン出来ないよ
ルート用テンプレートとは違い、sshdも入らないし、ubuntuユーザに初期パスワード設定されていないので、起動してもログイン出来ないのだ。これはセキュリティのための対処らしい。
ubuntuユーザにパスワード設定
$ lxc-attach -n ubu01 -- sudo passwd ubuntu
lxc-attachはコンテナにデフォルトユーザでログインしたつもりで外からコマンドを実行出来る。
親切にもダウンロードコンテナ作成するとその辺のガイドとかが表示される。
書いておきながら何だけど、デフォのubuntuユーザは触らずに、新たに作ったほうがいいと思う。
$ lxc-attach -n ubu01 -- sudo adduser user1
$ lxc-attach -n ubu01 -- sudo adduser user1 sudo
な感じで。
因みに、ユーザ起動コンテナのネットワークタイプはデフォルトの veth じゃないとだめらしい。
外に出れる。ホストからアクセスできる。が、外からはアクセス出来ないってこと。
セキュリティ的には良いが、外からアクセス出来ないとちょっとつまらないので、何とかしよう。
2015/08/05
svnrdump で uuid 取得できるね
今日は、実務の中でちょっとした発見ができたので、書き残しておくと思う。
世間にとっては既知なのかもしれないが・・・
日頃仕事でリポジトリ管理にオープン系の Svn と Git を扱っている。
Svnリポジトリの引っ越しやらバックアップやらで svnsync を使って同期状態にすることが多いが
「再配置(relocate)」が出来るようにするためには、リポジトリの UUID を同じにしておく必要がある。
svnsyncが出来るまでの基本手順
なので同期したいサーバー側で実行する必要があるかと思う。
実際の同期処理の、svnsync init と svnsync syncは、リモートから実行可能なので
アクセス可能なところから適当に。
本題はそこではなくて、再配置(relocate)可能な同期リポジトリにするためには先ほど書いたように
UUID を同じにしておく必要がある。
どうやって同期元リポジトリのUUIDを取得するか?
$ svnlook uuid src_repo_path とか
$ cat src_repo_path/db/uuid とか?
どちらにせよURLではなくファイルパス指定なので、
1.同期元リポジトリが存在するサーバー上で実行してコピペ?
2.NFSとかSambaとかsshfsとか使ってマウントしてuuidコピー?
手順のスクリプト化には厄介な話だ。自分はちょっと前まで実際に sshfs で元サーバーのリポジトリをマウントしてuuidコピーする手順をスクリプト化していた。苦肉の策。
すげー簡単な方法があった! やったーと思っているのは自分だけかも・・・
svnrdump は、svndump をリモートから出来るようにしたコマンドなので、同期したい側から元リポジトリのURL指定でダンプが取れる。
ありがたいことに、どのリビジョンを取得してもダンプ情報の3行目に元のUUIDが記述されている。
UUIDを取り出したいだけなので、0番取得としている。Rev#0は属性情報だけなのでどんな
リポジトリでも一瞬でダンプが取れる。
取れさえすれば、直接uuidファイルに書き込んでもよし、svnadmin setuuid を使ってもよし。
ということで、チェックアウトせずにリモート操作で、しかも簡単にuuidを取得する方法でした。
世間にとっては既知なのかもしれないが・・・
日頃仕事でリポジトリ管理にオープン系の Svn と Git を扱っている。
Svnリポジトリの引っ越しやらバックアップやらで svnsync を使って同期状態にすることが多いが
「再配置(relocate)」が出来るようにするためには、リポジトリの UUID を同じにしておく必要がある。
svnsyncが出来るまでの基本手順
svnadminはローカルパスを指定する必要があるし、pre-revprop-changeファイル作成が必要$ svnadmin create dest_repo_path $ echo "#!/bin/sh" > dest_repo_path/hooks/pre-revprop-change $ echo "exit 0" >> dest_repo_path/hooks/pre-revprop-change $ chmod +x dest_repo_path/hooks/pre-revprop-change
なので同期したいサーバー側で実行する必要があるかと思う。
実際の同期処理の、svnsync init と svnsync sync
アクセス可能なところから適当に。
本題はそこではなくて、再配置(relocate)可能な同期リポジトリにするためには先ほど書いたように
UUID を同じにしておく必要がある。
どうやって同期元リポジトリのUUIDを取得するか?
$ svnlook uuid src_repo_path とか
$ cat src_repo_path/db/uuid とか?
どちらにせよURLではなくファイルパス指定なので、
1.同期元リポジトリが存在するサーバー上で実行してコピペ?
2.NFSとかSambaとかsshfsとか使ってマウントしてuuidコピー?
手順のスクリプト化には厄介な話だ。自分はちょっと前まで実際に sshfs で元サーバーのリポジトリをマウントしてuuidコピーする手順をスクリプト化していた。苦肉の策。
すげー簡単な方法があった! やったーと思っているのは自分だけかも・・・
$ svnrdump dump -r 0これで取れる。しかも1ラインで。{src_repo_URL} | awk -e '/UUID/ { print $2 }' > uuid_file_path
svnrdump は、svndump をリモートから出来るようにしたコマンドなので、同期したい側から元リポジトリのURL指定でダンプが取れる。
ありがたいことに、どのリビジョンを取得してもダンプ情報の3行目に元のUUIDが記述されている。
UUIDを取り出したいだけなので、0番取得としている。Rev#0は属性情報だけなのでどんな
リポジトリでも一瞬でダンプが取れる。
取れさえすれば、直接uuidファイルに書き込んでもよし、svnadmin setuuid を使ってもよし。
ということで、チェックアウトせずにリモート操作で、しかも簡単にuuidを取得する方法でした。
登録:
投稿 (Atom)