JavaRush /Blogue Java /Random-PT /Primeiro contato com Docker
Viacheslav
Nível 3

Primeiro contato com Docker

Publicado no grupo Random-PT
A conteinerização é um mecanismo frequentemente usado na prática. Por exemplo, ao pesquisar no headhunter, você encontrará 477 vagas até hoje que mencionam Docker. Portanto, não seria uma má ideia familiarizar-se com o que é. Espero que esta breve revisão ajude a formar uma primeira ideia. Bem, ele apoiará isso com materiais adicionais, como cursos na Udemy. Primeira introdução ao Docker - 1

Introdução

Nesta breve revisão, gostaria de abordar um tópico como a conteinerização. E você precisa começar entendendo o que realmente é a conteinerização. De acordo com a Wikipedia, “ Conteinerização ” é a virtualização no nível do sistema operacional (ou seja, NÃO no hardware), na qual o kernel do sistema operacional mantém várias instâncias isoladas do espaço do usuário em vez de apenas uma. " Espaço do usuário " é o espaço de endereço da memória virtual do sistema operacional reservado para programas de usuário. As instâncias de espaço do usuário (comumente chamadas de contêineres) são completamente idênticas a uma única instância do sistema operacional do ponto de vista do usuário. O kernel garante o isolamento completo do contêiner, de modo que programas de contêineres diferentes não possam afetar uns aos outros. Acontece que a conteinerização é a virtualização de software, ou seja, a virtualização no nível do sistema operacional, pela qual o kernel do sistema operacional é responsável. Uma das características desta abordagem é que todos os contêineres usam um kernel comum, o mesmo do sistema operacional host (ou seja, aquele no qual os contêineres estão localizados). Isso permite que você se livre da sobrecarga de emular hardware virtual e iniciar uma instância completa do sistema operacional. Podemos dizer que se trata de uma virtualização “leve”. O kernel é a parte central do sistema operacional que fornece aos aplicativos acesso coordenado aos recursos do computador, como tempo do processador, memória, hardware externo e dispositivos externos de entrada e saída. O kernel também normalmente fornece serviços de sistema de arquivos e protocolo de rede. Em geral, este é o coração de todo o sistema. Para informações adicionais, pode ser útil revisar o material “ Informações gerais sobre contêineres ”. E mais algumas palavras para completar a introdução. Agora entendemos que um sistema operacional possui um kernel. Ele fornece isolamento para instâncias de espaço do usuário. Neste contexto, você pode se deparar com o termo “ cgroups ”. Este é o nome do próprio mecanismo do kernel Linux que permite que você consiga isso. Portanto, podemos dizer que o caminho da conteinerização começou com os sistemas Linux. Porém, a partir do Windows 10, também apareceu o suporte para conteinerização. Para trabalhar com virtualização, você precisa configurar o suporte à virtualização no BIOS do seu computador. Como fazer isso depende do computador. Por exemplo, pode ser assim:
Primeira introdução ao Docker - 2
No Windows você pode verificar isso de diferentes maneiras. Por exemplo, você pode baixar um utilitário especial do site da Microsoft: Ferramenta de detecção de virtualização assistida por hardware . Bom, vale a pena mencionar outro conceito importante – Hypervisor. Hypervisor é um monitor de máquina virtual, um programa que garante a execução paralela de vários sistemas operacionais em um computador. O hipervisor garante que os sistemas operacionais estejam isolados uns dos outros e compartilhe recursos entre os sistemas operacionais em execução. Um desses hipervisores é o Oracle VirtualBox .
Primeira introdução ao Docker - 3

Docker

Então, o que é virtualização é claro. Mas como usá-lo? E aqui o Docker vem em nosso auxílio. Docker é um software para automatizar a implantação e gerenciamento de aplicações em ambientes conteinerizados. Vale a pena começar com o fato de que o Docker é representado por um conceito como Docker Enginge. E você deve começar com o site oficial do Docker e a seção “ Visão geral do Docker ”.
Primeira introdução ao Docker - 4
A documentação diz que o docker consiste em:
  • Servidor Docker chamado processo Docker Daemon (dockerd).
  • Interface de linha de comando, também conhecida como CLI (docker).
  • Uma API REST que descreve como os programas podem “conversar” com o deamon e dizer-lhe o que fazer.
Antes de prosseguirmos, vamos instalar o docker, ou seja, instalar o daemon do docker. O site do Docker possui instruções para instalação do “ Docker for Windows ”. Curiosamente, o Docker tem seus próprios requisitos de sistema. E se você, como eu, tem um Windows antigo, por exemplo o Windows 7, então você precisa usar o Docker Toolbox.
Primeira introdução ao Docker - 5

Caixa de ferramentas Docker

Para instalar o Docker em máquinas antigas que não atendem aos requisitos do sistema. O site diz isso, “Legacy Desktop Solution”. Vamos para a página " Docker Toolbox " e faça o download. Este conjunto pesa cerca de 211 megabytes. Vamos instalá-lo como padrão, ou seja, simplesmente concordaremos humildemente com tudo, sem reorganizar os sinalizadores. Após a instalação verificaremos se está tudo bem. No futuro, o nosso campo de batalha será a linha de comando. Recomendo não usar a linha de comando do Windows, pois pode haver problemas não óbvios com ela. É melhor usar o bash shell. No Windows, a maneira mais recomendada de obtê-lo é instalar o sistema de controle de versão git , ainda será útil. Porque “empacotado” com ele estará a festa que precisamos. Para esta revisão usarei git bash. Você também pode instalar o bash com CYGWIN . Vamos lançar o bash ou git bash. Vamos ter certeza de que instalamos a Docker Machine, também conhecida como Docker Machine: docker-machine -version O que é essa Docker Machine? Docker Machine é um utilitário para gerenciar hosts dockerizados (são hosts nos quais o Docker Engine está instalado). Se imediatamente após a instalação do Docket Toolbox visualizarmos as máquinas docker usando o comando docker-machine ls, veremos uma lista vazia:
Primeira introdução ao Docker - 6
Vamos criar uma nova máquina. Para fazer isso, precisamos executar o comando create :: docker-machine create -- driver virtualbox javarushVeremos o log de criação da máquina docker:
Primeira introdução ao Docker - 7
O que nos interessa aqui é o seguinte. O que é Boot2Docker? Esta é uma distribuição Linux minimalista para rodar o Docker Engine (entendemos que o Docker funciona graças às ferramentas de virtualização do Linux, e no Windows o mecanismo necessário apareceu apenas a partir do Windows 10). Esta distribuição é baseada na distribuição " Tiny Core Linux ". Também mencionado sobre o VirtualBox VM. Isso ocorre porque especificamos --driver virtualbox. Uma nova máquina virtual foi criada no VirtualBox a partir da imagem Boot2Docker. Após a criação, podemos iniciar o VirtualBox (já que o VirtualBox é instalado com o Docker Toolbox) e ver a máquina virtual criada para a máquina docker:
Primeira introdução ao Docker - 8
Após a criação, seremos solicitados a executar o comando “ docker-machine env ” para obter as variáveis ​​de ambiente que precisam ser configuradas para conectar-se à máquina docker:
Primeira introdução ao Docker - 9
Depois de executar este comando usando docker-machine, nos conectamos a um host remoto dockerizado (neste caso, um virtual hospedado no Virtual Box) e podemos executar comandos docker localmente como se os estivéssemos executando em um host remoto. Para verificar, podemos executar o comando “ docker info ”. Se a conexão com a máquina docker não for estabelecida, receberemos um erro. E se tudo estiver bem, informações sobre o docker na máquina docker. Agora é a hora de entender como o Docker geralmente funciona e como usá-lo.
Primeira introdução ao Docker - 10

Contêineres Docker

Então temos o docker. Afinal, o que é esse docker? A documentação do Docker e a seção “ Introdução ” nos ajudarão a entender isso . A parte introdutória desta seção apresenta os conceitos do Docker . Afirma que Docker é uma plataforma para desenvolver, depurar e executar aplicações em contêineres. Portanto, o principal para o Docker são os contêineres. Mesmo se você olhar para o logotipo do Docker, verá que é uma baleia que segura contêineres nas costas. Mas o que é um contêiner? A seguir, na seção " Imagens e contêineres ", diz que um contêiner é uma instância em execução do Image. E Imagem é um “pacote” que contém tudo o que é necessário para a aplicação (código, ambiente, bibliotecas, configurações, etc.). Agora vamos tentar nós mesmos. O site do Docker tem uma seção chamada “ Amostras do Docker ” que inclui “ Docker para Iniciantes ”. Os exemplos daqui parecem mais interessantes para mim. Então, de repente, queríamos nos familiarizar com o Alpine Linux e podemos fazer isso usando contêineres Docker. Para obter uma imagem, devemos “puxá-la” ou “puxá-la” para fora. Portanto, executamos o comando docker pull :docker pull apline
Primeira introdução ao Docker - 11
Como podemos ver, estamos baixando de algum lugar. Por padrão, o Docker consulta seu repositório na rede https://hub.docker.com . Depois de recuperar a imagem com sucesso, podemos verificar a lista de imagens disponíveis executando o comando docker images :
Primeira introdução ao Docker - 12
Agora temos uma imagem apline. Como o contêiner é uma instância de imagem em execução, vamos lançar essa mesma imagem. Vamos iniciar o contêiner usando o comando docker run alpine. Como vemos, nada aconteceu. Se executarmos o comando docker pspara exibir todos os contêineres ativos, também não obteremos nada. Mas se executarmos, docker ps -averemos todos os containers:
Primeiro contato com Docker - 13
Acontece que não lançamos o Docker no modo interativo. Portanto, ele executou o comando e parou. O comando era abrir o terminal. Vamos fazer a mesma coisa, mas em modo interativo (com a flag -it ):
Primeira introdução ao Docker - 14
Como você pode ver, superado um erro e aproveitando a dica, chegamos ao container e podemos trabalhar nele! Para sair do container sem interromper seu funcionamento, você pode pressionar Ctrl + p + q. Se executarmos agora docker ps, veremos um contêiner ativo. Para entrar em um contêiner já em execução, execute o comando docker exec :
Primeiro contato com Docker - 15
Recomendo a leitura da descrição do exemplo do Docker para uma excelente descrição de como tudo isso acontece: “ 1.0 Executando seu primeiro contêiner ”. Gosto porque está tudo escrito ali de uma forma muito acessível e compreensível. Para reformular brevemente, estamos conectados usando docker-machine a uma máquina virtual executando Docker Daemon. Usando a CLI sobre a API REST, pedimos para iniciar a imagem alpina. Docker o encontra e, portanto, não o baixa. Docker cria um novo contêiner e executa o comando que especificamos neste contêiner. E tudo isso, claro, é bom. Mas por que precisamos de tudo isso? E aqui precisamos descobrir como o docker cria uma imagem. E ele os cria com base no dockerfile.
Primeira introdução ao Docker - 16

Dockerfile

Conforme declarado na referência do Dockerfile , um dockerfile é um arquivo de texto que contém todos os comandos para obter uma imagem. Na verdade, todas as imagens que recebemos (até mesmo Alpine, do exemplo acima) foram criadas a partir de um dockerfile. Vamos construir nossa imagem com uma aplicação Java. E primeiro precisamos deste aplicativo Java. Sugiro usar o sistema de compilação Gradle, sobre o qual você pode ler mais nesta breve revisão: “ Uma Breve Introdução ao Gradle ”. Nos ajudará na criação do projeto " Gradle Build init plugin ". Vamos criar um novo aplicativo Java usando Gradle: gradle init --type java-application Este comando cria um modelo de projeto Java. Este é um aplicativo independente, mas gostaríamos de criar um aplicativo web. Vamos remover as classes App e AppTest (elas foram geradas automaticamente pelo Gradle Build Init Plugin). Para criar rapidamente uma aplicação web, usaremos o tutorial do Gradle: “ Construindo Java Web Applications ”. De acordo com o tutorial, vamos fazer: Você tem que ter cuidado aqui. Como sempre, pode haver erros nos exemplos. Aqui está:
Primeira introdução ao Docker - 17
Agora, para testá-lo, vamos adicionar o plugin gretty ao build.gradle, conforme indicado na seção " Adicionar o plugin gretty e executar o aplicativo ":
plugins {
    id 'war'
    id 'org.gretty' version '2.2.0'
}
É interessante que Gretty não veja o erro HelloServletdescrito acima. Isso prova que um aplicativo pode se comportar de maneira diferente em ambientes diferentes. Gretty pode funcionar onde um servidor autônomo normal geraria um erro. Resta verificar se o aplicativo está funcionando corretamente. Vamos fazer:gradle appRun
Primeiro contato com Docker - 18
Se tudo estiver bem, use o comando gradle warpara coletar um arquivo com a extensão war (arquivo web). Por padrão, o gradle o constrói no formato \build\libs. Agora estamos prontos para escrever nosso dockerfile. Usando a " referência do Dockerfile " criaremos um Dockerfile. Vamos criar um arquivo chamado “Dockerfile” na raiz do nosso projeto Java (no mesmo local do script de construção). Vamos abri-lo para edição. Este arquivo possui formato próprio, descrito na seção " Referência do Dockerfile: Formato ". Qualquer dockerfile começa com uma instrução FROM, indicando a “imagem base”. Podemos dizer que esta é a imagem parental com base na qual fazemos a nossa imagem. É muito fácil escolhermos uma imagem pai. Uma aplicação web precisa de um servidor web. Por exemplo, podemos usar o servidor web Tomcat. Vamos ao repositório oficial do Docker, chamado docker hub . Olhamos lá para ver se a imagem que precisamos está lá:
Primeiro contato com Docker - 19
Também vale a pena entender que a imagem do Tomcat é chamada. Mas além do nome tem uma tag. Uma tag é como uma versão. As imagens do Tomcat de diferentes versões diferem em qual versão do Tomcat é usada, qual versão do jre e qual imagem base. Por exemplo, podemos obter uma imagem docker pull tomcat:9-jre8-alpine que usa a versão 9 do Tomcat, jre versão 8 e uma imagem alpina como base. Isso pode ser importante para reduzir o tamanho da nossa imagem:
Primeiro contato com Docker - 20
Como podemos ver, a diferença é enorme. Se construirmos nossa imagem baseada no Tomcata Alpine, começaremos com apenas 100 megabytes, e não com 600. Assim, adicionaremos o seguinte conteúdo ao dockerfile criado anteriormente:
# Базовый образ, "наследуемся" от него
FROM tomcat:9-jre8-alpine
# Копируем из Build Context'а собранный web archive в каталог томката
COPY build/libs/docker.war /usr/local/tomcat/webapps/docker.war
# Меняем рабочий каталог на томкатовский
WORKDIR /usr/local/tomcat
# Открываем порт 8080 для контейнера, т.к. его слушает томкат
EXPOSE 8080
E agora vamos executar o comando para construir a imagem: docker build -t jrdocker ..
Primeiro contato com Docker - 21
-t- isso é uma tag, ou seja, como chamar a imagem montada. O ponto no final significa que adicionamos o diretório atual (o diretório onde o dockerfile está localizado e de onde executamos o comando) a Build context. Build context- este é o contexto dos arquivos que estão disponíveis ao criar um dockerfile. Como você pode ver, graças a isso conseguimos copiar o arquivo war montado em nossa imagem, no diretório do servidor web. Agora vamos executar nossa imagem:docker run -d --rm -p 8888:8080 jrdocker
Primeiro contato com Docker - 22
Para saber se o servidor foi iniciado, você pode consultar o log do contêiner. O log pode ser obtido usando o comando docker logs, especificando o contêiner por seu ID ou nome. Por exemplo:
Primeiro contato com Docker - 23
Bem, não se esqueça que sempre podemos ir a um contêiner em execução pelo nome com o comando: winpty docker exec -it NameКонтейнера sh Agora só falta conectar. Anteriormente, especificamos EXPOSE , ou seja, permitimos acesso de dentro do contêiner à porta 8080. Quando iniciamos o contêiner em si, especificamos a tag -p ( portas de entrada ), correlacionando assim a porta 8080 no contêiner (o servidor web Tomcat está aguardando conexões lá) com a porta 8888 em uma máquina com um daemon docker. Como lembramos, lançamos o daemon docker não diretamente, mas por meio do docker-machine. Portanto, vamos mais uma vez solicitar dados em nossas máquinas docker usando o comando docker-machine ls e entrar em contato com o servidor no contêiner:
Primeira introdução ao Docker - 24
Assim, você e eu acabamos de lançar nosso aplicativo web em um contêiner Docker! ) Também gostaria de observar o seguinte. Em caso de problemas de acesso, lembre-se que a máquina Docker é antes de tudo uma máquina virtual Virtual BOx. Pode haver problemas com as configurações de rede da máquina virtual. Uma configuração funcional do VMBox pode ser assim:
Primeiro contato com Docker - 25
Primeiro contato com Docker - 26

Camadas

Já descobrimos que as imagens são criadas a partir de dockerfiles e que os dockerfiles são um conjunto de comandos. Também descobrimos que um dockerfile tem um pai. E que o tamanho das imagens é diferente. Curiosamente, você pode ver o histórico de como a imagem foi construída usando o comando docker history . Por exemplo:
Primeiro contato com Docker - 27
É importante dizer isso para entender que, em essência, cada imagem é um conjunto de imagens. Cada alteração de imagem (cada novo comando no dockerfile) cria uma nova camada que possui seu próprio ID. Você pode ler mais sobre camadas na documentação " Docker: Imagens e Camadas ". Também recomendo fortemente a leitura do artigo no Habré: “ Imagens Docker e contêineres em imagens ”.

Conclusão

Espero que esta breve visão geral tenha sido suficiente para que você se interesse pela conteinerização. Abaixo estão links para materiais adicionais que podem ser úteis: #Viacheslav
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION