cloud-init
cloud-init 是云实例初始化的行业标准工具,在实例首次启动时自动完成系统配置。Ubuntu 26.04 Server 默认预装 cloud-init,广泛支持 AWS、Azure、GCP、阿里云、腾讯云等云平台。
工作原理
cloud-init 在实例启动时按以下阶段执行:
- Generator - 检测是否在云环境中运行
- Local - 从本地数据源获取网络配置
- Network - 获取 metadata 和 user-data
- Config - 执行配置模块
- 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: trueShell 脚本格式
以 #!/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/cloudLast updated on