TranslateProject/translated/tech/LXD/Part 4 - LXD 2.0--Resource control.md
2016-12-27 21:23:56 +08:00

15 KiB
Raw Blame History

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

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

因为lxd容器管理有很多命令因此这篇文章会很长。 如果你想要快速地浏览这些相同的命令,你可以尝试下我们的在线演示

可用资源限制

LXD提供了不同的资源限制。其中一些绑定到容器本身如内存配额CPU限制和I/O优先级。一些与特定设备绑定如I/O带宽或磁盘使用限制。

与所有LXD配置一样资源限制可以在容器运行时动态更改。某些可能无法启用例如如果设置的内存值小于当前内存使用但LXD将会重试并且报告失败。

所有限制也可以通过配置文件继承在这种情况下每个受影响的容器将受到该限制的约束。也就是说如果在默认配置文件中设置limits.memory=256MB则使用默认配置文件通常是所有配置文件的每个容器的内存限制为256MB。

我们不支持资源限制池其中的限制将由一组容器共享因为我们没有什么好的方法由现有的内核API实现这些功能。

磁盘

这或许是最需要和最明显的需求。 只需设置容器文件系统的大小限制,并对容器强制执行。

这就是LXD让你做的 不幸的是,这比它听起来复杂得多。 Linux没有基于路径的配额而大多数文件系统只有基于用户和组的配额这对容器没有什么用处。

如果你正在使用ZFS或btrfs存储后端这意味着现在LXD只能支持磁盘限制。也有可能为LVM实现此功能但这取决于与它一起使用的文件系统并且如果结合实时更新那会变得棘手起来因为并不是所有的文件系统都允许在线增长几乎没有一个允许在线收缩。

CPU

当涉及到CPU的限制我们支持4种不同的东西

*只给我X个CPU核心

  在这种模式下你让LXD为你选择一组核心然后为更多的容器和CPU的上线/下线提供负载均衡。      容器只看到这个数量的CPU核心。 *给我一组特定的CPU核心例如核心13和5

  类似于第一种模式,除了没有发生负载均衡,你会被限制在那些核心,无论它们有多忙。 *给我你拥有的20

  在这种模式下你可以看到所有的CPU但调度程序将限制你使用20的CPU时间但这只有在负载状态才会这样所以如果系统不忙你的容器可以跑得很欢。当其他的容器也开始使用CPU时它会被限制。 *每测量200ms给我50ms并且不超过

  此模式与上一个模式类似你可以看到所有的CPU但这一次无论系统可能是多么空闲你只能使用你设置的极限时间下的尽可能多的CPU时间。在没有过量使用的系统上这可使你可以非常整齐地分割CPU并确保这些容器的持续性能。

另外还可以将前两个中的一个与最后两个之一相结合即请求一组CPU然后进一步限制这些CPU的CPU时间。

除此之外,我们还有一个通用的优先级调节方式,可以告诉调度器当你处于负载状态时,两个争夺资源的容器谁会取得胜利。

内存

内存听起来很简单只是给我多少MB的内存

它绝对可以那么简单。 我们支持这种限制以及基于百分比的请求比如给我10的主机内存

另外我们在上层支持一些额外的东西。 例如你可以选择在每个容器上打开或者关闭swap如果打开还可以设置优先级以便你可以选择哪些容器先将内存交换到磁盘

内存限制默认是“hard”。 也就是说,当内存耗尽时,内核将会开始杀掉你的那些进程。

或者你可以将强制策略设置为“soft”在这种情况下只要没有别的进程的情况下你将被允许使用尽可能多的内存。一旦别的进程想要这块内存你将无法分配任何内存直到你低于你的限制或者主机内存再次有空余。

网络 I/O

网络I/O可能是我们最简单的限制但是相信我实现真的不简单

我们支持两种限制。 第一个是对网络接口的速率限制。 你可以设置入口和出口的限制或者只是设置“最大”限制然后应用到出口和入口。这个只支持“桥接”和“p2p”类型接口。

第二种是全局网络I/O优先级仅当你的网络接口趋于饱和的时候再使用。

块 I/O

我把最古怪的放在最后。对于用户看起来它可能简单,但有一些情况下,它的结果并不会和你的预期一样。

我们在这里支持的基本上与我在网络I/O中描述的相同。

你可以直接设置磁盘的读写IO频率和速率并且有一个全局的块I/O优先级它会通知I/O调度程序更倾向哪个。

奇怪的是如何以及在哪里应用这些限制。不幸的是我们用于实现这些功能的底层使用的是完整的块设备。这意味着我们不能为每个路径设置每个分区的I/O限制。

这也意味着当使用可以支持多个块设备的ZFS或btrfs带或者不带RAID回到指定的路径我们并不知道这个路径是哪个块设备提供的。

这意味着,完全有可能,实际上有可能,容器使用的磁盘可能来自于多个不同的物理磁盘(绑定挂载或直接挂载)。

这就使限制变得很奇怪。为了使限制生效LXD具有猜测给定路径对应块设备的逻辑这其中包括询问ZFS和btrfs工具甚至可以在发现一个文件系统中的循环挂载的文件时递归地找出它们。

这个逻辑虽然不完美但通常会产生一组应该应用限制的块设备。LXD接着记录并移动到下一个路径。当遍历完所有的路径它就得到了非常奇怪的部分。它会平均你为相应块设备设置的限制然后应用这些。

这意味着你将在容器中“平均”地获得正确的速度,但这也意味着你不能对来自同一个物理磁盘的“/fast”和一个“/slow”目录应用不同的速度限制。 LXD允许你设置它但最后它会给你这两个值的平均值。

它怎么工作?

除了网络限制是通过较旧但是良好的“tc”实现的上述大多数限制是通过Linux内核的cgroup API来实现的。

LXD在启动时会检测你在内核中启用了哪些cgroup并且将只应用内核支持的限制。 如果你缺少一些cgroups守护进程会输出警告接着你的init系统将会记录这些。

在Ubuntu 16.04上默认情况下除了内存交换审计外将会启用所有限制它需要你通过“swapaccount = 1”这个内核引导参数启用它。

应用这些限制

上述所有限制都能够直接或者用某个配置文件应用于容器。容器范围的限制可以使用:

lxc config set CONTAINER KEY VALUE

对应配置文件:

lxc profile set PROFILE KEY VALUE

当指定特定设备时:

lxc config device set CONTAINER DEVICE KEY VALUE

对应配置文件

lxc profile device set PROFILE DEVICE KEY VALUE

完整有效的配置键、设备类型和设备键可以看这里

CPU

要限制使用任意两个cpu核心可以这么做

lxc config set my-container limits.cpu 2

要指定特定的cpu核心也就是之前说的第二和第四种

lxc config set my-container limits.cpu 1,3

更加复杂的情况还可以设置范围:

lxc config set my-container limits.cpu 0-3,7-11

The limits are applied live, as can be seen in this example: 限制实时生效,你可以看下面的例子

stgraber@dakara:~$ lxc exec zerotier -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1
processor : 2
processor : 3
stgraber@dakara:~$ lxc config set zerotier limits.cpu 2
stgraber@dakara:~$ lxc exec zerotier -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1

注意为了避免完全混淆用户空间lxcfs会重排/proc/cpuinfo中的条目以便没有错误。

就像LXD中的一切这些设置也可以应用在配置文件中

stgraber@dakara:~$ lxc exec snappy -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1
processor : 2
processor : 3
stgraber@dakara:~$ lxc profile set default limits.cpu 3
stgraber@dakara:~$ lxc exec snappy -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1
processor : 2

要限制容器使用10%的cpu时间要设置下cpu allowance

lxc config set my-container limits.cpu.allowance 10%

或者给他一个固定的cpu切片时间

lxc config set my-container limits.cpu.allowance 25ms/200ms

最后要将容器的cpu优先级调到最低

lxc config set my-container limits.cpu.priority 0

内存

要直接应用内存限制运行下面的命令:

lxc config set my-container limits.memory 256MB

支持的后缀后KB、MB、GB、TB、PB、EB

要关闭容器的内存交换(默认启用):

lxc config set my-container limits.memory.swap false

告诉内核首先交换指定容器的内存:

lxc config set my-container limits.memory.swap.priority 0

如果你不想要强制的内存限制:

lxc config set my-container limits.memory.enforce soft

磁盘和块I/O

不像CPU和内存磁盘和I/O限制是直接作用在实际的设备上的因此你需要编辑原始设备或者屏蔽某个具体的设备。

要设置磁盘限制需要btrfs或者ZFS

lxc config device set my-container root size 20GB

比如:

stgraber@dakara:~$ lxc exec zerotier -- df -h /
Filesystem                        Size Used Avail Use% Mounted on
encrypted/lxd/containers/zerotier 179G 542M  178G   1% /
stgraber@dakara:~$ lxc config device set zerotier root size 20GB
stgraber@dakara:~$ lxc exec zerotier -- df -h /
Filesystem                       Size  Used Avail Use% Mounted on
encrypted/lxd/containers/zerotier 20G  542M   20G   3% /

要限制速度,你可以:

lxc config device set my-container root limits.read 30MB
lxc config device set my-container root.limits.write 10MB

或者限制IO频率

lxc config device set my-container root limits.read 20Iops
lxc config device set my-container root limits.write 10Iops

最后你在一个过量使用的繁忙系统上,你或许想要:

lxc config set my-container limits.disk.priority 10

将那个容器的I/O优先级调到最高。

网络 I/O

只要机制可用网络I/O基本等同于块I/O。

比如:

stgraber@dakara:~$ lxc exec zerotier -- wget http://speedtest.newark.linode.com/100MB-newark.bin -O /dev/null
--2016-03-26 22:17:34-- http://speedtest.newark.linode.com/100MB-newark.bin
Resolving speedtest.newark.linode.com (speedtest.newark.linode.com)... 50.116.57.237, 2600:3c03::4b
Connecting to speedtest.newark.linode.com (speedtest.newark.linode.com)|50.116.57.237|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: '/dev/null'

/dev/null 100%[===================>] 100.00M 58.7MB/s in 1.7s 

2016-03-26 22:17:36 (58.7 MB/s) - '/dev/null' saved [104857600/104857600]

stgraber@dakara:~$ lxc profile device set default eth0 limits.ingress 100Mbit
stgraber@dakara:~$ lxc profile device set default eth0 limits.egress 100Mbit
stgraber@dakara:~$ lxc exec zerotier -- wget http://speedtest.newark.linode.com/100MB-newark.bin -O /dev/null
--2016-03-26 22:17:47-- http://speedtest.newark.linode.com/100MB-newark.bin
Resolving speedtest.newark.linode.com (speedtest.newark.linode.com)... 50.116.57.237, 2600:3c03::4b
Connecting to speedtest.newark.linode.com (speedtest.newark.linode.com)|50.116.57.237|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: '/dev/null'

/dev/null 100%[===================>] 100.00M 11.4MB/s in 8.8s 

2016-03-26 22:17:56 (11.4 MB/s) - '/dev/null' saved [104857600/104857600]

这就是如何将一个千兆网的连接速度限制到仅仅100Mbit/s的

和块I/O一样你可以设置一个总体的网络优先级

lxc config set my-container limits.network.priority 5

获取当前资源使用率

LXD API可以导出目前容器资源使用情况的一点信息,你可以得到:

  • 内存:当前、峰值、目前内存交换和峰值内存交换
  • 磁盘:当前磁盘使用率
  • 网络:每个接口传输的字节和包数。

另外如果你使用的是非常新的LXD在写这篇文章时的git版本你还可以在“lxc info”中得到这些信息

stgraber@dakara:~$ lxc info zerotier
Name: zerotier
Architecture: x86_64
Created: 2016/02/20 20:01 UTC
Status: Running
Type: persistent
Profiles: default
Pid: 29258
Ips:
 eth0: inet 172.17.0.101
 eth0: inet6 2607:f2c0:f00f:2700:216:3eff:feec:65a8
 eth0: inet6 fe80::216:3eff:feec:65a8
 lo: inet 127.0.0.1
 lo: inet6 ::1
 lxcbr0: inet 10.0.3.1
 lxcbr0: inet6 fe80::f0bd:55ff:feee:97a2
 zt0: inet 29.17.181.59
 zt0: inet6 fd80:56c2:e21c:0:199:9379:e711:b3e1
 zt0: inet6 fe80::79:e7ff:fe0d:5123
Resources:
 Processes: 33
 Disk usage:
  root: 808.07MB
 Memory usage:
  Memory (current): 106.79MB
  Memory (peak): 195.51MB
  Swap (current): 124.00kB
  Swap (peak): 124.00kB
 Network usage:
  lxcbr0:
   Bytes received: 0 bytes
   Bytes sent: 570 bytes
   Packets received: 0
   Packets sent: 0
  zt0:
   Bytes received: 1.10MB
   Bytes sent: 806 bytes
   Packets received: 10957
   Packets sent: 10957
  eth0:
   Bytes received: 99.35MB
   Bytes sent: 5.88MB
   Packets received: 64481
   Packets sent: 64481
  lo:
   Bytes received: 9.57kB
   Bytes sent: 9.57kB
   Packets received: 81
   Packets sent: 81
Snapshots:
 zerotier/blah (taken at 2016/03/08 23:55 UTC) (stateless)

总结

LXD团队花费了几个月的时间来迭代我们使用的这些限制语言。 它是为了在保持强大和功能明确的基础上同时保持简单。

实时的应用限制和继承配置文件,使其成为一种非常强大的工具,可以在不影响正在运行的服务的情况下实时管理服务器上的负载。

额外信息

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你可以在线尝试下


via: https://www.stgraber.org/2016/03/26/lxd-2-0-resource-control-412/

作者:Stéphane Graber 译者:geekpi 校对:校对者ID

本文由 LCTT 组织翻译,Linux中国 荣誉推出