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的结构应该是这样的:

docker lxc 区别 lxc vs docker_ubuntu

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