Docker para Iniciantes

Prof. Me. Samuel Rodrigues

No curso você irá

  • compreender os conceitos fundamentais do Docker
  • entender imagens e containers
  • gerenciar containers com Docker
  • criar e publicar suas próprias imagens Docker
  • entender networks e volumes
  • compor, configuar e executar serviços com Docker Compose

Sobre o Prof.

  • Cícero Samuel Clemente Rodrigues
  • Me. em Engenharia de Software pelo CESAR School
  • Prof. Sistema de Informação há 12 anos na Unijuazeiro
  • Servidor Federal de TI na UFCA há 7 anos

 

contato: samuelclerod@gmail.com

O que é o docker?

Docker remete a:

um projeto da comunidade open source; as ferramentas resultantes desse projeto; e a empresa Docker Inc, apoiadora do projeto

Docker é uma plataforma para desenvolvedores e sysdamins para desenvolver, implantar e executar aplicações com containers [linux]

Desenvolver

Implantar

Executar

O que é um Container?

São ambientes completamente isolados, com seus próprios processos, serviços e interfaces de rede, entretanto compartilhando o mesmo kernel do sistema operacional.

Antes, sobre imagens...

  • Uma imagem é um template com instruções para criar o ambiente desejado
  • Ela é imutável
  • Pode ser salva (pushed) em um registro (docker hub)
  • Para construir sua própria imagem, é necessário criar os passos necessários para cria-la e executa-la em um Dockerfile

sobre containers...

  • É uma instância da imagem em execução
  • Imagem só podem ser executadas em um docker daemon  como um container
  • Múltiplos containers podem se criados a partir de uma mesma imagem
  • Containers permitem executar aplicações em ambientes isolados
  • Muitos containers podem executar simultaneamente em um mesmo host
  • Containers executam diretamente no kernel da maquina host

ambiente de execução que provê portabilidade

A plataforma Docker

ainda sobre containers...

  • Construido a partir não de uma imagem, mas uma camada de imagens
  • Normalmente, na base temos um imagem linux de pequeno tamanho
  • A imagem da aplicação geralmente fica no topo

Máquina Virtual

Container

Sistemas Isolados

Aplicações Isolados

X

Máquina Virtual

Container

X

  • Cada maquina virtual tem seu próprio Sistema Operacional (Guest OS);

  • Isso exige muitos recursos da máquina host;

  • Como resultado disso:

    • É necessário “boot” do guest OS

    • Consome muitos recursos

  • Todos usam o kernel das máquinas host, e acima disso tudo está isolado (distribuição única);

  • o docker usa recursos do sistema de arquivos unix para criar ambientes isolados;

  • Como resultado disso:

    • Usa menos recursos

    • Pode iniciar em milisegundos

    • Ocupa menos espaço em disco

    • Usa menos memória

Podemos usar uma abordagem mista!

  • Utilizar máquinas virtuais para provisionar de forma rápida hosts docker com kernel isolado
  • Facilidade do docker de provisionar e escalar aplicações
  • Possível o uso de docker em kernel não-linux

Por que devo aprender docker?

Percentual de aplicações containerizadas...

Percentual de aplicações containerizadas em produção

Vocabulário comum para DevOps

Profissionais de

Desenvolvimento

Profissionais de

Operações

Dev sem docker [containers]

  • Necessário instalar aplicações específicas para cada tipo de sistema operacional
  • Cada ambiente tem seu próprio processo e problemas(issues) a serem resolvidas
  • Normalmente, é difícil gerir ou instalar 2 versões diferentes
  • Se tenho 10 ambientes, preciso refazer o processo nos 10 ambientes

Dev com  docker [containers]

  • um container pode ser distribuído
  • O ambiente é isolado da máquina hospedeira (host)
  • Todas configuração necessária está em um único ambiente
  • Um único comando instala toda a aplicação/ambiente
  • É possível rodar duas versões na mesmo tempo
  • Ambiente reciclável

Ops sem  docker [containers]

  • Necessário configurar o servidor
  • as dependecias podem gerar conflitos de versão
  • Inconsistências entre ambientes
  • O guia de implantação é textual
  • comum desentendimentos entre Devs e Ops

Ops com  docker [containers]

  • Devs e Ops trabalham juntos para empacotar a aplicação em containers
  • Nenhuma configuração é necessária no servidor, a não ser o Docker Runtime
  • Maior velocidade de distribuição e confiabilidade
  • Retorno fácil para versões funcionais (fallback)

Por que Devs adotam docker?

  • Ambiente seguro, limpo e portável

  • Não tem que se procupar com dependecias perdidas, pacotes e outras dores

  • Um comando para instalar o app

  • Execução de cada App em seu próprio ambiente isolado com suas próprias libs.

  • Pode-se reverter versões antigas dos ambientes

  • Automatizar teste, integração e empacotamento

  • Ambiente reciclável

  • Reduzir/eliminar preocupações sobre compatibilidade em outras plataformas

Por que Ops adotam docker?

  • Torna o ciclo de vida inteiro mais eficiente, consistente e repetitível

  • Aumenta a qualidade do código produzido por desenvolvedores

  • Elimina inconsistências entre ambientes de teste, desenvolvimento e produção

  • Promove a separação de preocupações

  • Retorno fácil para versões funcionais (Fallback to Working)

  • Aumento significante da velocidade e conficabilidade para implantação e integração contínuas

Por que não usar VM?

  • Velocidade de implantação

  • Portabilidade

  • Performance

  • Custo

  • Tamanho

  • Menos recursos de hosts

Instale o docker!

Temos duas versões do docker

Vamos usar essa aqui 👇

Como instalar o Docker Comunity Edition (CE)?

  • Docker Engine
  • Docker Desktop
  • Máquina Virtual
  • Docker Desktop
  • Máquina Virtual
  • Provido pelo Serviço

☝Vamos demonstrar essas opções

Docker Toolbox???

DEPRECATED

Vamos colocar a mão na massa!

Para verificar a versão:

docker --version

Para ver mais informações:

docker info

Verificando a versão do docker

Utilizando a imagem de teste do hello-world

docker run hello-world

Lista a imagem do hello-world

docker image ls

Testando o docker

Lista o hello-world container

docker container ls --all

Se ainda estivesse executando, não seria necessário o opção --all

Construindo um app da maneira docker

Seu novo ambiente de Dev

Problema

  • Para iniciar a construção de um app python, você precisa instalar e configurar o ambiente na sua máquina.
  • Esse ambiente tem que estar perfeito para que seu app rode como o esperado, e precisa combinar o ambiente de produção

Seu novo ambiente de Dev

Solução

  • Com docker você simplesmente usa um ambiente python em uma imagem, sem instalar nada.
  • Seu build pode incluir na imagem tudo que seu app precisa (ambiente, código e dependências viajam juntos)
  • Essas imagens são definidas no Dockerfile.

Definindo um container

  1. Crie um diretório vazio com o arquivo Dockerfile dentro e o acesse em um terminal.
  2. No Dockerfile , copie e cole o conteúdo abaixo e salve-o.
# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Definindo um container

Crie mais dois arquivos na pasta (são usados no Dockerfile):

Flask
Redis
from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

requirements.txt

app.py

Na pasta do projeto, no mesmo nível do Dockerfile digite:

docker build --tag=friendlyhello .

Build do app

Para verificar se a imagem foi criada digite

docker image ls

Execute o app, mapeando a porta 4000 da sua máquina para a porta 80 publicada usando -p:

docker run -p 4000:80 friendlyhello

Executando o app

  • No linux/bash, basta pressionar CTRL+C
  • no windows é necessário parar explicitamente o container, digitando
docker container ls

Parando o container

  • para verificar o container name ou id, digite
docker container stop <Container NAME or ID>
  • para deixar o app rodando em background (detached mode) executamos:
docker container ls

Rodando em background

  • para verificar o estado do container 
docker run -d -p 4000:80 friendlyhello

Compartilhando sua imagem

Registro

  • para implantar ou compartilhar a sua imagem, é necessário enviar para um registro.
  • um registro é uma coleção e reposititórios.
  • um repositório é uma coleção de imagens (como no git)
  • uma conta de registro pode criar muitos repositórios
  • O docker CLI usa o registro público do Docker por padrão, o dockerhub.

Login com Docker ID

  • Se você não tem uma conta Docker, se registre em  hub.docker.com.

     

  • Faça login com o comando

     

docker login

Tag de uma imagem

  • A notação para associar uma imagem logal com um repositório é username/repository:tag.

  • A tag é opcional, mas recomendada pois é o mecanismo o qual o registro versiona as imagens no docker.

  • para realizarmos o registro da nossa imagens digitamos algo como :

docker tag image username/repository:tag

No meu caso:

docker tag friendlyhello samuelclerod/get-started:v1

Para listar e visualizar as tags use:

docker image ls

Publicando uma imagem

Para publicar uma imagem tageada usamos:

docker push username/repository:tag

No meu caso:

docker push samuelclerod/get-started:v1

E para recuperar a imagem e executar:

docker run -p 4000:80 samuelclerod/get-started:v1

Orquestrando com docker-compose

O que é docker-compose?

  • Compose é uma ferramenta para definir e executar aplicações docker multi-container 
  • Com o Compose, utilizamos um arquivo para configurar nossos serviços da aplicação
  • Com um unico comando, é possível criar e iniciar todos os serviços a partir de uma configuração
  • Para aprender um pouco mais veja a lista de features.

Utilizando Compose, vamos configurar e executar uma aplicação Rails/PostgreSQL..

 

Mas antes de tudo, instale o Compose !

Defina o Dockerfile

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y \
	build-essential libpq-dev nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp

Crie uma pasta e nela insira do Dockerfile descrito abaixo:

source 'https://rubygems.org'
gem 'rails', '~>5'

O Gemfile

O Gemfile.lock VAZIO

Crie o docker-compose.yml

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - 3000:3000
    depends_on:
      - db

Construa o projeto

docker-compose run web rails new . --force --database=postgresql

O esqueleto abaixo irá gerar toda a estrutura da aplicação rails utilizando banco postgresql

Para usuários linux e mac é necessário repara os arquivos que foram gerados no container com root

sudo chown -R $USER:$USER .
docker-compose build

Com o Gemfile modificado, precisamos construir novamente

Conecte a aplicação ao banco

Por default, Rails espera um banco de dados no rodando no localhost

É necessário apontar para o container db e mudar o banco e o username com o padrão da imagem do postgresql.

Modifique o arquivo config/database.yml com codigo ao lado:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

Conecte a aplicação ao banco

Agora podemos iniciar os containers com:

docker-compose up

Crie o banco em outro terminal com:

Acesse a página inicial da aplicação em http://localhost:3000.

docker-compose run web rake db:create

Outros comandos

Parar a aplicação

docker-compose restart

Reiniciar a aplicação

docker-compose down

Reconstruindo a aplicação

Se modificar o Gemfile ou o docker-compose.yml para tentar outras configurações, é necessário reconstruir. 

Nesses caso execute:

docker-compose run web bundle install
docker-compose up --build

Para mais informações, visite o documentação do docker-compose

O que vimos nesse curso?

  • compreender os conceitos fundamentais do Docker
  • entender imagens e containers
  • gerenciar containers com Docker
  • criar e publicar suas próprias imagens Docker
  • entender networks e volumes
  • compor, configuar e executar serviços com Docker Compose

Próximos passos

  • Implantação com Docker
  • Docker Swarm
  • CI e CD com docker
  • kubernetes

Muito Obrigado!

Referências

Muito Obrigado!

Samuel Rodrigues

Made with Slides.com