Part 1 - LXD 2.0: LXD 入门
======================================

这是 [LXD 2.0 系列介绍文章][1]的第一篇。

![](https://linuxcontainers.org/static/img/containers.png)


### 关于 LXD 几个常见问题

#### 什么是 LXD ?

简单地说， LXD 就是一个提供了 REST API 的 LXC 容器管理器。

LXD 最主要的目标就是使用 Linux 容器而不是硬件虚拟化向用户提供一种接近虚拟机的使用体验。

#### LXD 和 Docker/Rkt 又有什么关系呢 ?

这是一个最常被问起的问题，现在就让我们直接指出其中的不同吧。

LXD 聚焦于系统容器，通常也被称为架构容器。这就是说 LXD 容器实际上如在裸机或虚拟机上运行一般运行了一个完整的 Linux 操作系统。

这些容器一般基于一个干净的发布镜像并会长时间运行。传统的配置管理工具和部署工具可以如在虚拟机、云和物理机器上一样与 LXD 一起使用。

相对的， Docker 关注于短期的、无状态的最小容器，这些容器通常并不会升级或者重新配置，而是作为一个整体被替换掉。这就使得 Docker 及类似项目更像是一种软件发布机制，而不是一个机器管理工具。

这两种模型并不是完全互斥的。你完全可以使用 LXD 为你的用户提供一个完整的 Linux 系统，而他们可以在 LXD 内安装 Docker 来运行他们想要的软件。


#### 为什么要用 LXD?

我们已经持续开发并改进 LXC 好几年了。 LXC 成功的实现了它的目标，它提供了一系列很棒的用于创建和管理容器的底层工具和库。

然而这些底层工具的使用界面对用户并不是很友好。使用它们需要用户有很多的基础知识以理解它们的工作方式和目的。同时，向后兼容旧的容器和部署策略也使得 LXC 无法默认使用一些安全特性，这导致用户需要进行更多人工操作来实现本可以自动完成的工作。

我们把 LXD 作为解决这些缺陷的一个很好的机会。作为一个长时间运行的守护进程， LXD 可以绕开 LXC 的许多限制，比如动态资源限制、无法进行容器迁移和高效的在线迁移；同时，它也为创造新的默认体验提供了机会：默认开启安全特性，对用户更加友好。


### LXD 的主要组件

LXD 是由几个主要组件构成的，这些组件都是 LXD 目录结构、命令行客户端和 API 结构体里下可见的。

#### 容器

LXD 中的容器包括以下及部分：

- 根文件系统
- 设备：包括磁盘、unix 字符/块设备、网络接口
- 一组继承而来的容器配置文件
- 属性（容器架构，暂时的或持久的，容器名）
- 运行时状态（当时为了记录检查点、恢复时用到了 CRIU时）

#### 快照

容器快照和容器是一回事，只不过快照是不可修改的，只能被重命名，销毁或者用来恢复系统，但是无论如何都不能被修改。

值得注意的是，因为我们允许用户保存容器的运行时状态，这就有效的为我们提供了“有状态”的快照的功能。这就是说我们可以使用快照回滚容器的 CPU 和内存。

#### 镜像

LXD 是基于镜像实现的，所有的 LXD 容器都是来自于镜像。容器镜像通常是一些纯净的 Linux 发行版的镜像，类似于你们在虚拟机和云实例上使用的镜像。

所以就可以「发布」容器：使用容器制作一个镜像并在本地或者远程 LXD 主机上使用。

镜像通常使用全部或部分 sha256 哈希码来区分。因为输入长长的哈希码对用户来说不好，所以镜像可以使用几个自身的属性来区分，这就使得用户在镜像商店里方便搜索镜像。别名也可以用来 1 对 1 地把对用户友好的名字映射到某个镜像的哈希码。

LXD 安装时已经配置好了三个远程镜像服务器（参见下面的远程一节）：

- “ubuntu：” 提供稳定版的 Ubuntu 镜像
- “ubuntu-daily：” 提供每天构建出来的 Ubuntu
- “images：” 社区维护的镜像服务器，提供一系列的 Linux 发布版，使用的是上游 LXC 的模板

LXD 守护进程会从镜像上次被使用开始自动缓存远程镜像一段时间（默认是 10 天），超过时限后这些镜像才会失效。

此外， LXD 还会自动更新远程镜像（除非指明不更新），所以本地的镜像会一直是最新版的。


#### 配置

配置文件是一种在一处定义容器配置和容器设备，然后应用到一系列容器的方法。

一个容器可以被应用多个配置文件。当构建最终容器配置时（即通常的扩展配置），这些配置文件都会按照他们定义顺序被应用到容器上，当有重名的配置时，新的会覆盖掉旧的。然后本地容器设置会在这些基础上应用，覆盖所有来自配置文件的选项。

LXD 自带两种预配置的配置文件：

- 「 default 」配置是自动应用在所有容器之上，除非用户提供了一系列替代的配置文件。目前这个配置文件只做一件事，为容器定义 eth0 网络设备。
- 「 docker” 」配置是一个允许你在容器里运行 Docker 容器的配置文件。它会要求 LXD 加载一些需要的内核模块以支持容器嵌套并创建一些设备入口。

#### 远程

如我之前提到的， LXD 是一个基于网络的守护进程。附带的命令行客户端可以与多个远程 LXD 服务器、镜像服务器通信。

默认情况下，我们的命令行客户端会与下面几个预定义的远程服务器通信：

- local：（默认的远程服务器，使用 UNIX socket 和本地的 LXD 守护进程通信）
- ubuntu：（ Ubuntu 镜像服务器，提供稳定版的 Ubuntu 镜像）
- ubuntu-daily：（ Ubuntu 镜像服务器，提供每天构建出来的 Ubuntu ）
- images：（ images.linuxcontainers.org 镜像服务器）

所有这些远程服务器的组合都可以在命令行客户端里使用。

你也可以添加任意数量的远程 LXD 主机来监听网络。匿名的开放镜像服务器，或者通过认证可以管理远程容器的镜像服务器，都可以添加进来。

正是这种远程机制使得与远程镜像服务器交互及在主机间复制、移动容器成为可能。

### 安全性

我们设计 LXD 时的一个核心要求，就是在不修改现代 Linux 发行版的前提下，使容器尽可能的安全。

LXD 使用的、通过使用 LXC 库实现的主要安全特性有：

- 内核名字空间。尤其是用户名字空间，它让容器和系统剩余部分完全分离。LXD 默认使用用户名字空间（和 LXC 相反），并允许用户在需要的时候以容器为单位打开或关闭。
- Seccomp 系统调用。用来隔离潜在危险的系统调用。
- AppArmor：对 mount、socket、ptrace 和文件访问提供额外的限制。特别是限制跨容器通信。
- Capabilities。阻止容器加载内核模块，修改主机系统时间，等等。
- CGroups。限制资源使用，防止对主机的 DoS 攻击。


为了对用户友好 ， LXD 构建了一个新的配置语言把大部分的这些特性都抽象封装起来，而不是如 LXC 一般直接将这些特性暴露出来。举了例子，一个用户可以告诉 LXD 把主机设备放进容器而不需要手动检查他们的主/次设备号来更新 CGroup 策略。

和 LXD 本身通信是基于使用 TLS 1.2 保护的链路，这些链路只允许使用有限的几个被允许的密钥。当和那些经过系统证书认证之外的主机通信时， LXD 会提示用户验证主机的远程足迹（SSH 方式），然后把足迹缓存起来以供以后使用。

### REST 接口

LXD 的工作都是通过 REST 接口实现的。在客户端和守护进程之间并没有其他的通讯手段。

REST 接口可以通过本地的 unix socket 访问，这只需要经过组认证，或者经过 HTTP 套接字使用客户端认证进行通信。

REST 接口的结构能够和上文所说的不同的组件匹配，是一种简单、直观的使用方法。

当需要一种复杂的通信机制时， LXD 将会进行 websocket 协商完成剩余的通信工作。这主要用于交互式终端会话、容器迁移和事件通知。

LXD 2.0 附带了 1.0 版的稳定 API。虽然我们在 1.0 版 API 添加了额外的特性，但是这不会在 1.0 版 API 的端点里破坏向后兼容性，因为我们会声明额外的 API 扩展使得客户端可以找到新的接口。

### 容器规模化

虽然 LXD 提供了一个很好的命令行客户端，但是这个客户端并不能管理多个主机上大量的容器。在这种使用情况下，我们可以使用 OpenStack 的 nova-lxd 插件，它可以使 OpenStack 像使用虚拟机一样使用 LXD 容器。

这就允许在大量的主机上部署大量的 LXD 容器，然后使用 OpenStack 的 API 来管理网络、存储以及负载均衡。

### 额外信息

LXD 的主站在: <https://linuxcontainers.org/lxd>

LXD 的 GitHub 仓库: <https://github.com/lxc/lxd>

LXD 的邮件列表: <https://lists.linuxcontainers.org>

LXD 的 IRC 频道: #lxcontainers on irc.freenode.net

如果你不想或者不能在你的机器上安装 LXD ，你可以在 web 上[试试在线版的 LXD] [2] 。

--------------------------------------------------------------------------------

via: https://www.stgraber.org/2016/03/11/lxd-2-0-introduction-to-lxd-112/

作者：[Stéphane Graber][a]
译者：[ezio](https://github.com/oska874)
校对：[PurlingNayuki](https://github.com/PurlingNayuki)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出

[a]: https://www.stgraber.org/author/stgraber/
[1]: https://www.stgraber.org/2016/03/11/lxd-2-0-blog-post-series-012/
[2]: https://linuxcontainers.org/lxd/try-it
