在 cloud-init 中创建 systemd 单元并启用它

Create systemd unit in cloud-init and enable it

我在 cloud-init 文件中创建了以下 systemd 单元:

- path: /etc/systemd/system/multi-user.target.wants/docker-compose.service
  owner: root:root
  permissions: '0755'
  content: |
      [Unit]
      Description=Docker Compose Boot Up
      Requires=docker.service
      After=docker.service

      [Service]
      Type=simple
      ExecStart=/usr/local/bin/docker-compose -f /opt/data/docker-compose.yml up -d
      Restart=always
      RestartSec=30

      [Install]
      WantedBy=multi-user.target

当我尝试 运行

sudo systemctl enable docker-compose.service

创建符号链接我得到这个:

Failed to execute operation: No such file or directory

不过我确定该文件在 /etc/systemd/system/multi-user.target.wants

检查涉及的每个文件是否存在且有效:

 ls -l  /etc/systemd/system/multi-user.target.wants/docker-compose.service
 ls -l /usr/local/bin/docker-compose
 ls -l /opt/data/docker-compose.yml
 systemd-analyze verify /etc/systemd/system/multi-user.target.wants/docker-compose.service

还要考虑时机。即使文件一旦完全启动就存在,当 cloud-init 运行时 /etc/systemd/system/multi-user.target.wants/ 是否存在?

在创建单元文件之后但在对其进行任何操作之前,应将更改通知 systemd:

systemctl daemon-reload

因此创建 docker-compose.service 文件的 cloud-init YAML 块应后跟:

runcmd:
- systemctl daemon-reload

我有同样的需求,但我正在按照一个食谱工作,该食谱说要创建 /etc/systemd/system/unit.service 然后执行 systemctl enable --now unit

所以我用 write_files 创建了单元文件,并在 text/x-shellscript 部分重新加载和启用,效果很好。 (用户脚本 运行 最后并按顺序排列,虽然我认为不能保证何时处理用户数据中的 write_files 键。我发现它在 user 密钥,因此您无法为 cloud-init 创建的用户设置所有权)。

我认为 runcmd 条目按列表顺序转换为用户脚本和 运行(在其他用户脚本之前或之后),所以如果您不喜欢 x-shellscript您可以重新加载并以这种方式启用的部分。 /var/log/cloud-init.log 是我检查顺序的地方,可能还有一个配置文件。

完全披露:我忘记了 systemctl daemon-reload 命令,但它仍然有效。实际上有一个警告来自 cloud-init 的 systemd 操作,因为它 运行ning 在 systemd 本身下,一些 systemd 命令可能等待 cloud-init 完成——死锁!