本記事は 新人Advent Calendar 2016 の6日目の記事です。
背景
私、インフラエンジニアなのですよ。仮想マシン立てて検証とかしたいじゃないですか。Ansibleで複数のホストをプロビジョニングとかしたいじゃないですか。
ところがですね、職場で支給されるPCが Windows 7 32bit版、メモリ 4GB とかいう貧弱なPCなんですよ。
一応、検証環境はあるんですけど、IPアドレスの申請が必要で、ちょっと試したい目的には申請・承認フローがめんどくさいし、そもそも、IPが枯渇気味らしい。
2038年まで待ってられない
ということで、仕方ないので、軽量仮想コンテナで我慢することとしています。
コンテナといえばDockerみたいな時代ではありますが、インフラエンジニア的にはシステムコンテナの LXC かなと思うわけです。
それに、ガチモンの仮想マシンより、圧倒的に速いので、自宅で環境汚したくないなぁって思う作業をするときは、LXCを使っています。
Windowsサーバーの検証を手元でやるのはすでに諦めています。
環境準備
個人的にUbuntuが大好きなので、以下、Ubuntu 16.04 でお話を進めます。
VirtualBoxで仮想マシンを適当に立てて、Ubuntuの環境を構築してください。職場ではメモリ1GBで立てています。
続いて、LXCをインストールします:
sudo apt install lxc
ためしにUbuntuのコンテナを作ってみる
実はこの段階でもうホストと同じUbuntuならLXCのコンテナが作れます。
lxcコンテナを作成する lxc-create コマンドの記法はおおよそ次の通りです:
lxc-create -n (container_name) -t (template) -- (template_options)
では実際に作ってみます:
sudo lxc-create -n ubuntu-test-container -t ubuntu -- -r xenial --mirror="http://ftp.jaist.ac.jp/ubuntu"
初回は各種パッケージのダウンロードがあるため、時間がかかりますが、2回目以降はすぐにコンテナを作成できます。-r
オプションでリリースを指定していますが、省略すると、ホストと同じリリースのコンテナが作成されます。
起動するには:
sudo lxc-start -n ubuntu-test-container
コンソールにアタッチするには:
sudo lxc-console -n ubuntu-test-container
抜けるときは:
Ctrl-Q -> A
停止するには:
sudo lxc-stop -n ubuntu-test-container
削除するときは:
sudo lxc-destroy -n ubuntu-test-container
Ubuntuのテンプレートの認証情報はデフォルトではユーザー名・パスワードともに ubuntu
です。SSHサーバーもデフォルトで入っているので、次のコマンドでIPアドレスを調べて、SSHでつなぐことができます:
sudo lxc-info -n ubuntu-test-container
また、テンプレートオプションを使って認証情報を設定することができます。次の例はコンテナ作成にユーザー名とパスワードを指定し、SSHの公開鍵を差し込むものです:
sudo lxc-create -n ubuntu-test-container -t ubuntu -- -r xenial --mirror="http://ftp.jaist.ac.jp/ubuntu" -S /home/popo/.ssh/id_rsa.pub -u popo --password password
CentOSのコンテナを作る
yumが要るので、インストールします:
sudo apt install yum
作り方自体は基本的に、Ubuntuのコンテナを作るときと同じです。
ただし、CentOSのテンプレートで作られるユーザーはrootのみで、パスワードはコンテナ作成時にランダムなものが生成され、初回ログイン時に設定することになります。
ですが、コンテナ作成時にパスワードを設定する方法もあります。こちらは既に記事にしていますので、参照してください。
各種テンプレートは /usr/share/lxc/templates に収められていますが、実体はどれもbashのスクリプトです。CentOSのパスワードの件もそうなのですが、テンプレートオプションにはないものの、いろいろ設定できるみたいなので、気になるテンプレートは覗いてみればよいと思います。
社内環境の場合はプロキシに要注意
そのままです。aptやyumにプロキシの設定が必要です。詳細はほかに譲ります。
注意点としては、設定するのはホスト側のaptやyumである点です。コンテナ作成時にはホスト側のものが使用されるからです。
使用リソース
できたてほやほやのコンテナの使用リソースは次の通りです:
Name: ubuntu-test-container
State: RUNNING
PID: 16536
IP: 10.0.3.169
CPU use: 0.58 seconds
BlkIO use: 9.12 MiB
Memory use: 20.24 MiB
KMem use: 0 bytes
Link: vethNLE20G
TX bytes: 1.23 KiB
RX bytes: 1.43 KiB
Total bytes: 2.66 KiB
メモリ使用量が少なくて良いですね。これで、4GBメモリでも仮想マシンが複数立てられます!!!!
AnsibleでLXCコンテナ作成・削除を自動化
(習作でロールにもなっていないのですが、いい感じにできたら、githubに上げます、そのうち。)
次のものをインストールします:
- sshpass(apt経由)
- ansible(pip経由)
- lxc-python2(同上)
おしながき:
- create-lxc-containers.yml
- destroy-lxc-containers.yml
- vars-containers.yml
- hosts
vars-containers.yml という名前で、立てるコンテナの情報を記載します。IPアドレスも指定しています。
注意点としては、SSH公開鍵はフルパスで指定する必要がある点です。
- containers:
- name: ubuntu01
template: ubuntu
ip_addr: 10.0.3.11
netmask_bit: 24
template_options: "-S /home/popo/.ssh/id_rsa.pub --packages python2.7"
env: {}
- name: ubuntu02
(中略)
- name: ubuntu03
(中略)
- name: centos01
template: centos
ip_addr: 10.0.3.21
netmask_bit: 24
template_options: "-R 7"
env:
root_password: "password"
root_expire_password: "no"
- name: centos02
(中略)
- name: centos03
(後略)
create-lxc-containers.yml は、vars-containers.yml 設定したコンテナ情報でコンテナを作ります。ループさせているので、設定のほうを増やせば、いくつでも立てられます。
個人的にこだわったのは、SSHのknown_hostsを操作しているところです。
というのも、コンテナを作成・削除するたびに、ホスト側のSSH公開鍵が変わるため、前の鍵の情報が残っているとエラーが出るためです。
- name: create LXC containers
hosts: localhost
vars_files:
- vars-containers.yml
tasks:
- name: lxc-create
become: true
become_method: sudo
lxc_container:
name: "{{ item.name }}"
template: "{{ item.template }}"
container_config:
- "lxc.network.ipv4={{ item.ip_addr }}/{{ item.netmask_bit }}"
template_options: "{{ item.template_options }}"
environment: "{{ item.env }}"
with_items: "{{ containers }}"
- name: delete ssh host keys from known_hosts
shell: "ssh-keygen -f ~/.ssh/known_hosts -R {{ item.ip_addr }}"
with_items: "{{ containers }}"
- name: register ssh host keys to known_hosts
shell: "ssh-keyscan -H {{ item.ip_addr }} >> ~/.ssh/known_hosts"
with_items: "{{ containers }}"
environment:
http_proxy: "http://proxy:8080"
https_proxy: "http://proxy:8080"
インベントリファイルには、コンテナを立てたあとにAnsibleで操作するための情報を含めています。(この情報はコンテナを立てるときには使いません。)
ubuntu01 ansible_ssh_host=10.0.3.11
ubuntu02 ansible_ssh_host=10.0.3.12
ubuntu03 ansible_ssh_host=10.0.3.13
centos01 ansible_ssh_host=10.0.3.21
centos02 ansible_ssh_host=10.0.3.22
centos03 ansible_ssh_host=10.0.3.23
[ubuntu]
ubuntu[01:03]
[centos]
centos[01:03]
[all:vars]
ansible_ssh_port=22
[ubuntu:vars]
ansible_user=ubuntu
ansible_python_interpreter=/usr/bin/python2.7
ansible_ssh_private_key=~/.ssh/id_rsa
ansible_sudo_pass=ubuntu
[centos:vars]
ansible_user=root
ansible_password=password
削除は destroy-lxc-containers.yml でおこないます。
- name: destroy containers
hosts: localhost
vars_files:
- vars-containers.yml
tasks:
- name: destroy containers
lxc_container:
name: "{{ item.name }}"
state: absent
with_items: "{{ containers }}"
become: true
- name: delete hosts from known_hosts
shell: "ssh-keygen -f ~/.ssh/known_hosts -R {{ item.ip_addr }}"
with_items: "{{ containers }}"
流し方は次の通りです:
ansible-playbook -i hosts (create|destroy)-lxc-containers.yml -K
ちょっと気になったこと
bash on Ubuntu on Windows でも動くのかしら~というのが気になったので、調べてみようと思いました。空き&余裕があれば、別日に記事にします。
あと、コンテナ名のubuntu-test-containersは長すぎた。
参考URL
- http://gihyo.jp/admin/serial/01/ubuntu-recipe/0226 - UbuntuでのLXCの操作方法について
- http://d.hatena.ne.jp/mrgoofy33/20110125/1295966614 - yumのプロキシ設定について
- http://qiita.com/nojima/items/2980ea490476e6fe5e23 - UbuntuのLXCテンプレートオプションについて
- http://qiita.com/kentarosasaki/items/b44b5ffb57a69085027e - Dockerと比較してLXCの紹介
- http://qiita.com/Surgo/items/709a07d68c6eafbad267 - DockerとLXCの比較
-
http://gihyo.jp/admin/serial/01/linux_containers?start=20 - LXCの技術的な解説
- http://gihyo.jp/admin/serial/01/linux_containers/0008 - このシリーズ内でとりあえず使ってみる回