如何使用 cloud-init 來預配置 LXD 容器

Simos Xenitellis發表於2018-02-24

當你正在建立 LXD 容器的時候,你希望它們能被預先配置好。例如在容器一啟動就自動執行 apt update來安裝一些軟體包,或者執行一些命令。

這篇文章將講述如何用 cloud-init 來對 LXD 容器進行進行早期初始化

接下來,我們將建立一個包含cloud-init指令的LXD profile,然後啟動一個新的容器來使用這個profile。

如何建立一個新的 LXD profile

檢視已經存在的 profile:

$ lxc profile list
+---------|---------+
| NAME    | USED BY |
+---------|---------+
| default | 11      |
+---------|---------+

我們把名叫 default 的 profile 複製一份,然後在其內新增新的指令:

$ lxc profile copy default devprofile

$ lxc profile list
+------------|---------+
| NAME       | USED BY |
+------------|---------+
| default    | 11      |
+------------|---------+
| devprofile | 0       |
+------------|---------+

我們就得到了一個新的 profile: devprofile。下面是它的詳情:

$ lxc profile show devprofile
config:
 environment.TZ: ""
description: Default LXD profile
devices:
 eth0:
 nictype: bridged
 parent: lxdbr0
 type: nic
 root:
 path: /
 pool: default
 type: disk
name: devprofile
used_by: []

注意這幾個部分: config:description:devices:name:used_by:,當你修改這些內容的時候注意不要搞錯縮排。(LCTT 譯註:因為這些內容是 YAML 格式的,縮排是語法的一部分)

如何把 cloud-init 新增到 LXD profile 裡

cloud-init 可以新增到 LXD profile 的 config 裡。當這些指令將被傳遞給容器後,會在容器第一次啟動的時候執行。

下面是用在示例中的指令:

 package_upgrade: true
 packages:
 - build-essential
 locale: es_ES.UTF-8
 timezone: Europe/Madrid
 runcmd:
 - [touch, /tmp/simos_was_here]

package_upgrade: true 是指當容器第一次被啟動時,我們想要 cloud-init 執行 sudo apt upgradepackages: 列出了我們想要自動安裝的軟體。然後我們設定了 localetimezone。在 Ubuntu 容器的映象裡,root 使用者預設的 localeC.UTF-8,而 ubuntu 使用者則是 en_US.UTF-8。此外,我們把時區設定為 Etc/UTC。最後,我們展示了如何使用 runcmd 來執行一個 Unix 命令

我們需要關注如何將 cloud-init 指令插入 LXD profile。

我首選的方法是:

$ lxc profile edit devprofile

它會開啟一個文字編輯器,以便你將指令貼上進去。結果應該是這樣的

$ lxc profile show devprofile
config:
  environment.TZ: ""
  user.user-data: |
    #cloud-config
    package_upgrade: true
    packages:
      - build-essential
    locale: es_ES.UTF-8
    timezone: Europe/Madrid
    runcmd:
      - [touch, /tmp/simos_was_here]
description: Default LXD profile
devices:
  eth0:
    nictype: bridged
    parent: lxdbr0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: devprofile
used_by: []

如何使用 LXD profile 啟動一個容器

使用 profile devprofile 來啟動一個新容器:

$ lxc launch --profile devprofile ubuntu:x mydev

然後訪問該容器來檢視我們的指令是否生效:

$ lxc exec mydev bash
root@mydev:~# ps ax
 PID TTY STAT TIME COMMAND
 1 ? Ss 0:00 /sbin/init
 ...
 427 ? Ss 0:00 /usr/bin/python3 /usr/bin/cloud-init modules --mode=f
 430 ? S 0:00 /bin/sh -c tee -a /var/log/cloud-init-output.log
 431 ? S 0:00 tee -a /var/log/cloud-init-output.log
 432 ? S 0:00 /usr/bin/apt-get --option=Dpkg::Options::=--force-con
 437 ? S 0:00 /usr/lib/apt/methods/http
 438 ? S 0:00 /usr/lib/apt/methods/http
 440 ? S 0:00 /usr/lib/apt/methods/gpgv
 570 ? Ss 0:00 bash
 624 ? S 0:00 /usr/lib/apt/methods/store
 625 ? R+ 0:00 ps ax
root@mydev:~#

如果我們連線得夠快,通過 ps ax 將能夠看到系統正在更新軟體。我們可以從 /var/log/cloud-init-output.log 看到完整的日誌:

Generating locales (this might take a while)...
 es_ES.UTF-8... done
Generation complete.

以上可以看出 locale 已經被更改了。root 使用者還是保持預設的 C.UTF-8,只有非 root 使用者 ubuntu 使用了新的locale 設定。

Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]

以上是安裝軟體包之前執行的 apt update

The following packages will be upgraded:
 libdrm2 libseccomp2 squashfs-tools unattended-upgrades
4 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 211 kB of archives.

以上是在執行 package_upgrade: true 和安裝軟體包。

The following NEW packages will be installed:
 binutils build-essential cpp cpp-5 dpkg-dev fakeroot g++ g++-5 gcc gcc-5
 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl

以上是我們安裝 build-essential 軟體包的指令。

runcmd 執行的結果如何?

root@mydev:~# ls -l /tmp/
total 1
-rw-r--r-- 1 root root 0 Jan 3 15:23 simos_was_here
root@mydev:~#

可見它已經生效了!

結論

當我們啟動 LXD 容器的時候,我們常常需要預設啟用一些配置,並且希望能夠避免重複工作。通常解決這個問題的方法是建立 LXD profile,然後把需要的配置新增進去。最後,當我們啟動新的容器時,只需要應用該 LXD profile 即可。


via: https://blog.simos.info/how-to-preconfigure-lxd-containers-with-cloud-init/

作者:Simos Xenitellis 譯者:kaneg 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關文章