在Ubuntu13.04VPS上开始使用LXC

来自菜鸟教程
跳转至:导航、​搜索

介绍

LXC 或 Linux 容器是基于现代 Linux 内核中包含的许多功能构建的系统,允许在单个父主机系统上创建和管理许多虚拟化 Linux 系统。 然而,与一些虚拟化解决方案不同的是,它没有使用硬件仿真,并且容器与主机共享内核,这使得 LXC 非常轻巧且易于上手。 此外,由于它仅依赖于主线内核功能,LXC 可以在 DigitalOcean 上的 KVM 映像中使用。

LXC 的一些主要优势包括:

Security - 通过在单独的容器中运行关键服务,您可以确保一个容器中的安全漏洞将更好地隔离,不会影响其他服务。 这听起来可能与 chroot 监狱非常相似,但 LXC 提供的不仅仅是文件系统隔离。

可移植性 - LXC 容器可以压缩并移动到具有相同处理器架构的任何其他主机。 这在您扩展应用程序时非常有用,因为可以轻松复制或移动单个服务。

Limits - 由于它使用 Linux cgroups,LXC 容器可以配置为限制资源。 在运行大量容器时,这可以确保最重要的容器优先。

注意:以下教程要求主机上的所有命令都以 root 用户身份执行。

警告: 不要尝试在 Debian 系统上使用以下教程。 尽管它们有相似之处,但 Debian LXC 软件包有许多缺陷,阻碍了容器与其主机系统之间的正确隔离。

安装

在我们可以创建我们的第一个 LXC 容器之前,我们需要安装管理和创建它们所需的工具:

apt-get install lxc

该软件包安装了 LXC 的要求,还为容器设置了网络结构。 软件包安装完成后,我们可以通过运行 lxc-checkconfig 检查内核并准备好配置:

$ lxc-checkconfig
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-3.8.0-19-generic
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: missing
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

您可能会注意到“用户命名空间”被指示为缺失; 理想情况下应该启用它,但是对于本教程中提出的用例,LXC 仍然可以在没有它的情况下运行。

创建新容器

使用 lxc-create 命令创建新的 LXC 容器。 我们'将使用ubuntu模板来创建和填充一个名为'test-container'的新容器:

lxc-create -n test-container -t ubuntu

此命令第一次可能需要几分钟才能完成,因为它会下载并缓存所有必需的组件。 但是,它最终会返回,您将在新容器中使用 debootstrap 创建一个非常小的 Ubuntu 安装。

创建输出的最后几行也会告诉我们创建容器的默认用户名和密码:

##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

在任何时候,我们都可以使用 lxc-ls --fancy 检查容器的状态,这将显示我们的容器处于停止状态:

# lxc-ls --fancy
NAME            STATE    IPV4  IPV6  AUTOSTART
----------------------------------------------
test-container  STOPPED  -     -     NO

保存配置文件后,下一步就是让我们的容器运行,这可以通过 lxc-start 来实现:

lxc-start -n test-container -d

该命令将立即返回,而容器将在后台启动。 几秒钟后,再次尝试 lxc-ls --fancy ,我们 ' 将看到容器正在运行并已分配 IP 地址:

# lxc-ls --fancy
NAME            STATE    IPV4        IPV6  AUTOSTART
----------------------------------------------------
test-container  RUNNING  10.0.3.143  -     NO

请注意,分配的 IP 属于内部网桥,这意味着无法从您的外部 DigitalOcean IP 访问容器,但可以访问 Internet。 在下一节中,我们将研究端口转发以允许容器内的服务侦听公共 VPS 接口。

最后,我们可以使用 lxc-console 访问我们的容器:

lxc-console -n test-container

这将使您进入为容器运行的常规登录提示,您可以在其中使用在创建 VPS (ubuntu/ubuntu) 期间提供的用户名/密码组合。 建议您更改任何将托管面向 Internet 的服务的容器的默认密码。

登录后,您会看到一个常规的 bash 提示符,您几乎可以在该提示符下在主机上执行任何操作。 由于这是一个最小的安装,您可能会注意到您使用的一些工具不存在,但如果需要,可以通过 apt-get 安装这些工具。

探索完新容器后,您可以退出其控制台并返回主机,方法是键入 Ctrl-A,然后键入 Q

安装服务

例如,我们将在容器中安装 nginx 并使其可以从 Internet 访问。 我们的容器正在有效地运行自己的 Ubuntu VPS 实例,这意味着安装服务与在主机本身上安装非常相似; 因此,即使在容器中,DigitalOcean 上的许多教程也应该可以很好地工作。

通过 lxc-console 连接后,我们可以安装 nginx 包:

sudo apt-get install nginx
sudo service nginx start

这将安装 nginx 并确保它正在运行,但我们还不能从主机的公共接口访问它。 如果您导航到 http://your-DO-ip 并注意它还没有响应,您会看到这种情况。

如前所述,容器被赋予在私有范围内的 IP,该 IP 在 NAT 后面运行,因此通常无法从 Internet 访问。 这类似于大多数家庭网络的运行方式,所有计算机在网关上共享一个 IP。

在主机 上使用 iptables 可以查看 NAT 是如何配置的:

# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24

此设置允许所有容器访问外部网络,但需要端口转发才能将容器上的服务公开到 Internet。

再次查看上面的 lxc-ls --fancy 输出,我们可以看到我们的容器被分配了私有 IP 10.0.3.143(这个' 可能对你不同)。 通过在预路由表中添加一个 iptables 规则,我们可以将 80 端口上的数据包转发到我们的 nginx 容器的 80 端口。

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 10.0.3.143:80

注意:如果主机上已经有服务监听 80 端口,则此规则会将所有数据包转发到容器(即使未运行),因此主机的服务将无法访问。

导航到 http://your-DO-ip 现在应该会显示默认的 nginx 页面,告诉我们设置和端口转发已经成功:

现在可以在新容器中为您希望运行的任何其他服务重复此过程。 这种方法的好处是,如果在 nginx 中发现并利用安全漏洞,攻击者将无法影响任何其他服务,例如您的数据库,而无需首先找到另一个漏洞来逃离容器。

添加限制

除了隔离之外,使用 LXC 的另一个巨大好处是它能够将 cgroup 限制应用于容器内的进程。

容器的限制在其配置文件中定义,我们的容器可以在 /var/lib/lxc/test-container/config 找到。

内存限制可用于设置容器的最大 RAM 使用量。 在这种情况下,我们将容器限制为 50MB 内存:

lxc.cgroup.memory.limit_in_bytes = 50000000

CPU 限制的定义略有不同; 与定义物理限制的内存不同,CPU 限制与 CPU“份额”一起运行:

lxc.cgroup.cpu.shares = 100

这些份额与任何物理量无关,而只是代表 CPU 资源的相对分配,这意味着具有更多份额的容器将获得更高的 CPU 访问优先级。 使用的数字是完全任意的,因此给一个容器 10 和另一个 20 与分别给它们 1000 和 2000 是一样的,因为它告诉我们的是第二个容器具有两倍的 CPU 共享优先级。 只需确保您与容器之间的规模保持一致。

在配置文件中更改 cgroup 限制后,您需要关闭并重新启动容器才能使更改生效。

或者,可以使用 lxc-cgroup 命令在正在运行的容器上临时设置限制:

lxc-cgroup -n test-container cpu.shares 100

自动启动

通常情况下,您希望容器在重新启动后自动启动,尤其是在它们托管服务的情况下。 默认情况下,容器不会在重启后启动,即使它们在关闭之前正在运行。

要使容器自动启动,您只需将其配置文件符号链接到 /etc/lxc/auto 目录:

ln -s /var/lib/lxc/test-container/config /etc/lxc/auto/test-container.conf

现在再次运行 lxc-ls --fancy 将显示我们的容器已设置为自动启动:

# lxc-ls --fancy
NAME            STATE    IPV4        IPV6  AUTOSTART
----------------------------------------------------
test-container  RUNNING  10.0.3.143  -     YES

销毁容器

完成容器后,可以将其从系统中删除以释放磁盘空间。 首先,确保使用 lxc-shutdown 停止容器:

lxc-shutdown -n test-container

这将尝试安全地关闭容器。 将 lxc-shutdown 替换为 lxc-stop 将执行容器的即时终止,这类似于在真机上拔下电源插头,可能会使数据处于损坏状态。 因此,仅在 lxc-shutdown 失败的情况下使用 lxc-stop

一旦停止并且您确定容器上没有您希望保留的数据,可以使用 lxc-destroy 将其销毁:

lxc-destroy -n test-container

概括

这显示了 LXC 容器的基本生命周期以及它们如何使您的设置受益。 如果您需要任何进一步的建议或帮助,请在下方发表评论。