uma breve introdução

Docker

  1. Introdução
  2. Fundamentos
    • Arquitetura
    • Componentes
    • Comandos
  3. Em prática (Linux)
    • Instalação
  4. Ferramentas
    • Packer (Imagem)
    • Compose (ambiente)

felipe f. rocha

Introdução

virtualização e containers

História

  1. Virtualização
    • Necessidade
      • Isolamento (sistema)
    • Tipos
      • Tipo 1
      • Tipo 2
  2. Container
  3. Docker (containerd)

Terminologia

  1. Container
  2. Image
  3. Container Image
  4. Image Layer (Camada)
  5. Registry (Banco de Imagem)
  6. Repository (repositório)
  7. Tag
  8. Base Image
  9. Platform Image
  10. Layer
  11. Container Runtime (High|Low)
  12. Container Engine

Container

  1. Isolamento (Aplicação)
    • namespace: user ns, network, mount, IPC,UTS, cgroups
    • cgroups: CPU, memory, I/O, etc
  2. Imagens
    • código
    • runtime
    • dependências
  3. Runtime
    • Multiplos containers
    • Único | Multi host
  4. Exemplo de Runtime
    • runC
    • Containerd
    • rkt

CNCF

  1. Projetos em avaliação:

OCI

  1. Open Container Initiative
  2. Normatização:
    • Runtime
      • filesystem bundle
    • Image
      • Manifest
      • filesystem serialization
      • Confiruações: OS
    • Distribution
      • Registry
      • client: push, pull
      • Manifest, config, tag
      • artifact, digest
  1. Projetos:
    • image-spec
    • distribution-spec
    • runtime-spec
    • artifacts, go-digest, runC

Fundamentos

docker ~= Paas - virtualização da camada de os

Arquitetura

  1. Client
    • CLI
    • Remote api
  2. Host (server)
    • Daemom (service) Rest API
    • Imagens
    • Containers
    • Redes (VN e Routes)
    • Volumes
  3. Registro
    • Catálogo de imagens

Cliente-Servidor

Versoes

Community & EE (engine)

  1. CE
    • Free
    • Open source
    • developers
    • Produção
    • Do it Yourself
  2. EE
    • Aplicações críticas
    • Imagens certificadas
    • Datacenter
    • Vulnerabilidades

Componentes

Image vs container

  1. Imagem
    • runtime
    • userspace OS
    • layers ("files")
  2. Container
    • runnable
    • não ocupa espaço
    • imutável
  3. Comparação

Image => classe

Container => intância

$ docker run helllo-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Componentes

Network & Volumes

  1. Network
    • Drivers:
      • Overlay
      • Bridge
      • host
      • macvlan
    • namespace
  2. Volumes
    • Nomeado
    • ~= mount

vol_name:path:access

$ docker run -itd --rm --name teste1 ubuntu
$ docker run -itd --rm --name teste2 ubuntu
$ docekr exec  teste1 ifconfig
$ docker exec  teste2 ifconfig
# Visualiza todos os dados de uma rede (containers 
# devem estar nessa rede)
$ docker network inspect bridge
$ docker exec teste1 ping <ip teste2>
$ docker exec teste2 ping <ip teste1>
$ docker cotainer stop $(docker container ls -a -q)
# Cria uma rede com um DNS junto, não é mais necessário 
# saber o ip
$ docker create network --driver bridge myNetwork
$ docker run -itd --rm --name teste1 --net myNetwork ubuntu
$ docker run -itd --rm --name teste2 --net myNetwork ubuntu
$ docker exec teste1 ping teste2
$ docker exec teste2 ping teste1
$ docker network connect|disconnect <net> <container>
$ docker cotainer stop $(docker container ls -a -q)
$ docker network rm myNetwork
$ sysctl net.ipv4.conf.all.forwarding=1
$ sudo iptables -P FORWARD ACCEPT
$ docker volume create myVolume
$ docker run -itd --rm --name -v myVolume:/tmp:ro teste1 ubuntu
$ docker run -itd --rm --name -v myVolume:/tmp teste2 ubuntu

comandos

$ docker run \
	# Os dois comandos abaixo são vistos na fora -it 
    # Permite interação com a aplicação no shell
	--interactive \ 
    # Abre uma nova sessão tty para comandos via shell ou aplicação
    --tty \
    # Roda em segundo plano (conflita com o comando atual)
    # -d \
	# Setar variaveis de ambiente
    -e MYVAR=variavelAmbiente1 \
    # Volume inicial vai conectar a pasta atual a pasta do container 
    # apresentada
    -v $PWD:/app  \
    # Pasta inicial onde o container inicializará
    -w /app \
    # Expoe a porta do container na porta do host
    -p 8080:80 \
    # Nomeia o container
    --name containerName \
    # Comando inicial ao rodar o container (Desabilita)
    --entrypoint "" \
    # Remove contaier assim que for finalizado
    --rm \
    # Limites de memória \
    # reserva mínima \
    --memory-reservation="256m" \
    # Limite máximo
    --memory="512m" \
    # CPU percentual core => 0.5 = 0.5core / 2.0 = cores
    --cpus=0.5 \
    # Restart policy (conflita com --rm)
    --restart on-failure \
    # Descrição do nome da imagem e sua versão
    ubuntu:latest \
    # Executa esse programa
    bash

comandos

# Lista processos
$ docker ps -a
# lista todas as imagens
$ docker image ls -a
# Lista todos os container
$ docker container ls -a
# Roda uma imagem
$ docker run <image_name or id>
# Para o container 
$ docker container stop <container_name or id>
# Remove o container
$ docker container rm  <container_name or id>
# Remove imagens não utilizadas
$ docker image prune -a
# Remove todos(as) <imagens|containers> da máquina
$ docker <image|container> rm $(docker <image|container> ls -a -q)
# builda  uma imagem de um docker file local importando o contexto 
# da pasta onde o comando foi executado
docker build -t nome_da_imagem_desejada:versão .
# Sobe imagem construída para o registro
docker push nome_da_imagem_desejada:versão

## Gestão de containers
$ sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.3/ctop-0.7.3-linux-amd64 -O /usr/local/bin/ctop
$ sudo chmod +x /usr/local/bin/ctop
$ 

Configurações gerais

# Lista processos
$ cat ~/.docker/config.json
{
	"auths": {
		"cemedacr.azurecr.io": {
			"auth": "adfasdfasdfasd="
		},
		"myresgistry.azurecr.io": {
			"auth": "asdfasdfsa==",
			"identitytoken": "asdfasdf.sdfasdfasdf.asdfasd-asdfasd-UHkiIU-asdf-asdf"
		}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/19.03.11 (linux)"
	}
}

Push and pull

# Docker push
$ docker build -t web1 .
$ docker image ls
$ docker image tag web1 felipefrocha89/web1:latest
$ docker image ls
$ docker iamge push felipefrocha89/web1:latest
$ docker image rm $(docker image ls felipefrocha89/web1 -q)
$ docker image ls
$ docker pull felipefrocha89/web1
$ docker image ls

Em prática

Instalações e configuração de imagem

Toolbox

VM & machine

  • VirtualBox (HyperV2):
    • VM com docker                 deamon
  • Machine (remote):
    • Criar servidores
    • Instalar docker

Docker versões especiais:

  • Windows & MacOS
    • HyperKit (HyperV1)
    • Hyper-V (HyperV1)

ENGINE

Bare Metal CE (Linux)

  • Daemon
    • Serviço
    • sudo
  • CLI:
    • local
  • Machine:
    • Remoto

 

# Remoção de isntalações prévias
$ sudo apt-get remove docker docker-engine docker.io containerd runc

# Instalação Ubuntu x86_64
# Dependências
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
    
# Registro de repositório
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# Instalação
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

# Add do sudoers
$ sudo usermod -aG docker $USER
# Install using bash script 
$ curl -fsSL https://get.docker.com | bash -
# Add to sudoers
$ sudo usermod -aG docker ${USER}
# Apply
$ su - ${USER}
# Check
$ id -nG

DOCKERFILE

Descrição e layers

  • Imagem:
    • Descreve
    • Organiza layer
    • Compara
    • Otimiza
# Imagem base nome e tag
FROM python:2.7-alpine

# Criar uma pasta base para copiar o codigo da aplicação
RUN mkdir /app
WORKDIR /app

# Copiara o arquivo de dependências e realizar o dowload (layer de dependencias)
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copiar os demais arquivos do programa (layer de aplicação)
COPY . .

# Labels permitem filtros otimizados em produção
LABEL   maintainer="!!Felipe Rocha <felipe.rocha@dtidigital.com.br>" \
        version="1.0"

# Expoe um volume automaticamente
VOLUME ["/app/public"]

# Copia script 
COPY docker-entrypoint.sh /
# Executa
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]

# Command é executando durante o início da imagem 
# CMD é sempr argumento do entrypoint (/bin/bash -c)
CMD flask run --host=0.0.0.0 --port=5000

Containerização

Migrando apps para Docker

  • Importante:
    • Dockerfile
    • .dockerignore
    • docker-compose
    • .env
  • Logs:
    • /tmp > STDOUT
  • .env
    • Separete environment
  • Stateless
    • Não armazene nada
    • Redis

Ferramentas

automação de imagens

packer

Criando imagens

  1. Automatização
    • Customização
    • CLI
  2. Providers
    • Docker (Dockerfile)
    • AWS ECR (registro)
  3. Provisioners
    • Ansible (config)
    • Shell (script)
source "amazon-ebs" "k8s-images-ready" {
  region = var.aws_region
  profile = "educate"
  source_ami = var.ami_id
  instance_type = var.instance_type
  ssh_username = var.ssh_username
  ami_name = format("educate-ff-%s", formatdate("YYYYMMDDhhmmss",timestamp()))
  ssh_keypair_name = "aws_educate"
  ssh_private_key_file = "../aws_educate.pem"
  vpc_id = var.vpc_id
  subnet_id = var.subnet_id
}

build {
  sources = [
    "source.amazon-ebs.k8s-images-ready",
  ]

  provisioner "shell"  {
    scripts  = [
      "./provisioners/scripts/python.sh",
      ]
  }

  provisioner "ansible"  {
    playbook_file = "../ansible/main.yml"
    user = var.ssh_username
    ansible_env_vars = [
      "ANSIBLE_HOST_KEY_CHECKING=false"
    ]
  }
}

compose

Gerenciado Ecosistema

  1. Automação
    1. CLI
    2. Múltiplas imagens
  2. Configuração
    1. Redes
    2. Volumes
    3. Variávies de ambiente
  3. Gerenciamento
    1. Versionamento
    2. Descrição do ambiente
version: "3"

services:
  vote:
    build: ./vote
    command: python app.py
    volumes:
     - ./vote:/app
    ports:
      - "5000:80"
    networks:
      - front-tier
      - back-tier

  result:
    build: ./result
    command: nodemon --inspect server.js
    volumes:
      - ./result:/app
    ports:
      - "5001:80"
    networks:
      - front-tier
      - back-tier
    env_file:
      - '.env'

  worker:
    build: ./worker
    networks:
      - back-tier
    env_file:
      - '.env'

  redis:
    image: 'redis:5.0.7-alpine'
    ports: ["6379"]
    networks:
      - back-tier

  db:
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
    networks:
      - back-tier
    env_file:
      - '.env'

volumes:
  db-data:

networks:
  front-tier:
  back-tier:

Felipe F. Rocha

felipefonsecarocha@gmail.com

 

OBRIGADO!!!

Docker, uma breve introdução

By Felipe Fonseca Rocha

Docker, uma breve introdução

Este breve deck é sobre #Docker, passando apenas os conceitos básicos e ferramentas para seu laborátorio pessoal. O foco apenas habilitar os interessados a começarem seus estudos com alguma noção.

  • 345