Appearance
基础设施即服务
目前考虑将云服务器上的 debian10,虚拟机上的 ubuntu22.04 全部升级成统一且方便升级的 cloudinit 镜像。本文就是进行测试
介绍 cloudinit
参考内容
是跨平台云实例初始化的行业标准多分布方法。它支持所有主要公共云提供商、私有云基础设施配置系统和裸机安装。
目前以下产品的官方包支持了 cloud-init,debian 虽然官方有提供镜像,但是似乎 ubuntu (官网是 Canonical 的,ubuntu 的发行商) 并没有列出他爹的镜像,倒反天罡了属于是
寻思了一下,统一使用 Debian 镜像+自编译 Linux 内核得了。理论上 ubuntu 内核更好一点,但是同样是需要自编译内核,而且我不喜欢 Ubuntu 的各种操作(snap 和 pro)
- Ubuntu
- archlinux
- CentOS
- RedHat
- FreeBSD
- fedora
- gentoo linux
- openSUSE
- Windows(有一个新的开源实现,cloudbase-init)
配置 cloudinit
在 PVE 上配置 cloudinit 其实比较简单。首先你要有一个支持 cloudinit 的系统,不论是自己安装 cloudinit 还是用提供好的镜像
bash
# 导入磁盘
qm importdisk <vmid> </path/to/img> local-lvm --format <qcow2|raw|vmdk>
# 调整磁盘大小
qm disk resize <vmid> <disk> <size>
到底用不用 ubuntu 其实是一个很纠结的问题,虽然 ubuntu 喜欢给你塞屎,也不如 debian 精简,但毫无疑问的是 ubuntu 确实更简单和广泛。举个例子,ubuntu 自带的 motd 除了广告外也会告诉你当前的状态如何,当你的命令未安装也会提示你该安装那些软件。甚至 nv 的 jetson 系列基本只支持 ubuntu。由于 Oracle 的服务器之前没有 debian12 的 arm 版本,装的也是 ubuntu 24.04 lts。就先暂时继续使用 ubuntu 吧,反正现在换起来就非常快了
这下真香了
bash
# 删除ubuntu的乐色广告和snap
apt purge snapd -y
rm /etc/update-motd.d/50-motd-news
rm /etc/update-motd.d/91-contract-ua-esm-status
rm /etc/update-motd.d/10-help-text
# ubuntu换源
sed -i -r 's/\/\/.*\.ubuntu\.com/\/\/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/*.sources
然后在虚拟机的硬件配置中添加一个 Cloudinit 设备,这样 Cloud-Init 页面就能显示具体的配置内容了
PVE 的 cloudinit 配置其实相当的简陋,只支持以下的部分内容,但也基本够用了。配置完毕后就点击重生成镜像设置,把配置写入到镜像内
- 权限: 用户名、密码、公钥
- 网络: DNS、IP
- 杂项: 是否升级软件
开机后就能正常运行了
初始化镜像
考虑到希望有开箱即用的体验,需要进行一些基础的初始化。整理了一下,大致有如下几类
- 访问
- SSH 秘钥和各类程序秘钥
- 配置调整
- 系统换源
- 统一安装软件
- 安装 systemd 脚本
- 初始化
- 初始化 script、data、mnt 目录
- 启动基础容器
由于 semaphore 的 web 界面比较憨批,存在一些 BUG。而且需要一个代码仓库来存储脚本,让我选择干脆省掉了这个多余的部分。看了下 gitea 的 milestone 因为 gitea 可以手动触发 action 的 1.23 版本会在 2024-12-18 的截止日期前发布,即一个月内。因此还是采用 gitea 作为 cicd 的工具
问题不大,只需要踩亿点点坑就能搞定所有的步骤。由于这玩意涉及到了太多的个性化内容,这里就只把一些特别需要注意的内容放上来。核心其实还是上面那整理到的问题,访问权限、下载加速、环境配置
考虑到需要适配虚拟机通用需求(目录挂载)、单独主机需求(比如按顺序执行脚本并启动容器)、物理机特别要求(SRIOV 配置)。所以我写了一个 init 服务的配置文件,它会运行指定目录下面的所有 shell 文件。需要什么就把脚本软连接进去就行
bash
apt update
apt upgrade -y
# 安装点基础软件
apt install -y git btop screen zstd lz4 build-essential curl cifs-utils qemu-guest-agent
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
mkdir /root/.ssh /data /script /mnt/Volume || echo "Skip"
# 如果通过ssh进行clone,第一次访问主机时会提醒你是否要链接,这时候其实可以通过提前扫描并写入的方式来避免被打断
ssh-keyscan -p 22 domain.io >> ~/.ssh/known_hosts
cp admin/init-jobs.service /etc/systemd/system
# 类似ubuntu的motd,我写了一系列脚本,通过软连接到上面的启动服务的启动文件夹中来控制系统的启动
ln -s ../admin/jobs/0-mount.sh .
mkdir /etc/systemd/system/docker.service.d || echo "Pass"
# 给docker配置代理
echo -e "[Service]" > /etc/systemd/system/docker.service.d/proxy.conf
echo -e 'Environment="HTTP_PROXY=http://10.0.0.8:7890"' >> /etc/systemd/system/docker.service.d/proxy.conf
echo -e 'Environment="HTTPS_PROXY=http://10.0.0.8:7890"' >> /etc/systemd/system/docker.service.d/proxy.conf
echo -e 'Environment="NO_PROXY=localhost,127.0.0.1,.example.com"' >> /etc/systemd/system/docker.service.d/proxy.conf
# 重载service文件,启动对应服务
systemctl daemon-reload
systemctl enable init-jobs.service
systemctl restart docker
cd /script/admin/jobs
/bin/bash start-basic-docker.sh
内核编译
自编译 linux kernel 后才发现非 LTS 内核过期的这么快。原本在配置开发板的时候 6.10 还感觉遥遥无期,现在 6.11 已经 Release 了,6.10 刚编译好就要 EOL 了。但是 6.1 和 6.8 还会有长期支持(6.8 是 ubuntu 维护),感觉有点神秘。升级内核是一个比较重的操作,我觉得还是编译有长期支持的内核好了
由于个人喜欢追新,因此考虑自动化编译更新的内核。参照 pve 模式,安装 debian 后编译安装较新的系统内核。但是目前的内核是直接复制的 ubuntu24.04 的 boot-config,没有考虑像 pve 一样针对虚拟化做调整或者是针对虚拟机做精简,可能需要后期再研究一下
bash
apt install -y --fix-missing linux-source
apt install -y git lz4 build-essential libncurses-dev bison flex libssl-dev
apt install -y debhelper-compat bc cpio kmod libelf-dev:native rsync zstd curl # 6.8 ubuntu 比 6.1 debian 多出来需要的软件
cd /usr/src
mkdir linux-source
tar -xf linux-source-* -C linux-source --strip-components=1 # 直接解压到指定目录
cd linux-source
cp /boot/config-`uname -r` .config # 复制当前配置文件,Docker内自己下载或者挂宿主的进来也行
### 重要,你需要决定到底如何配置内核
nano .config # 修改配置文件或者参考下面的
###
make olddefconfig # 更新配置文件,新设置为默认设置
# 修改证书相关的参数
scripts/config --set-val CONFIG_SYSTEM_TRUSTED_KEYRING n
scripts/config --set-val CONFIG_MODULE_SIG n
scripts/config --set-val CONFIG_MODULE_SIG_KEY '""'
scripts/config --set-val CONFIG_SYSTEM_TRUSTED_KEYS '""'
scripts/config --set-val CONFIG_BUILD_SALT '""'
scripts/config --disable MODULE_SIG_ALL
scripts/config --disable CONFIG_DEBUG_INFO_BTF
# 自定义内核参数
scripts/config --enable CONFIG_CIFS_SMB_DIRECT
make bindeb-pkg -j`nproc` # 编译完成后记得重新运行一次,看看有没有报错漏看了
# 删除debug内核,然后把内核丢进存储路径里
rm ../linux-image*dbg*.deb
mv ../linux-image*.deb /path/to/storage
dpkg -i *.deb