使用 LXD 的一些小技巧
稍微紀錄一下一些 LXD 環境設定的步驟
轉發某個 Port 到 LXD 上
lxc launch ubuntu:18.04 Apache
假設你的 container 叫做 Apacche,並且已經安裝好所需的東西
+--------+---------+------+-----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------+---------+------+-----------------------------------------------+------------+-----------+
| Apache | RUNNING | | fd42:d75f:90b5:e90b:216:3eff:fe88:e8ac (eth0) | PERSISTENT | 0 |
+--------+---------+------+-----------------------------------------------+------------+-----------+
透過以下指令新增一個 Proxy,取名為 myport80
,把所有所有 IP(0.0.0.0)到 Port 80 的連入連線,轉發到本機(容器)的 port 80
lxc config device add Apache myport80 proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
在容器外重新 curl
一次就能確認結果了
play_pc at lxd_server in ~
$ curl localhost
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Modified from the Debian original for Ubuntu
Last updated: 2016-11-16
See: https://launchpad.net/bugs/1288690
...下略...
在 LXD 裡面使用 VPN
lxc launch ubuntu:18.04 OpenVPN
假設你的 container 叫做 OpenVPN
+---------+---------+---------------------+-----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+---------+---------+---------------------+-----------------------------------------------+------------+-----------+
| OpenVPN | RUNNING | 10.52.196.93 (eth0) | fd42:d75f:90b5:e90b:216:3eff:fe7a:b07a (eth0) | PERSISTENT | 0 |
+---------+---------+---------------------+-----------------------------------------------+------------+-----------+
加入 tun
裝置
lxc config device add OpenVPN tun unix-char path=/dev/net/tun
安裝 OpenVPN 軟體
lxc exec OpenVPN -- apt install openvpn -y
進入 Container
lxc exec OpenVPN -- bash
[Optional] 如果你的 OpenVPN Server 需要帳號密碼的話,記得存在一個檔案裡面,等一下會用到
vim /etc/openvpn/ovpn_pass.txt chmod 600 /etc/openvpn/ovpn_pass.txt
格式如下:
帳號 密碼
然後記得要在
.ovpn
檔案裡加入auth-user-pass
選項(這邊假設叫做us_west.ovpn
)echo 'auth-user-pass ovpn_pass.txt' >> us_west.ovpn
複製設定檔到 /etc/openvpn
資料夾,並把副檔名改成 .conf
(本例為 us_west.ovpn
)
mv us_west.ovpn /etc/openvpn/us_west.conf
chmod 600 /etc/openvpn/us_west.conf
編輯設 /etc/default/openvpn
定檔,設定自動啟動,加入這一行(這邊用 us_west
舉例,請改成自己的設定檔名子)
AUTOSTART="us_west"
雖然不確定原因(我猜是因為 PID mapping),不過在 Container 裡面使用 OpenVPN Daemon 的話,請務必編輯 /lib/systemd/system/[email protected]
把下面那一行註解掉
LimitNPROC=10
完成之後記得 reload
systemctl daemon-reload
除了重新啟動 Container 之外,我們也可以透過 systemctl
手動操作
systemctl start openvpn@us_west
可以用這個指令來檢查自己的 IP 是不是有變
curl http://ipecho.net/plain
讓 LXD 存取外面的資料夾
lxc launch ubuntu:18.04 Share
假設你的 container 叫做 Share
+-------+---------+------+-----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+------+-----------------------------------------------+------------+-----------+
| Share | RUNNING | | fd42:d75f:90b5:e90b:216:3eff:fe13:ba17 (eth0) | PERSISTENT | 0 |
+-------+---------+------+-----------------------------------------------+------------+-----------+
假設你要分享家目錄裡的 Share
資料夾,並掛在 /mnt
lxc config device add Share myshare disk path=/mnt source=/home/使用者/Share
我們可以看到 Share 資料夾已經被掛載進來了,不過檔案擁有者好像怪怪的(不信可以自己 df
看看)
root@Share:/mnt# ls -l
total 0
-rw-rw-r-- 1 nobody nogroup 0 Nov 24 07:06 bar
-rw-rw-r-- 1 nobody nogroup 0 Nov 24 07:06 foo
而且沒辦法新增檔案?!
root@Share:/mnt# touch foobar
touch: cannot touch 'foobar': Permission denied
這是因為 idmap
的關係,透過這樣的機制,可以讓 Container 裡面執行的程式幾乎不可能逃出來
如果沒有特別更改的話,預設的情況是 +100000
,也就是說 Container 裡面的 root
其實是 uid=100000
的一般使用者
這裡有兩種解法:
- 更改 Share 資料夾的擁有者
sudo chown -R 100000:100000 ~/Share
- 手動為這個 Container 設定
idmap
,這個比較複雜,請見下一章節
手動設定 idmap
假設你的 container 叫做 Share
+-------+---------+------+-----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+------+-----------------------------------------------+------------+-----------+
| Share | RUNNING | | fd42:d75f:90b5:e90b:216:3eff:fe13:ba17 (eth0) | PERSISTENT | 0 |
+-------+---------+------+-----------------------------------------------+------------+-----------+
首先必須先關閉 Container,這樣才有辦法儲存設定
lxc stop Share
設定 idmap
,把 Container 裡面的 ubuntu(uid=1000
)對應到外面的使用者(uid=1000
)
lxc config set Share raw.idmap 'both 1000 1000'
還沒完,接下來還要編輯 /etc/subuid
、/etc/subgid
這兩個檔案,允許這樣的對應
echo "root:1000:1" | sudo tee -a /etc/subuid
echo "root:1000:1" | sudo tee -a /etc/subgid
為了套用剛才的修改,必須要重新啟動整個 LXD
服務,請先確定所有的 Container 都已經關閉
+-------+---------+------+------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+------+------+------------+-----------+
| Share | STOPPED | | | PERSISTENT | 0 |
+-------+---------+------+------+------------+-----------+
重新啟動 LXD
sudo systemctl restart lxd
進入 Container 看看
lxc exec Share -- su ubuntu --login
噹噹!
ubuntu@Share:/mnt$ ls -l
total 0
-rw-rw-r-- 1 ubuntu ubuntu 0 Nov 24 07:06 bar
-rw-rw-r-- 1 ubuntu ubuntu 0 Nov 24 07:06 foo
轉移現有的 container 到其他主機
lxc launch ubuntu:18.04 xenial
假設你的 container 叫做 xenial
+--------+---------+-----------------------+----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------+---------+-----------------------+----------------------------------------------+------------+-----------+
| xenial | RUNNING | | fd42:5f2:e4a1:2b7f:216:3eff:fe22:26c4 (eth0) | PERSISTENT | 0 |
+--------+---------+-----------------------+----------------------------------------------+------------+-----------+
兩台主機的 IP 分別是:
Host | IP |
---|---|
VSV_1 | 192.168.1.31 |
VSV_2 | 192.168.1.32 |
首先有一件事情很重要要先講:轉移的時候是 從來源主機把現有的 Container pull
過來
[VSV_1]:允許 VSV_2(新主機)連線到 VSV_1(舊主機)
# 設定 bind 位址和 port
lxc config set core.https_address 0.0.0.0:8443
# 設定密碼
lxc config set core.trust_password myPassword
# 設定 ufw
sudo ufw allow from 192.168.1.32 to any port 8443 proto tcp
[VSV_2]:把 VSV_1(舊主機)加為遠端主機
$ lxc remote add VSV_2 192.168.1.32
Generating a client certificate. This may take a minute...
Certificate fingerprint: ????????????????????????????????????????????????????????????????
ok (y/n)? y
Admin password for VSV_2:
Client certificate stored at server: VSV_2
$ lxc remote list
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| NAME | URL | PROTOCOL | AUTH TYPE | PUBLIC | STATIC |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| images | https://images.linuxcontainers.org | simplestreams | none | YES | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| local (default) | unix:// | lxd | file access | NO | YES |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| VSV_2 | https://192.168.1.32:8443 | lxd | tls | NO | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| ubuntu | https://cloud-images.ubuntu.com/releases | simplestreams | none | YES | YES |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
| ubuntu-daily | https://cloud-images.ubuntu.com/daily | simplestreams | none | YES | YES |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+
[VSV_2]:從 VSV_1(舊主機)把 container 搬過來
lxc copy VSV_2:xenial xenial
[VSV_2]:噹噹!
+--------+---------+-----------------------+----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------+---------+-----------------------+----------------------------------------------+------------+-----------+
| xenial | RUNNING | | fd42:a043:df96:b02e:216:3eff:fe57:771 (eth0) | PERSISTENT | 0 |
+--------+---------+-----------------------+----------------------------------------------+------------+-----------+
參考文件
- Instance configuration – LXD – system container manager
- A Beginner’s Guide to LXD: Setting Up an Apache Webserver In a Container | Linode
- how to auto start openvpn (client) on ubuntu cli? – Ask Ubuntu
- OpenVPN in LXD Container · GitHub
- Adding a shared host directory to an LXC/LXD Container – Ask Ubuntu
- Idmaps for user namespace – LXD – system container manager
- Custom user mappings in LXD containers | Stéphane Graber’s website
- Live Migration in LXD – LXD – system container manager
- LXD 2.0: Remote hosts and container migration [6/12] | Stéphane Graber’s website
- lxd/server.md at master · lxc/lxd
謝謝你的分享,剛開始用LXC開instance一直很不清楚如何對掛載點和網路做mapping。
你這樣解釋就清楚多了