Docker – Básico

Tópicos

  • O que é Docker.
  • Como Instalar.
  • Repositório Docker.
  • Imagens Docker
  • Iniciando containers.
  • Administração de containers.
  • Scripting.
  • Monitoramento de containers ( docker stats ).
  • Dockerfile.
  • Docker Networking
  • Compartilhando diretórios
  • O que é Docker.

    Docker é uma tecnologia de software que fornece containeres, promovido pela empresa Docker, Inc. O Docker fornece uma camada adicional de abstração e automação de virtualização de nível de sistema operacional no Windows e no Linux. O Docker usa as características de isolação de recurso do núcleo do Linux como cgroups e espaços de nomes do núcleo, e um sistema de arquivos com recursos de união, como OverlayFS e outros para permitir “containeres” independentes para executar dentro de uma única instância Linux, evitando a sobrecarga de iniciar e manter máquinas virtuais (VMs).

    Também pode ser visto como uma alternativa de virtualização em que o kernel da máquina hospedeira é compartilhado com a máquina virtualizada ou o software em operação, portanto um desenvolvedor pode agregar a seu software a possibilidade de levar as bibliotecas e outras dependências do seu programa junto ao software com menos perda de desempenho do que a virtualização do hardware de um servidor completo. Assim, o docker torna operações em uma infraestrutura como serviços web mais intercambiável, eficientes e flexíveis.

    Segundo uma análise da 451 Research, o “docker é uma ferramenta que pode empacotar um aplicativo e suas dependências em um recipiente virtual que pode ser executado em qualquer servidor Linux. Isso ajuda a permitir flexibilidade e portabilidade de onde o aplicativo pode ser executado, quer nas instalações, nuvem pública, nuvem privada, entre outros.

    Logo, aquela história de que a aplicação só funciona no computador do desenvolvedor acaba pois a aplicação inteira pode ser colocada dentro de um container e esse container pode ser utilizado em qualquer servidor docker.

    Principais componentes do Docker
  • docker daemon: usado para geneciar os containeres docker (LXC) no host onde ele roda.
  • docker CLI: usado para comandar e se comuinicar com o docker daemon
  • docker image index: um repositório (público ou privado) para as imagens do docker
  • Elementos principais do Docker
  • containeres docker: diretórios contendo tudo que constitui sua aplicação
  • docker images: imagens instantâneas dos containeres ou do S.O. básico (Ubuntu por exemplo)
  • Dockerfiles: scripts que automatizam o processo de construção de imagens
  • Como Instalar.
    Script automatizado
    
     $ curl -fsSL get.docker.com -o get-docker.sh
     $ sh get-docker.sh
    

    https://get.docker.com/

    Repositório Docker.

    Isso é bem interessante, existe um repositório chamado de docker hub, você pode visitar clicando aqui. Esse repositório serve basicamente como repositório de imagens. Você pode pesquisar por imagens e então baixar elas e inicar a imagem instantânea da distribuição/serviço.

    
    
    [docker@srv-docker docker]$ docker search debian
    INDEX       NAME                                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    docker.io   docker.io/ubuntu                              Ubuntu is a Debian-based Linux operating s...   7701      [OK]       
    docker.io   docker.io/debian                              Debian is a Linux distribution that's comp...   2577      [OK]       
    docker.io   docker.io/google/debian                                                                       52                   [OK]
    docker.io   docker.io/neurodebian                         NeuroDebian provides neuroscience research...   50        [OK]       
    docker.io   docker.io/arm32v7/debian                      Debian is a Linux distribution that's comp...   35                   
    docker.io   docker.io/armhf/debian                        Debian is a Linux distribution that's comp...   31                   
    docker.io   docker.io/itscaro/debian-ssh                  debian:jessie                                   23                   [OK]
    docker.io   docker.io/resin/armv7hf-debian                Debian is a Linux distro composed entirely...   18                   
    docker.io   docker.io/samueldebruyn/debian-git            a minimal docker container with debian and...   17                   [OK]
    docker.io   docker.io/arm64v8/debian                      Debian is a Linux distribution that's comp...   10                   
    docker.io   docker.io/eboraas/debian                      Debian base images, for all currently-avai...   8                    [OK]
    docker.io   docker.io/i386/debian                         Debian is a Linux distribution that's comp...   7                    
    docker.io   docker.io/rockyluke/debian                    Docker images of Debian.                        5                    
    docker.io   docker.io/vergissberlin/debian-development    Docker debian image to use for development...   5                    [OK]
    docker.io   docker.io/smartentry/debian                   debian with smartentry                          4                    [OK]
    docker.io   docker.io/vicamo/debian                       Debian docker images for all versions/arch...   3                    
    docker.io   docker.io/ppc64le/debian                      Debian is a Linux distribution that's comp...   2                    
    docker.io   docker.io/s390x/debian                        Debian is a Linux distribution that's comp...   2                    
    docker.io   docker.io/dockershelf/debian                  Repository for docker images of Debian. Te...   1                    [OK]
    docker.io   docker.io/holgerimbery/debian                 debian multiarch docker base image              1                    
    docker.io   docker.io/vpgrp/debian                        Docker images of Debian.                        1                    
    docker.io   docker.io/casept/debian-amd64                 A debian image built from scratch. Mostly ...   0                    
    docker.io   docker.io/igneoussystems/base-debian-client   Base image for debian clients                   0                    
    docker.io   docker.io/jdub/debian-sources-resource        Concourse CI resource to check for updated...   0                    [OK]
    docker.io   docker.io/trollin/debian                                                                      0                    
    

    A preferência dos resultados sempre vão ser os oficiais da distribuição/serviço, você pode adicionar uma tag ao final para procurar por uma versão especifica:

    
    [docker@srv-docker docker]# docker search debian:jessie
    

    Ou até mesmo a ultima liberada pelo mantenedor da imagem:

    
    [docker@srv-docker docker]# docker search debian:latest
    

    Imagens Docker

    As imagens docker constituem a base para os containeres docker de onde tudo começa a se formar. Elas são muito similares às imagens de disco padrão de sistema operacional que são utilizadas para executar aplicações em servidores e computadores de mesa.

    Tendo essas imagens (por exemplo uma base Ubuntu) permite-se a portabilidade perfeita entre sistemas.
    Eles constituem uma base sólida, consistente e confiável com tudo o que é necessário para executar as aplicações. Quando tudo é auto suficiente e o risco de atualizações ou modificações em nível de sistema é eliminado, o container torna-se imune a riscos externos que poderiam colocá-lo fora de ordem - evitando o "inferno de dependências".

    Quanto mais camadas (ferramentas, aplicações, etc) são adicionadas em cima da base, novas imagens podem ser formadas aplicando-se estas alterações. Quando um novo container é criado a partir de uma imagem salva (ou seja, com as alterações aplicadas), as coisas continuam de onde pararam. E o sistema de arquivos union, traz todas as camadas juntas como uma entidade única quando você trabalha com um container.

    Essas imagens de base podem ser explicitamente declaradas quando se trabalha com o docker CLI para criar diretamente um novo container ou, elas podem ser especificadas dentro de um Dockerfile para construção de imagem automatizada.

    Para iniciar com o docker, você pode pesquisar as imagens locais:

    
    [docker@srv-docker docker]# docker images
    

    Então vamos realizar o download de uma imagem,

    
    [docker@srv-docker docker]# docker pull debian:latest
    

    Se buscar novamente as imagens locais, irá encontrar a debian lá!

    Para remover imagens, você pode fazer da seguinte forma:

    
    [docker@srv-docker docker]# docker rmi debian
    

    Ela só será removida se não tiver nenhum container dependente dela, irei passar esse tipo de detalhe mais a frente.

    Iniciando containers.

    Agora que temos nossa imagem, você pode iniciar um container da seguinte forma:

    
    ~ docker run debian 
    


    Observe que ele irá iniciar e morrer, para evitar que isso ocorra, você pode executar no modo interativo passando um comando, no caso, o bash:

    
    ~ docker run --name containerName -it debian /bin/bash
    

    Os containers recebem nomes aleatórios, não definir nomes para o container é ruim pois você vai ter problemas para identificar quem é quem, uma forma de dar nomes à container na hora de inicializar é a seguinte:

    
    ~ docker run --name containerName -it debian /bin/bash
    

    Para sair do container, é só dar exit:

    
    root@51f7cb0a8162:/# exit
    

    O container vai constar na lista de containers disponíveis, você pode consultar todos os containers com o comando abaixo:

    
    [docker@srv-docker docker]$ docker ps -a
    container ID        IMAGE         COMMAND                  CREATED             STATUS                     PORTS                  NAMES
    66b810fdfeae        debian      "/bin/bash"              2 minutes ago       Exited (0) 2 minutes ago                          admiring_golick
    

    Observe o status do container, está como "Exited", ele pode ser reiniciado pelo nome ou ID simplesmente dando start utilizando o name ou id.

    
    [docker@srv-docker docker]$ docker start -i 66b810fdfeae
    

    Para evitar que o container fique ali no limbo, você pode remover o container assim que sair dele da seguinte forma:

    
    ~ docker run  --rm --name containerName -it debian /bin/bash
    


    Assim, quando sair do container, ele é removido automaticamente.

    Para remover containers, use:

    
    ~ docker rm containerNameOrID
    


    Administração de containers/imagens.

    Vamos supor que você esteja num container e quer verificar algo no servidor docker, fora do container, você pode utilizar as teclas:

    
    ctrl^P+Q
    

    Uma vez fora do container, você pode parar o container da seguinte forma:

    
    docker stop containerNameOrID
    

    Ou simplesmente matar ele!

    
    docker kill containerNameOrID
    

    Mas, agora, você não quis matar ninguém e já verificou o que queria fora do container, você pode voltar pro container simplesmente digitando:

    
    docker attach containerNameOrID
    

    Para verificar containers que estão em execução, simplesmente utilize o comando ps:

    
    [root@srv-docker docker]# docker ps
    container ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
    66b810fdfeae        debian              "/bin/bash"         13 minutes ago      Up 6 minutes                               admiring_golick
    2cb5618495a6        debian:stretch      "/bin/bash"         23 hours ago        Up 23 hours         0.0.0.0:4000->80/tcp   jekyls
    

    Com base nesses containers que estão em execução, você pode parar eles e depois iniciar. Para iniciar é só utilizar start:

    
    docker start containerNameOrID
    

    Caso queira iniciar o container e já entrar nele, pode utilizar -i:

    
    docker start -i containerNameOrID
    

    Para visualizar containers que não estão em execução porém estão presentes:

    	
    docker@N0tEvil:/$ docker ps -a
    container ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    d4daff4d1c54        ubuntu              "/bin/bash"         4 minutes ago      Exited (0) 16 minutes ago               big_cray
    

    Para remover esses caras, bom, você já aprendeu a usar o rm muitas linhas pra cima.

    Até aqui, sabemos que containers são volateis, se você deletar ou ele morrer, já era seu trampo. Existe uma forma de você salvar o seu container, como se fosse tirar um snapshot dele e gerar uma nova imagem em cima da atual, na real não é como, é isso que acontece.

    Para persistir mudanças no container:

    
    $ docker commit containerNameOrID  svendowideit/testimage:version3
    

    Uma observação é, acima você definiu o repositório como svendowideit, o nome da imagem é testimage e por ultimo é a tag version3. Você pode mandar esse container pro docker hub também, assim você poderá baixar de outros lugares assim como outras pessoas poderão, lembrando que o repositório é público. Se você quiser um privado, você precisa contratar algum serviço privado de repositório docker, porém esse lance não será abordado aqui.

    Vai gerar um sha256 -> Hash da camada que foi adicionada em cima, o docker nunca altera a imagem base.

    Você poderá então iniciar sua própria imagem gerada anteriormente simplesmente usando docker run, passando os devidos argumentos pro comando, claro.

    Para Visualizar alterações entre imagens, você pode executar:

    
    ~ docker diff  
    ~ docker diff e46faf784171
    

    Semelhança com git? Talvez. Ele vai mostrar todas as diferenças de dentro do container.

    Para executar comandos em um container, você utiliza o exec, pode ser utilizado como substituto do ssh ou do comando que está em operação no container na hora que ele foi construido. Ou seja, supondo que você inicou um container e para que ele não encerre, você deixou ele executando um loop besta, se você der append no container e der ctrl^C para sair do loop, o container para.

    
    ~ docker exec -it 3c97a996235f /bin/bash
    

    Então você pode utilizar o docker exec para entrar no container sem parar o processo principal, evitando que o container finalize depois que você saia.

    
    ID=$(docker run -d debian sh -c "while true;do sleep 1; done;"
    docker exec $ID /bin/bash
    docker exec
    

    Scripting.

    Removendo todos os containers interrompidos:

    
    [centos@srv-docker ~]$ docker rm -v $(docker ps -aq -f status=exited)
    

    Parando mais de um container ao mesmo tempo:

    
    ~ docker stop $(docker ps -q)
    
    Json

    Bom, os containers operam com um json bolado, você pode acessar eles e codar sua própria API se quiser, eu nunca precisei então não irei te mostrar como criar uma API, só irei te mostrar como puxar dados do container.

    Verificar mais a fundo o container:

    
    [root@srv-docker docker]# docker inspect admiring_golick
    [
        {
            "Id": "66b810fdfeae735ea2243cb58d06875dc3d59bf4a6c3b26773fbece2f87a4319",
            "Created": "2018-05-20T02:39:12.602015871Z",
            "Path": "/bin/bash",
            "Args": [],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 3337,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2018-05-20T02:45:46.191810949Z",
                "FinishedAt": "2018-05-20T02:39:17.383606751Z"
    --- saida omitida --- 
    

    Buscando informações mais especificas:

    
    [root@srv-docker docker]# docker inspect admiring_golick | grep IPAddress
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.3",
                        "IPAddress": "172.17.0.3",
    
    GO, sim a linguagem que eu não faço nem ideia ainda de como funciona

    Então, estamos aqui. Você pode utilizar templates em GO para tratar os Json, segue um exemplo:

    
    [docker@srv-docker docker]$ docker inspect  --format {{.NetworkSettings.IPAddress}} admiring_golick
    172.17.0.3
    

    Monitoramento de containers ( docker stats ).

    Eu tive uma briga feia com algumas soluções de monitoramento, acabou que engavetei minha pesquisa e entendi que poderia monitorar apenas com as ferramentas built-in do docker, para monitorar os containers em execução, você pode utilizar:

    
    [docker@srv-docker docker]$ docker stats
    container           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
    66b810fdfeae        0.00%               480 KiB / 1.796 GiB   0.03%               648 B / 648 B       3.85 MB / 0 B       1
    2cb5618495a6        0.00%               692 KiB / 1.796 GiB   0.04%               227 MB / 79.7 MB    148 MB / 1.59 GB    1
    

    Uma forma de ter um output mais userfriend seria empregar os templates GO, segue um exemplo:

    
    $ docker stats $(docker inspect -f {{.Name}} $(docker ps -q))
    CONTAINER           CPU %               MEM USAGE / LIMIT       MEM %               NET I/O             BLOCK I/O           PIDS
    /web3_commandexec   0.01%               6.852 MiB / 1.796 GiB   0.37%               3.3 kB / 648 B      24.3 MB / 12.3 kB   8
    /web4_notup2date    0.07%               117.7 MiB / 1.796 GiB   6.40%               2.2 kB / 648 B      82.8 MB / 549 kB    37
    /web1_threeparts    0.01%               6.848 MiB / 1.796 GiB   0.37%               3.63 kB / 648 B     24.3 MB / 12.3 kB   8
    /web2_passatempo    0.01%               6.848 MiB / 1.796 GiB   0.37%               1.14 kB / 648 B     24.3 MB / 12.3 kB   8
    /net2_telnet        0.00%               664 KiB / 1.796 GiB     0.04%               2.45 kB / 648 B     6.89 MB / 12.3 kB   3
    

    A diferença é que ele colocou o nome do caontainer ao invés da ID, fica mais fácil de identificar quem é quem agora!

    Dockerfile.

    Dockerfiles são scripts contendo uma série sucessiva de instruções, orientações e comandos que devem ser executados para formar uma nova imagem docker. Cada comando executado traduz-se para uma nova camada da cebola, formando o produto final. Elas basicamente substituem o processo de se fazer tudo manualmente e repetidamente. Quando um Dockerfile conclui a execução, você acaba tendo formado uma imagem, que então, você utiliza para iniciar ( ou seja, criar) um novo container.

    To cansado de escrever, vou só dar um exemplo de docker file:
    Crie um arquivo chamado Dockerfile

    
    FROM debian:stretch
    MAINTAINER R3bel
    RUN apt-get update && apt-get install telnetd -y && useradd -m -s /bin/bash ENG_Florentino && echo 'batatã' > ~ENG_Florentino/loveme && echo 'ENG_Florentino:diediedie' | chpasswd
    

    Então dê:

    
    docker build -t localrepo/imagename .
    

    Ele aceita várias outras instruções, muitas outras mesmo. Tem que lembrar que cada instrução, dependendo de qual, tipo o COPY vai adicionar uma outra camada à imagem. Outras instuções como CMD só poderá ser executada uma vez. Tem muitas outras instruções mesmo, porém eu n to afim de falar sobre isso agora, se você está lendo isso agora, quer dizer que ainda não tive saco pra melhorar esse doc.

    Docker Networking

    Abrindo portas externas no host para dentro do container:

    
    ~ docker run -it -d -p 8080:80  
    

    O comando acima vai redirecionar da porta 8080 do host para dentro do container na porta 80.

    Um outro exemplo, que eu tive que utilizar recentemente, eu defini várias interfaces virtuais no meu servidor Docker e queria colocar um contatiner em um IP, para definir isso, você pode fazer da seguinte forma:

    
    docker run -d -p 10.2.3.116:21:21 net02 /etc/init.d/vsftpd start
    

    O comando acima vai iniciar o container net02 como daemon(background) e vai passar o comando de start do serviço vsftpd, redirecionando tudo do endereço ip 10.2.3.116 na porta 21 para o container na porta 21.

    Se você for um bom observador, vai ter entendido que o comando acima está cagado pois o FTP não usa só uma porta, ele utiliza duas, para resolver isso, você pode fazer o seguinte:

    
    docker run -d -p 10.2.3.116:20:20 -p 10.2.3.116:21:21 net02 /etc/init.d/vsftpd start
    

    Eu já ia esquecendo de citar, se você usar o -P ao invés do -p, o Docker vai usar uma porta randomica, isso parece nonsense, mas é bem interessante para adotar em plataformas de CTF por exemplo, onde se cria um container para cada equipe.

    Agora, para linkar containers entre si?

    Os links do Docker são a maneira mais fácil de permitir que containers existentes no mesmo host conversem uns com os outros. Quando o modelo-padrão de rede do Docker é usado, a comunicação entre containeres ocorre por meio de uma rede interna da plataforma Docker, o que significa que as comunicações não são expostas para a rede do host.

    O Docker define variáveis de ambiente dentro do container-mestre para facilitar a comunicação com o container conectado. Mas isso ai você descobre por conta, é só dar o comando env dentro do container.

    Bom, então como que rola o bag, primeiro você cria o container que será conectado, depois o master, conectando no conectado?
    Subindo container que será coenctado:

    
    docker run -d --name badass debian:latest
    

    Subindo container mestre e conectando:

    
    docker run -d --link badass:bad debian:latest
    

    Quando o cabo pluga, o Docker já cria regras no netfilter aka iptables para permitir a comunicação entre os dois. Ele também adiciona no /etc/hosts o container e tal, assim você acessa pelo Hostname, que na verdade é só um alias pro IP.

    A estrutura do comando é a seguinte:

    
    --link :alias
    

    Então, eu falei ali do /etc/hosts, no caso, será criado um alias do container badass e dentro do /etc/hosts será adicionado o alias para o container badass com o nome de bad

    Compartilhando diretórios

    Aqui o naipe é o seguinte, você pode compartilhar diretórios do host com um ou mais containers ou entre containers.

    Compartilhando diretórios do host com containers

    Aqui você usa a flag -v

    
    docker run -v /home/fulano/app:/data debian 
    

    Outro exemplo:

    
    ~ docker run -it -d -p 8080:80 -v /que/queeuquero/:/pra/ond  
    
    Compartilhando diretórios entre containers

    Aqui você usa --volumes-from, essa fica de dever de casa!

    Fontes/Recursos

    http://www.diego-garcia.info/2015/02/15/docker-por-onde-comecar/
    https://get.docker.com/
    https://docs.docker.com/engine/reference/commandline/commit/#examples
    https://docs.docker.com/network/links/#communication-across-links

    One thought on “Docker – Básico

    Leave a comment

    This site uses Akismet to reduce spam. Learn how your comment data is processed.