如何在配置启动时在 Linux 容器 (LXD) 实例上运行命令
当您使用 lxc 命令启动实例时,LXD 可以使用 cloud-init 指令在第一次启动周期运行命令或脚本。
什么是 cloud-init?
cloud-init 处理云实例(包括 LXD 和 Linux 容器)的早期初始化。默认情况下,cloud-init 安装在 Ubuntu/CentOS 和所有其他主要云映像中。使用 cloud-init,您可以配置:
lxc/lxd 的示例 cloud-init 文件
- 主机名
- 更新系统
- 安装其他软件包
- 生成 ssh 私钥
- 将 ssh 密钥安装到用户的 .ssh/authorized_keys 中,以便他们无需密码即可登录
- 配置静态 IP 或网络
- 包括用户/群组
- 创建文件
- 安装并运行厨师菜谱
- 设置并运行 Puppet
- 添加 apt 或 yum 存储库
- 首次启动时运行命令
- 磁盘设置
- 配置 RHN 订阅等等。
让我们从一个例子开始。
步骤1:创建lxc容器
输入以下命令来创建一个名为 foo 的 Ubuntu LXC 容器(但暂时不要运行 lxc 容器):
$ lxc init ubuntu: foo
也可以创建基于 CentOS 7 的 Linux 容器:
$ lxc init images:centos/7/amd64 bar
您也可以应用某些配置文件:
$ lxc init images:ubuntu/xenial/amd64 C2 -p staticlanwan
步骤 2:创建 yml cloud-init 配置文件
在这个例子中,我将设置我的 lxc 主机名、更新我的系统,并将 ssh 密钥安装到用户的 .ssh/authorized_keys,以便他们无需密码即可登录:
$ vi config.xml
第一行必须是#cloud-config:
#cloud-config
接下来,我想在第一次启动时运行“apt-get upgrade”以下载并安装我的 Linux 容器的所有安全更新,因此附加:
设置主机名和域名并更新 /etc/hosts 文件:
第一次启动时运行以下命令。在本例中,更新 sshd 以仅监听私有 IP 并重新加载 sshd,附加:
# Apply updates using apt
package_upgrade: true
# Set hostname
hostname: foo
fqdn: foo.example.com
manage_etc_hosts: true
#Run command on first boot only bootcmd: - [sh, -c, "echo 'ListenAddress 192.168.1.100' >> /etc/ssh/sshd_config"] - systemctl reload ssh
您可以按如下方式安装 php7 和 nginx 包,并附加:
# Install packages packages: - nginx - php-common - php7.0 - php7.0-cli - php7.0-common - php7.0-fpm - php7.0-gd - php7.0-mysql - php7.0-opcache - php-pear
最后,为 vivek 登录安装一个 ssh-key,并将 vivek 也添加到 sudo 文件中,附加:
# User setup users: - name: vivek ssh-authorized-keys: - ***insert-your-key-here**** sudo: ['ALL=(ALL) NOPASSWD:ALL'] groups: sudo shell: /bin/bash
保存并关闭文件。
步骤 3:将 cloud-init 指令传递给包含用户数据的实例
您需要为 foo Linux 容器设置一个 user.user-data 变量,如下所示:
$ lxc config set foo user.user-data - < config.yml
要查看 foo 容器的 lxc 配置,请运行:
$ lxc config show foo
示例输出:
name: foo profiles: - default config: user.user-data: "#cloud-config\npackage_upgrade: true\n\n#Set hostname\nhostname: foo\nfqdn: foo.example.com\nmanage_etc_hosts: true\n\n#Run command on first boot only\nbootcmd:\n - [sh, -c, \"echo 'ListenAddress 192.168.1.100' >> /etc/ssh/sshd_config\"]\n - systemctl reload ssh\n \n# Install packages\npackages:\n - nginx\n - php-common\n - php7.0\n - php7.0-fpm\n - php7.0-gd\n - php7.0-mysql\n\n# User setup\nusers:\n - name: vivek\n ssh-authorized-keys:\n - ***insert-your-key-here****\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n groups: sudo\n shell: /bin/bash\n\n" volatile.apply_template: create volatile.base_image: 315bedd32580c3fb79fd2003746245b9fe6a8863fc9dd990c3a2dc90f4930039 volatile.eth0.hwaddr: 00:16:3e:3d:d9:47 volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]' devices: root: path: / type: disk ephemeral: false
步骤 4:启动容器
输入以下命令:
$ lxc start foo
等待2-5分钟。运行上述所有任务。
步骤 5:验证
要登录 foo LXC,请输入:
$ lxc exec foo bash
验证 sshd 是否绑定到私有 IP:
$ netstat -tulpn
验证软件包是否已安装且系统是否已更新:
$ sudo tail -f /var/log/apt/history.log
关于 LXD 无法与 cloud-init 一起使用的说明
请注意,LXD 中的 cloud-init 在网络启动后触发。换句话说,如果网络定义为 DHCP 或静态但无法获取 IP 地址,则可能导致 cloud-init 挂断。它会在没有太多警告的情况下失败。按照步骤 #4 中所述,在第一次启动容器之前设置以下命令:
$ lxc config set foo user.network_mode link-local
$ lxc start foo
LXD 的日志文件
如果您在使用 cloud-init 或 cloud-config 时遇到问题,请查看以下日志文件:
$ lxc exec foo bash
您可以在此处查看 cloud-init 处理配置文件的实际进程日志:
# tail -f /var/log/cloud-init.log
您的命令输出可以在此处找到:
# tail -f /var/log/cloud-init-output.log
我需要在主机服务器上安装 cloud-init 包吗?
不。
参考:
- Cloud-init 文档
- 云配置示例
- LXD 键/值配置信息
- LXD 主页
- LXD 容器管理程序
- 参见 lxc 命令手册页
- 在 Ubuntu 16.04 LTS 上安装 LXD 容器管理程序
- 如何在 Fedora Linux 26 上安装和设置 LXC(Linux 容器)
- 在KVM或Xen虚拟机下设置LXD容器
- 列出 LXD(Linux 容器)中的 VM 映像
- 升级由 Ubuntu/Debian 或 CentOS Linux 驱动的 LXD 容器
- 在 Linux 启动时自动启动 LXD 容器
- 重命名 LXD / LXC 容器的命令
- 在配置启动时在 Linux 容器 (LXD) 实例上运行命令
- 在云实例启动时,使用 shell 脚本中的 LXD(Linux 容器)创建 VM
- 将 LXD VM 移动/迁移到 Linux 上的另一台主机
- Fedora 安装并设置 LXD
- CentOS 7.x 安装并设置 LXD 服务器
- 在 Ubuntu 18.04 LTS 上安装 LXD 纯容器管理程序
- 使用 lxc 命令为 LXD 创建快照
- 在 CentOS/RHEL 8 上设置并安装 LXD
- Ubuntu 20.04 LTS 安装并设置 LXD
- 完整备份和恢复 LXD 容器
- 禁用 LXD 桥上的防火墙和 NAT 规则
- 使用 lxc 删除或移除 LXD 容器
- Linux 文件系统错误:事务失败解决方案
- Ubuntu 22.04 LTS 设置 LXD
- Debian 11 设置 LXD