LXD 2.0 系列(七):LXD中的Docker

这是 LXD 2.0 系列介绍文章的第七篇。

  1. LXD 入门
  2. 安装与配置
  3. 你的第一个 LXD 容器
  4. 资源控制
  5. 镜像管理
  6. 远程主机及容器迁移

为什么在 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 的容器:


  1. lxc launch ubuntu-daily:16.04 docker -p default -p docker 

-p default -p docker 表示 LXD 将 default 和 docker 配置文件应用于容器。default 配置文件包含基本网络配置,而 docker 配置文件告诉 LXD 加载几个必需的内核模块并为容器设置一些挂载。 docker 配置文件还支持容器嵌套。

现在让我们确保容器是最新的并安装 docker:


  1. lxc exec docker -- apt update 
  2. lxc exec docker -- apt dist-upgrade -y 
  3. lxc exec docker -- apt install docker.io -y 

就是这样!你已经安装并运行了一个 Docker 容器。

现在让我们用两个 Docker 容器开启一个基础的 web 服务:


  1. stgraber@dakara:~$ lxc exec docker -- docker run --detach --name app carinamarina/hello-world-app 
  2. Unable to find image 'carinamarina/hello-world-app:latest' locally 
  3. latest: Pulling from carinamarina/hello-world-app 
  4. efd26ecc9548: Pull complete  
  5. a3ed95caeb02: Pull complete  
  6. d1784d73276e: Pull complete  
  7. 72e581645fc3: Pull complete  
  8. 9709ddcc4d24: Pull complete  
  9. 2d600f0ec235: Pull complete  
  10. c4cf94f61cbd: Pull complete  
  11. c40f2ab60404: Pull complete  
  12. e87185df6de7: Pull complete  
  13. 62a11c66eb65: Pull complete  
  14. 4c5eea9f676d: Pull complete  
  15. 498df6a0d074: Pull complete  
  16. Digest: sha256:6a159db50cb9c0fbe127fb038ed5a33bb5a443fcdd925ec74bf578142718f516 
  17. Status: Downloaded newer image for carinamarina/hello-world-app:latest 
  18. c8318f0401fb1e119e6c5bb23d1e706e8ca080f8e44b42613856ccd0bf8bfb0d 
  19. stgraber@dakara:~$ lxc exec docker -- docker run --detach --name web --link app:helloapp -p 80:5000 carinamarina/hello-world-web 
  20. Unable to find image 'carinamarina/hello-world-web:latest' locally 
  21. latest: Pulling from carinamarina/hello-world-web 
  22. efd26ecc9548: Already exists  
  23. a3ed95caeb02: Already exists  
  24. d1784d73276e: Already exists  
  25. 72e581645fc3: Already exists  
  26. 9709ddcc4d24: Already exists  
  27. 2d600f0ec235: Already exists  
  28. c4cf94f61cbd: Already exists  
  29. c40f2ab60404: Already exists  
  30. e87185df6de7: Already exists  
  31. f2d249ff479b: Pull complete  
  32. 97cb83fe7a9a: Pull complete  
  33. d7ce7c58a919: Pull complete  
  34. Digest: sha256:c31cf04b1ab6a0dac40d0c5e3e64864f4f2e0527a8ba602971dab5a977a74f20 
  35. Status: Downloaded newer image for carinamarina/hello-world-web:latest 
  36. d7b8963401482337329faf487d5274465536eebe76f5b33c89622b92477a670f 

现在这两个 Docker 容器已经运行了,我们可以得到 LXD 容器的 IP 地址,并且访问它的服务了!


  1. stgraber@dakara:~$ lxc list 
  2. +--------+---------+----------------------+----------------------------------------------+------------+-----------+ 
  3. |  NAME  |  STATE  |         IPV4         |                      IPV6                    |    TYPE    | SNAPSHOTS | 
  4. +--------+---------+----------------------+----------------------------------------------+------------+-----------+ 
  5. | docker | RUNNING | 172.17.0.1 (docker0) | 2001:470:b368:4242:216:3eff:fe55:45f4 (eth0) | PERSISTENT | 0         | 
  6. |        |         | 10.178.150.73 (eth0) |                                              |            |           | 
  7. +--------+---------+----------------------+----------------------------------------------+------------+-----------+ 
  8. stgraber@dakara:~$ curl http://10.178.150.73 
  9. The linked container said... "Hello World!" 

总结

就是这样了!在 LXD 容器中运行 Docker 容器真的很简单。

现在正如我前面提到的,并不是所有的 Docker 镜像都会像我的示例一样,这通常是因为 LXD 带来了额外的限制,特别是用户命名空间。

在这种模式下只有 Docker 的 overlayfs 存储驱动可以工作。该存储驱动有一组自己的限制,这进一步限制了在该环境中可以有多少镜像工作。

如果您的负载无法正常工作,并且您信任该 LXD 容器中的用户,你可以试下:


  1. lxc config set docker security.privileged true 
  2. lxc restart docker 

这将取消激活用户命名空间,并以特权模式运行容器。

但是请注意,在这种模式下,容器内的 root 与主机上的 root 是相同的 uid。现在有许多已知的方法让用户脱离容器,并获得主机上的 root 权限,所以你应该只有在信任你的 LXD 容器中的用户可以具有主机上的 root 权限才这样做。

作者:Stéphane Graber

来源:51CTO

时间: 2024-12-31 01:55:14

LXD 2.0 系列(七):LXD中的Docker的相关文章

LXD 2.0 系列(八):LXD中的LXD

这是 LXD 2.0 系列介绍文章的第八篇. LXD 入门 安装与配置 你的第一个 LXD 容器 资源控制 镜像管理 远程主机及容器迁移 LXD 中的 Docker 介绍 在上一篇文章中,我介绍了如何在 LXD 中运行 Docker,这是一个访问由 Docker 提供的应用程序组合的很好方式,同时 Docker 还运行在 LXD 提供的安全环境中. 我提到的一个情况是为你的用户提供一个 LXD 容器,然后让他们使用他们的容器来运行 Docker.那么,如果他们自己想要在其容器中使用 LXD 运行

LXD 2.0系列之二:LXD安装和配置

本文讲的是LXD 2.0系列之二:LXD安装和配置,[编者的话]第三方调查报告显示LXD有潜质成为一款受欢迎的第三方容器管理工具.本文是LXD核心维护者.加拿大程序员Stéphane Graber有关LXD连载博文的第二篇. [LXD 2.0系列开篇:是时候讨论LXD的一切了][LXD 2.0系列之一:LXD简介][LXD 2.0系列之二:LXD安装和配置][LXD 2.0系列之三:你的第一个LXD容器][LXD 2.0系列之四:资源管理][LXD 2.0系列之五:镜像管理][LXD 2.0系列

LXD 2.0 系列(十二):调试,及给LXD做贡献

介绍 终于要结束了!这个大约一年前开始的这系列文章的最后一篇博文. LXD 入门 安装与配置 你的第一个 LXD 容器 资源控制 镜像管理 远程主机及容器迁移 LXD 中的 Docker LXD 中的 LXD 实时迁移 LXD 和 Juju LXD 和 OpenStack 调试,及给 LXD 做贡献 如果你从一开始就关注了这个系列,你应该已经使用了 LXD 相当长的时间了,并且非常熟悉它的日常操作和功能. 但如果出现问题怎么办?你可以做什么来自己跟踪问题?如果你不能,你应该记录什么信息,以便上游

LXD 2.0 系列(三):你的第一个 LXD 容器

这是 LXD 2.0 系列介绍文章的第三篇博客. LXD 入门 安装与配置 你的第一个 LXD 容器 资源控制 镜像管理 远程主机及容器迁移 LXD 中的 Docker LXD 中的 LXD 实时迁移 LXD 和 Juju LXD 和 OpenStack 调试,及给 LXD 做贡献 由于在管理 LXD 容器时涉及到大量的命令,所以这篇文章的篇幅是比较长的,如果你更喜欢使用同样的命令来快速的一步步实现整个过程,你可以尝试我们的在线示例! 创建并启动一个新的容器 正如我在先前的文章中提到的一样,LX

LXD 2.0 系列(四):资源控制

这是 LXD 2.0 系列介绍文章的第四篇. LXD 入门 安装与配置 你的第一个 LXD 容器 因为 LXD 容器管理有很多命令,因此这篇文章会很长. 如果你想要快速地浏览这些相同的命令,你可以尝试下我们的在线演示! 可用资源限制 LXD 提供了各种资源限制.其中一些与容器本身相关,如内存配额.CPU 限制和 I/O 优先级.而另外一些则与特定设备相关,如 I/O 带宽或磁盘用量限制. 与所有 LXD 配置一样,资源限制可以在容器运行时动态更改.某些可能无法启用,例如,如果设置的内存值小于当前

LXD 2.0 系列(九):实时迁移

这是 LXD 2.0 系列介绍文章的第九篇. LXD 入门 安装与配置 你的第一个 LXD 容器 资源控制 镜像管理 远程主机及容器迁移 LXD 中的 Docker LXD 中的 LXD 介绍 LXD 2.0 中的有一个尽管是实验性质的但非常令人兴奋的功能,那就是支持容器检查点和恢复. 简单地说,检查点/恢复意味着正在运行的容器状态可以被序列化到磁盘,要么可以作为同一主机上的有状态快照,要么放到另一主机上相当于实时迁移. 要求 要使用容器实时迁移和有状态快照,你需要以下条件: 一个非常新的 Li

LXD 2.0系列之开篇:是时候讨论LXD的一切了

本文讲的是LXD 2.0系列之开篇:是时候讨论LXD的一切了,[编者的话]第三方调查报告显示LXD有潜质成为一款受欢迎的第三方容器管理工具.本文是LXD核心维护者.加拿大程序员Stéphane Graber有关LXD连载博文的开篇. 我们一年半前开始这个项目,当越来越接近LXC,LXD和LXCFS 2.0的最终版本时,我想,是时候讨论一下LXD的一切. 这将是一个连载博文,和很多年前我写的"LXC 1.0我做了什么"系列类似,内容包括: [LXD 2.0系列开篇:是时候讨论LXD的一切

LXD 2.0系列之一:LXD简介

本文讲的是LXD 2.0系列之一:LXD简介,[编者的话]第三方调查报告显示LXD有潜质成为一款受欢迎的第三方容器管理工具.本文是LXD核心维护者.加拿大程序员Stéphane Graber有关LXD连载博文的第一篇. [LXD 2.0系列开篇:是时候讨论LXD的一切了][LXD 2.0系列之一:LXD简介][LXD 2.0系列之二:LXD安装和配置][LXD 2.0系列之三:你的第一个LXD容器][LXD 2.0系列之四:资源管理][LXD 2.0系列之五:镜像管理][LXD 2.0系列之六:

LXD 2.0 系列(六):远程主机及容器迁移

这是 LXD 2.0 系列介绍文章的第六篇. LXD 入门 安装与配置 你的第一个 LXD 容器 资源控制 镜像管理 远程协议 LXD 2.0 支持两种协议: LXD 1.0 API:这是在客户端和 LXD 守护进程之间使用的 REST API,以及在 LXD 守护进程间复制/移动镜像和容器时使用的 REST API. Simplestreams:Simplestreams 协议是 LXD 客户端和守护进程使用的只读.仅针对镜像的协议,用于客户端和 LXD 守护进程获取镜像信息以及从一些公共镜像