如何在供应启动时在Linux容器(LXD)实例上运行命令
如何执行常见的自动化配置任务,并在LXD实例启动后运行命令/脚本。
如何在启动时使用cloud-init在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配置文件
在此示例中,Im将设置我的lxc主机名,更新我的系统,并将ssh密钥安装到用户.ssh/authorized_keys,以便他们无需密码即可登录:
$ vi config.xml
第一行必须是"#cloud-config":
#cloud-config
接下来,如何在首次启动时运行apt-get upgrade,以下载并安装我的Linux容器的所有安全更新,因此添加:
# Apply updates using apt package_upgrade: true
设置主机名和域名并更新/etc/hosts文件:
# Set hostname hostname: foo fqdn: foo.theitroad.com manage_etc_hosts: true
首次启动时运行以下命令。
在这种情况下,更新sshd以仅侦听专用IP并重新加载sshd,然后追加:
#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
最后,安装一个用于登录Hyman的ssh-key,并将Hyman也添加到sudo文件中,追加:
# User setup users: - name: Hyman 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.theitroad.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: Hyman\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