Metonymical Deflection

ゆるく日々のコト・たまにITインフラ

CentOS7でLXC/LXDのコンテナ環境構築

CentOS7上でLXC/LXDのコンテナ環境を構築しました。
LXC/LXDはUbuntuメインですが、CentOSにおいてもsnapを使用することにより遜色なく使えたため、記事として残しておきます。

Windows版VMWareWorkstation12上でCentOS7.5を稼働させて構築しましたが、同様の手順でベアメタルサーバ上にも構築できます。

1.環境

1-1.VMWare
筐体                             : 自作PC
CPU                           : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
VMWare              : VMware(R) Workstation 12 Pro 12.5.9 build-7535481  
OS                               : CentOS7.5(1804)
Kernel                           : 3.10.0-862.el7.x86_64
Installed Environment Groups     : Minimal Install

WinおよびVMWare環境は以下の画像で確認してもらった方が良いかもしれません。
Win環境
f:id:metonymical:20180529200243j:plain
VMWare環境
f:id:metonymical:20181021182810j:plain
50GBのOS用とは別に100GBのHDDを追加しています。
これを母体(KVMで言うホストOS)として、LXC/LXD環境を構築していきます。

1-3.全体の流れ

事前準備
Kernelのアップグレード
snapd&LXDのインストール
コンテナのインストール

2.事前準備

2-1.セキュリティ設定の無効化

firewalldとSELinuxを無効化します。

sed -i -e "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
systemctl stop firewalld
systemctl disable firewalld

また、ここでは触れませんが、chronyなどで時刻同期を行ってください。

3.Kernelのアップグレード

Linux Containers
上記公式サイトのRequirementを読む限り、Kernel3.13以降でないとダメなようです。実際、CentOS7のKernel3.10系のままで進めると、LXDのインストール時に確実に止まってしまいます。このため、少々しんどいですが、Kernelのアップグレードを実施します。

3-1.リポジトリの登録
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

GPG-KeyとELRepoの登録を実施。

# yum list installed | grep kernel
kernel.x86_64                         3.10.0-862.el7                   @anaconda
kernel-tools.x86_64                   3.10.0-862.el7                   @anaconda
kernel-tools-libs.x86_64              3.10.0-862.el7                   @anaconda

現在インストールされているKernelのバージョンを確認

3-2.Kernelのアップグレード
yum --enablerepo=elrepo-kernel install kernel-ml

最新Kernelのインストール*1

# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
0 : CentOS Linux (4.18.12-1.el7.elrepo.x86_64) 7 (Core)
1 : CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)
2 : CentOS Linux (0-rescue-626b869879714a9cbe128e5b6f85dd89) 7 (Core)

# grub2-set-default 0
# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.18.12-1.el7.elrepo.x86_64
Found initrd image: /boot/initramfs-4.18.12-1.el7.elrepo.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-862.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-862.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-626b869879714a9cbe128e5b6f85dd89
Found initrd image: /boot/initramfs-0-rescue-626b869879714a9cbe128e5b6f85dd89.img
done
# reboot

menuentryを確認
初期起動Kernelに4.18.12-1.el7.elrepo.x86_64を選択
grub.cfgへの反映
再起動*2

4.snapd&LXDのインストール

4-1.snapdのインストール
yum -y install epel-release && yum -y install yum-plugin-copr
yum -y copr enable ngompa/snapcore-el7 && yum -y install snapd
systemctl enable --now snapd.socket

epelとyum-plugin-coprのインストール
coprの有効化とsnapdのインストール
snapdサービスの自動起動設定

4-2.grubbyの設定
grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
grubby --args="namespace.unpriv_enable=1" --update-kernel="$(grubby --default-kernel)"
sh -c 'echo "user.max_user_namespaces=3883" > /etc/sysctl.d/99-userns.conf'
reboot

詳細は省きますが、上記はいずれもnamespaceに関連したカーネルに渡す引数を設定しています。

4-3.LXDのインストール
snap search lxd

# snap search lxd
Name             Version        Developer       Notes  Summary
lxd-demo-server  0+git.f3532e3  stgraber        -      Online software demo sessions using LXD
lxd              3.6            canonical       -      System container manager and API
satellite        0.1.2          alanzanattadev  -      Advanced scalable Open source intelligence platform

上記コマンドにより、snap上でlxdが参照できています。

ln -s /var/lib/snapd/snap /snap
snap install lxd

# snap install lxd
Ensure prerequisites for "lxd" are available                            
Ensure prerequisites for "lxd" are available                            
~省略~
Download snap "core" (5662) from channel "stable"                       
Download snap "core" (5662) from channel "stable"      3% 23.2MB/s 3.87s
~省略~
Download snap "core" (5662) from channel "stable"    100% 11.2MB/s 0.0ns
Download snap "lxd" (9239) from channel "stable"                        
Download snap "lxd" (9239) from channel "stable"       2% 15.0MB/s 4.57s
~省略~
Download snap "lxd" (9239) from channel "stable"     100% 10.4MB/s 0.0ns

snapのシンボリックリンクを張る
lxdのインストール

lxdをインストールすると上記画面のように出力されます。最初はsnapdの”core”がインストールされた後、lxdのインストールが開始されます。

また、たびたび以下のエラーが出力され、lxdサービススタートに失敗してインストールが中断する場合があります。

snap install lxd

# snap install lxd
2018-10-20T23:31:34+09:00 INFO Waiting for restart...
error: cannot perform the following tasks:
- Copy snap "lxd" data (remove /var/snap/lxd/common/ns/shmounts: device or resource busy)
- Start snap "lxd" (9239) services ([start snap.lxd.daemon.unix.socket] failed with exit status 1: Job for snap.lxd.daemon.unix.socket failed. See "systemctl status snap.lxd.daemon.unix.socket" and "journalctl -xe" for details.)

その際は、気にせず以下のコマンドを2~3回、少し時間をおきながら繰り返してみてください。

snap install lxd

以下のコマンドによりlxdがインストールされていればOKです。

snap list

# snap list
Name  Version    Rev   Developer  Notes
core  16-2.35.4  5662  canonical  core
lxd   3.6        9239  canonical  -

5.コンテナのインストール

5-1.コンテナ格納用ストレージの準備

追加の100GBストレージをfdiskしておきます。
これにより、/dev/sdb1が作成されます。このパーティションはlxd初期設定時に設定します。

fdisk /dev/sdb
n
t
w

fdisk実施
パーティションを作成
パーティションシステムIDの設定
パーティション保存

5-2.lxd初期設定

以下のコマンドにより、初期設定が開始されます。

lxd init

# lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: 
Do you want to configure a new storage pool? (yes/no) [default=yes]: 
Name of the new storage pool [default=default]: 
Name of the storage backend to use (btrfs, ceph, dir, lvm) [default=btrfs]: 
Create a new BTRFS pool? (yes/no) [default=yes]: 
Would you like to use an existing block device? (yes/no) [default=no]: yes
Path to the existing block device: /dev/sdb1
Would you like to connect to a MAAS server? (yes/no) [default=no]: 
Would you like to create a new local network bridge? (yes/no) [default=yes]: 
What should the new bridge be called? [default=lxdbr0]: 
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
Would you like LXD to be available over the network? (yes/no) [default=no]: 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] 
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: 

基本的にはEnterで進めてOKですが、前項で作成したパーティションをコンテナ格納用ストレージとして使用する場合は、上記赤文字のように指定してください。

5-3.コンテナイメージファイルの確認
lxc image list images:

# lxc image list images:
If this is your first time running LXD on this machine, you should also run: lxd init
To start your first container, try: lxc launch ubuntu:18.04
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
|             ALIAS             | FINGERPRINT  | PUBLIC |               DESCRIPTION                |  ARCH   |   SIZE   |          UPLOAD DATE          |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
| alpine/3.4 (3 more)           | cc8b58012122 | yes    | Alpine 3.4 amd64 (20180627_17:50)        | x86_64  | 2.04MB   | Jun 27, 2018 at 12:00am (UTC) |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
| alpine/3.4/armhf (1 more)     | 7813a1299900 | yes    | Alpine 3.4 armhf (20180627_17:50)        | armv7l  | 1.63MB   | Jun 27, 2018 at 12:00am (UTC) |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
| alpine/3.4/i386 (1 more)      | 612c3ece0803 | yes    | Alpine 3.4 i386 (20180627_17:50)         | i686    | 1.88MB   | Jun 27, 2018 at 12:00am (UTC) |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
| alpine/3.5 (3 more)           | 0381c3c01c04 | yes    | Alpine 3.5 amd64 (20181004_13:00)        | x86_64  | 3.05MB   | Oct 4, 2018 at 12:00am (UTC)  |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
| alpine/3.5/arm64 (1 more)     | ec3eb4f0dd1e | yes    | Alpine 3.5 arm64 (20181004_13:28)        | aarch64 | 2.96MB   | Oct 4, 2018 at 12:00am (UTC)  |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
~省略~
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
|                               | ff280c2bb726 | yes    | Ubuntu-Core 16 i386 (20180925_19:01)     | i686    | 211.07MB | Sep 25, 2018 at 12:00am (UTC) |
+-------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+

上記コマンドにより、Linux Containersにアップロードされているコンテナイメージを参照することができます。
膨大な数がありますので、ここではgrepしてcentosに絞って参照してみます。

lxc image list images: | grep -i centos

# lxc image list images: | grep -i centos
| centos/6 (3 more)             | fa9b42139279 | yes    | Centos 6 amd64 (20181004_02:16)          | x86_64  | 75.55MB  | Oct 4, 2018 at 12:00am (UTC)  |
| centos/6/i386 (1 more)        | fbcfebb4cd8e | yes    | Centos 6 i386 (20181004_02:16)           | i686    | 75.79MB  | Oct 4, 2018 at 12:00am (UTC)  |
| centos/7 (3 more)             | 15089a354969 | yes    | Centos 7 amd64 (20181004_02:16)          | x86_64  | 83.47MB  | Oct 4, 2018 at 12:00am (UTC)  |
|                               | 029f614a0679 | yes    | Centos 7 amd64 (20181002_02:16)          | x86_64  | 83.47MB  | Oct 2, 2018 at 12:00am (UTC)  |
|                               | 19dcb4a810a0 | yes    | Centos 7 amd64 (20181003_02:16)          | x86_64  | 83.47MB  | Oct 3, 2018 at 12:00am (UTC)  |
|                               | 99deb61e666e | yes    | Centos 6 i386 (20181003_02:16)           | i686    | 75.79MB  | Oct 3, 2018 at 12:00am (UTC)  |
|                               | d4afdb0e3995 | yes    | Centos 6 amd64 (20181003_02:16)          | x86_64  | 75.55MB  | Oct 3, 2018 at 12:00am (UTC)  |
|                               | f47e537c7032 | yes    | Centos 6 amd64 (20181002_02:16)          | x86_64  | 75.55MB  | Oct 2, 2018 at 12:00am (UTC)  |
|                               | fc3ce1c88403 | yes    | Centos 6 i386 (20181002_02:16)           | i686    | 75.79MB  | Oct 2, 2018 at 12:00am (UTC)  |
5-4.コンテナのインストール
lxc launch images:centos/7/amd64 lxc751

# lxc launch images:centos/7/amd64 lxc751
Creating lxc751
Retrieving image: metadata: 100% (3.20GB/s)                                            
Retrieving image: rootfs: 1% (490.01kB/s)                                            
Retrieving image: rootfs: 2% (687.27kB/s)                                            
~省略~
Retrieving image: rootfs: 100% (3.14MB/s)                                            
Starting lxc751

上記コマンドによりcentos7のコンテナインストールが完了します。
公開サーバの「images:centos/7/amd64」からイメージをDLします。
初回はDLするのに2~3分程度かかりますが、2回目以降はローカルに保存されたコンテナイメージから展開されるため早いです。
また上記の例ではコンテナに「lxc751」という名前付与しています。

起動したコンテナは以下のように確認できます。

lxc list 

# lxc list 
+--------+---------+-----------------------+--------------------------------------------+------------+-----------+
|  NAME  |  STATE  |         IPV4          |                    IPV6                    |    TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+--------------------------------------------+------------+-----------+
| lxc751 | RUNNING | 10.164.132.246 (eth0) | fd42:45:88ee:25a6:216:3eff:fe60:6a5 (eth0) | PERSISTENT |           |
+--------+---------+-----------------------+--------------------------------------------+------------+-----------+
5-5.コンテナのbashへ移動
lxc exec lxc751 bash

# lxc exec lxc751 bash
[root@lxc751 ~]# 
[root@lxc751 ~]# ip add show
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
5: eth0@if6:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:60:06:a5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.164.132.246/24 brd 10.164.132.255 scope global dynamic eth0
       valid_lft 3269sec preferred_lft 3269sec
    inet6 fd42:45:88ee:25a6:216:3eff:fe60:6a5/64 scope global mngtmpaddr dynamic 
       valid_lft 3328sec preferred_lft 3328sec
    inet6 fe80::216:3eff:fe60:6a5/64 scope link 
       valid_lft forever preferred_lft forever

上記コマンドにより、ホストOS上からコンテナのbashへ移動できます。
IPアドレスが先に参照したlxc listで起動中のコンテナと同様であることが確認できます。

以上です。

6.最後に

以下のサイトを参考にさせて頂きました。
Home - LXDドキュメント翻訳プロジェクト
How to Set Up and Use LXD on CentOS Linux 7.x Server - nixCraft
LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術:連載|gihyo.jp … 技術評論社

gihyo.jpの記事は大変よくまとまっており、LXC/LXDのアーキテクチャもさることながら、コンテナ技術そのものやNamespace機能に関する理解が深まりますので、ぜひご一読ください。

先にも書きましたが、LXC/LXDはcanonicalが推し進めていることもありUbuntuがメインとなります。ただ、CentOS7に触れる記事がとても少なかったので、残しておきたいなと思いました。

今回はLXC/LXDのインストールとコンテナのインストールまででしたが、次回はコンテナのネットワーク周りについて書きたいと思います。私は本職がNWエンジニアなので、ここが一番の肝になってくるため、Linuxのネットワーク周りについても触れたいと思っています。

lxc networkコマンドで作成したブリッジの場合、私の使い方にはあまりマッチしなかったため、nmcliコマンドでブリッジを作成した場合についても併せて書きたいと思います。

*1:2018/10/21現在、リポジトリの参照先サーバによって、Kernel4.18.12やKernel4.18.14、Kernel4.18.15などがインストールされますが、いずれも支障はありません。

*2:過去記事で書いたNVMe-oF Target構築の際、SPDKをビルドする必要があったため、kernel-tools-libs kernel-toolsなどもアップグレードしましたが、LXC/LXDではビルドが不要なため、このまま再起動してしまいます。