The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.
LXD
Introdução
O LXD é um "hypervisor" de contêineres projetado para fornecer um conjunto fácil de ferramentas para gerenciar contêineres Linux, e atualmente seu desenvolvimento está sendo liderado por funcionários da Canonical. Você pode aprender mais sobre o projeto em geral em https://linuxcontainers.org/lxd/ .
Atualmente, o LXD é usado para infraestrutura de contêineres para Funtoo Containers e também é muito bem suportado no Funtoo Linux. Por esse motivo, é recomendável que você verifique o LXD e veja o que ele pode fazer por você.
Configuração básica no Funtoo
As etapas a seguir mostrarão como configurar um ambiente LXD básico no Funtoo Linux. Esse ambiente basicamente usa a configuração padrão do LXD - e será chamada de lxdbr0
, e usará o NAT para fornecer acesso à Internet aos seus contêineres. Além disso, será criado um pool de armazenamento padrão que simplesmente usará o armazenamento do sistema de arquivos existente, criando um diretório em /var/lib/lxd/storage-pools/default
para armazenar os contêineres criados. São possíveis configurações mais sofisticadas que usam pontes de rede dedicadas conectadas a interfaces físicas sem NAT, bem como pools de armazenamento dedicados que usam ZFS e BTRFS - no entanto, esses tipos de configurações geralmente são um exagero para uma estação de trabalho do desenvolvedor e devem ser tentados apenas por usuários avançados. Portanto, não os cobriremos aqui.
Requerimentos
Esta seção o guiará na configuração dos requisitos básicos para a criação de um ambiente LXD.
O primeiro passo é surgir o LXD e suas dependências. Faça o seguinte:
root # emerge -a lxd
Quando o LXD terminar de emergir, desejamos permitir que ele inicie por padrão:
root # rc-update add lxd default
Além disso, queremos configurar os seguintes arquivos. O /etc/security/limits.conf
deve ser modificado para ter as seguintes linhas:
/etc/security/limits.conf
* soft nofile 1048576
* hard nofile 1048576
root soft nofile 1048576
root hard nofile 1048576
* soft memlock unlimited
* hard memlock unlimited
# End of file
Além disso, queremos mapear um conjunto de IDs de usuário e de grupo para o usuário raiz, para que estejam disponíveis para seu uso. Faça isso criando os arquivos /etc/subuid
e /etc/subgid
com o seguinte conteúdo idêntico:
/etc/subuid
root:100000:1000000000
/etc/subgid
root:100000:1000000000
Neste ponto, estamos prontos para inicializar e iniciar o LXD.
Inicialização
Para configurar o LXD, primeiro precisaremos iniciar o LXD. Isso pode ser feito da seguinte forma:
root # /etc/init.d/lxd start
Neste ponto, podemos executar o lxd init
para executar um assistente de configuração para configurar o LXD:
root # lxd init Would you like to use LXD clustering? (yes/no) [default=no]: ↵ Do you want to configure a new storage pool? (yes/no) [default=yes]: ↵ Name of the new storage pool [default=default]: ↵ Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]: dir↵ Would you like to connect to a MAAS server? (yes/no) [default=no]: ↵ Would you like to create a new local network bridge? (yes/no) [default=yes]: ↵ What should the new bridge be called? [default=lxdbr0]: ↵ What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: ↵ What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: ↵ Would you like LXD to be available over the network? (yes/no) [default=no]: ↵ Would you like stale cached images to be updated automatically? (yes/no) [default=yes] ↵ Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: ↵ root #
Como você pode ver, escolhemos todas as opções padrão 'exceto' para o pool de armazenamento, onde optamos por usar um diretório baseado em armazenamento contêiner em vez de BTRFS. Agora, devemos poder executar a lxc image list
e obter uma resposta do daemon LXD:
root # lxc image list +-------+-------------+--------+-------------+------+------+-------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +-------+-------------+--------+-------------+------+------+-------------+ root #
Se você é capaz de fazer isso, configurou com êxito as partes principais do LXD! Observe que usamos o comando lxc
e não lxd
como fizemos no lxd init
- a partir deste momento, você usará o lxc
Não deixe que isso confunda você - o comando lxc
é a principal ferramenta de linha de comando para trabalhar com contêineres LXD.
Acima, você pode ver que nenhuma imagem está instalada. Imagens são instantâneos instaláveis de contêineres que podemos usar para criar novos contêineres. Então, como primeiro passo, vamos em frente e pegue uma imagem que possamos usar. Você deseja procurar em https://build.funtoo.org em busca de uma imagem LXD que funcione no hardware do seu computador. Por exemplo, eu consegui baixar o seguinte arquivo usando o wget
:
root # wget https://build.funtoo.org/1.3-release-std/x86-64bit/intel64-skylake/lxd-intel64-skylake-1.3-release-std-2019-06-11.tar.xz
Uma vez baixada, esta imagem pode ser instalada usando o seguinte comando:
root # lxc image import lxd-intel64-skylake-1.3-release-std-2019-06-11.tar.xz --alias funtoo Image imported with fingerprint: fe4d27fb31bfaf3bd4f470e0ea43d26a6c05991de2a504b9e0a3b1a266dddc69
Agora você verá a imagem disponível em nossa lista de imagens:
root # lxc image list +--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+ | funtoo | fe4d27fb31bf | no | 1.3 Release Skylake 64bit [std] 2019-06-14 | x86_64 | 279.35MB | Jun 15, 2019 at 3:09am (UTC) | +--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+ root #
Primeiro container
Agora é hora de lançar nosso primeiro contêiner. Isso pode ser feito da seguinte forma:
root # lxc launch funtoo testcontainer Creating testcontainer Starting testcontainer
Agora podemos ver o contêiner sendo executado via lxc list
:
root # lxc list +---------------+---------+------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +---------------+---------+------+-----------------------------------------------+------------+-----------+ | testcontainer | RUNNING | | fd42:8063:81cb:988c:216:3eff:fe2a:f901 (eth0) | PERSISTENT | | +---------------+---------+------+-----------------------------------------------+------------+-----------+ root #
Por padrão, nosso novo contêiner testcontainer
usará o perfil padrão, que conectará uma interface eth0
no contêiner ao NAT e também usará nosso pool de armazenamento LXD baseado em diretório. Agora podemos entrar no contêiner da seguinte maneira:
root # lxc exec testcontainer -- su --login testcontainer #
Como você deve ter notado, ainda não temos nenhuma rede IPv4 configurada. Embora o LXD tenha configurado uma ponte e um NAT para nós, juntamente com um servidor DHCP para consulta, na verdade, precisamos usar o dhcpcd
para procurar um endereço IP, então vamos configurá-lo:
testcontainer # echo "template=dhcpcd" > /etc/conf.d/netif.eth0 testcontainer # cd /etc/init.d testcontainer # ln -s netif.tmpl netif.eth0 testcontainer # rc-update add netif.eth0 default * service netif.eth0 added to runlevel default testcontainer # rc * rc is deprecated, please use openrc instead. * Caching service dependencies ... [ ok ] * Starting DHCP Client Daemon ... [ ok ] * Network dhcpcd eth0 up ... [ ok ] testcontainer #
Agora você pode ver que eth0
tem um endereço IPv4 válido:
testcontainer # ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.212.194.17 netmask 255.255.255.0 broadcast 10.212.194.255 inet6 fd42:8063:81cb:988c:25ea:b5bd:603d:8b0d prefixlen 64 scopeid 0x0<global> inet6 fe80::216:3eff:fe2a:f901 prefixlen 64 scopeid 0x20<link> ether 00:16:3e:2a:f9:01 txqueuelen 1000 (Ethernet) RX packets 45 bytes 5385 (5.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 20 bytes 2232 (2.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Hora de ter alguma diversão!
testcontainer # ego sync
Outro bom tutorial de administração do LXD
Esta seção contém outro bom tutorial do LXD que pode ser usado para aprender mais sobre perfis e outros recursos do LXD.
Terminologia
Os contêineres 'snapshots' como o nome indica, são os snapshots do contêiner no tempo, e não podem ser modificados de forma alguma. Vale a pena notar isso, porque os instantâneos podem armazenar o estado de tempo de execução do contêiner, o que nos dá a capacidade de instantâneos "com estado". Ou seja, a capacidade de reverter o contêiner, incluindo seu processador e estado de memória no momento do instantâneo.
LXD é baseado em 'imagem' , todos os contêineres LXD vêm de uma imagem. As imagens são geralmente imagens limpas um de distribuição Linux , semelhantes às que você usaria para uma máquina virtual ou instância de nuvem. É possível "publicar" um contêiner, criando uma imagem a partir dele que pode ser usada pelos hosts LXD locais ou remotos.
Nossa primeira imagem
Vamos sujar as mãos ainda mais e criar nossa primeira imagem. Usaremos uma imagem genérica do Funtoo Linux de 64 bits.
The Funtoo's default build host is building only westmere stage for now.
Pegue a imagem aqui: https://build.funtoo.org/funtoo-current/x86-64bit/intel64-westmere/lxd-latest.tar.xz
Pegue esse arquivo de hash : https://build.funtoo.org/funtoo-current/x86-64bit/intel64-westmere/lxd-latest.tar.xz.hash.txt
Check the hash of the downloaded file against the one from server. Proceed if they match.
Importe a imagem
Após o download bem-sucedido do arquivo, podemos finalmente importá-lo para o LXD e começar a usá-lo como nossa imagem "inicial" para todos os nossos contêineres.
root # lxc image import lxd-latest.tar.xz --alias funtoo Image imported with fingerprint: 6c2ca3af0222d503656f5a1838885f1b9b6aed2c1994f1d7ef94e2efcb7233c4 root # lxc image ls +--------+--------------+--------+------------------------------------+--------+----------+-----------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------+--------------+--------+------------------------------------+--------+----------+-----------------------------+ | funtoo | 6c2ca3af0222 | no | Funtoo Current Generic Pure 64-bit | x86_64 |227.99MB | Dec 13, 2017 at 11:01pm (UTC) | +--------+--------------+--------+------------------------------------+--------+----------+-----------------------------+
E aí temos nossa primeira imagem do Funtoo Linux importada dentro do LXD. Você pode fazer referência à imagem pelo alias ou pela impressão digital. Apelidos podem ser adicionados também mais tarde.
Deixe-me mostrar-lhe alguns usos básicos então.
Criando seu primeiro container
Então agora podemos lançar nosso primeiro contêiner. Isso é feito usando este comando:
root # lxc launch funtoo fun-1 Creating fun-1 Starting fun-1 root # lxc ls +-------+---------+------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +-------+---------+------+-----------------------------------------------+------------+-----------+ | fun-1 | RUNNING | | fd42:156d:4593:a619:216:3eff:fef7:c1c2 (eth0) | PERSISTENT | 0 | +-------+---------+------+-----------------------------------------------+------------+-----------+
lxc launch is a shortcut for lxc init and lxc start, lxc init creates the container without starting it.
Perfis intermezzo
O LXD tem a capacidade de alterar algumas configurações de contêiner, incluindo limitação de recursos, controle de inicialização do contêiner e uma variedade de opções de passagem de dispositivo usando o que é chamado de perfis. Vários perfis podem ser aplicados a um único contêiner e o último perfil substitui os outros, pois os recursos configurados são os mesmos para vários perfis. Deixe-me mostrar como isso pode ser usado.
Este é o perfil padrão que é herdado por todos os contêineres.
root # lxc profile list +---------+---------+ | NAME | USED BY | +---------+---------+ | default | 1 | +---------+---------+ root # lxc profile show default config: {} description: Default LXD profile devices: eth0: nictype: bridged parent: lxdbr0 type: nic root: path: / pool: default type: disk name: default used_by: - /1.0/containers/fun-1
Agora vamos editar esse perfil para nossos contêineres funtoo. Isso incluirá algumas coisas úteis.
root # lxc profile set default raw.lxc "lxc.mount.entry = none dev/shm tmpfs rw,nosuid,nodev,create=dir" root # lxc profile set default environment.LANG "en_US.UTF-8" root # lxc profile set default environment.LC_ALL "en_US.UTF-8" root # lxc profile set default environment.LC_COLLATE "POSIX"
Os perfis podem armazenar qualquer configuração que um contêiner possa ter (chave/valor ou dispositivos) e qualquer número de perfis podem ser aplicados a um contêiner. Os perfis são aplicados na ordem em que são especificados, para que o último perfil a especificar uma chave específica seja vencido. Em qualquer caso, a configuração específica do recurso sempre substitui a anterior proveniente de outros perfis.
O perfil padrão é definido para qualquer novo contêiner criado que não especifique uma lista de perfis diferentes.
LXD supports simple instance types. Those are represented as a string which can be passed at container creation time. containers.md#instance-types
Usando nosso primeiro container
Depois de concluir todas essas personalizações, podemos começar a usar nosso contêiner.O próximo comando daremos dentro do shell do contêiner.
root # lxc exec fun-1 bash
Agora você deve ver um prompt diferente começando com
fun-1 ~ #
Se executarmos top ou ps, por exemplo, veremos apenas os processos do contêiner.
fun-1 ~ # ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 4248 748 ? Ss+ 13:20 0:00 init [3] root 266 0.0 0.0 30488 472 ? Ss 13:20 0:00 /usr/sbin/sshd root 312 0.2 0.0 17996 3416 ? Ss 13:29 0:00 bash root 317 0.0 0.0 19200 2260 ? R+ 13:29 0:00 ps aux
Como você pode ver, apenas os processos do contêiner são mostrados. O usuário que executa os processos é root. O que acontece se procurarmos todos os processos sshd, por exemplo, na caixa do host?
root # ps aux|grep ssh root 14505 0.0 0.0 30564 1508 ? Ss Sep07 0:00 /usr/sbin/sshd 100000 25863 0.0 0.0 30488 472 ? Ss 15:20 0:00 /usr/sbin/sshd root 29487 0.0 0.0 8324 828 pts/2 S+ 15:30 0:00 grep --colour=auto sshd root #
Como você pode ver, o processo sshd está sendo executado no usuário com o uid 100000 na máquina host e possui um PID diferente.
Ações básicas com contêineres
Listando contêineres
root # lxc ls +-------+---------+-----------------------+------------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +-------+---------+-----------------------+------------------------------------------------+------------+-----------+ | fun-1 | RUNNING | 10.214.101.187 (eth0) | fd42:156d:4593:a619:a5ad:edaf:7270:e6c4 (eth0) | PERSISTENT | 0 | | | | | fd42:156d:4593:a619:216:3eff:fef7:c1c2 (eth0) | | | +-------+---------+-----------------------+------------------------------------------------+------------+-----------+
lxc ls também aceita argumentos como filtros. Por exemplo, lxc ls web listará todos os contêineres que têm web em seus nomes.
Detalhes do contêiner
root # lxc info c1 Name: c1 Remote: unix:// Architecture: x86_64 Created: 2017/09/08 02:07 UTC Status: Running Type: persistent Profiles: default, prf-funtoo Pid: 6366 Ips: eth0: inet 10.214.101.79 vethFG4HXG eth0: inet6 fd42:156d:4593:a619:8619:546e:43f:2089 vethFG4HXG eth0: inet6 fd42:156d:4593:a619:216:3eff:fe4a:3d4f vethFG4HXG eth0: inet6 fe80::216:3eff:fe4a:3d4f vethFG4HXG lo: inet 127.0.0.1 lo: inet6 ::1 Resources: Processes: 6 CPU usage: CPU usage (in seconds): 25 Memory usage: Memory (current): 69.01MB Memory (peak): 258.92MB Network usage: eth0: Bytes received: 83.65kB Bytes sent: 9.44kB Packets received: 188 Packets sent: 93 lo: Bytes received: 0B Bytes sent: 0B Packets received: 0 Packets sent: 0
Configuração do contêiner
root # lxc config edit c1 root ### This is a yaml representation of the configuration. root ### Any line starting with a '# will be ignored. root ### root ### A sample configuration looks like: root ### name: container1 root ### profiles: root ### - default root ### config: root ### volatile.eth0.hwaddr: 00:16:3e:e9:f8:7f root ### devices: root ### homedir: root ### path: /extra root ### source: /home/user root ### type: disk root ### ephemeral: false root ### root ### Note that the name is shown but cannot be changed architecture: x86_64 config: image.architecture: x86_64 image.description: Funtoo Current Generic Pure 64-bit image.name: funtoo-generic_64-pure64-funtoo-current-2016-12-10 image.os: funtoo image.release: "1.0" image.variant: current volatile.base_image: e279c16d1a801b2bd1698df95e148e0a968846835f4769b24988f2eb3700100f volatile.eth0.hwaddr: 00:16:3e:4a:3d:4f volatile.eth0.name: eth0 volatile.idmap.base: "0" volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]' volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]' volatile.last_state.power: RUNNING devices: {} ephemeral: false profiles: - default - prf-funtoo stateful: false description: ""
Pode-se também adicionar variáveis de ambiente.
root # lxc config set <container> environment.LANG en_US.UTF-8 root # lxc config set <container> environment.LC_COLLATE POSIX
Gerenciando arquivos
Snapshots
Cloning, copying and moving containers
Resource control
O LXD oferece uma variedade de limites de recursos. Alguns deles estão vinculados ao próprio contêiner, como cotas de memória, limites de CPU e prioridades de E/S. Alguns estão vinculados a um dispositivo específico, como largura de banda de E/S ou limites de uso do disco.
Como em toda a configuração do LXD, os limites de recursos podem ser alterados dinamicamente enquanto o contêiner está em execução. Alguns podem falhar na aplicação, por exemplo, se definir um valor de memória menor que o uso atual da memória, mas o LXD tentará de qualquer maneira e reportará a falha.
Todos os limites também podem ser herdados por meio de perfis. Nesse caso, cada contêiner afetado será restringido por esse limite. Ou seja, se você definir limits.memory = 256MB no perfil padrão, todos os contêineres que usarem o perfil padrão (geralmente todos eles) terão um limite de memória de 256MB.
Disco
Definir um limite de tamanho no sistema de arquivos do contêiner e aplicá-lo ao contêiner. No momento, o LXD suporta apenas limites de disco se você estiver usando o back-end de armazenamento ZFS ou btrfs.
Para definir um limite de disco (requer btrfs ou ZFS):
root # lxc config device set c1 root size 20GB
CPU
Para limitar apenas um contêiner a qualquer 2 CPUs, faça:
root # lxc config set c1 limits.cpu 2
Para fixar em núcleos específicos da CPU, por exemplo, o segundo e o quarto:
root # lxc config set c1 limits.cpu 1,3
Intervalos de fixação mais complexos como esse também funcionam:
root # lxc config set c1 limits.cpu 0-3,7-11
Memória
Para aplicar um limite de memória simples, execute:
root # lxc config set c1 limits.memory 256MB
(Os sufixos suportados são kB, MB, GB, TB, PB e EB)
Para desativar a área de troca (swap) do contêiner (o padrão é ativado):
root # lxc config set c1 limits.memory.swap false
Para dizer ao kernel para trocar a memória deste contêiner primeiro:
root # lxc config set c1 limits.memory.swap.priority 0
E, finalmente, se você não deseja impor limites de memória rígida:
root # lxc config set c1 limits.memory.enforce soft
Network
Block I/O
Resource limits using profile - Funtoo Containers example
Então, eu vou criar três perfis para imitar os limites de recursos dos contêineres atuais do Funtoo.
Price | RAM | CPU Threads | Disk Space | Sign Up |
---|---|---|---|---|
$15/mo | 4GB | 6 CPU Threads | 50GB | Sign Up! (small) |
$30/mo | 12GB | 12 CPU Threads | 100GB | Sign Up! (medium) |
$45/mo | 48GB | 24 CPU Threads | 200GB | Sign Up! (large) |
Vou criar um perfil e copiá-lo / editá-lo para as duas opções restantes.
root # lxc profile create res-small root # lxc profile edit res-small config: limits.cpu: "6" limits.memory: 4GB description: Small Variant of Funtoo Containers devices: root: path: / pool: default size: 50GB type: disk name: small used_by: [] root # lxc profile copy res-small res-medium root # lxc profile copy res-small res-large root # lxc profile set res-medium limits.cpu 12 root # lxc profile set res-medium limits.memory 12GB root # lxc profile device set res-medium root size 100GB root # lxc profile set res-large limits.cpu 24 root # lxc profile set res-large limits.memory 48GB root # lxc profile device set res-large root size 200GB
Agora vamos criar um contêiner e atribuir os perfis res-small e funtoo a ele.
root # lxc init funtoo c-small root # lxc profile assign c-small res-small root # lxc profile add c-small funtoo
Image manipulations
Remote hosts
Running systemd container on a non-systemd host
Para usar systemd no contêiner, é necessária uma versão recente (> = 4.6) do kernel, com suporte para namespaces do cgroup. O openrc do Funtoo tem a correção para montar os systemd cgroups, o que é suficiente para executar os distribuidores baseados em systemd lxd containers.
If you want to get systemd
hierarchy mounted automatically on system startup, using /etc/fstab
will not work, but the
No results
can be used for this. First you needed to edit the /etc/cgroup/cgconfig.conf
and add:
/etc/cgroup/cgconfig.conf
mount {
"name=systemd" = /sys/fs/cgroup/systemd;
}
Então você precisa iniciar o daemon cgconfig:
root # rc-service cgconfig start
O daemon pode ser iniciado conforme necessário ou automaticamente na inicialização do sistema, simplesmente adicionando-o ao grupo padrão:
root # rc-update add cgconfig default
PART X - LXD in LXD
PART Y - Docker in LXD
PART Z - LXD FAQ
List of tested and working images
These are images from the https://images.linuxcontainers.org repository available by default in lxd. You can list all available images by typing following command (beware the list is very long):
root # lxc image list images: +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.3 (3 more) | ef69c8dc37f6 | yes | Alpine 3.3 amd64 (20171018_17:50) | x86_64 | 2.00MB | Oct 18, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.3/armhf (1 more) | 5ce4c80edcf3 | yes | Alpine 3.3 armhf (20170103_17:50) | armv7l | 1.53MB | Jan 3, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.3/i386 (1 more) | cd1700cb7c97 | yes | Alpine 3.3 i386 (20171018_17:50) | i686 | 1.84MB | Oct 18, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.4 (3 more) | bd4f1ccfabb5 | yes | Alpine 3.4 amd64 (20171018_17:50) | x86_64 | 2.04MB | Oct 18, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.4/armhf (1 more) | 9fe7c201924c | yes | Alpine 3.4 armhf (20170111_20:27) | armv7l | 1.58MB | Jan 11, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.4/i386 (1 more) | 188a31315773 | yes | Alpine 3.4 i386 (20171018_17:50) | i686 | 1.88MB | Oct 18, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.5 (3 more) | 63bebc672163 | yes | Alpine 3.5 amd64 (20171018_17:50) | x86_64 | 1.70MB | Oct 18, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | alpine/3.5/i386 (1 more) | 48045e297515 | yes | Alpine 3.5 i386 (20171018_17:50) | i686 | 1.73MB | Oct 18, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ ... +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | | fd95a7a754a0 | yes | Alpine 3.5 amd64 (20171016_17:50) | x86_64 | 1.70MB | Oct 16, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | | fef66668f5a2 | yes | Debian stretch arm64 (20171016_22:42) | aarch64 | 96.56MB | Oct 16, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | | ff18aa2c11d7 | yes | Opensuse 42.3 amd64 (20171017_00:53) | x86_64 | 58.92MB | Oct 17, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+ | | ff4ef0d824b6 | yes | Ubuntu zesty s390x (20171017_03:49) | s390x | 86.88MB | Oct 17, 2017 at 12:00am (UTC) | +---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
These are the images that are known to work with current LXD setup on Funtoo Linux:
Image | Init | Status |
---|---|---|
CentOS 7 | systemd | Working |
Debian Jessie (8) - EOL April/May 2020 | systemd | Working (systemd - no failed units) |
Debian Stretch (9) - EOL June 2022 | systemd | Working |
Fedora 26 | systemd with cgroup v2 | Not Working |
Fedora 25 | systemd | Working |
Fedora 24 | systemd | Working |
Oracle 7 | systemd | Working (systemd - no failed units) |
OpenSUSE 42.2 | systemd | Working |
OpenSUSE 42.3 | systemd | Working |
Ubuntu Xenial (16.04 LTS) - EOL 2021-04 | systemd | Working |
Ubuntu Zesty (17.04) - EOL 2018-01 | systemd | Working |
Alpine 3.3 | OpenRC | Working |
Alpine 3.4 | OpenRC | Working |
Alpine 3.5 | OpenRC | Working |
Alpine 3.6 | OpenRC | Working |
Alpine Edge | OpenRC | Working |
Archlinux | systemd with cgroup v2 | Not Working |
CentOS 6 | upstart | Working (systemd - no failed units) |
Debian Buster | systemd with cgroup v2 | Not Working |
Debian Sid | systemd with cgroup v2 | Not working |
Debian Wheezy (7) - EOL May 2018 | ? | ? (more testing needed) |
Gentoo | OpenRC | Working (all services started) |
Oracle 6 | upstart | ? (mount outputs nothing) |
Plamo 5 | ? | ? |
Plamo 6 | ? | ? |
Sabayon | systemd with cgroup v2 | Not Working |
Ubuntu Artful (17.10) - EOL 2018-07 | systemd with cgroup v2 | Not Working |
Ubuntu Core 16 | ? | ? |
Ubuntu Trusty (14.04 LTS) - EOL 2019-04 | upstart | Working |
Features
Some of the biggest features of LXD are:
- Secure by design (unprivileged containers, resource restrictions and much more)
- Scalable (from containers on your laptop to thousand of compute nodes)
- Intuitive (simple, clear API and crisp command line experience)
- Image based (no more distribution templates, only good, trusted images)
- Live migration
Unprivileged Containers
LXD uses unprivileged containers by default. The difference between an unprivileged container and a privileged one is whether the root user in the container is the “real” root user (uid 0 at the kernel level).
The way unprivileged containers are created is by taking a set of normal UIDs and GIDs from the host, usually at least 65536 of each (to be POSIX compliant) and mapping those into the container.
The most common example and what most LXD users will end up with by default is a map of 65536 UIDs and GIDs, with a host base id of 100000. This means that root in the container (uid 0) will be mapped to the host uid 100000 and uid 65535 in the container will be mapped to uid 165535 on the host. UID/GID 65536 and higher in the container aren’t mapped and will return an error if you attempt to use them.
From a security point of view, that means that anything which is not owned by the users and groups mapped into the container will be inaccessible. Any such resource will show up as being owned by uid/gid “-1” (rendered as 65534 or nobody/nogroup in userspace). It also means that should there be a way to escape the container, even root in the container would find itself with just as much privileges on the host as a nobody user.
LXD does offer a number of options related to unprivileged configuration:
- Increasing the size of the default uid/gid map
- Setting up per-container maps
- Punching holes into the map to expose host users and groups
Relationship with LXC
LXD isn't a rewrite of LXC, in fact it's building on top of LXC to provide a new, better user experience. Under the hood, LXD uses LXC through liblxc and its Go binding to create and manage the containers.
It's basically an alternative to LXC's tools and distribution template system with the added features that come from being controllable over the network.