Isolando ambientes de desenvolvimento com contêineres LXD
Falarei sobre uma abordagem para organizar ambientes de desenvolvimento locais isolados em minha estação de trabalho. A abordagem foi desenvolvida sob a influência dos seguintes fatores:
Diferentes linguagens requerem diferentes IDEs e conjuntos de ferramentas;
Diferentes projetos podem usar diferentes versões de conjuntos de ferramentas e bibliotecas.
A abordagem é desenvolver dentro de contêineres LXD executados localmente em um laptop ou estação de trabalho com saída gráfica redirecionada para o host.
Configuração de exemplo Ubuntu 20.04.
Reflexões sobre opções e motivos são apresentadas no final do artigo.
1. Instalação do LXD
В Ubuntu 20.04 O LXD não está mais disponível para instalação como pacote deb, apenas via snap:
$ snap install lxd
Após a instalação você precisa realizar a inicialização:
$ lxd init
O único parâmetro que mudo é storage bakend - Eu uso dir como o mais simples. Como não uso fotos e cópias, os avisos em documentação Eles não me assustam:
Da mesma forma, o back-end do diretório deve ser considerado uma opção de último recurso.
Ele suporta todos os principais recursos do LXD, mas é terrivelmente lento e ineficiente, pois não funciona
cópias instantâneas ou instantâneos e, portanto, precisa sempre copiar todo o armazenamento da instância.
2. Configuração do perfil LXD
Perfis em LXD — são conjuntos de parâmetros aplicados a vários contêineres. Para minhas necessidades, o único perfil criado por padrão é suficiente para mim default com as seguintes alterações:
$ lxc profile device add default X0 disk source=/tmp/.X11-unix/X0 path=/tmp/.X11-unix/X0 — para que aplicações em contêineres possam interagir com o servidor host X11;
$ lxc profile set default environment.DISPLAY :0 - para que a variável ambiental DISPLAY foi instalado corretamente em contêineres;
Criando um contêiner baseado em uma imagem images:ubuntu/20.04:
$ lxc launch images:ubuntu/20.04 dev1
Eu prefiro imagens do repositório https://images.linuxcontainers.org, uma vez que possuem menos software pré-instalado. Por esta razão adicionei o prefixo images: ao nome da imagem. A criação de um contêiner baseado em uma imagem do repositório Ubuntu pode ser feita da seguinte forma: $ lxc launch ubuntu/20.04 dev1.
Bônus! É muito fácil colocar uma GPU em um contêiner para que os aplicativos executados nele possam usar a placa gráfica. Para fazer isso você precisa:
As janelas do aplicativo serão exibidas no host, mas serão executadas dentro do contêiner - semelhante ao encaminhamento de gráficos usando ssh.
Não desligo os contêineres em execução manualmente, porque não vejo muito sentido nisso - limito-me a fechar as janelas dos aplicativos em execução.
5. Conclusão
Prefiro não usar um sistema operacional host para desenvolvimento, pois isso exigiria a instalação de ferramentas de desenvolvimento, depuração de versões de bibliotecas, configuração de componentes do sistema de uma maneira específica e outras manipulações. Tudo isso pode levar a um comportamento inesperado em outro software que não seja de desenvolvimento, ou mesmo em todo o sistema operacional. Por exemplo, alterações na configuração do OpenSSL podem fazer com que o sistema operacional pare de iniciar corretamente.
Tentei diferentes ferramentas para isolar ambientes de desenvolvimento:
máquinas virtuais (KVM, VirtualBox, etc.) são a opção mais óbvia, mas consomem significativamente mais recursos, embora não existam outras opções de desenvolvimento em Windows (se o host for Linux);
ferramentas de desenvolvimento em nuvem executadas em uma máquina local (Cloud9 em um contêiner ou máquina virtual, Eclipse Che, etc.) - elas não são desenvolvidas para este modo de operação, requerem configuração e manutenção adicionais, é melhor usá-las para os fins pretendidos propósito - na nuvem;
Os contêineres Docker são novamente destinados a outra coisa; na minha opinião, eles não são muito convenientes para prototipagem rápida usando software que ainda não está empacotado em contêineres separados.
A abordagem escolhida me impressiona pela sua simplicidade e baixa barreira de entrada. Nos próprios contêineres, você pode usar abordagens específicas do projeto: instalar e configurar tudo manualmente, ou usar automação (Puppet, Ansible, etc.), até mesmo implantar Infraestrutura baseada em Docker. Eu também uso contêineres LXD para executar software específico que requer a instalação de um grande número de dependências ou uma versão diferente do sistema operacional - neste caso você pode criar um contêiner com a versão desejada do sistema operacional, por exemplo $ lxc launch images:ubuntu/16.04 dev16.
É importante lembrar que em termos de isolamento, a conteinerização tem uma superfície de ataque maior em comparação com a virtualização – o host e o contêiner compartilham um único núcleo, uma vulnerabilidade que pode permitir que malware escape do contêiner. Ao experimentar software duvidoso, é melhor usar mecanismos de isolamento mais apropriados.