Ubuntu LXC
建立 LXC 容器
安裝 LXC
sudo apt install lxc -y
lxc-create 看嘸的語法
lxc-create --help lxc-create --name=NAME --template=TEMPLATE [OPTION...] Options : -n, --name=NAME NAME of the container -t, --template=TEMPLATE Template to use to setup container
實在是看不懂,只好上網找,消化一下整理並簡化。
lxc-create 消化後的語法
lxc-create -t download -n $lxcname -- -d ubuntu -r $release -a amd64 -t download 快取資料夾 (1) --name (新建的) 容器名稱 $lxcname (2) --dist 作業系統 ubuntu --release 作業系統版本 (release) (3) --arch 指定架構 amd64。
1 | 下載的 lxc 儲存在 /var/cache/lxc/download |
2 | 容器檔案會放在 /var/lib/lxc/$lxcname |
3 | $release 是什麼?
這裡的參數 bionic 是 ub18,xenial 是 ub16,那其他版本呢?
Releases - Ubuntu Wiki
Version Code name $releae Ubuntu 20 Focal Fossa focal Ubuntu 18 Bionic Beaver bionic Ubuntu 16 Xenial Xerus xenial Ubuntu 14 Trusty Tahr trusty |
先別急著建立容器,建議您看一下 設置 LXC 採用 br0 橋接網路。
建立 base18 容器
# 容器命名為 base18, 先建立基本容器, 安裝基本功能後再複製至新容器
lxcname=base18
sudo lxc-create -t download -n $lxcname -- -d ubuntu -r bionic -a amd64 (1)
1 | 若出現下列錯誤,等一段時間再試一次。 ERROR: Unable to fetch GPG key from keyserver. |
啟動容器
lxcname=base18
# 啟動容器
sudo lxc-start -n $lxcname (1)
# 登入容器,帳戶為 root 帳戶
sudo lxc-attach -n $lxcname
# 設定 root 帳戶密碼
passwd
# 設定 ubuntu 帳戶密碼 (已有 ubuntu 及 www-data 帳戶)
# ubuntu 帳戶密碼預設值為 ubuntu
passwd ubuntu
# 採用 dist-upgrade 更新
apt update && apt dist-upgrade -y
# lxc 可安裝常用套件 nano
apt install nano -y
# 可接續安裝其他套件或調整 (2)
# 離開容器
exit
1 | 依據版本不同可能不需要 -n 參數,如 sudo lxc-start $lxcname 。 |
2 | 可依據 Ubuntu 安裝手冊 安裝必要套件。 |
LXC 設置
LXC 全局設置 /etc/default/lxc-net
USE_LXC_BRIDGE="true"(1)
1 | "true" 表示啟用 lxcbr0 (LXC 內建的 NAT) 介面,"false" 則為取消。 |
編輯容器組態
lxcname=base18
nano /var/lib/lxc/$lxcname/config
/var/lib/lxc/$lxcname/config
# 可加入 LXC 自動開機
lxc.start.auto = 1
# Container specific configuration
lxc.uts.name = base18 (1)
# Network configuration
# Ubuntu 18
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0 (2)
# lxc.net.0.link = br0 (3)
# lxc.net.0.ipv4 = 192.168.1.102/24 (4)
# lxc.net.0.ipv4.gateway = 192.168.1.254
# Ubuntu 16
lxc.network.type = veth
lxc.network.link = lxcbr0 (2)
# lxc.network.link = br0 (3)
# lxc.network.ipv4 = 192.168.1.102/24 (4)
# lxc.network.ipv4.gateway = 192.168.1.254
1 | 指定容器的名稱,一般會指定成容器目錄名稱,但該值似乎無作用。 |
2 | lxcbr0:LXC 預設的 NAT 網路介面。 |
3 | 自行建立的 br0 橋接網路介面。 |
4 | 如果容器採用固定 IP 按實際修改。 |
前續的步驟完成,再複製 LXC 容器。
lxcname=base18
newlxc=new18
lxc-stop -n $lxcname
# lxc-copy [-n] <container-name> -N <new-container-name>
lxc-copy -n $lxcname -N $newlxc (1)
1 | $newlxc 是 容器名稱 跟 容器主機名稱 沒有關係,記得要去改新容器內的主機名稱。 |
LXC 常用指令
#檢查版本
lxc-info --version
# 判斷 linux 核心是否支援 LXC
lxc-checkconfig
lxc-ls --help
# 列出容器
lxc-ls -f
lxcname=base18
# 修改組態
nano /var/lib/lxc/$lxcname/config
# 啟動容器
lxc-start -n $lxcname
# 註: 在舊版的 lxc 需要前置 -n,如 lxc-start -n $lxcname
# 停止容器
lxc-stop -n $lxcname
# 登入容器,帳戶為 root 帳戶
lxc-attac -n $lxcname
# 登入容器 (需要輸入使用者名和密碼)
lxc-console -n $lxcname
# 檢查佔用多少記憶體及其他狀態
lxc-info -n $lxcname
# 複製容器
# lxc-copy [-n] <container-name> -N <new-container-name>
lxc-stop -n $lxcname
lxc-copy -n $lxcname -N <new-container-name>
# 刪除容器
lxc-destroy -n <container-name>
設置 LXC 採用 br0 橋接網路
LXC 在預設的情況下採用 NAT 的方式,容器只能被 Host 存取,如果其他主機要能存取,Host 必須採用橋接網卡(br0)。
先完成下列,再取消 LXC 預設 NAT 橋接。
/etc/default/lxc-net
# USE_LXC_BRIDGE="true"
USE_LXC_BRIDGE="false"(1)
1 | 取消 LXC 的橋接。 |
修改 LXC 建立容器的預設值,將網路介面指向橋接介面。
/etc/lxc/default.conf
lxc.net.0.type = veth
#lxc.net.0.link = lxcbr0
lxc.net.0.link = br0(1)
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
1 | LXC 的網路介面指向橋接 br0 介面 |
調整容器組態,檔案在 Host 主機上
/var/lib/lxc/$lxcname/config
# Network configuration
lxc.net.0.type = veth
# lxc.net.0.link = lxcbr0
lxc.net.0.link = br0(1)
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:77:ee:2c
# lxc.net.0.ipv4 = 192.168.1.102/24(2)
# lxc.net.0.ipv4.gateway = 192.168.1.254
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:77:ee:2c
1 | LXC 的網路介面指向橋接 br0 介面 |
2 | 如果容器採用固定 IP 按實際修改。 |
LXC 容器橋接測試
進入容器,檢查一下位置是否為 LAN (別忘了,如果是在設置之前已啟動容器,應該重啟它)
lxcname=base18
lxc-start -n $lxcname
lxc-attach -n $lxcname
ifconfig (1)
ip a
ip -c a
1 | 出錯 bash: ifconfig: command not found,可參考: command line - ifconfig missing after Ubuntu 18.04 install - Ask Ubuntu ,
改用 ip 吧!如果要用 ifconfig,則安裝 sudo apt install net-tools ,或者查看 sudo apt-cache search ifconfig 看是要裝那一個。 |
LXC 容器備份
容器以 tar 壓縮或解壓縮只有一個重點,採用 --numeric-owner 保留容器檔案權限。
- 關於 --numeric-owner
-
LXC 容器檔案的 uid/gid (User Identifier/Group Identifier) 為容器專屬, 但執行 tar 的 Host 系統會嘗試解析容器檔案的 uid/gid,解決檔案擁有權問題。 採用 --numeric-owner 保留容器檔案的 uid/gid, 不要讓 Host 去做一些跟自己毫無關係的解析動作,若將其解析為其他值則會發生不良情況。
- 參考: ubuntu - How do I Backup / Move LXC containers? - Stack Overflow
-
The --numeric-owner flag is very important! Without it, the container may not boot because the uid/gids get mangled in the extracted file system.
容器備份及傳送
停止容器
lxcname=base18
cd /var/lib/lxc/$lxcname
lxc-stop -n $lxcname
壓縮時直接在共享目錄建立 tar 檔案 (Windows shared folder)
tar --numeric-owner -czvf /mnt/share/$lxcname.tar.gz ./*
壓縮時直接將壓縮檔以 ssh 傳送至目標主機
# 切換目錄至來源容器
# cd /var/lib/lxc/$lxcname
# 設定目標主機的 root 帳戶及主機位置
UserHost='root@192.168.1.1'
# LXC 的容器名稱,這時要決定。
# 先檢查目標主機
ssh $UserHost ls /var/lib/lxc/
# 新容器名稱
newlxc=base18
# 建立目標主機資料夾
ssh $UserHost mkdir /var/lib/lxc/$newlxc
tar --numeric-owner -czvf - ./* | ssh $UserHost "cat > /var/lib/lxc/$newlxc/clone.tar.gz"
目標主機解壓
# ssh $UserHost
newlxc=base18
# 直接解壓 Windows shared folder 內的 tar
mkdir /var/lib/lxc/$newlxc/
cd /var/lib/lxc/$newlxc/
tar --numeric-owner -xzvf /mnt/share/base18.tar.gz .
# 目標主機已有, 直接解壓即可
cd /var/lib/lxc/$newlxc/
tar --numeric-owner -xzvf clone.tar.gz .
調整目標主機內容器名稱
newlxc=base18
# 若需要產生 MAC
OID="00:16:3e"
RAND=$(echo $newlxc | md5sum | sed 's/\(..\)\(..\)\(..\).*/\1:\2:\3/')
echo "$OID:$RAND"
# 修改容器組態
nano /var/lib/lxc/$newlxc/config
# 啟動容器
lxc-start -n $newlxc
lxc-attach -n $newlxc
# 修改容器內的主機名稱
nano /etc/hostname
nano /etc/hosts
# 離開容器
exit
# 重啟容器, 以便更新容器入的主機名稱
lxc-stop -n $newlxc
lxc-start -n $newlxc