Escolar Documentos
Profissional Documentos
Cultura Documentos
19 de julho de 2018
/
Infra
/
2 Comments
Estou estudando Docker. Por isso, subi dois containers, um com uma aplicação construída em Java e outro com o banco de dados MySQL.
Subi os dois containers e salvei alguns dados no banco, no outro dia, quando subi a aplicação de novo, percebi que os dados do banco tinham
sumido.
Toda a vez que um container é removido, ele perde todas as suas informações, isto é, tudo que estava salvo no container é deletado, o que faz
sentido já que, pensando em escalabilidade, um container pode ser, quando necessário, tanto criado ou excluído.
Contudo existem algumas informações que não devemos perder, os dados do banco são exemplo, neste caso, essa era uma aplicação de teste,
mas e se estivesse em produção?
O usuário poderia acessar a aplicação um dia e notar que todos os dados sumiram. Já pensou ter que realizar todos os cadastros de novo, sem
falar de informações, como dados de vendas, que seriam perdidos.
Ou seja, queremos falar para o Docker criar um repositório de dados para os containers, ou, como é chamado volume.
Vamos falar para o docker que queremos criar um volume volume create chamado dados-do-banco, no meu caso:
Aparentemente deu tudo certo, mas como podemos saber quais são nossos volumes? Bem, podemos falar para o docker listá-los (ls):
docker volume ls
Neste comando o Docker nos mostra qual o nome do volume e o seu driver. Isto é, qual é a forma que ele deve montar o volume. No meu
caso, este é o driver local, o driver padrão (built-in) do Docker.
Dessa forma, estamos falando para o Docker criar um container e associar o diretório /var/lib/mysql ao volume dados-do-banco. Nossa
aplicação precisa de uma senha para se logar no banco de dados, então vamos falar que este container, em seu ambiente (-e, environment),
terá a senha alura:
Legal, agora basta falarmos qual é a imagem que criará nosso container, no nosso caso, é a imagem do MySQL:
Legal nosso container está rodando, vamos fazer alguns testes para testar nosso volume. Em uma outra aba no terminal, vamos falar para o
docker que queremos executar alguns comandos em um container (container exec) com um terminal interativo (-ti) no nosso container
bd com o interpretador /bin/bash:
Vamos logar no mysql com o usuário (-u) root e com a senha -p alura:
Vamos criar (create) um banco de dados (database) para fazer o nosso teste, no meu caso, vou chamar esse banco de dados de loja:
Vamos sair do nosso container, para isso, podemos apertar as teclas CTRL + D até voltarmos ao nosso terminal, ou então, utilizar o atalho
Ctrl + P + Q. Falamos para o docker parar o nosso container (container stop) db e em seguida falar para ele removê-lo (container rm):
docker container stop db
docker container rm db
Mesmo tendo removido o container, as informações dele devem ter ficado salvas no volume. Vamos criar um novo container, dessa vez vou
nomeá-lo de banco e referenciar o mesmo volume dados-do-banco ao diretório /var/lib/mysql:
Vamos ver se nossas informações ficaram salvas, vamos acessar esse novo container com o comando docker container exec -it banco
/bin/bash e acessar o mysql
mysql -u root -p
Vamos falar para o banco de dados mostrar (show) as bases de dados existentes (databases):
show databases;
Veja que nossa base de dados loja está aparecendo normalmente, ou seja, conseguimos manter os dados mesmo após o container ter sido
excluído.
Para saber mais
Nós podemos referenciar mais de um container para o mesmo volume. Ou seja, nós podemos ter dois ou mais container referenciando para o
mesmo volume.
Esses nosso volumes ficam guardados no diretório /var/lib/docker/volumes/, porém, conseguimos também criar volumes em outros
diretórios, basta que na hora da criação do container, passar como parâmetro o caminho da pasta, ao invés do nome do volume:
Nós vimos como criar um volume, mas como podemos removê-lo? Nós podemos falar para o docker remover o volume (volume rm):
Lembrando que para remover um volume, nenhum container pode estar utilizando-o.
O Docker ganhou muito espaço tanto no cenário de desenvolvimento quanto no de infra, isso porque ele vem com o objetivo de facilitar o
desenvolvimento de aplicações.
Aqui na Alura, temos um curso Docker, nele você aprenderá tudo sobre o que é um container, como fazer eles se comunicarem, além de
aprender como criar suas próprias imagens para personalizar seus container.
Nossa equipe escreveu alguns testes para o programa que estamos desenvolvendo entrar em produção. Toda nova funcionalidade do sistema
deve antes passar por esses testes para depois entrar em produção.
Quando testei o código na minha máquina, funcionou. Porém, quando passei o código para outros desenvolvedores, ele não funcionou!
Investigando um pouco mais, percebi que existiam dependências e versões específicas de frameworks e bibliotecas que não eram resolvidas
nas máquinas dos outros desenvolvedores.
Nesse caso o problema ocorreu com os testes, mas e se fosse o código em produção?
Precisamos de ambientes iguais, tanto para desenvolvimento, testes e produção. Ou seja, em todos esses ambientes, a versão das bibliotecas,
frameworks e demais dependências devem ser iguais. Do contrário, podem causar erros.
Outra forma de fazer isso é criar apenas um ambiente e replicá-lo para todos do time. Ou seja, criamos apenas uma vez esse ambiente e ele é
repassado para todos da equipe. Para isso, podemos utilizar containers.
Num primeiro contato, definimos containers como uma “virtualização não convencional”. Isto é, em uma virtualização tradicional,
colocamos outro sistema operacional em cima do nosso.
Esse sistema virtualizado possuí o proprio kernel e hardwares virtual. Já quando criamos containers, estamos compartilhando o kernel e o
hardware da máquina com os containers.
Ou seja, nosso container possui apenas as bibliotecas e binários necessários para seu funcionamento. Por isso, são mais leves do que a
virtualização tradicional.
Um desses sistemas de criação de containers é o Docker. Com ele conseguimos criar nossos containers a partir de imagens, que nada mais
são do que especificações de containers.
Dessa forma, quando precisarmos testar nosso programa, basta criar um container (ou containers) baseado na nossa imagem. Portanto,
precisamos criar uma imagem.
Por exemplo, podemos criar uma imagem da nossa aplicação e rodá-la em um container. Para isso, vamos criar um arquivo chamado
aplicacao.dockerfile.
Nesse arquivo, temos que falar qual a imagem que estamos nos baseando para criar nossa imagem. Como minha aplicação é em Python, vou
dizer que ela se baseia (FROM) na imagem do python.
FROM python
Nossa aplicação utiliza um microframework Python para web chamado Flask. Ou seja, nossa imagem precisa ter esse framework para a
aplicação funcionar. Logo, dizer para o Dockerfile rodar (RUN) o comando para instalá-lo:
Queremos que o container rode nossa aplicação. Portanto precisamos copiar (COPY) o código da nossa aplicação para a nossa imagem. No
meu caso, o código está na pasta src, logo, vou copiar esse diretório para o diretório /src:
Temos que acessar nossa aplicação de alguma forma. Para isso, nós podemos expor (EXPOSE) uma porta do nosso container. Dessa forma,
sempre que quisermos acessar a aplicação podemos utilizar essa porta do container.
Já temos o interpretador do Python, o código da aplicação e uma porta para conseguir acessá-la. Falta alguma coisa?
Falta iniciarmos a aplicação! Para fazer isso, podemos dizer que quando o container for criado, isto é, no seu ponto de entrada do container
(ENTRYPOINT) vamos pedir para o "python”, executar nossa aplicação: ”/src/app.py”
EXPOSE 5000
Copy
Pronto! Temos um Dockerfile file especificando uma imagem. Contudo, perceba que não temos a imagem pronta. Para isso, precisamos falar
para o Docker construí-la.
Lá pedimos para o Docker construir (build), baseado no arquivo (-f) aplicacao.dockerfile, com o nome (-t) que, no meu caso, vou
chamar de yurimatheus/app (nome-do-usuário/nome-da-imagem) já que é um padrão no Docker.
Também precisamos dizer que todos os arquivos para construir a imagem estão neste diretório, para isso, utilizamos o ponto (.) no final do
comando:
Legal! Criamos nossa imagem! Vamos criar um container dessa imagem para testar se nossas configurações funcionaram.
Portanto, vamos falar para o docker rodar (run) um container baseado na imagem que acabamos de criar (yurimatheus/app):
Neste caso, vou falar que a porta (-p) 8080 da nossa máquina host vai ser mapeada para a porta 5000 do container, que foi a porta que
especificamos no Dockerfile:
Funcionou! Temos nossa aplicação rodando em um container com uma imagem que nós mesmos criamos.
Além de copiar arquivos para a imagem, podemos também criar volumes. Como o container é um processo isolado do sistema host, quando
salvamos algo no container e este é reiniciado, ou desativado, nós perdemos esses dados.
É aí que os volumes entram em cena. Com volumes fazemos uma cópia dos dados do container na nossa máquina local. Dessa forma, mesmo
se o container parar, ainda temos os dados disponíveis.
Podemos também utilizar o Docker para reduzir nossos gastos como, por exemplo, os gastos com servidores. Ao invés de ter um servidor
para cada aplicação, podemos ter containers.
Podemos tem um container para cada ambiente, testes, homologação, produção. Ou então, podemos ter diversos containers nesses ambientes.
Um para cada serviço, criando assim, uma arquitetura de microserviços.
Para gerenciar esses diversos containers, o Docker nos oferece uma ferramenta chamada de Docker Compose. Com ele, conseguimos compor
uma aplicação com diversos containers.
No curso de Docker da Alura, além de aprender sobre como o Docker funciona, como criar suas imagens, a como subir seus container na
nuvem, você também aprende a utilizar o Docker Compose.
Porém, quando o número de containers começa a crescer muito, mesmo com o Docker Compose é difícil de gerenciá-los. Por isso, foram
surgindo outras ferramentas, uma muito utilizada é o Kubernetes.
Com ele conseguimos orquestrar nossos containers com base em um único arquivo de configuração.
Aqui na Alura, temos um curso de Kubernetes, onde você aprenderá a realizar essa orquestração. A realizar a comunicação de containers da
aplicação com banco de dados, a escalar seus containers e realizar o balanceamento de carga, entre outras coisas.
Criando um repositório local de imagens Docker
7 de fevereiro de 2018
/
Infra
/
0 Comments
Criei algumas imagens no Docker e queria compartilhá-las com os outros desenvolvedores da empresa. Para isso, consigo usar os próprios
repositórios do Docker, como o Docker Hub, ou o Docker Store. Lá nós colocamos nossas imagens e elas ficam disponíveis para download.
Porém se eu colocar minha imagens nesses repositórios, só vou conseguir baixá-las se estiver com internet. Quero que essas imagens fiquem
sempre disponíveis na minha rede local. Dessa forma mesmo sem internet terei acesso a elas.
Criando o repositório
O Docker trabalha com containers. Então, nada mais justo, que seu repositório de imagens também seja um container. Então para criarmos
nosso repositório local basta iniciarmos um container.
No Docker, esse repositório local se chama Registry. Então para criarmos nosso repositório local, basta ir até o servidor e digitar:
Mas dessa maneira travamos o terminal com a execução desse container, ou seja, não podemos utilizar esse terminal enquanto nosso
container estiver rodando. Para que isso não ocorra, basta falar para o Docker rodar nosso container no background (-d).
Nosso Registry está rodando, mas como vamos acessá-lo? Quando nós acessamos um serviço na rede, por exemplo o site da Alura,
precisamos ter acesso a esse serviço. Ou seja, precisamos de uma porta de acesso.
No caso de sites, a porta padrão é a porta 80. Já o nosso registry utiliza por padrão a porta 5000.
Então vamos dizer ao Docker para ele iniciar nosso repositório mapeando a porta (-p) 5000 do nosso host para a porta **5000 **do nosso
container.
Uma boa prática quando criamos containers é dar nomes para eles. Isso facilita sua administração. Como estamos criando um repositório de
imagens, podemos dar o nome (--name) repositorio.
Se nosso container do Registry cair, será um problema? Precisamos garantir que mesmo se o container caia, outro suba em seu lugar. Ou
seja, queremos reiniciar (--restart) nosso container sempre que ele cair:
Para liberar essa porta, basta dizer para o firewall (firewall-cmd) adicionar uma regra, que no nosso caso pode ser permanente (--
permanent), e adicionar a porta (--add-port) que queremos liberar. Também precisamos dizer qual o protocolo de comunicação que, neste
caso, é o protocolo tcp
Agora temos que reiniciar o firewall para que nossa alteração fique válida:
firewall-cmd --reload
Pronto nosso repositório foi criado. Agora os computadores da nossa rede podem enviar imagens para ele. Mas como enviamos uma imagem
para o registry?
Logo, queremos dizer para o docker criar uma referência (tag) da imagem do wordpress com o nosso repositório. Neste caso, vou utilizar o
endereço IP do nosso registry, que no meu caso é o 192.168.0.10, na porta 5000. E o nome dessa imagem no repositório também será
wordpress.
Agora tudo que precisamos fazer é enviar, de fato, a imagem para o repositório. Para isso, utilizamos o comando docker push passando a
imagem que queremos colocar no servidor que no nosso é 192.168.0.10:5000/wordpress
Hum… por que não funcionou? No nosso servidor criamos o nosso registry, liberamos a porta no firewall e mesmo assim não conseguimos
enviar a imagem para ele.
Como nós não utilizamos nenhum método de autenticação, nem certificados de segurança, o Docker considera esse nosso repositório
inseguro.
Para conseguir enviar imagens para o nosso repositório, precisamos dizer para o controlador do Docker que confiamos nesse registry. Ou
seja, precisamos dizer isso para o Docker Daemon.
Para dizer para o Docker Daemon que confiamos no nosso repositório, precisamos editar o seu arquivo de configuração. No Ubuntu 16.04,
esse arquivo fica em /lib/systemd/system/docker.service.
Neste arquivo existe uma linha escrita ExecStart, vamos comentar essa linha (#) e em baixo vamos realizar nossa configuração.
Vamos dizer que quando o Docker iniciar (ExecStart) o daemon do Docker (/usr/bin/dockerd) vai adicionar um repositório considerado
inseguro (--insecure-registry):
Agora vamos pedir para o sistema (systemctl) reiniciar o daemon (daemon-reload) para que nossas configurações passem a valer. Como
essas são as configurações do Docker, vamos reiniciar (restart) esse serviço também:
systemctl daemon-reload
Para aumentar a segurança do nosso repositório, podemos criar sistemas de autenticação e utilizar certificados de segurança. Um exemplo de
como faz essas configurações, está na documentação do Docker.
Perceba que as imagens ficam no container repositorio que está no servidor. Ou seja, se esse container for excluído as imagens se
perderão.
Por isso, uma boa prática é criar volumes entre o container e a máquina host. Pois, mesmo se o container for excluído, temos uma cópia das
imagens na máquina.
Neste caso utilizamos o endereço IP para se comunicar com o repositório. Porém, podemos utilizar um nome como uma URI. Para isso,
temos que configurar um serviço de DNS.
Docker e containers são um dos assuntos mais comentados nos dias de hoje. Muitas coisas foram facilitadas pelos containers, tanto na parte
de infraestrutura, quanto na parte do desenvolvimento.
Por isso aqui na Alura temos um curso de Docker. Nele você aprenderá sobre como o Docker funciona, como utilizar e criar containers,
como criar suas próprias imagens e muito mais.
Como os containers estão sendo muito utilizados, algumas ferramentas foram criadas para facilitar sua administração. Uma ferramenta muito
utilizada é o Kubernetes.
Com ele conseguimos gerenciar nossos containers, criar balanceamento de cargas entre nossos container e realizar sua comunicação de uma
forma mais simples.
No curso de Kubernetes você vê algumas dessas técnicas e, no final, consegue realizar o deploy da aplicação na nuvem.
Estou com um container com uma aplicação PHP que se comunica com um banco de dados para efetuar alguns testes antes de ir para
produção. Então, fui rodar o container, porém quando realizei o login me deparei com os seguintes erros:
A aplicação precisa de um banco de dados para rodar, como estamos utilizando o Docker, o jeito mais simples é subir outro container para
representar o banco de dados. Mas por que não consigo fazer esses dois containers se comunicarem?
Com o docker composer instalado, podemos dizer como queremos subir esses dois containers.
O arquivo YAML
Queremos falar para o Docker Compose como ele deve subir nosso containers, para isso, temos que criar um arquivo com a extensão YAML,
neste caso, vou chamar de aplicacao.yaml.
A primeira coisa que devemos informar no arquivo é a versão do Docker Compose que estamos utilizando. Nesse caso, vou utilizar a versão
3.4 que é a mais recente.
version: '3.4'
Copy
Já dissemos qual versão estamos utilizando, agora precisamos indicar quais containers vamos criar, ou seja, quais serão os serviços
(services) que o Compose vai subir.
Temos dois serviços que queremos subir, o banco de dados e a aplicação web. Então vamos começar especificando o serviço da nossa
aplicação.
version: '3.4'
services:
app:
Copy
Nossa aplicação está baseada na imagem (image) yuri/web, e podemos dar o nome (container_name) de app por exemplo:
version: '3.4'
services:
app:
image: yuri/web
container_name: app
Copy
Nós precisamos também mapear as portas (ports) que nosso container vai usar. Neste caso, vou mapear a porta 8080 do nosso host, para a
porta 80 do nosso container:
version: '3.4'
services:
app:
image: yuri/web
container_name: app
ports:
- 8080:80
Copy
Bom, nosso container depende (depends_on) de um banco de dados, então vamos falar isso em nosso arquivo do Compose. Neste caso, vou
falar que ele depende do serviço db:
version: '3.4'
services:
app:
image: yuri/web
container_name: app
ports:
- 8080:80
depends_on:
- db
Copy
db é o nome do nosso serviço de banco de dados. Ele nada mais é do que outro container, logo, podemos especificar no mesmo arquivo
.yaml do serviço de aplicação.
version: '3.4'
services:
app:
image: yuri/web
container_name: app
ports:
- 8080:80
depends_on:
- db
db:
Copy
Se ele também é um container, então é igualmente baseado em uma imagem. Neste caso, nosso banco de dados será baseado na imagem do
MySQL. E vou nomeá-lo de db
#Restante da configuração
db:
image: mysql
container_name: db
Copy
Mas como conseguiremos acessar nosso banco de dados? Ele precisa de um usuário, correto?
Quando a imagem do MySQL está subindo como um container, ela lê algumas variáveis de ambiente (environment). Essas variáveis
definem algumas informações como usuário, senha, entre outras. Podemos especificar essas variáveis no próprio arquivo do Compose.
Neste caso, por se tratar de um teste, vou utilizar o usuário **root **(MYSQL_USER=root) e não vou alocar nenhuma senha
(MYSQL_ALLOW_EMPTY_PASSWORD=yes). Mas lembrando, nunca devemos usar isso em produção por motivos de segurança:
#Restante da configuração
db:
image: mysql
container_name: db
environment:
- MYSQL_USER=root
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
Copy
Também podemos falar para o Compose criar o banco de dados automaticamente quando ele subir o container. Neste caso, vou criar o banco
de dados loja:
#Restante da configuração
db:
image: mysql
container_name: db
environment:
- MYSQL_USER=root
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=loja
Copy
Pronto! Configurações terminadas. E agora como conseguimos fazer o Docker subir esses dois containers?
No terminal conseguimos falar para o docker-compose baseado no arquivo (-f, file) aplicacao.yaml, subir (up) os containers
especificados:
Hum… não obtemos sucesso. Será que o Docker Compose não criou nosso banco de dados?
Na verdade ele criou! Porém, como não existem tabelas, a aplicação não funcionou.
Para resolver esse problema basta falar para o docker executar (exec) um terminal (-t) interativo (-i) com o nosso container, db no caso.
Mas qual terminal vamos executar?
Agora, basta executar o mysql com o usuário (-u) root que teremos acesso ao banco de dados.
Caso for necessário persistir essas informações, podemos criar um volume entre nossa máquina local e o container. Dessa forma, todas as
informações salvas no container serão salvas na nossa máquina local.
Neste caso utilizamos o Docker Compose para subir nossos dois containers e realizar a comunicação entre eles.
Porém nós podíamos utilizar o próprio Docker para isso. Basta criar uma rede (network) e atribuir nossos container a ela. Contudo, com o
Docker Compose, temos mais facilidade para a orquestração desses containers.
Aqui na Alura temos um curso sobre Docker que nos mostra como utilizar o Docker Compose, como criar nossas imagens, entre muitas
outras coisas.
Ah, é! Não deixe de compartilhar conosco o que achou do Docker Compose nos comentários.
http://blog.alura.com.br/category/infra/page/4/
Quando falamos em desenvolvimento de softwre é comum ter diversos ambientes, por exemplo:
Desenvolvimento
Teste
Homologação
Produção
E outra coisa comum no mundo de desenvolvimento é ter divergências entre estes ambientes.
Para cada máquina virtual temos uma instalação completa do S.O. que queremos virtualizar, além de ter o próprio hardware virtualizado.
Se por exemplo eu precisar de uma biblioteca comum para todas as máquinas virtuais, preciso instalar em cada uma delas.
O Docker usa uma abordagem diferente, ele utiliza o conceito de container. Como assim container?
Com a chegada dos containers foi possível transportar mercadorias de uma forma segura, de fácil manipulação e com pouco, ou nenhum,
trabalho braçal no carregamento ou descarregamento. E é justamente isso que o Docker tenta fazer com nossos softwares.
Para fazer isso precisamos garantir que nosso ambiente de Produção tenha todos os pré-requisitos instalados, de preferência uma versão do
S.O. parecida com a do ambiente de Desenvolvimento entre outros cuidados que devem ser tomados (relacionados a permissionamento,
serviços dependentes e etc…).
Com o Docker temos um container com nosso software. Esse container é levado inteiro para o outro ambiente.
Com isso não precisamos nos preocupar com pré-requisitos instalados no outro ambiente, versão do S.O., permissionamento e se quisermos
podemos ter containers para os serviços dependentes também. Dessa forma minimizamos muito a divergência entre os ambientes.
O projeto LXC usa por baixo dos panos diversas funcionalidades presentes no Kernel do Linux. Abaixo vou listar algumas dessas
funcionalidades:
chroot – Reponsavel por mapear os diretórios do S.O. e criar o ponto de montagem (/, /etc, /dev, /proc entre outros).
cgroup – Reponsável por controlar os recursos por processo. Com ele podemos por exemplo limitar o uso de memória e/ou processador para
um processo específico.
kernel namespace – Com ele podemos isolar processos, ponto de montagem entre outras coisas. Com esse isolamento, conseguimos a
sensação de estar usando uma máquina diferente da máquina host. Pois enxergamos somente o ponto de montagem especifico e processos
especificos, inclusive nossos processos começam com PID baixo.
kernel capabilities – Entre outras coisas, conseguimos rodar alguns comandos de forma privilegiada.
Mão na massa
Agora que temos uma noção do que é e para que serve o Docker, vamos fazer o download da ferramenta e começar nesse mundo de
containers.
Instalando o Docker
Atualmente Docker está disponível em duas versões Docker Community Edition(CE) e Docker Enterprise Edition(EE).
Em ambas as versões temos acesso a toda a API, basicamente a diferença entre as duas versões é o perfil desejado de aplicações. No EE
temos um ambiente homologado pela Docker com toda infraestrutura certificada, segura pensada para o mundo enterprise. Já na versão CE
podemos chegar ao mesmo nível que EE porém de uma forma manual.
Nesse link você pode encontrar as distribuições para downloads em cada sistema operacional disponível e os passos para instalação.
Feito a instalação, execute esse comando no terminal docker --version. Se a instalação ocorreu com sucesso deve ser impresso algo
semelhante a isso Docker version 17.03.1-ce, build c6d412e.
Imagens
O Docker trabalha com o conceito de images, ou seja, para colocar um container em funcionamento o Docker precisa ter a imagem no host.
Essas imagens podem ser baixadas de um repositório (a nomenclatura para esse repositório é registry) ou criadas localmentes e compiladas.
Esse é o link para o registry do Docker.
Nesse registry podemos ter imagens oficiais e não oficiais. Além de podermos criar nossas próprias imagens, também é possível fazer upload
dela em um registry.
Baixando Imagens
Para baixar uma imagem podemos usar o comando docker pull e o nome da imagem que queremos baixar. Vamos baixar a imagem do
Ubuntu, para isso execute o seguinte comando no terminal: docker pull ubuntu.
Aqui o Docker baixou nossa imagem. Percebam que uma imagem é composta de várias camadas, por esse motivo teve que fazer vários
Downloads/Pulls.
Para listar todas as imagens podemos usar o comando docker images. O retorno desse comando é algo semelhante a isso:
O nome da imagem é exibido na coluna REPOSITORY, cada imagem tem um identificador único que é exibido na coluna IMAGE ID. A coluna
TAG indica a “versão” da imagem do ubuntu. O latest quer dizer que é a última “versão” da imagem (a mais recente).
Executando Containers
A partir da imagem podemos iniciar quantos containers quisermos através do comando docker run.
Para acessarmos um terminal do Ubuntu podemos usar o comando docker run -i -t ubuntu ou docker run -it ubuntu. O parâmetro -
i indica que queremos um container interativo, o -t indica que queremos anexar o terminal virtual tty do container ao nosso host.
Para ver os containers em execução podemos usar o comando docker ps (em outro terminal ou aba), e ele exibirá um retorno parecido com
esse:
Aqui temos informações sobre os containers em execução, como id, imagem base, comando inicial, há quanto tempo foi criado, status, quais
portas estão disponíveis e/ou mapeadas para acesso e o nome do mesmo. Quando não especificamos um nome ao iniciá-lo, será gerado um
nome aleatóriamente.
Quando encerramos um container ele não será mais exibido na saida do comando docker ps, porém isso não significa que o container não
existe mais. Para verificar os containers existentes que foram encerrados podemos usar o comando docker ps -a e teremos uma saída
parecida com essa:
Como o próprio status do container informa, o mesmo já saiu de execução e no nosso caso saiu com status 0 (ou seja saiu normalmente).
Removendo containers
Para remover o container podemos usar o comando docker rm e informar o id do container ou o nome dele. Para nosso caso poderíamos
executar o comando docker rm 43aac92b4c99 ou docker rm dreamy_bassi para remover o container por completo.
Caso tenhamos a necessidade de remover todos os container (em execução ou encerrados) podemos usar o comando docker rm $(docker
ps -qa). A opção -q do comando docker ps tem como saída somente os ids dos containers, essa lista de ids é passado para o docker rm e
com isso será removido todos os containers.
Só será possível remover um container caso o mesmo não esteja em execução, do contrário temos que encerrar o container para removê-lo.
Nesse momento podemos pensar que o Docker é meio mágico (e é…kkk). Dado uma imagem ele pode rodar um ou mais containers com
pouco esforço, mas como são feitas as images?
Uma imagem pode ser criada a partir de um arquivo de definição chamado de Dockerfile, nesse arquivo usamos algumas diretivas para
declarar o que teremos na nossa imagem. Por exemplo se olharmos a definição da imagem do Ubuntu podemos ver algo semelhante a isso:
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
.
RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container
CMD ["/bin/bash"]
Com um arquivo Dockerfile podemos compilá-lo com o comando docker build. Ao compilar um arquivo Dockerfile temos uma
imagem. Mas isso é um assunto para um próximo post.
E você já usa o Docker? Conte-nos sobre suas aventuras com essa técnologia. Se não conhece não deixe de conferir nosso curso de docker na
Alura.