LXD 2.0 系列(七):LXD 中的 Docker
為什麼在 LXD 中運行 Docker
正如我在系列的第一篇中簡要介紹的,LXD 的重點是系統容器,也就是我們在容器中運行一個完全未經修改的 Linux 發行版。LXD 的所有意圖和目的並不在乎容器中的負載是什麼。它只是設置容器命名空間和安全策略,然後運行 /sbin/init
來生成容器,接著等待容器停止。
應用程序容器,例如由 Docker 或 Rkt 所實現的應用程序容器是非常不同的,因為它們用於分發應用程序,通常在它們內部運行單個主進程,並且比 LXD 容器生命期更短暫。
這兩種容器類型不是相互排斥的,我們的確看到使用 Docker 容器來分發應用程序的價值。這就是為什麼我們在過去一年中努力工作以便讓 LXD 中運行 Docker 成為可能。
這意味著,使用 Ubuntu 16.04 和 LXD 2.0,您可以為用戶創建容器,然後可以像正常的 Ubuntu 系統一樣連接到這些容器,然後運行 Docker 來安裝他們想要的服務和應用程序。
要求
要讓它正常工作要做很多事情,Ubuntu 16.04 上已經包含了這些:
- 支持 CGroup 命名空間的內核(4.4 Ubuntu 或 4.6 主線內核)
- 使用 LXC 2.0 和 LXCFS 2.0 的 LXD 2.0
- 一個自定義版本的 Docker(或一個用我們提交的所有補丁構建的)
- Docker 鏡像,其受限於用戶命名空間限制,或者使父 LXD 容器成為特權容器(
security.privileged = true
)
運行一個基礎的 Docker 載荷
說完這些,讓我們開始運行 Docker 容器!
首先你可以用下面的命令得到一個 Ubuntu 16.04 的容器:
lxc launch ubuntu-daily:16.04 docker -p default -p docker
-p default -p docker
表示 LXD 將 default
和 docker
配置文件應用於容器。default
配置文件包含基本網路配置,而 docker
配置文件告訴 LXD 載入幾個必需的內核模塊並為容器設置一些掛載。 docker
配置文件還支持容器嵌套。
現在讓我們確保容器是最新的並安裝 docker:
lxc exec docker -- apt update
lxc exec docker -- apt dist-upgrade -y
lxc exec docker -- apt install docker.io -y
就是這樣!你已經安裝並運行了一個 Docker 容器。
現在讓我們用兩個 Docker 容器開啟一個基礎的 web 服務:
stgraber@dakara:~$ lxc exec docker -- docker run --detach --name app carinamarina/hello-world-app
Unable to find image 'carinamarina/hello-world-app:latest' locally
latest: Pulling from carinamarina/hello-world-app
efd26ecc9548: Pull complete
a3ed95caeb02: Pull complete
d1784d73276e: Pull complete
72e581645fc3: Pull complete
9709ddcc4d24: Pull complete
2d600f0ec235: Pull complete
c4cf94f61cbd: Pull complete
c40f2ab60404: Pull complete
e87185df6de7: Pull complete
62a11c66eb65: Pull complete
4c5eea9f676d: Pull complete
498df6a0d074: Pull complete
Digest: sha256:6a159db50cb9c0fbe127fb038ed5a33bb5a443fcdd925ec74bf578142718f516
Status: Downloaded newer image for carinamarina/hello-world-app:latest
c8318f0401fb1e119e6c5bb23d1e706e8ca080f8e44b42613856ccd0bf8bfb0d
stgraber@dakara:~$ lxc exec docker -- docker run --detach --name web --link app:helloapp -p 80:5000 carinamarina/hello-world-web
Unable to find image 'carinamarina/hello-world-web:latest' locally
latest: Pulling from carinamarina/hello-world-web
efd26ecc9548: Already exists
a3ed95caeb02: Already exists
d1784d73276e: Already exists
72e581645fc3: Already exists
9709ddcc4d24: Already exists
2d600f0ec235: Already exists
c4cf94f61cbd: Already exists
c40f2ab60404: Already exists
e87185df6de7: Already exists
f2d249ff479b: Pull complete
97cb83fe7a9a: Pull complete
d7ce7c58a919: Pull complete
Digest: sha256:c31cf04b1ab6a0dac40d0c5e3e64864f4f2e0527a8ba602971dab5a977a74f20
Status: Downloaded newer image for carinamarina/hello-world-web:latest
d7b8963401482337329faf487d5274465536eebe76f5b33c89622b92477a670f
現在這兩個 Docker 容器已經運行了,我們可以得到 LXD 容器的 IP 地址,並且訪問它的服務了!
stgraber@dakara:~$ lxc list
+--------+---------+----------------------+----------------------------------------------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------+---------+----------------------+----------------------------------------------+------------+-----------+
| docker | RUNNING | 172.17.0.1 (docker0) | 2001:470:b368:4242:216:3eff:fe55:45f4 (eth0) | PERSISTENT | 0 |
| | | 10.178.150.73 (eth0) | | | |
+--------+---------+----------------------+----------------------------------------------+------------+-----------+
stgraber@dakara:~$ curl http://10.178.150.73
The linked container said... "Hello World!"
總結
就是這樣了!在 LXD 容器中運行 Docker 容器真的很簡單。
現在正如我前面提到的,並不是所有的 Docker 鏡像都會像我的示例一樣,這通常是因為 LXD 帶來了額外的限制,特別是用戶命名空間。
在這種模式下只有 Docker 的 overlayfs 存儲驅動可以工作。該存儲驅動有一組自己的限制,這進一步限制了在該環境中可以有多少鏡像工作。
如果您的負載無法正常工作,並且您信任該 LXD 容器中的用戶,你可以試下:
lxc config set docker security.privileged true
lxc restart docker
這將取消激活用戶命名空間,並以特權模式運行容器。
但是請注意,在這種模式下,容器內的 root 與主機上的 root 是相同的 uid。現在有許多已知的方法讓用戶脫離容器,並獲得主機上的 root 許可權,所以你應該只有在信任你的 LXD 容器中的用戶可以具有主機上的 root 許可權才這樣做。
額外信息
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/13/lxd-2-0-docker-in-lxd-712/
作者:Stéphane Graber 譯者:geekpi 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive