コンテナ環境というとkubernetesやdockerばかりが取り上げられますが、開発環境という意味では向いていません。
LXD/LXCは「システムコンテナ」であり、docker等のような「アプリケーションコンテナ」とは異なります。
- アプリケーションコンテナ:
マイクロサービスのアプリケーション毎にコンテナを持ち、アプリケーションの停止とともにコンテナも廃棄される - システムコンテナ:
コンテナ内でシステムが起動していて、利用方法はVM(仮想マシン)に似ているが、コンテナ型なのでVMよりパフォーマンス優位
これらの特徴から考えて、アプリケーションの開発環境はLXDの方が向いています。コンテナを開発プロジェクト毎に作れば、開発環境をクリーンに保つこともできて精神的にも良いですね。
この記事では、LXDのインストール、仮想環境の立ち上げ(cloud-init)、使い方を紹介していきます。
- インストール前の環境
- LXDインストール
- LXDコンテナ作成
- cloud-initを使ったLXDコンテナ作成時の事前設定
- LXDのいろいろな設定
- LXDコマンドまとめ:チートシート
- LXDコンテナは最強の開発環境
インストール前の環境
PCは、普段から使ってるデスクトップPCです。機種の詳細は別のブログ記事を参照してください。

超小型PC(Intel NUC)のLinux系の開発環境構築記事です。第一回目はOSインストールです。デュアルブート環境にします!
OS: Ubuntu 20.04 LTS (Desktop)
LXDインストール
Ubuntu 20.04からLXDのインストールがsnap推奨になっているのでsnapでインストールします。
LXDのストレージで使うbtrfsはaptで入れます。(統一されてないのが気持ち悪いですね。)
~$ sudo snap install lxd
~$ sudo apt install btrfs-progs
LXDのコンフィグの初期化をします。すべてデフォルト設定で良いです。
~$ sudo lxd init
デフォルトですすめて、最後にyamlで設定を表示するところでyesと回答すると以下のような設定になっていることが確認できます。
config: {}
networks:
- config:
ipv4.address: auto
ipv6.address: auto
description: ""
name: lxdbr0
type: ""
storage_pools:
- config:
size: 30GB
description: ""
name: default
driver: btrfs
profiles:
- config: {}
description: ""
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
cluster: null
LXDコンテナ作成
LXDコンテナは、たくさんあるコンテナイメージを使って作成されます。
どのようなコンテナイメージがあるかを見ていきましょう。
まずはイメージを保持してるリモートリポジトリにどんなところが登録されているのか見てみます
~$ sudo lxc remote list
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| NAME | URL | PROTOCOL | AUTH TYPE | PUBLIC | STATIC |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| images | https://images.linuxcontainers.org | simplestreams | none | YES | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| local (default) | unix:// | lxd | file access | NO | YES |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| ubuntu | https://cloud-images.ubuntu.com/releases | simplestreams | none | YES | YES |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| ubuntu-daily | https://cloud-images.ubuntu.com/daily | simplestreams | none | YES | YES |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
images内にどんなイメージがあるか見てみます。
~$ sudo lxc image alias list images:
めっちゃ出てきますね。。。。
今回は、ubuntu 20.04のcloud対応イメージを使いたいので検索してみます。
~$ sudo lxc image alias list images:ubuntu/20.04/cloud
+----------------------------+--------------+-----------------+-------------+
| ALIAS | FINGERPRINT | TYPE | DESCRIPTION |
+----------------------------+--------------+-----------------+-------------+
| ubuntu/20.04/cloud | 79d1b80de78b | CONTAINER | |
+----------------------------+--------------+-----------------+-------------+
| ubuntu/20.04/cloud | b76405f72d76 | VIRTUAL-MACHINE | |
+----------------------------+--------------+-----------------+-------------+
| ubuntu/20.04/cloud/amd64 | 79d1b80de78b | CONTAINER | |
+----------------------------+--------------+-----------------+-------------+
| ubuntu/20.04/cloud/amd64 | b76405f72d76 | VIRTUAL-MACHINE | |
手動で一つ立ち上げてみましょう。(ubuというコンテナ名でubuntu/20.04/cloudイメージで立ち上げ)
~$ sudo lxc launch images:ubuntu/20.04/cloud ubu
~$ sudo lxc list
+-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
| ubu | RUNNING | 10.246.9.113 (eth0) |fd42:6aab:85bc:47ba:216:3eff:fe98:1c93 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
コンテナのIPアドレスは、コンテナ向けプライベートアドレスから勝手に割り振られます。(僕の環境ではIPv4 10.246.9.xxx)
コンテナ向けのアドレスの確認方法は次のようになります。(ブリッジインタフェースのlxdbr0を確認する)
~$ sudo lxc network show lxdbr0
config:
ipv4.address: 10.246.9.1/24
ipv4.nat: "true"
ipv6.address: fd42:6aab:85bc:47ba::1/64
ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
:
この出来上がったコンテナに入る方法は、lxcコマンド経由か、ネットワーク経由になります。
作ったばかりではsshの設定ができていないので、最初はlxcコマンド経由でコンテナに入り、そこで各種セットアップ作業を行うことになります。
~$ sudo lxc exec ubu bash
root@ubu:~# ls
root@ubu:~#
後は、aptでopenssh-server入れてssh設定を行えばssh 10.246.9.113
といったコマンドで接続できるようになります。
次のセクションでは事前設定付きでコンテナを立ち上げるので、現在のコンテナを消しておきましょう。
~$ sudo lxc stop ubu
~$ sudo lxc delete ubu
cloud-initを使ったLXDコンテナ作成時の事前設定
Ubuntuのcloudイメージはcloud-initと呼ばれるコンテナの最初の起動時に設定を自動で行ってくれる便利な機能に対応しています。
そこで、LXDコンテナ作成時にすぐにssh接続できるように初期設定をcloud-initを使って投入します。
方法1: LXD profileを利用する
LXDでコンテナ作成する場合、通常は「default」プロファイルというlxd init
で作成したプロファイルが利用されますが、別のプロファイルを作成することも可能です。以下のコマンドで作成、編集ができます。
~$ lxc profile create cloud-profile #作成
~$ lxc profile edit cloud-profile #編集
編集する内容を以下のようにするとssh接続が自動でできるようになります。
config:
user.user-data: |
#cloud-config
hostname: ubu
locale: ja_JP.utf8
timezone: Asia/Tokyo
package_upgrade: true
package_reboot_if_required: true
users:
- name: hoge
uid: 1000
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- <host pcのssh pub key >
packages:
- openssh-server
description: my default container
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
name: cloud-profile
used_by: []
作成したプロファイルでコンテナを作成する場合は-p プロファイル名
を付けます
~$ sudo lxc launch images:ubuntu/20.04/cloud ubu -p cloud-profile
コンテナが出来上がったらsshしてみましょう。
~$ sudo lxc list
+--------+---------+---------------------+-----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------+---------+---------------------+-----------------------------------------------+-----------+-----------+
| ubu | RUNNING | 10.246.9.174 (eth0) | fd42:6aab:85bc:47ba:216:3eff:febb:2c51 (eth0) | CONTAINER | 0 |
+--------+---------+---------------------+-----------------------------------------------+-----------+-----------+
~$ ssh 10.246.9.174
The authenticity of host '10.246.9.174 (10.246.9.174)' can't be established.
ECDSA key fingerprint is ......
さらに別の方法を試します。一旦、今のコンテナを消しましょう。
~$ sudo lxc stop ubu
~$ sudo lxc delete ubu
方法2: コンテナ作成時にcloud-initのyamlファイルを読み込ませる
この方法はコンテナをデフォルトで作成(ただし、作成するだけで立ち上げない)、その後、cloud-initを読み込ませる方法です。
~$ sudo lxc init images:ubuntu/20.04/cloud ubu #launchではなくinitを使う
~$ lxc config set ubu user.user-data - < lxd-cloud-config.yaml
~$ lxc start ubu
ここで読み込ませるlxd-cloud-config.yamlは、以下のようなファイルです。
#cloud-config
hostname: ubu
locale: ja_JP.utf8
timezone: Asia/Tokyo
package_upgrade: true
package_reboot_if_required: true
users:
users:
- name: hoge
uid: 1000
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- <host pcのssh pub key >
packages:
- openssh-server
方法1と同じことをしているのですが、yamlが外部ファイルにある方が管理はしやすいかもしれません。
LXDのいろいろな設定
LXDホストとファイル共有
LXDコンテナとホストでファイル共有するためには、お互いが同じuid/gidを使うアカウントが必要になります。
今回cloud-initでuid: 1000
をしていしてuserを作成していますが、ubuntuでは初期ユーザが1000番になるため、それを利用します。
まず、ホストとコンテナで同じidになっているか確認します。
~$ id
uid=1000(hoge) gid=1000(hoge) groups=1000(hoge)...
~$ ssh 10.246.9.174
hoge@ubu:~$ id
uid=1000(hoge) gid=1000(hoge) groups=1000(hoge)
同じidになっているので、host/containerで共通だということを知らせる設定をします。
さらにディスクをシェア設定します。
~$ sudo lxc config set ubu raw.idmap 'both 1000 1000';
~$ sudo lxc config device add ubu my_share disk source=/data/my_share path=/my_share;
これでホスト側/data/my_share
においたファイルがコンテナ側/my_share
で共有されます。
LXDホストの外部インタフェースへの接続
ホストの外部インタフェース(例:192.168.0.10)のポート(例:8080)に来た接続をコンテナ(例:10.246.9.10)のポート(例:8888)につなぎたいといった場合の設定です。
lxcのproxy機能を使います。
# lxc config device add <container> <proxy name> proxy listen=tcp:<host ip>:<host port> connect=tcp:<container ip>:<container port> bind=host
lxc config device add ubu http8080 proxy listen=tcp:192.168.0.10:8080 connect=tcp:10.246.9.10:8888 bind=host
この方法を使うと、外部からのsshを転送したり、webサービスを外部に公開したりできるようになりますね。
LXDコマンドまとめ:チートシート
LXDのコマンドはlxcです。よく使うコマンドの一覧を載せておきます。
コマンド | 意味 |
---|---|
lxc list | 現在のコンテナの一覧 |
lxc start <container> | containerを起動 |
lxc stop <container> | containerを停止 |
lxc delete <container> | containerを削除 |
lxc profile list | profileの一覧 |
lxc profile create <profile> | profileを作成 |
lxc profile edit <profile> | profileを編集 |
lxc profile delete <profile> | profileを削除 |
lxc launch <image> <container> -p <profile> | imageとprofileを使ってcontainerを作成、起動 |
lxc init <image> <container> -p <profile> | imageとprofileを使ってcontainerを作成 |
lxc network list | ネットワークの一覧 |
lxc network <interface> | ネットワークinterfaceの詳細 |
lxc storage list | ストレージのリスト |
lxc exec <container> bash | containerに入ってbash起動。その後container内作業可能 |
lxc file push <local file> <container>/path/of/container/ | local fileをcontainerの/path/of/container/にコピー |
lxc remote list | イメージリポジトリの一覧 |
lxc image alias list <repo>:<search> | repoリポジトリの中のsearchに一致するイメージをリスト |
lxc config device add/set/delete <container> | containerにデバイス(network, storage等)を追加・変更・削除する |
LXDコンテナは最強の開発環境
特定のバージョンの特定のOSでいつでも開発環境を作ったり消したりできる便利さを体験できると、今までの環境がいろいろなモジュールで汚れた環境に見えてきます笑
ようこそLXDの世界へ!