LXD 2.0 系列(六):遠程主機及容器遷移
遠程協議
LXD 2.0 支持兩種協議:
- LXD 1.0 API:這是在客戶端和 LXD 守護進程之間使用的 REST API,以及在 LXD 守護進程間複製/移動鏡像和容器時使用的 REST API。
- Simplestreams:Simplestreams 協議是 LXD 客戶端和守護進程使用的只讀、僅針對鏡像的協議,用於客戶端和 LXD 守護進程獲取鏡像信息以及從一些公共鏡像伺服器(如 Ubuntu 鏡像)導入鏡像。
以下所有內容都將使用這兩個協議中的第一個。
安全
LXD API 的驗證是通過客戶端證書在 TLS 1.2 上使用最近的密鑰驗證的。 當兩個 LXD 守護進程必須直接交換信息時,源守護程序生成一個臨時令牌,並通過客戶端傳輸到目標守護程序。 此令牌僅可用於訪問特定流,並且會被立即撤銷,因此不能重新使用。
為了避免中間人攻擊,客戶端工具還將源伺服器的證書發送到目標伺服器。這意味著對於特定的下載操作,目標伺服器會被提供源伺服器的 URL、所需資源的一次性訪問令牌以及伺服器應該使用的證書。 這可以防止中間人攻擊,並且只允許臨時訪問所傳輸的對象。
網路需求
LXD 2.0 使用這樣一種模型,某個操作的目標(接收端)直接連接到源以獲取數據。
這意味著你必須確保目標伺服器可以直接連接到源、可以更新任何所需的防火牆。
我們有個允許反向連接的計劃,允許通過客戶端代理本身以應對那些嚴格的防火牆阻止兩台主機之間通信的罕見情況。
與遠程主機交互
LXD 使用的是「遠程」的概念,而不是讓我們的用戶總是提供主機名或 IP 地址,然後在他們想要與遠程主機交互時驗證證書信息。
默認情況下,唯一真正的 LXD 遠程配置是 local:
,這也是默認的遠程(所以你不必輸入它的名稱)。這個本地(local:
)遠程使用 LXD REST API 通過 unix 套接字與本地守護進程通信。
添加一台遠程主機
假設你已經有兩台裝有 LXD 的機器:你的本機以及遠程那台我們稱為「foo」的主機。
首先你需要確保「foo」正在監聽網路,並設置了一個密碼,以便得到一個遠程 shell,運行:
lxc config set core.https_address [::]:8443
lxc config set core.trust_password something-secure
在你本地 LXD 上,你需要使它對網路可見,這樣我們可以從它傳輸容器和鏡像:
lxc config set core.https_address [::]:8443
現在已經在兩端完成了守護進程的配置,你可以添加「foo」到你的本地客戶端:
lxc remote add foo 1.2.3.4
(將 1.2.3.4 替換成你的 IP 或者 FQDN)
看上去像這樣:
stgraber@dakara:~$ lxc remote add foo 2607:f2c0:f00f:2770:216:3eff:fee1:bd67
Certificate fingerprint: fdb06d909b77a5311d7437cabb6c203374462b907f3923cefc91dd5fce8d7b60
ok (y/n)? y
Admin password for foo:
Client certificate stored at server: foo
你接著可以列出遠端伺服器,你可以在列表中看到「foo」:
stgraber@dakara:~$ lxc remote list
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| NAME | URL | PROTOCOL | PUBLIC | STATIC |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| foo | https://[2607:f2c0:f00f:2770:216:3eff:fee1:bd67]:8443 | lxd | NO | NO |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| images | https://images.linuxcontainers.org:8443 | lxd | YES | NO |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| local (default) | unix:// | lxd | NO | YES |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| ubuntu | https://cloud-images.ubuntu.com/releases | simplestreams | YES | YES |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| ubuntu-daily | https://cloud-images.ubuntu.com/daily | simplestreams | YES | YES |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
與它交互
好了,所以我們已經有了一台定義好的遠程伺服器,我們現在可以做些什麼?
現在,就如你看到的,唯一的不同是你必須告訴 LXD 要哪台主機運行。
比如:
lxc launch ubuntu:14.04 c1
它會在默認主機(lxc remote get-default
),也就是你的本機上運行。
lxc launch ubuntu:14.04 foo:c1
這個會在 foo 上運行。
列出遠程主機正在運行的容器可以這麼做:
stgraber@dakara:~$ lxc list foo:
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| c1 | RUNNING | 10.245.81.95 (eth0) | 2607:f2c0:f00f:2770:216:3eff:fe43:7994 (eth0) | PERSISTENT | 0 |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
你要記住的一件事是你需要在遠程主機上同時指定鏡像和容器。因此如果你在「foo」上有一個「my-image」的鏡像,並且希望從它創建一個「c2」的容器,你需要運行:
lxc launch foo:my-image foo:c2
最後,就如你希望的那樣得到一個遠程容器的 shell:
lxc exec foo:c1 bash
複製容器
在兩台主機間複製容器就如它聽上去那樣簡單:
lxc copy foo:c1 c2
你會有一個新的從遠程「c1」複製過來的本地「c2」容器。這需要停止「c1」容器,但是你可以在運行的時候只複製一個快照:
lxc snapshot foo:c1 current
lxc copy foo:c1/current c3
移動容器
除非你在做實時遷移(將會在之後的文章中講到),不然你需要在移動前先停止容器,接著就會如你預料的那樣。
lxc stop foo:c1
lxc move foo:c1 local:
這個例子等同於:
lxc stop foo:c1
lxc move foo:c1 c1
是如何工作的
正如你期望的那樣, 與遠程容器的交互時 LXD 使用的 REST API 並不是通過本地 Unix 套接字,而是通過 HTTPS 傳輸。
當兩個守護程序之間交互時會變得有些棘手,如複製和移動的情況。
在這種情況下會發生:
- 用戶運行
lxc move foo:c1 c1
。 - 客戶端聯繫
local:
遠程以檢查是否現有「c1」容器。 - 客戶端從「foo」獲取容器信息。
- 客戶端從源「foo」守護程序請求遷移令牌。
- 客戶端將遷移令牌以及源 URL 和「foo」的證書發送到本地 LXD 守護程序以及容器配置和周圍設備。
- 然後本地 LXD 守護程序使用提供的令牌直接連接到「foo」 a) 它連接到第一個控制 websocket b) 它協商文件系統傳輸協議(zfs 發送/接收,btrfs 發送/接收或者純 rsync) c) 如果在本地可用,它會解壓用於創建源容器的鏡像。這是為了避免不必要的數據傳輸。 d) 然後它會將容器及其任何快照作為增量傳輸。
- 如果成功,客戶端會命令「foo」刪除源容器。
在線嘗試
沒有兩台機器來嘗試遠端交互和複製/移動容器?
沒有問題,你可以使用我們的 demo 服務。這裡甚至還包括了一步步的指導!
額外信息
LXD 的主站在: https://linuxcontainers.org/lxd
LXD 的 GitHub 倉庫: https://github.com/lxc/lxd
LXD 的郵件列表: https://lists.linuxcontainers.org
LXD 的 IRC 頻道: #lxcontainers on irc.freenode.net
作者簡介:我是 Stéphane Graber。我是 LXC 和 LXD 項目的領導者,目前在加拿大魁北克蒙特利爾的家所在的Canonical 有限公司擔任 LXD 的技術主管。
via: https://www.stgraber.org/2016/04/12/lxd-2-0-remote-hosts-and-container-migration-612/
作者:Stéphane Graber 譯者:geekpi 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive