如何在供应启动时在Linux容器(LXD)实例上运行命令

时间:2020-01-09 10:43:30  来源:igfitidea点击:

如何执行常见的自动化配置任务,并在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