lxd版本:4.0.5
Liunux:Ubuntu 20.04.1 LTS
lxc是Linux Container的简称,也就是Linux容器。lxc/lxd和docker容器相比,更接近虚拟机的环境,docker容器是面向服务的,而lxc/lxd是面向系统的,它提供了一个完整的系统。但它和虚拟机的区别是虚拟机是硬件隔离,虚拟机虚拟硬件,然后在这个硬件基础上启动独立的pc内核,而lxc/lxd容器仍然是和其他容器共享宿主机的内核的。lxd是lxc的升级版,简化了许多操作。
lxc/lxd的使用场景介于虚拟机和docker容器之间。如果你需要一个完整的系统,要在这个系统里面执行较复杂的操作,比如mount、systemctl、snap之类的,这个时候docker或者podman容器可能就无法满足你了,但是虚拟机又太笨重,一台机器开几个实例,宿主机就吃不消了。也就是说在需要大量轻量虚拟机的场景下,lxc/lxd就可以成为你的选择。
lxc/lxd的定位就是系统容器,目前不支持任何应用程序容器镜像,比如docker的镜像,官方也不打算支持。而docker是应用程序容器。所以通过这两种容器的定位,我们就知道在什么场景下应该选择哪种容器。
在使用上,网上的资料不像docker那么丰富,但是官方的文档其实还算详细。
这里列出一些比较有用的操作。
1.安装。这里我用的是snap安装,可参考官方文档:https://linuxcontainers.org/lxd/getting-started-cli/#getting-the-packages
另外ubuntu官方也有相关的文档:https://ubuntu.com/server/docs/containers-lxd
2.配置镜像仓库代理:
lxc remote add tuna-images https://mirrors.tuna.tsinghua.edu.cn/lxc-images/ --protocol=simplestreams --public
# 列出仓库里的镜像
lxc image list tuna-images:
# 指定搜索范围
lxc image list tuna-images:ubuntu
# 看更详细的信息
lxc image list tuna-images:ubuntu
拉取镜像时要指明镜像仓库,否则就不会从镜像仓库下载,比如如果要启动ubuntu16的32位容器,应该像下面这样:
lxc launch tuna-images:ubuntu/16.04/i386 ubuntu16-04-32
3.容器挂载本地目录:
lxc config device add ubuntu16-04-32 test disk source=/home/test path=/home/test
lxd的配置被称作device,每个配置都有一个device名称,这里test就是该配置的名称。source是宿主机,path是容器。ubuntu16-04-32是容器名。
4.容器映射端口:
lxc config device add ubuntu16-04-32 mynet proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
上面listen里面的ip是指外部请求宿主机的ip白名单,80是端口号,connect的ip是指容器的地址,80是容器的端口号。ubuntu16-04-32是容器名,mynet是该配置的名称,这个可以通过命令:lxc config device show ubuntu16-04-32看到。
5.容器快照,这个和虚拟机的快照差不多,可以通过它快速让容器恢复快照记录的状态:
# 记录快照
lxc snapshot ubuntu16-04-32 2021-3-10
# 恢复快照
lxc restore ubuntu16-04-32 2021-3-10
# 复制快照创建新容器
lxc copy ubuntu16-04-32/2021-3-10 testcontainer
# 发布快照为镜像,默认发布到本地
lxc publish ubuntu16-04-32/2021-3-10 --alias ubuntu16-04-32-my
# 发布并公开
lxc publish ubuntu16-04-32/2021-3-10 --alias ubuntu16-04-32-my public=true
# 导出镜像,导出的文件格式为.tar.gz
lxc image export ubuntu16-04-32-my /home/ubuntu16-04-32-my
# 导入镜像
lxc image import /home/ubuntu16-04-32-my.tar.gz --alias ubuntu16-04-32-my --public
6.查看本地容器列表:
lxc list
查看本地镜像列表:
lxc image list
7.查看容器日志:
lxc info ubuntu16-04-32-1 --show-log
8.将远程镜像下载到本地,但不启动:
lxc image copy tuna-images:ubuntu/16.04/i386 local:
# 如果要保持镜像更新,则可以加auto-update参数
lxc image copy tuna-images:ubuntu/16.04/i386 local: --alias ubuntu32 --auto-update
9.官方的镜像或者其他镜像仓库的镜像可能不一定能满足你的需求,这个时候,你可以通过自制镜像来定制一些镜像。这里我以Ubuntu官方提供的ubuntu-base-16.04.6-base-i386.tar.gz的系统包为例制作镜像。制作镜像其实只需要提供一个metadata.yaml文件,并打包就可以,metadata.yaml文件的内容可以像下面这么写:
architecture: i386
creation_date: 1609430400
expiry_date: 4765104000
properties:
architecture: i386
description: ubuntu-base-16.04.6-base-i386
name: ubuntu-base-16.04.6-base-i386
os: ubuntu
release: 16.04.6-base
事实上,还有一个属性比较重要,叫做templates,上面的文件里没有用到。这个属性相当于对于容器进行定制化操作,写入一些提前预制的文件。比如如果你把官方的ubuntu16.04/i386镜像导出来,它的metadata.yaml长这样:
architecture: i386
creation_date: 1615214785
expiry_date: 1617806785
properties:
architecture: i386
description: Ubuntu xenial i386 (20210308_14:40)
name: ubuntu-xenial-i386-default-20210308_14:40
os: ubuntu
release: xenial
serial: "20210308_14:40"
variant: default
templates:
/etc/hostname:
when:
- create
- copy
create_only: false
template: hostname.tpl
properties: {}
/etc/hosts:
when:
- create
- copy
create_only: false
template: hosts.tpl
properties: {}
其中hostname.tpl的内容如下:
{{ container.name }}
hosts.tpl的内容如下:
127.0.1.1 {{ container.name }}
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
可以看出来,这里的templates的作用是在容器启动的时候,将hostname.tpl的内容拷贝到容器文件/etc/hostname里面,将hosts.tpl的内容拷贝到容器文件/etc/hosts里面。
编辑好metadata.yaml之后,使用下面的命令进行打包:
tar -zcvP -f metadata.tar.gz metadata.yaml
然后使用下面的命令,加载容器:
lxc image import ./metadata.tar.gz ./ubuntu-base-16.04.6-base-i386.tar.gz --alias ubuntu16-04-32-base
如果要使用template,那么打包的metadata.tar.gz的结构应该是这样的:
templates目录存放的是模板文件文件,比如hosts.tpl和hostname.tpl。
该部分更多的信息可以参考:https://stgraber.org/2016/03/30/lxd-2-0-image-management-512/。
10.进入到容器:
lxc exec ubuntu16-04-32-base /bin/bash
11.重新配置lxc的方法:
lxd init