====== 安裝 Ubuntu + LXD 移轉 PVE 內的舊 CT ====== * 主要是因為在 Proxmox 內有一些 CentOS 7 的 CT 導致無法升級 PVE 到 9.x (參考 [[tech/pve6_and_pve7|讓_pve_6_內的_centos7_的_ct_移轉至_pve_7_的妥協做法]] * 因為這些 CentOS 7 的 CT 內服務不易移轉到其他新版的 OS, 所以嘗試將這些 CT 由 Proxmox 移轉到 Ubuntu 24.04 (VM) 內使用 LXD 來管理 ===== 0. 建立 Ubuntu 24.04 VM ===== * 安裝標準 Ubuntu 24.04 (4Core, 4G RAM 60G SSD) * Network : * IP : 192.168.1.210/24 * GW : 192.168.1.1 * 建立給 lxd 使用 bridge ens18 網路 apt update && apt install -y bridge-utils mkdir -p /root/netplan-backup mv /etc/netplan/*.yaml /root/netplan-backup/ cat > /etc/netplan/01-netcfg.yaml << 'EOF' network: version: 2 renderer: networkd ethernets: ens18: dhcp4: no dhcp6: no bridges: br0: interfaces: [ens18] addresses: [192.168.1.210/24] routes: - to: default via: 192.168.1.1 metric: 100 # 明確 metric,避免衝突 nameservers: addresses: [1.1.1.1, 8.8.8.8] parameters: stp: false forward-delay: 0 EOF netplan generate # 應無錯誤/警告 netplan apply # 套用(暫斷網幾秒;用 console 執行以防 SSH 斷) ===== 1. 使用 Snap 安裝 LXD 與相關配置 ===== ==== 安裝 LXD ==== * # 安裝 snapd apt update apt install snapd -y # 安裝 LXD snap install lxd # 初始化 LXD lxd init --auto ==== 設定讓 cgroupv1 可以使用的 systemd 服務 ==== * /usr/local/bin/mount-cgroup-v1.sh # 建立 systemd 服務來自動 mount v1 控制器(持久化,重啟後生效): # 建立啟動腳本(mount) cat > /usr/local/bin/mount-cgroup-v1.sh << 'EOF' #!/bin/bash set -e # 建立目錄(新增 systemd) mkdir -p /sys/fs/cgroup/{cpu,cpuacct,cpuset,memory,devices,freezer,blkio,net_cls,net_prio,pids,perf_event,systemd} # Mount v1 控制器(新增 systemd) mount -t cgroup -o none,name=cpu cpu /sys/fs/cgroup/cpu || true mount -t cgroup -o none,name=cpuacct cpuacct /sys/fs/cgroup/cpuacct || true mount -t cgroup -o none,name=cpuset cpuset /sys/fs/cgroup/cpuset || true mount -t cgroup -o none,name=memory memory /sys/fs/cgroup/memory || true mount -t cgroup -o none,name=devices devices /sys/fs/cgroup/devices || true mount -t cgroup -o none,name=freezer freezer /sys/fs/cgroup/freezer || true mount -t cgroup -o none,name=blkio blkio /sys/fs/cgroup/blkio || true mount -t cgroup -o none,name=net_cls net_cls /sys/fs/cgroup/net_cls || true mount -t cgroup -o none,name=net_prio net_prio /sys/fs/cgroup/net_prio || true mount -t cgroup -o none,name=pids pids /sys/fs/cgroup/pids || true mount -t cgroup -o none,name=perf_event perf_event /sys/fs/cgroup/perf_event || true mount -t cgroup -o none,name=systemd systemd /sys/fs/cgroup/systemd || true echo "cgroup v1 controllers (incl. systemd) mounted successfully." EOF * /usr/local/bin/umount-cgroup-v1.sh # 更新 umount 腳本(新增 systemd) cat > /usr/local/bin/umount-cgroup-v1.sh << 'EOF' #!/bin/bash set -e umount /sys/fs/cgroup/systemd 2>/dev/null || true umount /sys/fs/cgroup/perf_event 2>/dev/null || true umount /sys/fs/cgroup/pids 2>/dev/null || true umount /sys/fs/cgroup/net_prio 2>/dev/null || true umount /sys/fs/cgroup/net_cls 2>/dev/null || true umount /sys/fs/cgroup/blkio 2>/dev/null || true umount /sys/fs/cgroup/freezer 2>/dev/null || true umount /sys/fs/cgroup/devices 2>/dev/null || true umount /sys/fs/cgroup/memory 2>/dev/null || true umount /sys/fs/cgroup/cpuset 2>/dev/null || true umount /sys/fs/cgroup/cpuacct 2>/dev/null || true umount /sys/fs/cgroup/cpu 2>/dev/null || true echo "cgroup v1 controllers unmounted." EOF # 設定權限 chmod +x /usr/local/bin/mount-cgroup-v1.sh /usr/local/bin/umount-cgroup-v1.sh * /etc/systemd/system/cgroup-v1-legacy.service # 建立單位檔案 cat > /etc/systemd/system/cgroup-v1-legacy.service << 'EOF' [Unit] Description=Mount legacy cgroup v1 controllers for LXC containers After=systemd-remount-fs.service Before=lxd.service [Service] Type=oneshot RemainAfterExit=true ExecStart=/usr/local/bin/mount-cgroup-v1.sh ExecStop=/usr/local/bin/umount-cgroup-v1.sh [Install] WantedBy=multi-user.target EOF * 啟用服務: systemctl daemon-reload systemctl enable --now cgroup-v1-legacy.service systemctl restart cgroup-v1-legacy.service systemctl status cgroup-v1-legacy.service * 驗證 mount(檢查主機): mount | grep cgroup # 應看到多個 v1 mount 如 /sys/fs/cgroup/cpu 等 cat /proc/cgroups # 應顯示 v1 控制器可用 ===== 2. 將 proxmox 的 ct 匯出 ===== * Exp. 將 proxmox 的 ct-118 使用 vzdump 產生的 vzdump-lxc-118-2025_11_13-14_03_41.tar 複製到 Ubuntu VM 內 vzdump 118 --dumpdir /tmp scp /tmp/vzdump-lxc-118-2025_11_13-14_03_41.tar jonathan@192.168.1.210:/tmp ===== 3. 建立 LXD image ===== * 使用 root 權限執行 sudo -i mkdir test mv /tmp/vzdump-lxc-118-2025_11_13-14_03_41.tar test/ cd test tar -xvf vzdump-lxc-118-2025_11_13-14_03_41.tar ls -la # (會看到一堆檔案) # 查看系統版本 cat etc/os-release * 將當前目錄的所有系統檔案打包成 rootfs # 排除原始備份檔 tar --numeric-owner -czf rootfs.tar.gz \ --exclude='vzdump-lxc-118-2025_11_13-14_03_41.tar' \ --exclude='rootfs.tar.gz' \ . # 檢查打包結果 ls -lh rootfs.tar.gz * LXD 需要 metadata 檔案來識別映像 cat > metadata.yaml << 'EOF' architecture: x86_64 creation_date: 1699862400 properties: description: CentOS 7 from Proxmox CT-118 os: centos release: "7" EOF # 打包 metadata tar -czf metadata.tar.gz metadata.yaml # 確認兩個檔案都存在 ls -lh metadata.tar.gz rootfs.tar.gz ===== 4. 建立與啟動 LXD 容器 ===== * 導入為 LXD 映像 Exp. ct-linsport lxc image import metadata.tar.gz rootfs.tar.gz --alias ct-linsport * 查看導入的映像 lxc image list root@lin-web-210:~/test# lxc image list +-------------+--------------+--------+------------------------------+--------------+-----------+------------+------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE | +-------------+--------------+--------+------------------------------+--------------+-----------+------------+------------------------------+ | ct-linsport | 62085b012d6b | no | CentOS 7 from Proxmox CT-118 | x86_64 | CONTAINER | 1633.91MiB | Nov 13, 2025 at 6:20am (UTC) | +-------------+--------------+--------+------------------------------+--------------+-----------+------------+------------------------------+ * 從映像創建容器 Exp. ct-118 lxc init ct-linsport ct-118 * 設定權限配置參數檔 ct-118-raw.conf 與相關權限設定 cat > ct-118-raw.conf << 'EOF' # 放寬安全限制 lxc.apparmor.profile=unconfined lxc.cap.drop= # 自動 mount:proc rw、sys mixed、cgroup mixed(關鍵:自動處理 v1) lxc.mount.auto=proc:rw sys:mixed cgroup:mixed # 手動 bind v1 控制器(僅 systemd 作為補充,optional) lxc.mount.entry=/sys/fs/cgroup/systemd /sys/fs/cgroup/systemd none bind,create=dir,optional 0 0 EOF # 讀取並設定 lxc config set ct-118 raw.lxc "$(cat ct-118-raw.conf)" # 設定特權模式 lxc config set ct-118 security.privileged true lxc config set ct-118 security.nesting true * 設定容器可以對外連結虛擬網卡 # Override eth0 為獨立 nic type(移除 profile 影響) lxc config device override ct-118 eth0 type=nic # 移除 eth0(現在可移除,因為已 override) lxc config device remove ct-118 eth0 # 新增全新 eth0 nic:macvlan 模式,綁 ens18 lxc config device add ct-118 eth0 nic nictype=bridged parent=br0 name=eth0 * 啟動容器 # 啟動容器 lxc start ct-118 # 查看容器狀態 lxc list ===== 5. 進入容器測試 ===== * # 進入容器 lxc exec ct-118 -- bash # 檢查系統 cat /etc/redhat-release hostname ip addr systemctl status # 退出 exit ===== FAQ ===== ==== 1. 發現無法自動啟動服務 (systemctl 權限問題) ==== * Ubuntu 24.04 host 要先設定好 mount-cgroup-v1.sh / umount-cgroup-v1.sh / cgroup-v1-legacy.service 這些環境配置 * 重建容器與設定正確權限 # 停止容器(如果卡住) lxc stop ct-118 --force || true # 刪除容器 (保留映像) lxc delete ct-118 # 重新創建 lxc init ct-linsport ct-118 # 創建設定檔案(完整的 systemd 支援配置) cat > ct-118-raw.conf << 'EOF' # 放寬安全限制 lxc.apparmor.profile=unconfined lxc.cap.drop= # 自動 mount:proc rw、sys mixed、cgroup mixed(關鍵:自動處理 v1) lxc.mount.auto=proc:rw sys:mixed cgroup:mixed # 手動 bind v1 控制器(僅 systemd 作為補充,optional) lxc.mount.entry=/sys/fs/cgroup/systemd /sys/fs/cgroup/systemd none bind,create=dir,optional 0 0 EOF # 讀取並設定 lxc config set ct-118 raw.lxc "$(cat ct-118-raw.conf)" # 設定特權模式 lxc config set ct-118 security.privileged true lxc config set ct-118 security.nesting true # 啟動容器 lxc start ct-118 # 檢查容器狀態 lxc info ct-118 # 查看啟動日誌 lxc info ct-118 --show-log | tail -50 # 等待幾秒讓系統啟動 sleep 5 # 檢查狀態 lxc info ct-118 | grep Processes # 查看容器狀態 lxc list ==== 2. 發現容器無法對外連結 ===== * 要在 Ubuntu 24.04 Host 建立可以對外網卡的 Bridge Exp. br0 * 將原本容器的網卡刪除更換成這 br0 Exp. # Override eth0 為獨立 nic type(移除 profile 影響) lxc config device override ct-118 eth0 type=nic # 移除 eth0(現在可移除,因為已 override) lxc config device remove ct-118 eth0 # 新增全新 eth0 nic:macvlan 模式,綁 ens18 lxc config device add ct-118 eth0 nic nictype=bridged parent=br0 name=eth0 ==== 3. 如何啟動 Web UI ===== * 設定 config root@lin-web-210:~# lxd --version 5.21.4 LTS root@lin-web-210:~# lxc config set core.https_address [::] root@lin-web-210:~# lxc config set core.https_address 0.0.0.0:8443 root@lin-web-210:~# lxc config show config: core.https_address: 0.0.0.0:8443 root@lin-web-210:~# lxc config trust list +------+------+-------------+-------------+------------+-------------+ | TYPE | NAME | COMMON NAME | FINGERPRINT | ISSUE DATE | EXPIRY DATE | +------+------+-------------+-------------+------------+-------------+ * 因為 LXD Web UI 是採用雙向 SSL 認證方式, 所以第一次進入網址要產生與下載憑證 Exp. https://192.168.1.210:8443 - 瀏覽器會彈出選擇憑證, 如果沒有憑證或取消就會進入 Step 1. TLS login 設定畫面 \\ {{:tech:螢幕擷取畫面_2025-11-14_103428.png?1000|}} - 下載憑證( Exp. lxd-ui-192.168.1.210.pfx )後匯入讓瀏覽器可以使用 - 開啟瀏覽器無痕模式, 彈出選擇憑證時, 選擇剛剛匯入的憑證 Exp. \\ {{:tech:螢幕擷取畫面_2025-11-14_104711.png|}} - 看到網頁 Step 2. 設定畫面 - 回到 LXD Server 執行 lxc auth identity create tls/lxd-ui --group admins產生 identity token Exp. root@lin-web-210:~# lxc auth identity create tls/lxd-ui --group admins TLS identity "tls/lxd-ui" (4fd2xxxx-xxxx-xxxx-xxxx-xxxxxxxx88bc) pending identity token: eyJjbGllbnxxxxxxxxxxxxxxxxxxxxIsImZpbmdlcnByaW5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxmI2NSIsImFkZHJlc3NlcyI6WyIxOTIuMTY4LjExLxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0aWZpY2F0ZSJ9 - 將產生的 identity token 貼上 Step 2. \\ {{:tech:螢幕擷取畫面_2025-11-14_104936.png?1000|}} - 點下 Connet 後就會進入 Web UI \\ {{:tech:螢幕擷取畫面_2025-11-14_105240.png?1000|}} \\ {{:tech:螢幕擷取畫面_2025-11-14_105422.png?1000|}} * 如果需要設定透過反向代理 Exp. NPM 原本雙向 SSL 認證就無法順利傳遞, 必須要增加設定 OIDC (Exp. Google oAuth 認證) 方式來達成, 可參考 - [[tech/ubuntu_lxd/oidc]] {{tag>pve ct lxd}}