LinuxKit
22/04/2017Docker cresceu bastante no último ano, atendendo as demandas dos usuários que solicitavam suporte nativo para os ambientes que estavam usando. Essas demandas eram carregadas de desafios técnicos já que muitos dos ambientes não tinham um subsistema Linux, necessário para executar os containers.
Ao projetar o subsistema Linux que atenderia as demandas, o time de desenvoledores do Docker em conjunto com empresas parceiras como Intel, IBM, ARM e Microsoft, trabalharam para que o projeto fosse modular, compacto, seguro e principalmente portátil. Os frutos desse trabalho foram os projetos Docker para Mac, Windows, AWS, Azure e Google Cloud.
Na DockerCon 2017 o código fonte do kit usado na construção de todas as plataformas foi aberto e apresentado ao público como LinuxKit, um conjunto de ferramentas que possibilita a construção de sistemas operacionais especializados para containers.
Como funciona ?
No LinuxKit tudo é construído dentro de um container. Quer dizer que não é
necessário instalar dependências e isso torna o uso fácil.
Dependendo da plataforma escolhida para executar o Kernel, a ferramenta fornece
diferentes saídas: iso-bios
, iso-efi
, gcp-img
ou ainda kernel
+ initrd.
Essa imagem do kernel gerada é uma imagem do Docker com um arquivo bzImage
para o kernel a ser executado de fato, e um arquivo kernel.tar
que contém alguns módulos.
A ferramenta chamada moby
(se você não viu nada sobre moby ainda) converte
um arquivo de especificação yaml
em uma ou mais imagens inicializáveis.
Esse arquivo yaml
é utilizado para descrever o kernel bem como os aplicativos
e serviços necessários. Veja o exemplo:
-
Kernel
é a especificação de uma imagem Docker do kernel, essa imagem contém uma versão de kernel e um tarball do sistema de arquivos, ou seja, os módulos do sistema. -
init
é a base init do sistema também especificado em uma imagem Docker, que é descompactado como o sistema base, nesse caso: init, containerd, runc e outras ferramentas. -
onboot
traz os containers do sistema que são executados em ordem sequencial. -
services
são os serviços, que normalmente funcionam durante todo o tempo em que o sistema está ativo. -
outputs
formata a saída no processo de build para diferentes plataformas, são como arquivosISOs
.
Note que em quase todas as seções existe a palavra-chave image
, pois tudo é
aplicado em containers.
Um pouco de prática
Para esse exemplo é necessário ter uma versão recente do Golang e Docker instalados e claro o clone do projeto:
$ git clone https://github.com/linuxkit/linuxkit.git
Em seguida é preciso gerar o binário que vai fornecer o CLI da ferramenta, o moby
:
$ cd linuxkit
$ make
$ cp bin/moby /usr/local/bin/
$ moby
Please specify a command.
USAGE: moby [options] COMMAND
Commands:
build Build a Moby image from a YAML file
run Run a Moby image on a local hypervisor or remote cloud
version Print version information
help Print this message
Run (moby COMMAND --help) for more information on the command
Options:
-q Quiet execution
-v Verbose execution
O projeto possui alguns exemplos prontos e neste caso utilizaremos um do Google Cloud Platform.
Os exemplos ficam em examples/
, antes de executar é necessário ter uma conta GCP configurada.
Você pode instalar o SDK do Google seguindo essas instruções https://cloud.google.com/sdk/.
Em seguida:
$ export CLOUDSDK_CORE_PROJECT=infoslack-1337
$ export CLOUDSDK_COMPUTE_ZONE=us-east1-b
$ gcloud auth login
Depois de realizar a autenticação na conta do Google podemos executar o exemplo:
$ cd examples
$ moby build gcp.yml
$ ls
6.7M -rw-r--r-- 1 root root 6.7M Apr 22 21:24 gcp-bzImage
4.0K -rw-r--r-- 1 root root 27 Apr 22 21:24 gcp-cmdline
57M -rw-r--r-- 1 root root 57M Apr 22 21:25 gcp.img.tar.gz
50M -rw-r--r-- 1 root root 50M Apr 22 21:24 gcp-initrd.img
4.0K -rw-r--r-- 1 root root 1.9K Apr 22 21:20 gcp.yml
O arquivo principal gerado é o gcp.img.tar.gz
com 57MB, agora só precisamos
realizar o upload do mesmo para o Google e iniciar o sistema, hora de chamar o moby
mais uma vez:
$ moby run gcp -project infoslack-1337 gcp.img.tar.gz
Esse procedimento leva alguns minutos e no final estaremos logados dentro da instância
que foi criada. Agora podemos verificar se os serviços que são containers estão em execução,
neste exemplo por padrão teremos como container manager o Runc
:
$ runc list
ID PID STATUS BUNDLE
nginx 759 running /containers/services/nginx
rngd 798 running /containers/services/rngd
sshd 797 running /containers/services/sshd
Na listagem recebemos os 3 serviços em execução: Nginx, SSHD e o rngd que é um serviço para o kernel. Agora podemos fazer um request no ip público da instância e verificar se o Nginx responde corretamente:
$ http -h 104.196.170.124
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 612
Content-Type: text/html
Date: Sun, 23 Apr 2017 00:55:56 GMT
ETag: "58e66cf5-264"
Last-Modified: Thu, 06 Apr 2017 16:29:41 GMT
Server: nginx/1.11.13
Touché! O container do Nginx respondeu corretamente. Ao final deste exemplo foi possível produzir um sistema operacional especializado para executar containers, enviar para o cloud do Google e ver um serviço em funcionamento. O tempo gasto entre geração de imagem e upload para cloud foi de aproximadamente 10 minutos. PS: minha conexão não estava muito estável durante os testes.
Conclusão
Apesar do projeto estar em fase inicial já da para ter uma ideia do seu potencial e perceber a forte inspiração nos Unikernels já que um dos objetivos é prover um sistema operacional imutável. Acredito que daqui em diante projetos como RancherOS farão bom uso dessa ferramenta e teremos também opções de plataformas automatizadas para construção de sistemas operacionais com foco em containers como é o caso RACKN que já está fazendo algo com LinuxKit + Kubernetes.
Happy Hacking ;)
Referências
- https://blog.docker.com/2017/04/introducing-linuxkit-container-os-toolkit/
- https://rackn.com/2017/04/21/docker-linuxkit-provision/
- https://github.com/linuxkit/linuxkit/blob/master/docs/gcp.md
- https://github.com/linuxkit/linuxkit/blob/master/docs/architecture.md
- https://github.com/linuxkit/linuxkit
- https://mobyproject.org/