阅读446 返回首页    go 阿里云 go 技术社区[云栖]


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

介绍

LXD 2.0 中的有一个尽管是实验性质的但非常令人兴奋的功能,那就是支持容器检查点和恢复。

简单地说,检查点/恢复意味着正在运行的容器状态可以被序列化到磁盘,要么可以作为同一主机上的有状态快照,要么放到另一主机上相当于实时迁移。

要求

要使用容器实时迁移和有状态快照,你需要以下条件:

  • 一个非常新的 Linux 内核,4.4 或更高版本。
  • CRIU 2.0,可能需要一些 cherry-pick 的提交,具体取决于你确切的内核配置。
  • 直接在主机上运行 LXD。 不能在容器嵌套下使用这些功能。
  • 对于迁移,目标主机必须至少实现源主机的指令集,目标主机内核必须至少提供与源主机相同的系统调用,并且在源主机上挂载的任何内核文件系统也必须可挂载到目标主机上。

Ubuntu 16.04 LTS 已经提供了所有需要的依赖,在这种情况下,您只需要安装 CRIU 本身:


  1. apt install criu

使用 CRIU

有状态快照

一个普通的快照看上去像这样:


  1. stgraber@dakara:~$ lxc snapshot c1 first
  2. stgraber@dakara:~$ lxc info c1 | grep first
  3. first (taken at 2016/04/25 19:35 UTC) (stateless)

一个有状态快照看上去像这样:


  1. stgraber@dakara:~$ lxc snapshot c1 second --stateful
  2. stgraber@dakara:~$ lxc info c1 | grep second
  3. second (taken at 2016/04/25 19:36 UTC) (stateful)

这意味着所有容器运行时状态都被序列化到磁盘并且作为了快照的一部分。可以像你还原无状态快照那样还原一个有状态快照:


  1. stgraber@dakara:~$ lxc restore c1 second
  2. stgraber@dakara:~$

有状态快照的停止/启动

比方说你由于升级内核或者其他类似的维护而需要重启机器。与其等待重启后启动所有的容器,你可以:


  1. stgraber@dakara:~$ lxc stop c1 --stateful

容器状态将会写入到磁盘,会在下次启动时读取。

你甚至可以看到像下面那样的状态:


  1. root@dakara:~# tree /var/lib/lxd/containers/c1/rootfs/state/
  2. /var/lib/lxd/containers/c1/rootfs/state/
  3. ├── cgroup.img
  4. ├── core-101.img
  5. ├── core-102.img
  6. ├── core-107.img
  7. ├── core-108.img
  8. ├── core-109.img
  9. ├── core-113.img
  10. ├── core-114.img
  11. ├── core-122.img
  12. ├── core-125.img
  13. ├── core-126.img
  14. ├── core-127.img
  15. ├── core-183.img
  16. ├── core-1.img
  17. ├── core-245.img
  18. ├── core-246.img
  19. ├── core-50.img
  20. ├── core-52.img
  21. ├── core-95.img
  22. ├── core-96.img
  23. ├── core-97.img
  24. ├── core-98.img
  25. ├── dump.log
  26. ├── eventfd.img
  27. ├── eventpoll.img
  28. ├── fdinfo-10.img
  29. ├── fdinfo-11.img
  30. ├── fdinfo-12.img
  31. ├── fdinfo-13.img
  32. ├── fdinfo-14.img
  33. ├── fdinfo-2.img
  34. ├── fdinfo-3.img
  35. ├── fdinfo-4.img
  36. ├── fdinfo-5.img
  37. ├── fdinfo-6.img
  38. ├── fdinfo-7.img
  39. ├── fdinfo-8.img
  40. ├── fdinfo-9.img
  41. ├── fifo-data.img
  42. ├── fifo.img
  43. ├── filelocks.img
  44. ├── fs-101.img
  45. ├── fs-113.img
  46. ├── fs-122.img
  47. ├── fs-183.img
  48. ├── fs-1.img
  49. ├── fs-245.img
  50. ├── fs-246.img
  51. ├── fs-50.img
  52. ├── fs-52.img
  53. ├── fs-95.img
  54. ├── fs-96.img
  55. ├── fs-97.img
  56. ├── fs-98.img
  57. ├── ids-101.img
  58. ├── ids-113.img
  59. ├── ids-122.img
  60. ├── ids-183.img
  61. ├── ids-1.img
  62. ├── ids-245.img
  63. ├── ids-246.img
  64. ├── ids-50.img
  65. ├── ids-52.img
  66. ├── ids-95.img
  67. ├── ids-96.img
  68. ├── ids-97.img
  69. ├── ids-98.img
  70. ├── ifaddr-9.img
  71. ├── inetsk.img
  72. ├── inotify.img
  73. ├── inventory.img
  74. ├── ip6tables-9.img
  75. ├── ipcns-var-10.img
  76. ├── iptables-9.img
  77. ├── mm-101.img
  78. ├── mm-113.img
  79. ├── mm-122.img
  80. ├── mm-183.img
  81. ├── mm-1.img
  82. ├── mm-245.img
  83. ├── mm-246.img
  84. ├── mm-50.img
  85. ├── mm-52.img
  86. ├── mm-95.img
  87. ├── mm-96.img
  88. ├── mm-97.img
  89. ├── mm-98.img
  90. ├── mountpoints-12.img
  91. ├── netdev-9.img
  92. ├── netlinksk.img
  93. ├── netns-9.img
  94. ├── netns-ct-9.img
  95. ├── netns-exp-9.img
  96. ├── packetsk.img
  97. ├── pagemap-101.img
  98. ├── pagemap-113.img
  99. ├── pagemap-122.img
  100. ├── pagemap-183.img
  101. ├── pagemap-1.img
  102. ├── pagemap-245.img
  103. ├── pagemap-246.img
  104. ├── pagemap-50.img
  105. ├── pagemap-52.img
  106. ├── pagemap-95.img
  107. ├── pagemap-96.img
  108. ├── pagemap-97.img
  109. ├── pagemap-98.img
  110. ├── pages-10.img
  111. ├── pages-11.img
  112. ├── pages-12.img
  113. ├── pages-13.img
  114. ├── pages-1.img
  115. ├── pages-2.img
  116. ├── pages-3.img
  117. ├── pages-4.img
  118. ├── pages-5.img
  119. ├── pages-6.img
  120. ├── pages-7.img
  121. ├── pages-8.img
  122. ├── pages-9.img
  123. ├── pipes-data.img
  124. ├── pipes.img
  125. ├── pstree.img
  126. ├── reg-files.img
  127. ├── remap-fpath.img
  128. ├── route6-9.img
  129. ├── route-9.img
  130. ├── rule-9.img
  131. ├── seccomp.img
  132. ├── sigacts-101.img
  133. ├── sigacts-113.img
  134. ├── sigacts-122.img
  135. ├── sigacts-183.img
  136. ├── sigacts-1.img
  137. ├── sigacts-245.img
  138. ├── sigacts-246.img
  139. ├── sigacts-50.img
  140. ├── sigacts-52.img
  141. ├── sigacts-95.img
  142. ├── sigacts-96.img
  143. ├── sigacts-97.img
  144. ├── sigacts-98.img
  145. ├── signalfd.img
  146. ├── stats-dump
  147. ├── timerfd.img
  148. ├── tmpfs-dev-104.tar.gz.img
  149. ├── tmpfs-dev-109.tar.gz.img
  150. ├── tmpfs-dev-110.tar.gz.img
  151. ├── tmpfs-dev-112.tar.gz.img
  152. ├── tmpfs-dev-114.tar.gz.img
  153. ├── tty.info
  154. ├── unixsk.img
  155. ├── userns-13.img
  156. └── utsns-11.img
  157. 0 directories, 154 files

还原容器也很简单:


  1. stgraber@dakara:~$ lxc start c1

实时迁移

实时迁移基本上与上面的有状态快照的停止/启动相同,除了容器目录和配置被移动到另一台机器上。


  1. stgraber@dakara:~$ lxc list c1
  2. +------+---------+-----------------------+----------------------------------------------+------------+-----------+
  3. | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
  4. +------+---------+-----------------------+----------------------------------------------+------------+-----------+
  5. | c1 | RUNNING | 10.178.150.197 (eth0) | 2001:470:b368:4242:216:3eff:fe19:27b0 (eth0) | PERSISTENT | 2 |
  6. +------+---------+-----------------------+----------------------------------------------+------------+-----------+
  7. stgraber@dakara:~$ lxc list s-tollana:
  8. +------+-------+------+------+------+-----------+
  9. | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
  10. +------+-------+------+------+------+-----------+
  11. stgraber@dakara:~$ lxc move c1 s-tollana:
  12. stgraber@dakara:~$ lxc list c1
  13. +------+-------+------+------+------+-----------+
  14. | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
  15. +------+-------+------+------+------+-----------+
  16. stgraber@dakara:~$ lxc list s-tollana:
  17. +------+---------+-----------------------+----------------------------------------------+------------+-----------+
  18. | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
  19. +------+---------+-----------------------+----------------------------------------------+------------+-----------+
  20. | c1 | RUNNING | 10.178.150.197 (eth0) | 2001:470:b368:4242:216:3eff:fe19:27b0 (eth0) | PERSISTENT | 2 |
  21. +------+---------+-----------------------+----------------------------------------------+------------+-----------+

限制

正如我之前说的,容器的检查点/恢复还是非常新的功能,我们还在努力地开发这个功能、修复已知的问题。我们确实需要更多的人来尝试这个功能,并给我们反馈,但我不建议在生产中使用这个功能。

我们跟踪的问题列表在 Launchpad上

我们估计在带有 CRIU 的 Ubuntu 16.04 上带有几个服务的基本的 Ubuntu 容器能够正常工作。然而在更复杂的容器、使用了设备直通、复杂的网络服务或特殊的存储配置下可能会失败。

要是有问题,CRIU 会尽可能地在转储时失败,而不是在恢复时。在这种情况下,源容器将继续运行,快照或迁移将会失败,并生成一个日志文件用于调试。

在极少数情况下,CRIU 无法恢复容器,在这种情况下,源容器仍然存在但将被停止,并且必须手动重新启动。

发送 bug 报告

我们正在跟踪 Launchpad 上关于 CRIU Ubuntu 软件包的检查点/恢复相关的错误。大多数修复 bug 工作是在上游的 CRIU 或 Linux 内核上进行,但是这种方式我们更容易跟踪。

要提交新的 bug 报告,请看这里。

请务必包括:

  • 你运行的命令和显示给你的错误消息
  • lxc info 的输出(*)
  • lxc info <container name>的输出
  • lxc config show -expanded <container name> 的输出
  • dmesg(*)的输出
  • /proc/self/mountinfo 的输出(*)
  • lxc exec <container name> - cat /proc/self/mountinfo 的输出
  • uname -a(*)的输出
  • /var/log/lxd.log(*)的内容
  • /etc/default/lxd-bridge(*)的内容
  • /var/log/lxd/<container name>/ 的 tarball(*)

如果报告迁移错误,而不是状态快照或有状态停止的错误,请将上面所有含有(*)标记的源与目标主机的信息发来。

原文发布时间为:2017-03-04

本文来自云栖社区合作伙伴“Linux中国”

最后更新:2017-05-25 17:01:47

  上一篇:go  在 Atomic 主机上远程使用 Docker
  下一篇:go  如何用 R 语言的 Shiny 库编写 web 程序