Introdução ao Docker para NetDevOps

11 minute read

No mundo das Redes, NetDevOps é uma das palavras que está na moda no período de 1 ano para cá. Mas o que é NetDevOps, ou mesmo DevOps? Nesta série de 3 partes, responderemos a essas perguntas e também mergulharemos em uma implementação do NetDevOps usando Ansible, GitHub, Jenkins e Vrnetlab.

alt

Buenas NetCoders… Neste artigo veremos sobre Docker, iremos aprender sobre os fundamentos desta ferramenta aplicada a Network Infrastructure As Code.

Este artigo é muito importante para construirmos uma casca sólida de conhecimento introdutório sobre Docker, e como implementaremos esta ferramenta para construirmos uma infraestrutura como código (IAC) de testes automatizados para aplicarmos a metodologia CI/CD, nos próximos artigos. Pegue seu café e vamos nessa!

Tópicos

  • Introdução
  • VM vs Docker
    • VM
    • Docker
  • Instalação
  • Comandos básicos

Introdução

O Docker é um serviço de contêiner, uma engine de contêiner. É um software que empacota todas as dependências de sua aplicação ou de uma aplicação que você deseja criar e as colocam dentro de um contêiner.

A partir do momento que você tem sua aplicação distribuída em contêiner, você pode compartilhar estes contêineres para a sua equipe trabalhar junto. Baseado nisso, não vai ter mais aquele problema de que, “na minha máquina funcionou”.

Com o Docker, o time pode trabalhar nas aplicações utilizando as mesmas dependências uns aos outros. Isso acontece pelo fato de que as aplicações são baseadas nas dependências de file system ou até mesmo serviços que rodam na máquina do dev.

Versões de aplicações variam muito do uso de pessoas para pessoas, por exemplo, dev-01 está com a versão do PHP “x”, o dev-02 está com a versão do PHP “xpto”. As vezes, a aplicação pode rodar apenas em uma versão específica do PHP. É devido à estes problemas de versões que as aplicações possuem, que surgiu aquela famosa frase mencionada acima, “na minha máquina funcionou”.

O Docker se propõe para que, sua aplicação independente de onde ela estiver, em qual SO ela estiver alocada, ela sempre funcionará da mesma forma para todos os SO, independente das bibliotecas que os compõe.

O Docker separa a sua aplicação de forma virtualizada, você pode escolher dentro do contêiner as bibliotecas e ferramentas que irão compor sua aplicação. Exemplo:

Temos 03 containeres:

  • Container 01 - Aplicação node API
  • Container 02 - Aplicação MySql, BD para a aplicação node consultar serviços de BD.
  • Container 03 - Página PHP que consome serviços da API node e joga estes serviços para dentro de uma página HTML.

Em cada um destes contêineres irá rodar uma versão da ferramenta principal, e também irá rodar dentro de um SO base, de acordo com o estilo de aplicação - Exemplo: aplicação node precisa rodar numa distro Linux. Aplicação MySql também precisa rodar numa distro Linux ou Windows. A aplicação PHP, além de uma distro Linux, precisaria indexar junto ao contêiner, o serviço apache para hospedar está página, ou, se fosse uma aplicação .NET, precisaria rodar encima de uma distro Windows e dentro deste SO, instalar o IIS, servidor de aplicação da Microsoft.

Obs: Vale ressaltar que estes três contêineres, em conjunto, eles irão rodarem dentro de um SO específico, por exemplo, o Windows. Isso não interfere pelo fato de que o Docker tem diversas bibliotecas baixadas junto ao software que integra as dependências de ferramentas que você precisa. Óbvio que para as imagens que não vem instaladas juntas ao Docker, ao serem baixadas via repositório Docker hub, irão vir junto as dependências destas imagens.

VM vs Docker

VM

Utilizando recurso de VM, irá ter um SO principal encima desta infraestrutura:

alt

O hypervisor é um recurso principal e acaba sendo o mais caro nesta solução, pois, é este software que faz a distribuição de recursos de hardware para serem alocados em cada VM de acordo com a aplicação que você irá rodar. O hypervisor poderia ser VMware ESXI, por exemplo.

Dentro de cada VM seria alocado um SO para servir de base à sua aplicação, em seguida virá as bibliotecas e binários dessa VM, e por fim teremos de fato a aplicação no terceiro bloco de VM.

Obs: Com este tipo de solução, de certa forma acaba tendo muito desperdício de recursos de hardware, além de ficarmos refém do hypervisor para ter este tipo de cenário utilizando VMs para hospedarem as aplicações.

Docker

O Docker não depende de um hypervisor para rodar seus contêineres, ele utiliza as próprias features do kerner do próprio host onde ele está instalado. Dessa forma a inicialização é mais rápida e em poucos segundos a sua aplicação já está no ar com todas as dependências que ela precisa para rodar encima do Docker e de qualquer outra máquina, desde que esteja também com o Docker instalado:

alt

Para que as sua aplicações possam consumir menos recursos de hardware, o seu host físico precisaria rodar em uma distribuição Linux para que o Docker consiga consumir os recursos do kernel de seu SO. Todos os recursos de file system seria compartilhado, é essa magia que torna o Docker incrível de se implementar.

Instalação

A instalação do Docker e suas dependências é bem fácil de instalar mas primeiro, precisamos atualizar o índice do pacote e preparar o apt para instalar repositórios HTTP:

thiago@thiago:~$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    Software-properties-common

Em seguida, precisamos adicionar a chave GPG para apt e verificarmos se a chave corresponde à impressão digital 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88:

thiago@thiago:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
thiago@thiago:~$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ desconhecida] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

thiago@thiago:~$

Depois de puxarmos dados do Docker via comando curl, agora iremos adicionar um repositório Docker estável ao apt:

thiago@thiago:~$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

Por fim, atualizaremos o índice do pacote e em seguida iremos instalar o Docker Engine e o containerd:

thiago@thiago:~$ sudo apt-get update
thiago@thiago:~$ sudo apt-get install docker-ce docker-ce-cli containerd.io

Para validarmos que o Docker está instalado, faremos a execução de um contêiner básico para confirmar se a instalação foi bem-sucedida:

thiago@thiago:~$ sudo docker run hello-world

Opcionalmente, poderá ser adicionado seu nome de usuário ao Docker group, caso queira utilizar o Docker como um usuário não root. Costumo fazer em ambiente de laboratório, mas isso pode não ser apropriado para seu ambiente de produção, portanto, verifique com sua equipe de segurança antes de fazer isso na produção:

thiago@thiago:~$ sudo usermod -aG docker `id -un`

Pronto, o Docker agora já está instalado!

Comandos básicos

  • docker - executando só esta palavra, do lado client irá ser listado os seguintes comandos: ``` bash thiago@thiago:~$ docker Usage: docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options: –config string Location of client config files (default “/home/thiago/.docker”) -c, –context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with “docker context use”) -D, –debug Enable debug mode -H, –host list Daemon socket(s) to connect to -l, –log-level string Set the logging level (“debug”|”info”|”warn”|”error”|”fatal”) (default “info”) –tls Use TLS; implied by –tlsverify –tlscacert string Trust certs signed only by this CA (default “/home/thiago/.docker/ca.pem”) –tlscert string Path to TLS certificate file (default “/home/thiago/.docker/cert.pem”) –tlskey string Path to TLS key file (default “/home/thiago/.docker/key.pem”) –tlsverify Use TLS and verify the remote -v, –version Print version information and quit

Management Commands: builder Manage builds config Manage Docker configs container Manage containers context Manage contexts engine Manage the docker engine image Manage images network Manage networks node Manage Swarm nodes plugin Manage plugins secret Manage Docker secrets service Manage services stack Manage Docker stacks swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes

Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container’s changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container’s filesystem events Get real time events from the server exec Run a command in a running container export Export a container’s filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes


* `docker image ls` -  Lista as imagens que eu tenho pré carregadas dentro do ambiente de repositório Docker local:
``` bash
thiago@thiago:~$ docker image ls
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
vr-xcon                     latest              9d2298bb92b0        6 days ago          147MB
vrnetlab/vr-xcon            latest              9d2298bb92b0        6 days ago          147MB
veos                        4.18.10M            12915790e700        6 days ago          889MB
debian                      stretch             b33ba41eae78        11 days ago         101MB
ciscotestautomation/pyats   latest              4872b666b62f        7 months ago        609MB
hello-world                 latest              bf756fb1ae65        11 months ago       13.3kB
busybox                     latest              b534869c81f0        12 months ago       1.22MB
  • #cd /var/lib/docker/ - Diretório onde estão todas as dependências do Docker:
    root@thiago:/var/lib/docker# l
    builder/  buildkit/  containers/  image/  network/  overlay2/  plugins/  runtimes/  swarm/  tmp/  trust/  volumes/
    root@thiago:/var/lib/docker# 
    root@thiago:/var/lib/docker# alias l="ls -la"
    root@thiago:/var/lib/docker# l
    total 56
    drwx--x--x 14 root root 4096 nov 23 08:17 .
    drwxr-xr-x 75 root root 4096 nov 23 08:04 ..
    drwx------  2 root root 4096 dez 12  2019 builder
    drwx--x--x  4 root root 4096 dez 12  2019 buildkit
    drwx------  8 root root 4096 nov 23 15:30 containers
    drwx------  3 root root 4096 dez 12  2019 image
    drwxr-x---  3 root root 4096 dez 12  2019 network
    drwx------ 31 root root 4096 nov 23 15:30 overlay2
    drwx------  4 root root 4096 dez 12  2019 plugins
    drwx------  2 root root 4096 nov 23 08:17 runtimes
    drwx------  2 root root 4096 dez 12  2019 swarm
    drwx------  2 root root 4096 nov 23 09:48 tmp
    drwx------  2 root root 4096 dez 12  2019 trust
    drwx------  2 root root 4096 dez 12  2019 volumes
    
  • root@thiago:/var/lib/docker# docker image pull <nome_imagem> - Este comando pega a imagem do ubuntu no repositório remoto do Docker, seria o Docker hub, isso acontece pelo fato de que, dentro das dependências do Docker existe uma API que pega a imagem que você solicitou:
    root@thiago:/var/lib/docker# docker image pull ubuntu
    Using default tag: latest
    latest: Pulling from library/ubuntu
    da7391352a9b: Pull complete 
    14428a6d4bcd: Pull complete 
    2c2d948710f2: Pull complete 
    Digest: sha256:c95a8e48bf88e9849f3e0f723d9f49fa12c5a00cfc6e60d2bc99d87555295e4c
    Status: Downloaded newer image for ubuntu:latest
    docker.io/library/ubuntu:latest
    root@thiago:/var/lib/docker# 
    root@thiago:/var/lib/docker# 
    root@thiago:/var/lib/docker#
    
  • root@thiago:/var/lib/docker# docker image rm ubuntu - Faz a exclusão de uma imagem específica:
    root@thiago:/var/lib/docker# docker image rm ubuntu
    Untagged: ubuntu:latest
    Untagged: ubuntu@sha256:c95a8e48bf88e9849f3e0f723d9f49fa12c5a00cfc6e60d2bc99d87555295e4c
    Deleted: sha256:f643c72bc25212974c16f3348b3a898b1ec1eb13ec1539e10a103e6e217eb2f1
    Deleted: sha256:9386795d450ce06c6819c8bc5eff8daa71d47ccb9f9fb8d49fe1ccfb5fb3edbe
    Deleted: sha256:3779241fda7b1caf03964626c3503e930f2f19a5ffaba6f4b4ad21fd38df3b6b
    Deleted: sha256:bacd3af13903e13a43fe87b6944acd1ff21024132aad6e74b4452d984fb1a99a
    root@thiago-ThinkPad-T430:/var/lib/docker#
    

Obs: Quando carregamos uma imagem ao Docker, vale ressaltar que estamos carregando apenas uma camada dessa imagem, o Docker não carrega a imagem completa, isso é bom por que você só baixa as imagens de acordo com o que você quer mexer dentro da imagem, ou seja, você baixa pacotes da imagem.

  • root@thiago:/var/lib/docker# docker container ls - Lista todos os contêineres em status de execução:
    root@thiago:/var/lib/docker# docker container ls
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                PORTS                                                                  NAMES
    b6869525935a        veos:4.18.10M       "/launch.py"        6 days ago          Up 6 days (healthy)   22/tcp, 80/tcp, 443/tcp, 830/tcp, 5000/tcp, 10000-10099/tcp, 161/udp   veos2
    812a511d67ac        veos:4.18.10M       "/launch.py"        6 days ago          Up 6 days (healthy)   22/tcp, 80/tcp, 443/tcp, 830/tcp, 5000/tcp, 10000-10099/tcp, 161/udp   veos1
    root@thiago:/var/lib/docker#
    
  • root@thiago:/var/lib/docker# docker container ls -a - Visualiza todos os contêineres em execução e parados:
    root@thiago:/var/lib/docker# docker container ls -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                                                                  NAMES
    b6869525935a        veos:4.18.10M       "/launch.py"             6 days ago          Up 6 days (healthy)        22/tcp, 80/tcp, 443/tcp, 830/tcp, 5000/tcp, 10000-10099/tcp, 161/udp   veos2
    812a511d67ac        veos:4.18.10M       "/launch.py"             6 days ago          Up 6 days (healthy)        22/tcp, 80/tcp, 443/tcp, 830/tcp, 5000/tcp, 10000-10099/tcp, 161/udp   veos1
    b783ca1bbb0c        vr-xcon             "/xcon.py --p2p veos…"   6 days ago          Exited (0) 6 days ago                                                                             bridge-veos1-2-veos2-2
    2e7522fd9a82        vr-xcon             "/xcon.py --p2p veos…"   6 days ago          Exited (0) 6 days ago                                                                             vr-xcon2
    347b1a433650        hello-world         "/hello"                 6 days ago          Exited (0) 6 days ago                                                                             hardcore_spence
    542664784e9d        busybox             "sh"                     11 months ago       Exited (0) 11 months ago                                                                          gracious_curran
    root@thiago:/var/lib/docker
    
  • root@thiago:/var/lib/docker# docker container stop veos1 veos2 - Stop para todos os contêineres em execução:
    root@thiago:/var/lib/docker# docker container stop veos1 veos2
    veos1
    veos2
    
  • root@thiago:/home/thiago/netdev/vrnetlab# docker container exec -it veos1 bash - Este comando entra no bash do contêiner, desta forma você pode inserir comandos para manipular um contêiner específico.
    root@thiago:/home/thiago/netdev/vrnetlab# docker container exec -it veos1 bash
    root@3b0d6974ba32:/#
    

Bom, por hoje é só. E aí, o que achou deste artigo? Comente aqui embaixo, vai ser legal contar com sua presença por aqui.

Tags:

Categories:

Updated:

Leave a Comment