2018-02-24 13:56:18 +08:00
|
|
|
|
如何使用 cloud-init 来预配置 LXD 容器
|
2018-01-22 23:18:58 +08:00
|
|
|
|
======
|
2018-02-24 13:56:18 +08:00
|
|
|
|
|
|
|
|
|
当你正在创建 LXD 容器的时候,你希望它们能被预先配置好。例如在容器一启动就自动执行 `apt update`来安装一些软件包,或者运行一些命令。
|
|
|
|
|
|
|
|
|
|
这篇文章将讲述如何用 [cloud-init][1] 来对 [LXD 容器进行进行早期初始化][2]。
|
|
|
|
|
|
2018-01-22 23:18:58 +08:00
|
|
|
|
接下来,我们将创建一个包含cloud-init指令的LXD profile,然后启动一个新的容器来使用这个profile。
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
### 如何创建一个新的 LXD profile
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
查看已经存在的 profile:
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```shell
|
|
|
|
|
$ lxc profile list
|
|
|
|
|
+---------|---------+
|
|
|
|
|
| NAME | USED BY |
|
|
|
|
|
+---------|---------+
|
|
|
|
|
| default | 11 |
|
|
|
|
|
+---------|---------+
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
我们把名叫 `default` 的 profile 复制一份,然后在其内添加新的指令:
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```shell
|
|
|
|
|
$ lxc profile copy default devprofile
|
|
|
|
|
|
|
|
|
|
$ lxc profile list
|
|
|
|
|
+------------|---------+
|
|
|
|
|
| NAME | USED BY |
|
|
|
|
|
+------------|---------+
|
|
|
|
|
| default | 11 |
|
|
|
|
|
+------------|---------+
|
|
|
|
|
| devprofile | 0 |
|
|
|
|
|
+------------|---------+
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
我们就得到了一个新的 profile: `devprofile`。下面是它的详情:
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
$ 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: []
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
注意这几个部分: `config:` 、 `description:` 、 `devices:` 、 `name:` 和 `used_by:`,当你修改这些内容的时候注意不要搞错缩进。(LCTT 译注:因为这些内容是 YAML 格式的,缩进是语法的一部分)
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
### 如何把 cloud-init 添加到 LXD profile 里
|
|
|
|
|
|
|
|
|
|
[cloud-init][1] 可以添加到 LXD profile 的 `config` 里。当这些指令将被传递给容器后,会在容器第一次启动的时候执行。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
下面是用在示例中的指令:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
package_upgrade: true
|
|
|
|
|
packages:
|
|
|
|
|
- build-essential
|
|
|
|
|
locale: es_ES.UTF-8
|
|
|
|
|
timezone: Europe/Madrid
|
|
|
|
|
runcmd:
|
|
|
|
|
- [touch, /tmp/simos_was_here]
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
`package_upgrade: true` 是指当容器第一次被启动时,我们想要 `cloud-init` 运行 `sudo apt upgrade`。`packages:` 列出了我们想要自动安装的软件。然后我们设置了 `locale` 和 `timezone`。在 Ubuntu 容器的镜像里,root 用户默认的 `locale` 是 `C.UTF-8`,而 `ubuntu` 用户则是 `en_US.UTF-8`。此外,我们把时区设置为 `Etc/UTC`。最后,我们展示了[如何使用 runcmd 来运行一个 Unix 命令][3]。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
我们需要关注如何将 `cloud-init` 指令插入 LXD profile。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
我首选的方法是:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ lxc profile edit devprofile
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
它会打开一个文本编辑器,以便你将指令粘贴进去。[结果应该是这样的][4]:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
$ 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: []
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
### 如何使用 LXD profile 启动一个容器
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
使用 profile `devprofile` 来启动一个新容器:
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ lxc launch --profile devprofile ubuntu:x mydev
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
然后访问该容器来查看我们的指令是否生效:
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```shell
|
|
|
|
|
$ 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:~#
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
如果我们连接得够快,通过 `ps ax` 将能够看到系统正在更新软件。我们可以从 `/var/log/cloud-init-output.log` 看到完整的日志:
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Generating locales (this might take a while)...
|
|
|
|
|
es_ES.UTF-8... done
|
|
|
|
|
Generation complete.
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
以上可以看出 `locale` 已经被更改了。root 用户还是保持默认的 `C.UTF-8`,只有非 root 用户 `ubuntu` 使用了新的`locale` 设置。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
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]
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
以上是安装软件包之前执行的 `apt update`。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
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.
|
|
|
|
|
```
|
2018-02-24 13:56:18 +08:00
|
|
|
|
|
|
|
|
|
以上是在执行 `package_upgrade: true` 和安装软件包。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
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
|
|
|
|
|
```
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
以上是我们安装 `build-essential` 软件包的指令。
|
|
|
|
|
|
|
|
|
|
`runcmd` 执行的结果如何?
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
root@mydev:~# ls -l /tmp/
|
|
|
|
|
total 1
|
|
|
|
|
-rw-r--r-- 1 root root 0 Jan 3 15:23 simos_was_here
|
|
|
|
|
root@mydev:~#
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
可见它已经生效了!
|
|
|
|
|
|
|
|
|
|
### 结论
|
|
|
|
|
|
2018-02-24 13:56:18 +08:00
|
|
|
|
当我们启动 LXD 容器的时候,我们常常需要默认启用一些配置,并且希望能够避免重复工作。通常解决这个问题的方法是创建 LXD profile,然后把需要的配置添加进去。最后,当我们启动新的容器时,只需要应用该 LXD profile 即可。
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
via: https://blog.simos.info/how-to-preconfigure-lxd-containers-with-cloud-init/
|
|
|
|
|
|
|
|
|
|
作者:[Simos Xenitellis][a]
|
|
|
|
|
译者:[kaneg](https://github.com/kaneg)
|
2018-02-24 13:56:18 +08:00
|
|
|
|
校对:[wxy](https://github.com/wxy)
|
2018-01-22 23:18:58 +08:00
|
|
|
|
|
|
|
|
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
|
|
|
|
|
|
|
|
|
[a]:https://blog.simos.info/author/simos/
|
|
|
|
|
[1]:http://cloudinit.readthedocs.io/en/latest/index.html
|
|
|
|
|
[2]:https://github.com/lxc/lxd/blob/master/doc/cloud-init.md
|
|
|
|
|
[3]:http://cloudinit.readthedocs.io/en/latest/topics/modules.html#runcmd
|
|
|
|
|
[4]:https://paste.ubuntu.com/26313399/
|