Skip to Content
文档服务器cloud-init

cloud-init

cloud-init 是云实例初始化的行业标准工具,在实例首次启动时自动完成系统配置。Ubuntu 26.04 Server 默认预装 cloud-init,广泛支持 AWS、Azure、GCP、阿里云、腾讯云等云平台。

工作原理

cloud-init 在实例启动时按以下阶段执行:

  1. Generator - 检测是否在云环境中运行
  2. Local - 从本地数据源获取网络配置
  3. Network - 获取 metadata 和 user-data
  4. Config - 执行配置模块
  5. Final - 执行最终模块(如运行脚本)
# 查看 cloud-init 版本 cloud-init --version # 查看 cloud-init 状态 cloud-init status # 查看详细状态 cloud-init status --long

数据源

Metadata

由云平台提供的实例元数据,包含实例 ID、IP 地址、主机名等:

# 在 AWS EC2 中获取 metadata(IMDSv2) TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/ # 在阿里云 ECS 中获取 metadata curl http://100.100.100.200/latest/meta-data/ # 在腾讯云 CVM 中获取 metadata curl http://metadata.tencentyun.com/latest/meta-data/

User-data

用户自定义的初始化配置,支持多种格式。

user-data 配置

Cloud-config 格式(最常用)

以 #cloud-config 开头的 YAML 文件:

#cloud-config # 设置主机名 hostname: web-server-01 fqdn: web-server-01.example.com # 创建用户 users: - name: deploy groups: sudo, docker shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL ssh_authorized_keys: - ssh-ed25519 AAAA... deploy@workstation - name: monitor groups: [] shell: /bin/bash ssh_authorized_keys: - ssh-ed25519 AAAA... monitor@management # 设置时区 timezone: Asia/Shanghai # NTP 配置 ntp: enabled: true servers: - ntp.aliyun.com - cn.ntp.org.cn # 语言环境 locale: en_US.UTF-8 # 更换 APT 源 apt: primary: - arches: [default] uri: https://mirrors.tuna.tsinghua.edu.cn/ubuntu # 安装软件包 packages: - nginx - docker.io - fail2ban - htop - curl - vim # 升级所有包 package_update: true package_upgrade: true package_reboot_if_required: true # 写入文件 write_files: - path: /etc/nginx/sites-available/default content: | server { listen 80; server_name _; root /var/www/html; index index.html; } owner: root:root permissions: '0644' - path: /etc/sysctl.d/99-custom.conf content: | net.ipv4.ip_forward = 1 net.core.somaxconn = 65535 owner: root:root permissions: '0644' # 运行命令(在 cloud-init 配置阶段执行) runcmd: - sysctl -p /etc/sysctl.d/99-custom.conf - systemctl enable --now nginx - systemctl enable --now fail2ban - ufw allow ssh - ufw allow 80/tcp - ufw allow 443/tcp - ufw --force enable # 启用/禁用 SSH 密码登录 ssh_pwauth: false # SSH 密钥配置 ssh_keys: ed25519_private: | -----BEGIN OPENSSH PRIVATE KEY----- ... -----END OPENSSH PRIVATE KEY----- ed25519_public: ssh-ed25519 AAAA... # 设置密码(hash 值) chpasswd: expire: false users: - name: deploy type: RANDOM # 最终消息 final_message: "Cloud-init 完成!耗时 $UPTIME 秒。" # 首次启动完成后执行的命令 power_state: mode: reboot message: "cloud-init 配置完成,正在重启..." timeout: 30 condition: true

Shell 脚本格式

以 #!/bin/bash 开头:

#!/bin/bash set -euxo pipefail # 更新系统 apt update && apt upgrade -y # 安装基础工具 apt install -y nginx docker.io # 配置防火墙 ufw allow ssh ufw allow 80/tcp ufw --force enable # 自定义脚本 echo "Setup complete at $(date)" > /var/log/cloud-init-custom.log

多部分格式(MIME Multi-Part)

组合多种格式:

# 使用 cloud-init 工具创建多部分消息 cloud-init devel make-mime \ --attach script.sh:text/x-shellscript \ --attach config.yaml:text/cloud-config \ > combined-userdata.txt

常见使用场景

初始化 Docker 环境

#cloud-config packages: - docker.io - docker-compose-v2 groups: - docker users: - name: deploy groups: sudo, docker shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL ssh_authorized_keys: - ssh-ed25519 AAAA... write_files: - path: /etc/docker/daemon.json content: | { "registry-mirrors": ["https://mirror.ccs.tencentyun.com"], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } } runcmd: - systemctl enable --now docker - docker pull nginx:alpine

初始化磁盘

#cloud-config disk_setup: /dev/vdb: table_type: gpt layout: true overwrite: false fs_setup: - label: data filesystem: ext4 device: /dev/vdb1 overwrite: false mounts: - ["/dev/vdb1", "/data", "ext4", "defaults,noatime", "0", "2"] runcmd: - mkdir -p /data

加入集群

#cloud-config runcmd: - curl -sfL https://get.k3s.io | K3S_URL=https://master:6443 K3S_TOKEN=mytoken sh -

本地测试

使用 Multipass

# 安装 Multipass sudo snap install multipass # 使用 cloud-config 启动实例 multipass launch 26.04 --name test --cloud-init cloud-config.yaml # 进入实例 multipass shell test # 查看 cloud-init 日志 multipass exec test -- cat /var/log/cloud-init-output.log

使用 LXD

# 通过 LXD 测试 cloud-init lxc launch ubuntu:26.04 test --config=user.user-data="$(cat cloud-config.yaml)" lxc exec test -- cloud-init status --wait lxc exec test -- cat /var/log/cloud-init-output.log

本地验证配置

# 验证 cloud-config 语法 cloud-init schema --config-file cloud-config.yaml # 使用 devel 子命令调试 cloud-init devel render /path/to/userdata.yaml

日志与调试

# 主日志文件 sudo cat /var/log/cloud-init.log # 输出日志 sudo cat /var/log/cloud-init-output.log # 查看已执行的模块 sudo cat /run/cloud-init/result.json # 查看用户数据 sudo cat /var/lib/cloud/instance/user-data.txt # 查看实例数据 sudo cloud-init query --all # 查看特定字段 sudo cloud-init query instance_id sudo cloud-init query region sudo cloud-init query local_hostname

重新运行 cloud-init

# 清除 cloud-init 状态(用于测试) sudo cloud-init clean # 清除并重启以重新执行 sudo cloud-init clean --reboot # 仅清除日志 sudo cloud-init clean --logs # 手动触发特定阶段 sudo cloud-init init sudo cloud-init modules --mode config sudo cloud-init modules --mode final

禁用 cloud-init

在非云环境中,可以禁用 cloud-init:

# 方法 1:创建禁用标记文件 sudo touch /etc/cloud/cloud-init.disabled # 方法 2:通过 grub 内核参数 # 在 /etc/default/grub 的 GRUB_CMDLINE_LINUX 中添加: # cloud-init=disabled # 方法 3:卸载 sudo apt remove cloud-init -y sudo rm -rf /etc/cloud /var/lib/cloud
Last updated on