【编者的话】第三方调查报告显示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中的Docker]
[LXD 2.0系列之八:LXD中的LXD]
[LXD 2.0系列之九:在线迁移]
[LXD 2.0系列之十:LXD和Juju]
[LXD 2.0系列之十一:LXD和OpenStack]
[LXD 2.0系列之十二:调试和改进LXD]
LXD 2.0系列的第三篇博文,创建你的第一个LXD容器。
就像之前博文中提到的,LXD命令行客户端会预先配置一些镜像源。Ubuntu是覆盖所有体系架构和发布版本的官方镜像,当然也有其他发行版的一些非官方镜像可以使用,由社区制作,LXC上游贡献者负责维护。
如果想要的是Ubuntu最好的支持版本,你只需要:
lxc launch ubuntu:
注:尽管这个命令的涵义是最新的Ubuntu LTS版本,如在脚本中使用,最好还是指定实际使用的发行版本,如下所示:
To get the latest, tested, stable image of Ubuntu 14.04 LTS, you can simply run:
简单执行这个命令,就可以获取到最新Ubuntu14.04 LTS经测试的稳定镜像:
lxc launch ubuntu:14.04
容器名称将会随机指定。如果想指定专门的容器名称,这样做:
lxc launch ubuntu:14.04 c1
Should you want a specific (non-primary) architecture, say a 32bit Intel image, you can do:
也许你需要一个非主流的体系架构镜像,比如32位的Intel镜像:
lxc launch ubuntu:14.04/i386 c2
使用“ubuntu:”参数只提供官方经测试的Ubuntu镜像。如果你需要还未测试过的当天build,适合开发版本的话,就需要用“ubuntu-daily:”这个参数:
lxc launch ubuntu-daily:devel c3
这个例子中,最新的Ubuntu开发版本会被自动选择使用。
当然也可以指明某个版本昵称,比如:
lxc launch ubuntu-daily:xenial c4
Alpine镜像可使用“images:”标签来启动:
lxc launch images:alpine/3.3/amd64 c5
获取完整的Ubuntu镜像列表:
lxc image list ubuntu:
lxc image list ubuntu-daily:
获取所有非官方镜像列表:
lxc image list images:
获取所有带别名的镜像列表,比如在“ubuntu:”标签下:
lxc image alias list ubuntu:
如果需要只创建一个或一批容器,但不立刻启动,就必须将命令中的“lxc launch”换成“lxc init”。所有的选项参数都是相同的,唯一的区别只是容器被创建后不会自启。
lxc init ubuntu:
获取所有容器:
lxc list
你可以将很多的参数传入这个命令来改变列表栏呈现的内容。但是如果一个系统中有大量的容器存在,默认的列表栏呈现方式会显得比较慢(由于需要从容器中获得网络信息),不过你可以这样做:
lxc list --fast
结果只会呈现那些较少需要服务端协同处理的列表栏。
你也可以根据容器名或者某个参数进行过滤:
stgraber@dakara:~$ lxc list security.privileged=true
------ --------- --------------------- ----------------------------------------------- ------------ -----------
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
------ --------- --------------------- ----------------------------------------------- ------------ -----------
| suse | RUNNING | 172.17.0.105 (eth0) | 2607:f2c0:f00f:2700:216:3eff:fef2:aff4 (eth0) | PERSISTENT | 0 |
------ --------- --------------------- ----------------------------------------------- ------------ -----------
这个例子中,只列出了特权级容器。
stgraber@dakara:~$ lxc list --fast alpine
------------- --------- -------------- ---------------------- ---------- ------------
| NAME | STATE | ARCHITECTURE | CREATED AT | PROFILES | TYPE |
------------- --------- -------------- ---------------------- ---------- ------------
| alpine | RUNNING | x86_64 | 2016/03/20 02:11 UTC | default | PERSISTENT |
------------- --------- -------------- ---------------------- ---------- ------------
| alpine-edge | RUNNING | x86_64 | 2016/03/20 02:19 UTC | default | PERSISTENT |
------------- --------- -------------- ---------------------- ---------- ------------
这个例子中,只列出了名字中带有“alpine”的容器(也支持复杂的正则表达式)。
显而易见的是list命令无法告诉你容器的所有信息,但你可以这样做:
lxc info <container>
比如:
stgraber@dakara:~$ lxc info zerotier
Name: zerotier
Architecture: x86_64
Created: 2016/02/20 20:01 UTC
Status: Running
Type: persistent
Profiles: default
Pid: 31715
Processes: 32
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::c0a4:ceff:fe52:4d51
zt0: inet 29.17.181.59
zt0: inet6 fd80:56c2:e21c:0:199:9379:e711:b3e1
zt0: inet6 fe80::79:e7ff:fe0d:5123
Snapshots:
zerotier/blah (taken at 2016/03/08 23:55 UTC) (stateless)
还是需要很多常用的容器管理命令。
比如为批量操作接受多个容器名。
容器的启动
lxc start <container>
容器的停止
lxc stop <container>
如果容器失去控制(比如不响应SIGPWR),可强制执行:
lxc stop <container> --force
容器的重启
lxc restart <container>
也可强制执行:
lxc restart <container> --force
容器的暂停
在这种模式下,所有容器的任务都将收到一个等同于SIGSTOP的指令,也就是说这些任务仍可见和继续使用内存,但无法从调度器那得到CPU的时间片。
这很适合如下场景:有一个很吃CPU的容器,需要蛮久才能启动,但又不经常被使用。你可以先将它启动,然后暂停,当需要的时候再启动。
lxc pause <container>
容器的删除
最后,要干掉这个容器,你只要删掉它就好:
lxc delete <container>
注:同样可以用“-force”强制删除。
LXD提供了一系列容器设置,包括资源限制,容器启动控制,还有多个设备介入选项。由于篇幅,本文不会囊括所有的内容。
目前LXD支持一下设备类型:
获取所有可用的配置组列表:
lxc profile list
查看给定的配置组内容:
lxc profile show <profile>
若需要修改:
lxc profile edit <profile>
针对给定的容器,修改多个配置组:
lxc profile apply <container> <profile1>,<profile2>,<profile3>,...
这些配置,对容器而言是唯一的,不要将它放入到一个配置组,可直接修改:
lxc config edit <container>
这和配置组修改方式很像。
如果不想在编辑器中修改所有的内容,也可以针对单独的键值进行修改:
lxc config set <container> <key> <value>
或者增加设备,例如:
lxc config device add my-container kvm unix-char path=/dev/kvm
为一个叫“my-container”的容器增加/dev/kvm设备入口
这也可通过“lxc profile set”和“lxc profile device add”做到。
读取本地配置
lxc config show <container>
或者获取更多的配置信息(包括配置组的键值)
lxc config show --expanded <container>
例如:
stgraber@dakara:~$ lxc config show --expanded zerotier
name: zerotier
profiles:
- default
config:
security.nesting: "true"
user.a: b
volatile.base_image: a49d26ce5808075f5175bf31f5cb90561f5023dcd408da8ac5e834096d46b2d8
volatile.eth0.hwaddr: 00:16:3e:ec:65:a8
volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]'
devices:
eth0:
name: eth0
nictype: macvlan
parent: eth0
type: nic
limits.ingress: 10Mbit
limits.egress: 10Mbit
root:
path: /
size: 30GB
type: disk
tun:
path: /dev/net/tun
type: unix-char
ephemeral: false
That one is very convenient to check what will actually be applied to a given container.
注:除非在文档中有说明,所有的配置键值和设备入口都可在运行着的容器中生效。也就是说,你可以在运行着的容器中直接增加删除设备,或修改安全配置组,而无需重启该容器。
LXD允许你直接在容器中执行命令。大多数的使用场景是在容器中获取shell或者运行某些管理者的任务。
和SSH相比,直接获取shell,不需要容器在网络中可达,也不用在容器中安装专门的软件和配置。
Execution environment
LXD在容器中执行命令的方式比较特别,它无法获知哪种shell会被使用,有哪些环境变量,HOME目录的路径在哪。
通过LXD执行命令,都会以容器的root用户,配以最小的PATH环境变量,HOME环境变量则为/root。
额外的环境变量,可以通过命令行传入,或通过“environment.<key>”配置选项永久设置在容器中。
在容器中获取一个shell:
lxc exec <container> bash
当然这里有个前提,就是容器中bash已经安装。
更多复杂的命令,需要隔离符,来传递:
lxc exec <container> -- ls -lh /
要设置或者改变环境变量,可使用“–env”参数
stgraber@dakara:~$ lxc exec zerotier --env mykey=myvalue env | grep mykey
mykey=myvalue
Because LXD has direct access to the container’s file system, it can directly read and write any file inside the container. This can be very useful to pull log files or exchange files with the container.
由于LXD能进入容器的文件系统,所以可以直接读写容器中的任何文件。这一点对容器中日志文件的拉取或者文件的交换非常有用。
> lxc file pull <container>/<path> <dest>
比如:
stgraber@dakara:~$ lxc file pull zerotier/etc/hosts hosts
或者直接从标准输出获得:
stgraber@dakara:~$ lxc file pull zerotier/etc/hosts -
127.0.0.1 localhost
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
> lxc file push <source> <container>/<path>
这是一个很方便的功能:从指定的路径拉取一个文件,在你的默认文本编辑器中打开,最后当你关闭这个文件时会传递回该容器中。
lxc file edit <container>/<path>
LXD lets you snapshot and restore containers. Snapshots include the entirety of the container’s state (including running state if –stateful is used), which means all container configuration, container devices and the container file system.
LXD允许你给容器打快照,也支持快照恢复。快照中包含容器的整个状态(包括运行时状态,如果使用了-stateful参数的话):容器所有的配置,设备以及文件系统。
> lxc snapshot <container>
这将会得到一个名为snapX的快照,其中X是一个递增的数字。
你也可以命名快照:
lxc snapshot <container> <snapshot name>
“lxc list”可得到容器中的快照数量,但实际快照列表只在“lxc info”中可见。
lxc info <container>
> lxc restore <container> <snapshot name>
> lxc move <container>/<snapshot name> <container>/<new snapshot name>
新容器和快照是等同的,除了某些冲突的信息需要重置(比如MAC地址):
lxc copy <source container>/<snapshot name> <destination container>
> lxc delete <container>/<snapshot name>
干净的发行版镜像很好用,不过,有些时候你还是想要往容器中安装一些东西,配置,或者将它分叉成多个容器。
> lxc copy <source container> <destination container>
目的容器和源容器是等同的,除了快照和冲突的键值(如MAC地址)会被重置。
LXD lets you copy and move containers between hosts, but that will get covered in a later post.
LXD允许你在不同的主机间复制和搬移容器,这将会在下个博文中进行讨论。
目前,“move”命令可以用来重命名一个容器:
lxc move <old name> <new name>
这里有一个要求,容器必须是停止的状态,那么容器里面的一切都会原样保存,包括冲突的信息(MAC地址等等)。
这篇长文覆盖了大多数平时运维需要用到的命令。
显然易见的是很多这些命令都有额外的参数,帮助你更有效地使用LXD容器和调整专门的容器配置。学习这些命令的最好方法就是看看它们的帮助文档(增加–help的参数)。
如果你等不及未来的博文,就想尝试LXD,你可以在网上根据我们的指导,通过浏览器免费 在线试用LXD !
原文链接: LXD 2.0: Your first LXD container [3/12] (翻译:Henry Huang )
==================================================
译者介绍
Henry Huang ,供职于AWS,曾负责集群运维的工作。