当你正在创建 LXD 容器的时候,你希望它们能被预先配置好。例如在容器一启动就自动执行 apt update
来安装一些软件包,或者运行一些命令。
这篇文章将讲述如何用 cloud-init 来对 LXD 容器进行进行早期初始化 。
接下来,我们将创建一个包含cloud-init指令的LXD profile,然后启动一个新的容器来使用这个profile。
如何创建一个新的 LXD profile 查看已经存在的 profile:
1 2 3 4 5 6 7 $ lxc profile list +---------|---------+ | NAME | USED BY | +---------|---------+ | default | 11 | +---------|---------+
我们把名叫 default
的 profile 复制一份,然后在其内添加新的指令:
1 2 3 4 5 6 7 8 9 10 11 $ lxc profile copy default devprofile $ lxc profile list +------------|---------+ | NAME | USED BY | +------------|---------+ | default | 11 | +------------|---------+ | devprofile | 0 | +------------|---------+
我们就得到了一个新的 profile: devprofile
。下面是它的详情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ lxc profile show devprofileconfig: environment.TZ: "" description: Default LXD profiledevices: eth0: nictype: bridged parent: lxdbr0 type: nic root: path: / pool: default type: diskname: devprofileused_by: []
注意这几个部分: config:
、 description:
、 devices:
、 name:
和 used_by:
,当你修改这些内容的时候注意不要搞错缩进。(LCTT 译注:因为这些内容是 YAML 格式的,缩进是语法的一部分)
如何把 cloud-init 添加到 LXD profile 里 cloud-init 可以添加到 LXD profile 的 config
里。当这些指令将被传递给容器后,会在容器第一次启动的时候执行。
下面是用在示例中的指令:
1 2 3 4 5 6 7 8 package_upgrade : truepackages :- build-essentiallocale : es_ES.UTF-8timezone : Europe/Madridruncmd :- [touch, /tmp/simos_was_here]
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 命令 。
我们需要关注如何将 cloud-init
指令插入 LXD profile。
我首选的方法是:
1 2 $ lxc profile edit devprofile
它会打开一个文本编辑器,以便你将指令粘贴进去。结果应该是这样的 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ lxc profile show devprofile config : environment.TZ : "" user.user-data : | 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
来启动一个新容器:
然后访问该容器来查看我们的指令是否生效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ 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
看到完整的日志:
1 2 3 4 Generating locales (this might take a while )... es_ES.UTF-8. .. done Generation complete.
以上可以看出 locale
已经被更改了。root 用户还是保持默认的 C.UTF-8
,只有非 root 用户 ubuntu
使用了新的locale
设置。
1 2 3 4 Hit: 1 http:Get: 2 http:Get: 3 http:
以上是安装软件包之前执行的 apt update
。
1 2 3 4 5 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
和安装软件包。
1 2 3 4 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
执行的结果如何?
1 2 3 4 5 root@mydev :~ 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中国 荣誉推出