Kubernete parte III

Olá pessoal,

 

Depois de algum tempo sem falar sobre Kubernetes hoje vamos mostrar como podemos criar um ambiente altamente disponível de servidores web.

Conforme comentado nos posts anteriores, podemos criar um service Web e dentro desse service eu posso ter milhões de containers, onde o Kubernetes fará toda a parte de Balanceamento de carga com o que chamamos de Replication Controller.

Vamos criar então o Replication Controller:

 

vim web-rc.yml

apiVersion: v1
kind: ReplicationController 
metadata:
 name: web-controller
spec:
 replicas: 2
 selector:
   name: nginx
 template:
   metadata:
     labels:
       name: nginx
   spec:
     containers:
       - name: nginx
         image: nginx
         ports:
           - containerPort: 80

kind: É o tipo de objeto que o Kubernetes ira criar, nesse caso ele vai criar

Replicas: Quantos pods dessa imagem sempre deve existir, caso exista um número menor que o indicado, o Kubernetes irá criar outros pods até chegar ao número determinado em replicas.

 

Para criar o Replication Controller execute:

kubectl create -f web-rc.yml

 

Você poderá ver RC criado com o comando:

kubectl get replicationcontrollers

 

Agora vamos criar o Service que é aquele que faz com que o usuário consiga criar a aplicação:

 

vim web-service.yml

kind: Service
apiVersion: v1
metadata:
  name: web-service
spec:
  selector:
    name: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
kubectl create -f web-service.yml

Feito isso você pode executar o comando abaixo e verá que existe 2 pods de Nginx rodand:

kubectl get pods

Com tudo isso pronto você pode pegar e testar executando um curl no ip do seu servidor, no meu caso estou executando a partir do minion1, então vou acessar o minion2 e executar:

curl -qa http://seuip

E a página inicial do nginx será mostrada, você pode pegar e parar um pod e notará que o Kubernetes irá criar outro, pois no Replication Controller colocamos como 2 replicas.

Então tá pessoal por hoje era só, continue ligado em nosso canal e em breve estaremos fazendo um vídeo mostrando mais sobre o Kubernetes.

Montando Volumes no Docker

Olá!

Hoje, nós do mundodocker.com.br, vamos ver como podemos utilizar a funcionalidade de volumes no Docker. Um volume pode ser apenas o mapeamento de pasta entre o host e container, bem como o mapeamento de uma pasta entre containers.

Gerenciando volumes

Host – Container

Na imagem abaixo podemos visualizar como fica o mapeamento entre host e container:

host_containerPodemos analisar os pontos positivos e negativos dessa abordagem em:

Prós:

– Menor overhead para acesso disco, pois não há analise pela libcontainer das chamadas para esse volume mapeado;

– É possível mapear o mesmo volume para múltiplos containers, forma primitiva de replicação de dados entre containers (lembrando que neste caso não há controle de arquivos lidos e escritos ao mesmo tempo, quem deve ser responsável por isso é o filesystem do volume, não o volume em si);

– Persistência de dados, não há risco do container cair ou ser removido e os dados desaparecerem;

Contras:

– Sucessível possíveis brechas de segurança a nível de filesystem, escalonamento de privilégios, pois neste ambiente não há controle pela libcontainer.

– Não escalável, pois  atrela-se o container ao host ou pelo menos ao mapeamento.

– Dificulta administração, pois há mais uma camada de gerenciamento que deve ser muito bem estruturada.

Container – Container

Na imagem abaixo podemos visualizar como fica o mapeamento entre containers:

container_containerPodemos analisar os pontos positivos e negativos dessa abordagem em:

Prós:

– Portável, pois o volume não está mais atrelado ao host;

– É possível mapear o mesmo volume para múltiplos containers, forma primitiva de replicação de dados entre containers (lembrando que neste caso não há controle de arquivos lidos e escritos ao mesmo tempo, quem deve ser responsável por isso é o filesystem do volume, não o volume em si);

– Persistência de dados, não há risco do container cair ou ser removido e os dados desaparecerem;

Contras:

– Maior overhead para acesso disco, pois há analise pela libcontainer das chamadas para esse volume mapeado;

– Maior complexidade, pois há mais passos a serem seguidos para criação e remoção de containers;

Criando e montando volumes

Adicionando um volume de dados

Para mapear o volume do container a uma pasta no host basta executar o comando:

docker run -d --name meucontainer -v /var/app imagem

Será criado um novo diretório dentro do container chamado /var/app, caso o mesmo já exista, será sobrescrito por este novo.

Verificando volume

Você pode verificar quais volumes um container possui executando o comando:

docker inspect meucontainer

O resultado do comando será parecido com isso:

...
Mounts": [
    {
        "Name": "fac362...80535",
        "Source": "/var/lib/docker/volumes/fac362...80535/_data",
        "Destination": "/var/app",
        "Driver": "local",
        "Mode": "",
        "RW": true
    }
]
...

Por padrão todos os volumes são montandos como leitura e escrita, você pode montar o volume como apenas leitura, basta executar:

docker run -d --name meucontainer -v /var/app:ro imagem

Note o :ro no final do /var/app, isso quer dizer que este volume é apenas leitura.

Montando um diretório do host como um volume de dados

Para mapear o volume do container a uma pasta no host basta executar o comando:

docker run -d --name meucontainer -v /var/app:/var/www/html imagem

Será criado um novo diretório dentro do container chamado /var/app, caso o mesmo já exista, será sobrescrito por este novo.

Criando e montando um container como um volume de dados

É possível você criar um container com um volume que pode ser compartilhado com demais containers, isso é uma prática comum quando deseja-se ter alguma persistência de dados e que não esteja atrelado ao host onde o container está. Para isso, crie o container conforme abaixo:

docker create -v /dados --name meucontainer imagem /bin/true

Agora, no próximo container basta você utilizar o parametro –volumes-from para que o volume criado no container acima seja mapeado para o novo container, algo como isso:

docker run -d --volumes-from dados--name meucontainer1 imagem

Você pode criar quantos containers desejar mapeando este volume, inclusive pode mapear o volume de um container, por exemplo:

docker run -d --volumes-from container1 --name meucontainer2 imagem

Com isso não é necessário mapear obrigatoriamente o container de volume, e sim algum container que já utiliza ele. Outro ponto importante a se observar nessa caso é que:

  • Quando removido o container de volume os demais containers não perdem os dados, pois continuará existindo neste container a pasta montada;
  • Para remover o volume nesse caso é necessário remover todos os containers que foram criando mapeando este container e em seguida executar o comando: docker em -v

 

Bom pessoal, espero que tenham gostado, esse assunto é muito importante dentro do Docker, espero fazer um vídeo e disponibilizar para vocês um prática usando volumes.

Não fique com dúvida, mande e-mail para: [email protected] e vamos conversando, ajude a divulgar o blog e disseminar conhecimento, abraço!

Rede no Docker

Oi pessoal!

Neste post vamos detalhar como o Docker trabalha com o ambiente multi-host, vamos trazer alguns exemplos práticos e vamos detalhar cada caso de uso. Boa leitura!

O que muda no Docker 1.9?

Bom, primeiramente o que existia até o Docker 1.8 continua, o que muda é que foram acrescentado alguns comandos, e como explicado neste post, na versão 1.9 a funcionalidade de rede do Docker é tratada como um plugin, sendo possível assim utilizar formas mais elaboradas de rede, sem a necessidade de modificação em sua aplicação. Abaixo uma listagem dos comandos adicionados:

  • docker network create
  • docker network connect
  • docker network ls
  • docker network rm
  • docker network disconnect
  • docker network inspect

Criando uma rede – Bridge

Quando você instala o Docker Engine, ele cria automaticamente uma interface local de comunicação, tanto para o host – container, quanto para container-container, chama-se docker0 , ela é uma interface virtual criada em modo bridge com a interface principal, isso faz com que seja possível o container se comunicar com a internet, geralmente é atribuído para essa interface é o ip: 172.21.0.1/16, e quando não definido, os containers terão um ip dessa rede.

Na versão 1.9 do Docker é possível criar basicamente dois tipos de rede: Bridge (forma tradicional, e acessível apenas de dentro do host) ou do tipo Overlay (que possibilita a comunicação entre outros hosts com Docker, possibilitando assim a criação de cluster de Docker). Abaixo você pode visualizar como é possível criar uma rede em modo Bridge:

$ docker network create minha-rede
cds4554wfedcsaafe564fef3648e8d9d181sase98d8ef8c7ed561e89d9
$ docker network inspect minha-rede
[
    {
        "Name": "minha-rede",
        "Id": "cds4554wfedcsaafe564fef3648e8d9d181sase98d8ef8c7ed561e89d9",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {},
        "Options": {}
    }
]

Claro que você pode criar uma rede especificando qual range de ip você deseja que seus containers utilizem, veja:

$ docker network create --driver=bridge --subnet=172.28.0.0/16 --ip-range=172.28.5.0/24 --gateway=172.28.5.254 br0
03449da9dc22133889c55b3497bcd821b83e64b20608a680ce6e5025bd491118
$ docker network inspect br0
[
 {
 "Name": "br0",
 "Id": "03449da9dc22133889c55b3497bcd821b83e64b20608a680ce6e5025bd491118",
 "Scope": "local",
 "Driver": "bridge",
 "IPAM": {
 "Driver": "default",
 "Config": [
 {
 "Subnet": "172.28.0.0/16",
 "IPRange": "172.28.5.0/24",
 "Gateway": "172.28.5.254"
 }
 ]
 },
 "Containers": {},
 "Options": {}
 }
]

Quando você criar o container basta especificar agora que deseja utilizar essa rede, com o comando abaixo é possível fazer isso:

$ docker run --net=br0 -itd --name=container3 busybox
b9b6cea6195c0b66133933364e806d14644f97625c2a7270170fa5b6e4984f22
$ docker network inspect br0
[
 {
 "Name": "br0",
 "Id": "03449da9dc22133889c55b3497bcd821b83e64b20608a680ce6e5025bd491118",
 "Scope": "local",
 "Driver": "bridge",
 "IPAM": {
 "Driver": "default",
 "Config": [
 {
 "Subnet": "172.28.0.0/16",
 "IPRange": "172.28.5.0/24",
 "Gateway": "172.28.5.254"
 }
 ]
 },
 "Containers": {
 "b9b6cea6195c0b66133933364e806d14644f97625c2a7270170fa5b6e4984f22": {
 "EndpointID": "32970bd2ebb403851b559f81ec9916ddd4f791d5a9c2f30a093a5c1626e7f089",
 "MacAddress": "02:42:ac:1c:05:01",
 "IPv4Address": "172.28.5.1/16",
 "IPv6Address": ""
 }
 },
 "Options": {}
 }
]

Legal não? Você pode criar uma arquitetura que possibilite você isolar determinados containers, e fazer com que eles não tenha acesso a internet por exemplo, isso é útil para containers que executam aplicação de apoio, como redis, mongo, etc.

Criando uma rede – Overlay

Note que no caso acima, como não foi definido parâmetros adicionais, o Docker criou uma rede em modo Bridge. Diferentemente do modo Bridge, o Overlay necessita que alguns requisitos sejam atendidos, dentre eles podemos destacar:

  • Acesso a um serviço de chave-valor distribuído, o Docker suporta Consul, Etcd ou ZooKeeper;
  • Um Cluster já montado com acesso a este serviço de chave-valor distribuído;
  • Daemon do Docker configurado corretamente em cada host do cluster.
  • Host com Kernel 3.16 ou superior.

As opções disponíveis para criação de uma rede Overlay são:

  • --cluster-store
  • --cluster-store-opt
  • --cluster-advertise

Também é uma boa ideia, embora não obrigatório, que você instale o Docker Swarm para gerenciar o cluster. O Swarm fornece o serviço de descoberta e gestão de servidor que pode te ajudar na implementação.

Quando você cria uma rede, o Docker Engine não sobrepõe a rede criada no momento da instalação. Você pode substituir esse padrão e especificar uma sub-rede diretamente usando a opção –subnet. Em uma rede em modo Bridge você pode criar apenas uma única sub-rede, uma rede Overlay suporta múltiplas sub-redes.

Além da opção --subnetwork, você também especificar os parametros --gateway, --ip-range e --aux-address. Veja como ficaria a criação da rede:

$ docker network create -d overlay
  --subnet=192.168.0.0/16 --subnet=192.170.0.0/16
  --gateway=192.168.0.100 --gateway=192.170.0.100
  --ip-range=192.168.1.0/24
  --aux-address a=192.168.1.5 --aux-address b=192.168.1.6
  --aux-address a=192.170.1.5 --aux-address b=192.170.1.6
  minha-rede-multihost

O único cuidado que você deve ter é não criar sub-redes conflitantes, isso causará um erro no momento da criação ou mau funcionando no ambiente que deseja montar.  Estando a rede criada, basta criar o container passando como parâmetro ao nome da rede, veja:

$ docker run -itd --net=minha-rede-multihost busybox

 

Nos próximos posts vamos trazer detalhadamente um ambiente com Overlay, desde a configuração dos pré-requisitos até a criação de containers em múltiplos hosts, quem sabe um vídeo .

Por hoje era isso, esperamos ter ajudado e tendo dúvidas nos avise para conversarmos, e claro, nos ajude divulgando o Blog!

Melhores praticas Dockerfile

Muitas pessoas pensam que construir uma imagem é apenas iniciar um container, realizar algumas alterações e assim realizar o commit da mesma. Ou até mesmo escrever um Dockerfile do jeito que quiser e pronto a imagem está pronta e agora é só colocar em produção. Com algumas técnicas na criação do Dockerfile é possível fazer o seu Build passar de 10 minutos para apenas 10 segundos.

Baseado nas dúvidas que o pessoal acaba tendo no dia a dia resolvemos a equipe do mundodocker.com.br resolveu dar algumas dicas referentes a como deixar o seu Dockerfile o mais otimizado possível.

Use o .dockerignore

O .dockerignore possui a mesma funcionalidade do .gitignore, fazendo com que você possa gerar a sua imagem excluindo alguns arquivos que estejam no diretório do seu Dockerfile.

Não instale pacotes desnecessários

Para reduzir o tamanho de sua imagem e o tempo de construção dela, não instale pacotes que você acha que poderá usar um dia, instale apenas o necessário para que sua aplicação possa rodar de forma integra e segura. Muitas vezes pacotes desnecessários possuem uma série de dependências o que pode acarretar um tempo maior de construção da imagem.

Construa o minimo de camadas possíveis

Cada comando “RUN”, “COPY”, “ADD” acaba adicionando uma camada a mais em sua imagem, então quanto mais comandos conseguir executar de uma vez só melhor.

Use tags

Quando você for realizar o docker build utilize o parâmetro -t para que você possa organizar melhor sua estrutura de imagens e no desenvolvimento ficará mais fácil para saber o qual release essa imagem representa.
docker build . -t php:56-0-4

apt-get

Nunca utilize apenas apt-get update utilize sempre apt-get update && apt-get install. Por exemplo você tem o seguinte Dockerfile:


FROM UBUNTU
apt-get update
apt-get install wget

Você executa isso e depois de algum tempo você altera o Dockerfile e coloca assim:


FROM UBUNTU
apt-get update
apt-get install wget vim

Ao executar o build o Docker não irá executar o apt-get update fazendo com que o vim esteja desatualizado no momento da instalação.

Nunca mapear a porta pública no Dockerfile

Você NUNCA deve mapear a porta do seu host em seu Dockerfile:


#Não faça isso
EXPOSE 80:8080

#Faça isso
EXPOSE 80

Deixe sempre o que mais será alterado para o final

Como o Dockerfile trabalha com camadas, então você sempre devera deixar para o final a parte que é mais dinâmica em seu Dockerfile, pois ao rodar o seu Dockerfile pela segunda vez, o Docker irá olhar onde foi modificado o arquivo e irá refazer as camadas abaixo da modificação. Então se você tem uma parte que demora algum tempo e você não irá precisar modificar ela constantemente então é melhor você deixar essa parte no topo.


FROM ubuntu
RUN apt-get install -y nodejs
RUN mkdir /var/www
ADD app.js /var/www/app.js

FROM ubuntu
RUN apt-get install -y nodejs
RUN mkdir /var/www
ADD package.json /var/www/package.json

Nessa alteração de Dockerfile o Docker irá apenas refazer a camada do ADD e não irá baixar novamente o node e criar o diretorio /var/ Assim economizando tempo de Build e também tamanho em disco.

Então tá pessoal espero que tenham gostado desse post referente a dicas de como criar melhor o seu Dockerfile. Qualquer dúvida é só deixar um comentário que iremos reponder o mais rápido possível.

Docker API com Python

Oi pessoal!

Hoje, nós do mundodocker.com.br, vamos nos aprofundar um pouco mais na API do Docker, entenda de que forma você pode integra-la com alguma linguagem de programação. Como explicado neste post, o Docker é dividido basicamente em duas partes: Engine e CLI, ou seja, podemos acessar o Docker Engine de qualquer lugar, desde que o mesmo tenha sua API exposta, neste link: https://docs.docker.com/reference/api/remote_api_client_libraries são relacionadas todas as bibliotecas em diversas linguagens que podem ser utilizadas para manipular a API do Docker, ou seja, você não precisa se preocupar, se prefere PHP, há uma biblioteca em PHP, se prefere Java, há uma biblioteca em Java, se prefere GO, bom, há uma biblioteca também, e assim para muitas outras linguagens.

Vamos a prática!

Primeiro você deve instalar a biblioteca Docker no Python, para isso instale o pip.
Se for CentOS 7:

# rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# yum -y install python-pip

Se for Ubuntu:

# apt-get instal python-pip

Instalado o pip, execute:

# pip install docker-py

Para criar um container você pode utilizar o seguinte script:

import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
container = objdocker.create_container(image=imagem, command=comando, hostname=host+":4500",mem_limit="1000m",name=nome_Container)
objdocker.start(container,port_bindings={port_Container: ('0.0.0.0', port_Host)})
Para saber a utilização de recursos de um container, pode utilizar o script:
import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
objdocker.stats_container = objdocker.stats('nome_Container')
for stat in objdocker.stats_container:
print(stat)
Para saber algumas informações do Docker, pode utilizar:
import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
objdocker.info()
Para remover um container, você pode utilizar:
import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
objdocker.stats_container = objdocker.stop('nome_Container')
Você pode também habilitar a API do Docker para ser acessível remotamente, para isso, basta editar o /etc/sysconfig/docker (CentOS) ou /etc/init/docker.conf (Ubuntu) deixando-o assim:
DOCKER_OPTS='-H tcp://0.0.0.0:PORTA -H unix:///var/run/docker.sock'

 

Reinicie o Docker:

# service docker restart

E pronto, agora você pode manipular esse host de Docker remotamente, pode utilizar os mesmos script acima trocando apenas a base_url, algo parecido com isso:

objdocker=docker.Client(base_url="tcp://host_remoto:PORTA",,version="1.20",timeout=30)

A partir disso é possível realizar algumas automatizações de tarefas, e claro é possível integrar isso em algum dashboard ou ferramenta para poder administrar seus containers de forma mais organizada.

Espero ter ajudado e se gostou ajude divulgando nosso Blog, abraço!

Docker e Git parte 2

Olá pessoal, hoje estarei dando continuidade ao vídeo “Utilizando Git com Docker parte I” onde mostrei como poderíamos interagir com o Docker e Git. Nessa segunda parte vou mostrar como podemos criar uma imagem com o Git e Apache para fazermos deploy da nossa aplicação de uma forma rápida e fácil.

 

 

 

Bem legal né? Fique por dentro das novidades do Blog e nos ajude divulgando o mundodocker.com.br. Abraço!

MundoDocker – Eventos

Oi Pessoal,

Hoje o post é rápido, apenas para trazer a vocês nossa experiência no TcheLinux Caxias do Sul. Para quem nos acompanha nas rede sociais, ficou sabendo que iriamos participar de mais um edição do TcheLinux (um dos maiores eventos de tecnologia open source do Rio Grande do Sul), dessa vez em Caxias do Sul, na serra gaúcha.
O evento estava muito bem organizado, e o lugar não poderia ser melhor, com infraestrutura suficiente para atender os participantes, sem falar na localização. Com a ajuda de alguns amigos, conseguimos alguns registro fotográficos do evento, veja:

A nossa contribuição ao evento foi com uma palestra: Escalonando o mundo com Kubernetes, como o Google sobrevive. Essa apresentação teve como objetivo mostrar aos presentes como o Kubernetes funciona, como ele é utilizado dentro do Google e como você utiliza ele sem nem saber . Compartilhamos a apresentação em nosso Slideshare, para você, que não estava no evento, possa ver um pouco sobre o que levamos ao evento:

http://slideshare.net/MundoDocker/escalonando-o-mundo-com-kubernetes

Gostaríamos de agradecer ao TcheLinux pela oportunidade e a Ftec que disponibilizou o local para o evento. Por hoje era isso, grande abraço! Ahhh e nos ajude divulgando o blog

Desenvolvimento com Docker

Oi Pessoal,

A intenção hoje é trazer para vocês um conteúdo mais voltado para as equipes de desenvolvimento, ilustrando como é possível automatizar alguns pontos do seu trabalho utilizando Docker e como ele tornará as equipes mais eficientes naquilo que precisam ser: Entrega de resultado, óbvio.

Neste exemplo abordaremos um pouco sobre como é fácil montar um ambiente de desenvolvimento local utilizando nginx, php e mysql, este será, é claro, o primeiro passo em seu caminho para utilizar docker no seu dia-a-dia. Bom, chega de conversa, mãos a obra :).

Obviamente, nesse post não abordaremos como você deve instalar o Docker, para isso temos esse post que vai lhe ajudar muito, veja também que vamos usar nesse ambiente o docker compose, e claro, levamos em consideração que você está utilizando Docker em seu host de desenvolvimento, seja ele Windows, Linux ou Mac, e não no servidor de produção.

A receita

Ok, atendo a esses requisitos, e agora Cristiano, o que faço?

Primeiramente você deve criar, dentro de seu diretório de trabalho um arquivo para que o Docker Compose possa dar inicio a sua stack, e como você viu no post sobre o docker compose, o formato dele é de um arquivo do tipo Yaml, vamos utilizar a versão 2 do Docker Compose, que trás algumas melhorias, mas que difere um pouco na sintaxe, veja o exemplo que vamos usar nesse post:

# Utilizando sintaxe da versão 2:
version: '2'

volumes:
 database_data:
 driver: local

services:
###########################
# Container Web (Nginx)
###########################
 nginx:
 image: nginx:latest
 ports:
 - 8080:80
 volumes:
 - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
 volumes_from:
 - php

###########################
# Container PHP
###########################
 php:
 build: ./php/
 expose:
 - 9000
 volumes:
 - .:/var/www/html

###########################
# Container de banco de dados (MySQL)
###########################
 mysql:
 image: mysql:latest
 expose:
 - 3306
 volumes:
 - database_data:/var/lib/mysql
 environment:
 MYSQL_ROOT_PASSWORD: senha
 MYSQL_DATABASE: projeto
 MYSQL_USER: projeto
 MYSQL_PASSWORD: projeto

A grande diferença entre a versão 1 e 2 do Docker Compose está relacionado a utilização de algumas tags especiais, entre elas: services e volumes. Essas tags obviamente foram adicionadas por um bom motivo, e esse motivo é você poder ter múltiplos serviços dentro de uma stack, mas ter a flexibilidade de escalonar ou modificar atributos de um único serviço dentro de sua stack, sem precisar mexer em toda ela, isso é muito bom, não?

Outro motivo está relacionado ao uso de volumes para a persistência de dados, você não quer perder todo seu trabalho se seu container for acidentalmente removido, certo? E uma das grandes vantagens nesse caso é que você pode especificar um driver para volume que seja persistente não apenas em seu host, mas distribuído em um cluster de volume, explicamos um pouco sobre isso aqui e aqui, em nosso exemplo vamos usar local mesmo.

 

Inside

Note que nas linhas que referem-se ao container PHP, não há referência para imagem, o motivo é simples, faremos o build da imagem no mesmo momento de subir a stack, ou seja, quando rodarmos o docker-compose up -d o docker realizará o build do Dockerfile que encontra-se dentro da pasta php e utilizará a imagem gerada por esse build para iniciar o container php.

Mas e o que tem nesse Dockerfile? Calma, não íamos deixar isso de lado, veja abaixo como é esse Dockerfile:

FROM php:7.0-fpm 
RUN docker-php-ext-install pdo_mysql  
&& docker-php-ext-install json

Em nosso lab, usaremos como base a imagem do php 7.0 em fpm, e baseado nisso instalaremos algumas extensões, para que posteriormente possamos utilizá-las. Note que não é algo muito elaborado, mas poderia, caso você tenha essa necessidade. Na imagem em questão, há um binário responsável pela instalação das extensões, que é o docker-php-ext-install, ele realiza o download e instalação da extensão e sua ativação no php.ini global.

Note também que definimos expor a porta 9000 do container php para que o container do serviço web possa acessa-lo e assim processar as requisições. O arquivo de configuração do servidor web deve ser assim:

server {

 # Set the port to listen on and the server name
 listen 80 default_server;

 # Set the document root of the project
 root /var/www/html/public;

 # Set the directory index files
 index index.php;

 # Specify the default character set
 charset utf-8;

 # Setup the default location configuration
 location / {
 try_files $uri $uri/ /index.php;
 }

 # Specify the details of favicon.ico
 location = /favicon.ico { access_log off; log_not_found off; }

 # Specify the details of robots.txt
 location = /robots.txt { access_log off; log_not_found off; }

 # Specify the logging configuration
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;

 sendfile off;

 client_max_body_size 100m;

 # Specify what happens when PHP files are requested
 location ~ .php$ {
 fastcgi_split_path_info ^(.+.php)(/.+)$;
 fastcgi_pass php:9000;
 fastcgi_index index.php;
 include fastcgi_params;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_param APPLICATION_ENV development;
 fastcgi_intercept_errors off;
 fastcgi_buffer_size 16k;
 fastcgi_buffers 4 16k;
 }

 # Specify what happens what .ht files are requested
 location ~ /.ht {
 deny all;
 }
}

Veja que na opção: fastcgi_pass definimos como php:9000 ou seja, o nome do container na porta que expomos no docker-compose. Lembrando que você pode ter acesso a stack completa baixando esse exemplo de nosso repositório no gitub.

Para o Container de banco de dados, utilizamos a imagem oficial do MySQL, definimos apenas os dados de acesso e nome do banco de dados que gostaríamos de criar, e claro definimos um volume onde serão persistidos os dados desse banco.

Agora finalmente basta você subir a sua stack, para isso:

docker-compose up -d

Depois do docker compose realizar todo o processo de build da sua stack, basta você acessar o ambiente web pelo endereço: http://localhost:8080 e você terá como retorno a pagina inicial do seu site (que em nosso teste é apenas um phpinfo).

Próximos passos

 Bom, agora você só precisar criar :), quando você ficar alguma modificação na pasta onde está o projeto, elas serão refletidas no site, ou seja, modificando o seu index.php será alterado no site que está rodando nos container, isso porque mapeamos a pasta local como sendo a public do servidor web/php. O mais interessante dessa abordagem é poder movimentar esse ambiente para onde quiser, imagem que isso tudo faz parte de seu código versionado no git, basta chegar em basta e rodar um git clone do seu projeto (ou pull) e você terá o mesmo ambiente de desenvolvimento.

Gostou? Não gostou? Tem dúvida? Deixa nos comentários que vamos conversando! E como sempre, nos ajude divulgando o blog.

Grande abraço!

Docker EE e CE

Oi Pessoal!

No último dia 02 de março, o Docker anunciou uma grande mudança em sua plataforma, lançando oficialmente a versão enterprise da engine de containers mais utilizada atualmente. Mas o que muda? Responderemos isso e mais algumas outras dúvidas neste post!

Esse movimento adotado pelo Docker em, dividir, as versões da sua engine é algo já esperado pela comunidade, e para alguns veio até tarde. Mas por que isso agora? Por um motivo simples, produto. O Docker vem já algum tempo sendo desenvolvido como uma plataforma, agregando a cada nova release alguma correção que resolve um problema ou uma feature que melhora algum aspecto da engine.

Agora temos claro as linhas de trabalho do Docker, e como serão realizadas as atualizações na plataforma. As entregas de novas features, correção de bug, etc, seguiram a mesma linha adotada por outras empresas, ou seja, correção de bug e fix mais frequentes do que novas features, com isso a comunidade não precisará aguardar tanto tempo para ter uma correção já na engine.

Para ficar mais claro, dá uma olhada nessa imagem:

Docker Enterprise Edition

Fonte: https://blog.docker.com/2017/03/docker-enterprise-edition

Como você pode notar, as entregas para a versão community serão mais frequentes, e serão baseadas em correções e fix, tendo uma cadência mensal. Já entregas que envolvem novas features ou mudanças significativas nas engine serão realizadas a cada três meses. Já a versão enterprise terá apenas entregas trimestrais, com correções e novas features (caso tenha é claro) e o suporte será de um ano, baseado na data de lançamento.

Mas por que essa agora?

Há algum tempo estamos divulgando, ensinando e ajudando diversos públicos ao uso do Docker, tendo em vista versatilidade dessa plataforma, é claro e obvio a necessidade de adaptação do modelo de negócio para atender esses públicos, por exemplo:

Note que são perfis diversos, com necessidades e expectativas diferentes, mas em algum momento complementares. A versão enterprise do Docker visa o público que não quer apenas brincar, mas sim colocar em produção e disponibilizar para cliente.

Na imagem acima temos um apanhado geral das diferenças e onde cada versão é aplicada. Isso quer dizer que não posso colocar o Docker CE em produção? Não, isso quer dizer que se você usar a versão enterprise terá mais facilidade, já com a versão community será possível mas você terá mais trabalho.

 

Mudou o nome?

Sim, a versão community será algo parecido com isso:

# docker -v
Docker version 17.03.0-ce, build 60ccb22

Não teremos mais a nomenclatura de 1.xx, teremos então: ano.mes com a distinção entre CE e EE.

 

Tem mais alguma coisa nova?

Sim!!! Você já deve ter visto no anuncio oficial, agora há uma forma de você certificar seu ambiente seguindo as diretrizes do Docker, está disponível a Docker Store, um hub para publcação de recursos oficialmente homologados pelo Docker. Com isso, se você desejar criar um plugin para o Docker, por exemplo, você pode, atendendo uma série de requisitos, ter este plugin homologado e com certificado do Docker, o que obviamente aumenta sua relevância para quem usa.

Mas o que o Docker quer com isso? Te lembra daquelas imagens ali de cima, onde eram ilustrados os diferentes públicos que o Docker atende? Pois bem, dessa forma o Docker provê um recurso oficial, homologado e com o selo de aprovação deles para plugins, imagens, S.O, etc., atendendo assim a uma necessidade do mundo enterprise: “É confiável? Quem mantém?” dentre outras questões que este publico levanta no momento de decidir entre tecnologias.

Resumo, sim, o Docker acaba de se dividir em Community e Enterprise, até onde as coisas legais estarão na versão community só Deus sabe, mas a tendência é que sempre tenhamos  com o que brincar. E claro, para quem não quer perder tempo fazendo tudo na mão, existe a enterprise, que facilita tudo o que é possível.

Ufa, agora sim acabou

Nos ajude divulgando o blog! Grande abraço!

 

SwarmKit

Oi Pessoal,

Hoje, você não pode pensar em utilizar Docker em produção em larga escala sem ter alguma forma de automação e orquestração dessa “coisa”, graças a comunidade e algumas empresas, temos ferramentas que podem nos auxiliar nessas tarefas, todas juntas ou em partes, é claro. Atualmente as ferramentas mais conhecidas para orquestração e scale em Docker são Kubernetes e Mesos, existem muitos projetos mantidos pela comunidade nesse sentido, mas nenhum deles com tanta representatividade quanto aos mencionados anteriormente. Para não ficar de fora desse mundo, a Docker vem trabalhando bastante em uma suite que atenda essa necessidade, e que futuramente seja incorporado ao Docker Data Center, o projeto chama-se Swarmkit, e hoje, aqui no MundoDocker, vamos ver um pouco mais sobre ele.

O Que é?

O Swarmkit é uma suite para escalonamento e orquestração para sistemas distribuídos, ele possui um sistema de descoberta de nós, agendamento de tarefas, e utiliza o raft-based consensus para coordenação do cluster.

O que tem de bom?

  • Como já mencionado, ele utiliza o raft-based consensus, isso garante uma melhor coordenação do cluster, eliminando assim o ponto único de falha.
  • Todo os nós do cluster Swarm conversam de forma segura, e para ajudar nisso o Swarmkit utiliza TLS para autenticação, autorização e transporte dos dados entre os nós.
  • Swarmkit foi projeto para ser simples, por isso ele é independente de base de dados externas, ou seja, tudo que você precisa para utiliza-lo já está nele.

Ele é composto basicamente de duas camadas: Worker e Manager nodes, para entender cada um:

Worker: Responsável por executar as tarefas utilizar um Executor, por padrão o Swarmkit vem com o Docker Container Executor, mas que pode ser trocado caso deseja.

Manager: Basicamente é o nó eleito pelo administrador para ser o ponto central de administração, lembrando que quanto você adiciona um nó no cluster de Swarm você define se esse nó será Manager ou não.

Como outras ferramentas, para o Swarmkit as tarefas são organizadas em serviços, e para esse serviço você define o que deseja fazer, por exemplo: Crie replicas desse serviço todo dia as 10h, ou: Atualize um container por vez baseado nessa nova imagem.

Features

  • Oquestração
  1. Estado desejado: O Swarmkit analise constantemente o cluster, garantindo que todos os serviços estejam de acordo com o pretendido pelo usuário, isso faz com que um serviço seja provisionado em outro nó caso algum falhe.
  2. Tipo de serviço: atualmente o Swarmkit suporta apenas 2 tipos: 1 – Replicas, onde você define quantas cópias daquele container deseja, e 2 – Global, onde você especifica o que deve ser executado em cada nó do cluster.
  3. Atualização: Você pode modificar a qualquer momento o estado de um serviço, seja para para-lo ou escala-lo, quando você atualiza um serviço, por padrão ele executa essa tarefa de atualização de uma vez só para todos os nós do cluster, mas você pode definir de outras duas formas essa atualização: 1 – Paralela, onde o administrador define quantas tarefas de atualização podem ser executadas por mês ou 2 – Delay, dessa forma o Swarmkit executará as tarefas de atualização de serviço de forma sequencial, ou seja, uma tarefa só será executada caso a anterior já tenha terminado.
  4. Politicas de restart: A camada de orquestração monitora o estado das tarefas e reage as falhas aplicando a regra definida pelo usuário, dentro dessas regras o administrador pode definir número máximo de tentativos de restart de um serviço, quanto tempo depois de uma falha esse serviço deve ser reiniciado, etc. Por padrão o Swarmkit reinicia o serviço dentro de outro nó disponível no cluster, isso garante que os serviços dos nós defeituosos sejam iniciados em outros nós o mais rápido possível.
  • Agendamento
  1. Recursos: O Swarmkit sabe, através das checagens constantes, como está a saúde de cada nó, com isso, quando um serviço precisa ser reiniciado ou realocado, por padrão essa tarefa será realizada no melhor nó do cluster;
  2. Restrições: O administrador pode limitar o reinicio de um serviço em determinados nós, isso pode ser feito através de labels, exemplo: node.labels.foo!=bar1
  • Gerenciamento de cluster
  1. State Store: Permite ter uma visão macro de todo o cluster, como suas informações ficam em memória, permite ao nó de gerenciamento tomar decisões de forma muito mais rápida e segura.
  2. Gerenciamento da topologia: O administrador pode alternar quais são os nós de gerenciamento e qual são os Workers através de chamadas de API ou CLI.
  3. Gerenciamento de nós: É possível definir um nó como pausado, por exemplo, com isso os serviços que estavam alocados neste nó serão iniciados nos demais nós, assim como a execução de novas tarefas permanece bloqueada.
  • Segurança
  1. TLS: Todos os nós se conversam através de TLS, e os nós de gerenciamento agem como autoridade certificadora de todos os demais nós, e são responsáveis pela emissão de certificados para os nós que entram no cluster.
  2. Politica de aceitação: O administrador pode aplicar regras de auto-aceitação, aceitação manual ou troca de chaves, isso claro na adição de novos nós ao cluster, por default o Swarmkit utiliza auto-aceitação.
  3. Troca de certificados: É possível definir a frequência com a qual serão alterados os certificados ssl utilizados para comunicação do cluster, por padrão o tempo é de 3 meses, mas pode-ser definir qualquer período maior que 30 minutos.

Vamos brincar?

Instalando

O Swarmkit foi desenvolvido em GO, então tenha todo o ambiente pré-configurado e claro, baixe os fontes para seu $GOPATH, você pode utilizar:

[root@docker1 ~]# go get github.com/docker/swarmkit/

Acesse o diretório, e execute:

[root@docker1 ~]# make binaries

Isso fará com que sejam instaladas as ferramentas para utilização do Swarmkit, em seguida você pode testar sua instalação:

[root@docker1 ~]# make setup
[root@docker1 ~]# make all

Agora adicione o swarmd e swarmctl ao seu $PATH e seja feliz utilizando ele, veja abaixo alguns exemplos.

Montando o Cluster

No primeiro nó, execute:

[root@docker1 ~]# swarmd -d /tmp/docker1 --listen-control-api /tmp/manager1/swarm.sock --hostname docker1

Nos demais nós, execute:

[root@docker2 ~]# swarmd -d /tmp/node-2 --hostname docker2 --join-addr 10.1.1.1:4242
[root@docker3 ~]# swarmd -d /tmp/node-3 --hostname docker3 --join-addr 10.1.1.1:4242

Você pode agora, utilizar outro host para administrar o cluster, no nosso exemplo utilizando o docker4, veja:

[root@docker4 ~]# export SWARM_SOCKET=/tmp/manager1/swarm.sock
[root@docker4 ~]# swarmctl node ls
ID             Name    Membership  Status  Availability  Manager status
--             ----    ----------  ------  ------------  --------------
6rj5b1zx4makm  docker1  ACCEPTED    READY   ACTIVE        REACHABLE *
91c04eb0s86k8  docker2  ACCEPTED    READY   ACTIVE        
nf6xx9hpf3s39  docker3  ACCEPTED    READY   ACTIVE        

Criando os serviços

Vamos começar devagar, veja como subir um ambiente em redis:

[root@docker4 ~]# swarmctl service create --name redis --image redis:3.0.5
6umyydpxwtzfs3ksgz0e

Listando os serviços:

[root@docker4 ~]# swarmctl service ls
ID                         Name   Image        Replicas
--                         ----   -----        ---------
6umyydpxwtzfs3ksgz0e      redis  redis:3.0.5  1

Inspecionando o serviço:

[root@docker4 ~]# swarmctl service inspect redis
ID                : 6umyydpxwtzfs3ksgz0e
Name              : redis
Replicass         : 1
Template
 Container
  Image           : redis:3.0.5

Task ID                      Service    Instance    Image          Desired State    Last State               Node
-------                      -------    --------    -----          -------------    ----------               ----
6umyydpxwtzfs3ksgz0e         redis      1           redis:3.0.5    RUNNING          RUNNING Up About an hour    docker1

Atualizando serviço:

Conforme mencionado anteriormente, podemos atualizar o status de um serviço, no nosso exemplo vamos aumentar o número de replicas dele, veja:

[root@docker4 ~]# swarmctl service update redis --replicas 6
6umyydpxwtzfs3ksgz0e

[root@docker4 ~]# swarmctl service inspect redis
ID                : 6umyydpxwtzfs3ksgz0e
Name              : redis
Replicas          : 6
Template
 Container
  Image           : redis:3.0.5

Task ID                      Service    Instance    Image          Desired State    Last State               Node
-------                      -------    --------    -----          -------------    ----------               ----
xaoyxbuwe13gsx9vbq4f         redis      1           redis:3.0.5    RUNNING          RUNNING Up About an hour     docker1
y8cu8nvl1ggh4sl0xxs4         redis      2           redis:3.0.5    RUNNING          RUNNING 10 seconds ago    docker2
ksv9qbqc9wthkrfz0jak         redis      3           redis:3.0.5    RUNNING          RUNNING 10 seconds ago    docker2
nnm9deh7t0op6rln3fwf         redis      4           redis:3.0.5    RUNNING          RUNNING 10 seconds ago    docker1
4ya5eujwsuc6cr7xlnff         redis      5           redis:3.0.5    RUNNING          RUNNING 10 seconds ago    docker3
9o4pmrz6q6pf9ufm59mk         redis      6           redis:3.0.5    RUNNING          RUNNING 10 seconds ago    docker3

Vamos atualizar a imagem do serviço?

[root@docker4 ~]# swarmctl service update redis --image redis:3.0.6
6umyydpxwtzfs3ksgz0e

[root@docker4 ~]# swarmctl service inspect redis
ID                : 6umyydpxwtzfs3ksgz0e
Name              : redis
Replicas          : 6
Template
 Container
  Image           : redis:3.0.6

Task ID                      Service    Instance    Image          Desired State    Last State                Node
-------                      -------    --------    -----          -------------    ----------                ----
xaoyxbuwe13gsx9vbq4f         redis      1           redis:3.0.6    RUNNING          RUNNING 5 seconds ago    docker3
y8cu8nvl1ggh4sl0xxs4         redis      2           redis:3.0.6    RUNNING          RUNNING 6 seconds ago    docker1
ksv9qbqc9wthkrfz0jak         redis      3           redis:3.0.6    RUNNING          RUNNING 5 seconds ago    docker2
nnm9deh7t0op6rln3fwf         redis      4           redis:3.0.6    RUNNING          RUNNING 6 seconds ago    docker1
4ya5eujwsuc6cr7xlnff         redis      5           redis:3.0.6    RUNNING          RUNNING 6 seconds ago    docker2
9o4pmrz6q6pf9ufm59mk         redis      6           redis:3.0.6    RUNNING          RUNNING 6 seconds ago    docker3

Por padrão todos os containers foram atualizados de uma única vez, isso tem suas vantagens e desvantagens, mas como explicado, você pode mudar essa execução para fazer em partes, veja:

[root@docker4 ~]# swarmctl service update redis --image redis:3.0.7 --update-parallelism 3 --update-delay 20s

Com isso, serão refeitos 3 containers por vez e entre eles terá um intervalo de 20 segundos.

Gerenciando nós

O Swarmkit monitora a saúde de cluster, e baseado nisso toma ações em cima dos serviços, você pode realizar ações manuais também, como por exemplo, retirar um nós do cluster, veja:

[root@docker4 ~]# swarmctl node drain docker1

[root@docker4 ~]# swarmctl node ls
ID             Name    Membership  Status  Availability  Manager status
--             ----    ----------  ------  ------------  --------------
6rj5b1zx4makm  docker1  ACCEPTED    READY   DRAIN         REACHABLE
91c04eb0s86k8  docker2  ACCEPTED    READY   ACTIVE        REACHABLE *
nf6xx9hpf3s39  docker3  ACCEPTED    READY   ACTIVE        REACHABLE

[root@docker4 ~]# swarmctl service inspect redis
ID                : 6umyydpxwtzfs3ksgz0e
Name              : redis
Replicas          : 6
Template
 Container
  Image           : redis:3.0.7

Task ID                      Service    Instance    Image          Desired State    Last State               Node
-------                      -------    --------    -----          -------------    ----------               ----
xaoyxbuwe13gsx9vbq4f         redis      1           redis:3.0.7    RUNNING          RUNNING 2 minute ago     docker2
y8cu8nvl1ggh4sl0xxs4         redis      2           redis:3.0.7    RUNNING          RUNNING 2 minute ago     docker3
ksv9qbqc9wthkrfz0jak         redis      3           redis:3.0.7    RUNNING          RUNNING 30 seconds ago    docker2
nnm9deh7t0op6rln3fwf         redis      4           redis:3.0.7    RUNNING          RUNNING 34 seconds ago    docker3
4ya5eujwsuc6cr7xlnff         redis      5           redis:3.0.7    RUNNING          RUNNING 28 minutes ago    docker2
9o4pmrz6q6pf9ufm59mk         redis      6           redis:3.0.7    RUNNING          RUNNING 29 seconds ago    docker3

O Swarmkit é uma ferramenta em desenvolvimento ainda, mas você pode utilizar ela em seus labs e entender um pouco melhor como pode trabalhar em cluster com Docker. Espero que tenham gostado, e nos ajude divulgando o blog

Abraço!

Docker no Windows Server 2016

Olá Pessoal!

A Microsoft acaba de lançar o Windows Server 2016 Preview, que trará consigo o Docker Engine nativo, isso mesmo, a mesma engine utilizada dentro de distribuições Linux estará disponível no Windows Server. Quais benefícios isso trás?

 Flexibilização da infraestrutura, da mesma forma que no Linux, não será necessário instanciar uma VM ou máquina física para realizar deploy de uma aplicação.

Mais ferramentas para desenvolvedores, já existe um plugin para o Visual Studio, onde você poderá desenvolver sua aplicação e publica-la automaticamente dentro de um container, deu build foi pro ar!

Claro, isso não foi um trabalho fácil, houve um grande esforço por parte da Microsoft para que fosse possível integrar o Docker Engine ao Kernel do Windows e mesmo assim há algumas limitações, como por exemplo:  Não será possível, pelo menos não na versão preview, o uso de container Linux dentro Windows Server 2016, isso claro por motivos óbvios, pois o Kernel do host é bastante diferente do Kernel do container. Claro para testes ele pode ser utilizado sem problema.

OK, mas como ficou a arquitetura?

Bem parecido com o Docker no Linux, a Microsoft adicionou ao Kernel do Windows alguns recursos que possibilitam criar um ambiente isolado a nível de userspace, e uso limitado de recursos, na imagem abaixo podemos ter uma ideia de como ficou:

windows_docker

Fiquem atentos, nos próximos posts vamos colocar na prática o Docker no Windows Server 2016, continuem nos acompanhando aqui no blog, facebook ou nosso canal no youtube.

Referência:

Introducing the Technical Preview of Docker Engine for Windows Server 2016

Serviços Windows em Docker

Oi Pessoal,

Já vimos em alguns posts, por exemplo este, este e este, como é possível ter seu ambiente Windows em Docker, ou Docker para Windows. Pois bem, a intenção hoje é nos aprofundarmos mais em como é possível portar um ambiente já existente para dentro de containers no Windows, ou seja, veremos como migrar sua aplicação .net que atualmente está em uma máquina virtual para um container, isso de forma bem simples e rápida.

 

Do início

Antes de tudo, precisamos nos situarmos sobre o uso de algumas ferramentas, e aqui entra a parte fundamental desse processo, que é entender como funciona o Image2Docker, para quem não o conhece, este é um módulo do powershell que possibilita a criação de arquivo(s) Dockerfile(s) a partir de um VHD, VHDx ou ainda uma imagem WIM. Você não precisa estar com a máquina virtual ligada para realizar esse processo, o Image2Docker inspeciona o disco offline coletando informações sobre o que você tem instalado ali, e claro, ele serve apenas para ambiente Windows, então ele já possui uma tabela pré-determinada de aplicações que devem ser verificadas.

Após finalizado o scan, ele monta um Dockerfile baseado na imagem do Windows Server Core (microsoft/windowsservercore), é claro que ele não portará tudo de seu ambiente, por exemplo, se você tem instalado uma base MySQL na VM Windows que escaneou, essa instalação não será portada para o Dockerfile, e consequentemente terá que ser portada manualmente depois. Aqui está uma lista de softwares/aplicações que o Image2Docker busca, e que são suportados por ele:

  • IIS e aplicações ASP.NET
  • MSMQ
  • DNS
  • DHCP
  • Apache
  • SQL Server

Ou Seja, se dentro de seu VHD você possuir algum desses softwares instalados, o Image2Docker gerará o Dockerfile baseado nisso.

image2docker

 

Instalação

Há duas formas de instalação, Você pode instalar o módulo nativo do Image2Docker, o processo é simples:

Install-Module Image2Docker
Import-Module Image2Docker

Neste caso, se você não tiver todas as dependências instaladas, ele fará essa instalação de forma automática (caso você aprove é claro).
Outro método é você utilizar a última versão diretamente do repositório, neste caso você terá que instalar algumas coisas antes, como por exemplo:

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201
Install-Module -Name Pester,PSScriptAnalyzer,PowerShellGet

Feito isso, basta agora realizar o download do módulo e importa-lo:

mkdir docker
cd docker
git clone https://github.com/sixeyed/communitytools-image2docker-win.git
cd communitytools-image2docker-win
Import-Module .Image2Docker.psm1

É muito importante ressaltar que ele foi desenvolvido para rodar em versões superiores a 5.0 do Poweshell, então se atende a esse detalhe.

 

Convertendo

Vamos começar as poucos, digamos que você tenha uma máquina virtual com IIS instalado com algumas aplicações e quer porta-la para container Docker, é possível? Sim, o Image2Docker suporta VMs em Windows 2016, 2012, 2008 e 2003, independente da tecnologia utilizada, seja ela ASP.NET WebForms, ASP.NET MVC, ASP.NET WebApi.

Para você rodar Image2Docker, precisará informar alguns parâmetros, dentre eles:

  • ImagePath – Localização do VHD, VHDx ou WIM
  • Artifact – Que tipo de serviço você quer portar para um Dockerfile, deve ser um dos itens da listagem acima.
  • ArtifactParam – Parametro que deve ser utilizado apenas se o artefato for IIS, pois é possível especificar apenas um site a ser portado.
  • OutputPath – Localização de onde você salvará o Dockerfile

Chega de papo, vamos ao trabalho, para converter uma VM com IIS e todos os seus sites para um único Dockerfile, basta executar:

ConvertTo-Dockerfile -ImagePath C:VMSwin-2016-iis.vhd -Artifact IIS -Verbose -OutputPath c:dockeriis

A saída desse comando deve ser algo como isso aqui:

VERBOSE: IIS service is present on the system
VERBOSE: ASP.NET is present on the system
VERBOSE: Finished discovering IIS artifact
VERBOSE: Generating Dockerfile based on discovered artifacts in
:C:UsersmundodockerAppDataLocalTemp287653115-6dbb-40e8-b88a-c0142922d954-mount
VERBOSE: Generating result for IIS component
VERBOSE: Copying IIS configuration files
VERBOSE: Writing instruction to install IIS
VERBOSE: Writing instruction to install ASP.NET
VERBOSE: Copying website files from
C:UsersmundodockerAppDataLocalTemp287653115-6dbb-40e8-b88a-c0142922d954-mountwebsitesaspnet-mvc to
C:dockeriis
VERBOSE: Writing instruction to copy files for aspnet-mvc site
VERBOSE: Writing instruction to create site aspnet-mvc
VERBOSE: Writing instruction to expose port for site aspnet-mvc

Ao final da execução do comando, ele gerará um Dockerfile dentro da pasta c:dockeriis com o seguinte conteúdo:

# Instalar a feature do IIS
RUN Add-WindowsFeature Web-server, NET-Framework-45-ASPNET, Web-Asp-Net45
RUN Enable-WindowsOptionalFeature -Online -FeatureName IIS-ApplicationDevelopment,IIS-ASPNET45,IIS-BasicAuthentication...

# Adicionar o site mvc no IIS
COPY aspnet-mvc /websites/aspnet-mvc
RUN New-Website -Name 'aspnet-mvc' -PhysicalPath "C:websitesaspnet-mvc" -Port 8081 -Force
EXPOSE 8081

# Adicionar o site webapi no IIS
COPY aspnet-webapi /websites/aspnet-webapi
RUN New-Website -Name 'aspnet-webapi' -PhysicalPath "C:websitesaspnet-webapi" -Port 8082 -Force
EXPOSE 8082

Lembrando, no exemplo acima nós portamos todos os sites do IIS para um único Dockerfile, é possível especificar apenas um site, para isso:

ConvertTo-Dockerfile -ImagePath C:VMSwin-2016-iis.vhd -Artifact IIS -ArtifactParam aspnet-webforms -Verbose -OutputPath c:dockeriis

Dessa forma, apenas o site chamado: aspnet-webforms será portado para um Dockerfile.

 

Converti, e agora?

Tendo gerado o Dockerfile, basta você seguir o fluxo normal de criação de imagem Docker, por exemplo:

docker build -t mundodocker/site-webforms .

Dessa forma você criará uma imagem chamada: mundodocker/site-webforms e poderá utiliza-la da mesma forma como as demais, apenas lembrando que essa imagem fará a criação do site e copiará os arquivos do site que havia na VM para dentro do container, vamos rodar:

docker run -d -p 8080:8083 mundodocker/site-webforms

Basta agora, você acessar o endereço de sua aplicação, para isso você terá que saber o ip do container criado, então execute:

docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' ID_DO_CONTAINER

Agora sim, basta acessar o ip que esse comando retornará, na porta 8080, algo assim: http://172.28.192.4:8080 e você poderá visualizar a aplicação que você tinha em um VM, agora dentro de um container

 

Dica final

Imagine que você tenha diversos sites dentro do mesmo IIS, e queira portar cada um para um container diferente, qual seria o método normal? Rodar o comando N vezes até ter todos portados, certo? Pois bem, você pode automatizar isso, criar um script em powershell que faça essa “mágica” sem muito esforço. O script pode ser parecido como este:

$sites = @("aspnet-mvc", "aspnet-webapi", "aspnet-webforms", "static")
foreach ($site in $sites) { 
    ConvertTo-Dockerfile -ImagePath C:VMSwin-2016-iis.vhd -Artifact IIS -ArtifactParam $site -Verbose -OutputPath "c:docker$website" -Force
    cd "c:docker$site"
    docker build -t "mundodocker/$site" .
}

Dessa forma ele gerará tanto o Dockerfile para cada site assim como as imagens para cada um.

 

Gostaram? Ficaram com dúvidas? Deixe nos comentários ou no nosso fórum, que tanto nós quanto nossos leitores poderão ajudar. E como sempre, ajude divulgando o blog.

Grande abraço!

Docker Secrets

Oi pessoal! 

Para o artigo de hoje, contamos com a ajuda de um grande amigo nosso, o Wellington F. Silva, que colocou em seu blog um texto muito bacana sobre o que é e como funcionam as secrets no Docker 1.13. No decorrer desse post entenderemos como essa nova funcionalidade trabalha, sua origem e claro, o impacto disso em nosso dia-a-dia, #vamoslá?

 

O que é o secret?

Quando estamos trabalhando em um projeto e precisamos passar informações sensíveis para o ambiente, tais como senhas, chaves privadas, tokens, chaves de APIs e afins sempre passamos pelo problema de não podermos deixar no controle de versão e devemos sempre utilizar uma maneira segura de trafegar esses segredos.

Muitas vezes acabamos trabalhando com variáveis de ambiente para guardar essas informações, o que não é recomendado por alguns motivos.

Diogo Monica que é um dos engenheiros de software da Docker mencionou em um comentário que variáveis de ambiente quebram o princípio de “least surprise” e podem levar a eventuais vazamentos de segredos já que estão acessíveis de várias maneiras, tais como linked containers, através do *docker inspect*, de processos filhos e até de arquivos de logs já que em caso de exceptions da aplicação muitos frameworks fazem o dump do contexto, inclusive o valor das variáveis de ambiente no arquivo de log.

 

Um pouco da história

Em Janeiro de 2015 houve uma proposta de adicionar o comando `docker vault` numa alusão ao Vault Project da Hashicorp para fazer a gerencia de segredos dentro do próprio Docker. Segue o link para a issue 10310 no GitHub. A discussão evoluiu e virou a issue 13490, onde trataram do roadmap para o atual Docker Secrets.

 

Como funciona?

O Docker Secrets funciona como um cofre onde você pode colocar coisas sensíveis lá e só que tem a chave do cofre consegue utilizar, no caso essa chave é designada aos nós dos serviços que a chave for atribuída.

 

Dicas

  • Só funciona no Swarm Mode onde toda a comunicação entre os nós é por padrão encriptada.
  • Se utiliza do algoritmo de RAFT para persistir o segredo de forma encriptada por todos os nós managers e distribuir aos containers que fizerem parte do serviço ao qual a chave for atribuída.

Segue diagrama da própria Docker:

Criando um secret

Podemos criar um secret de duas maneiras, usando o STDIN:

$ echo "ConteudoDoSecret" | docker secret create um-secret -

Ou lendo um arquivo:

$ docker secret create novo-secret $HOME/senhas.txt

 

Listando, removendo e demais opções

Para listar as secrets disponíveis:

$ docker secrets ls
  ID NAME CREATED UPDATED
  8ulrzh4i1kdlxeypgh8hx5imt um-secret 3 minutes ago 3 minutes ago
  n95fprwd2trpqnjooojmpsh6z novo-secret About an hour ago About an hour ago

Demais opções do que fazer com os secrets como remover, inspecionar, etc podem ser listadas com o help:

$ docker secret --help

 

Usando o secret criado

Podemos criar um serviço usando um secret criado com o comando:

$ docker service create --name demo --secret um-secret mysql:5.7

Podemos remover um secret de algum serviço existente

$ docker service update --secret-rm um-secret demo

Ou podemos adicionar um secret a algum service que esteja de pé:

$ docker service update --secret-add novo-secret demo

 

Quando atrelamos um secret a um service podemos então acessar qualquer um dos containers que estejam rodando nesse service no path /run/secrets. Dentro do container nesse path vai existir um arquivo plain text com o nome igual ao definido no nome do secret e com o conteúdo desejado, o secret em plain text. No nosso caso seria no path /run/secrets/novo-secret.

 

Bem legal não é? Ajude divulgando o blog, e fique ligado teremos muitas novidades em breve, então se não se inscreveu em nossa newsletter, inscreva-se ;). Até a próxima.

 

Fonte: http://dumpscerebrais.com/2017/02/como-trabalhar-com-secrets-no-docker-1-13-x/

Docker e Flannel

Oi Pessoal!

A intenção hoje é chamar a atenção para um dos recursos que está presente no Docker e que as vezes passa despercebido para muitos dos utilizadores dessa tecnologia, que é trabalhar com rede. Já vimos aqui no blog como trabalhar com Docker Network, mas com a ascensão do docker 1.12 ficou ainda mais fácil mudar a forma de como se utilizar rede, você pode integrar o Docker com diversos plugins e tecnologias de rede, hoje veremos como utilizar o Flannel para ser seu backend de rede.

Para quem não conhece, o Flannel é um projeto que foi inicialmente desenvolvido pela CoreOS, mas que atualmente é mantido, além da própria empresa, pela comunidade. Ele utiliza um serviço de chave-valor para persistir as informações sobre alocação de ip entre hosts e containers, por padrão ele utiliza o Etcd (que por coincidência é desenvolvido e mantido pela CoreOS também ), veja abaixo algumas das características do Flannel e a diferença em relação ao Docker Network:

                              Flannel              Docker Overlay Network
Modelo                        VxLAN ou UDP                            VxLAN
Isolamento de aplicação                        CIDR Schema                      CIDR Schema
Protocolos suportados                              Todos                            Todos
Serviço de nome                                Não                              Não
Requer backend externo                                Sim                              Sim
Tipo de encriptação                                TLS                              Não
 vNIC por Container                                Não                              Sim
Restrição de subnet por container                                Não                              Sim

Como podem notar o Flannel tem algumas vantagens e desvantagens em relação ao Docker Network, destacam-se a comunicação encriptada que ele provê e não ter a possibilidade de criar subnet diferente por cliente, ou seja, todos os containers fazem parte da mesma rede. Se você está pensando em utilizar Kubernetes, leve em consideração o Flannel, pois é um dos plugins mais utilizados com esse orquestrador. Vamos colocar a mão na massa?

Instalação e dependências

Servidor Etcd

Nosso exemplo foi baseado no Centos 7 64 bits, mas você pode utilizar em outro S.O sem problema. Vamos lá, primeiramente você deve habilitar o repositório Extras do CentOS, para isso edite o CentOS-Base.repo e coloque habilite-o, veja:

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#released updates
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
enable=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Agora vamos instalar o backend do Flannel, que é o etcd (serviço de chave valor em memória), o etcd é utilizada para armazenar as informações sobre as redes que serão distribuídas entre os containers. Vamos lá:

[root@host-etcd ~]#  yum install etcd

Edite o /etc/etcd/etcd.conf alterando o ETCD_LISTEN_CLIENT_URLS, em nosso teste colocamos 0.0.0.0, ou seja, o etcd estará acessível através de qualquer ip do host, veja:

ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"

Cuide para que a porta 2389 esteja liberado no firewall desse host. Agora vamos aproveitar que estamos no host de etcd e vamos já deixar configurado a rede que será utilizada pelos hosts de Docker. Para isso, crie um arquivo, em nosso lab: rede.json e adicione o seguinte código:

{
 "Network": "192.0.0.0/16",
 "SubnetLen": 22,
 "Backend": {
 "Type": "vxlan",
 "VNI": 1
 }
}

Onde:

  • Network – Bloco de rede que será distribuída para os containers;
  • SubnetLen – Tamanho do bloco alocada para cada host, ou seja, cada host receberá um /22 do bloco 192.0.0.0/16, isso que dizer que poderíamos ter até 1000 containers em 1 host.
  • Type – Tipo do canal que será utilizado, lembra que no Flannel você pode escolher em vxlan ou udp, pois bem, é aqui que você configura isso, por experiência própria, recomendamos utilizar vxlan, pois há menos overhead.

O que faço com isso agora? Importe no etcd ;), lembrando que o etcd trabalha com chave=valor, então execute:

[root@host-etcd ~]# etcdctl set /mundodocker/network/config < rede.json

Onde:

  • /mundodocker/network/config – chave
  • rede.json – valor

Agora vamos ver se essas informações foram persistidas no etcd:

[root@host-etcd ~]#etcdctl get /mundodocker/network/config
{
 "Network": "192.0.0.0/16",
 "SubnetLen": 22,
 "Backend": {
 "Type": "vxlan",
 "VNI": 1
 }
}

 

Servidores Docker

Não esqueça, em todos os hosts temos que ativar o repositório de extras do CentOS, da mesma forma que foi feita acima. Vamos as instalações das dependências, o docker é claro:

[root@host-docker01 ~]# curl -fsSL https://get.docker.com/ | sh

Agora o Flannel:

[root@host-docker01 ~]# yum install flannel -y

Vamos as configurações agora, começamos pelo Flannel, para isso, edite o arquivo: /etc/sysconfig/flanneld, modificando as linhas:

FLANNEL_ETCD = Servidor do Etcd.
FLANNEL_ETCD_KEY = Key definida no Etcd.

Veja como deve ficar:

[root@host-docker01 ~]# cat /etc/sysconfig/flanneld | grep -v ^#
FLANNEL_ETCD="http://host-etcd:2379"
FLANNEL_ETCD_KEY="/mundodocker/network"

Agora inicie o serviço do Flannel:

[root@host-docker01 ~]# systemctl enable flanneld
[root@host-docker01 ~]# systemctl start flanneld

Note que ele criará uma interface de rede chamada flannel.1, que será utilizada para comunicação entre os hosts. Note também que será criado um arquivo dentro de: /run/flannel/subnet.env com as informações sobre a rede que o host assumiu, esse arquivo será utilizado daqui a pouco.

Agora vamos configurar nosso serviço de Docker para utilizar a rede Flannel configurada anteriormente, para isso, edite o arquivo: /lib/systemd/system/docker.service adicionando a linha: EnvironmentFile=-/run/flannel/subnet.env e alterando a forma como o Docker será iniciado, veja como deve ficar:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
 
[Service]
Type=notify
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/docker daemon -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
 
[Install]
WantedBy=multi-user.target

Agora basta iniciar/reiniciar o serviço do Docker:

[root@host-docker01 ~]# systemctl enable docker.service
[root@host-docker01 ~]# systemctl start docker.service

Não esqueça de fazer isso em todos os hosts de Docker que você quer colocar nessa rede.

 

Vamos testar?

Basta você criar um container em cada host, em nosso teste criamos um baseado na imagem do CentOS:

Host 1:

[root@host-docker01 ~]# docker run -it centos /bin/bash

Host 2:

[root@host-docker02 ~]# docker run -it centos /bin/bash

Agora basta você pingar de um container para o outro, ou se quiser fazer um teste mais real, você pode instalar um banco de dados ou servidor web em um dos containers e tentar acessar via ip da rede Flannel pelo outro container. Como você deve ter notado esse processo é bem simples e resolve grandes problemas com rede no Docker, como por exemplo a comunicação entre multi-host.

Por hoje era isso, espero que tenha ajudado, e como sempre, nos ajude divulgando o blog

Abraço!

Docker Swarm na Prática

Oi Pessoal!

Fizemos um vídeo mostrando na prática como é possível criar um cluster de Swarm e gerenciar seus serviços com ele, veja também como você pode portar sua stack do Docker Compose para dentro do cluster via o Docker Stack. Veja:

Este é apenas um vídeo de lab, lembramos que você deve se ater a alguns outros pontos nesse ambiente antes de colocar em produção, OK?

Contamos com a ajuda de vocês para divulgação do blog, grande abraço!

Kubernetes e Docker

Olá pessoal,

Hoje vamos iniciar uma série de posts demonstrado como podemos utilizar o Kubernetes como ferramenta de automatização, distribuição de carga, monitoramento e orquestração entre containers.

Kubernetes é um sistema de código aberto que foi desenvolvido pelo Google para gerenciamento de aplicativos em containers através de múltiplos hosts de um cluster. Tem como principal objetivo facilitar a implantação de aplicativos baseados em microservices. Ele foi baseado na experiência do Google de muitos anos trabalho com containers, adaptando o  para se trabalhar com Docker.

O Kubernetes foi muito útil para ser utilizado até o Docker Swarm 1.0, pois disponibilizava muitos recursos que o Docker não disponibilizava até aquele momento, entre eles: Balanceamento de carga e movimento de containers sem perda de dados.

A principal vantagem que se tem ao utilizar o Kubernetes é que você não está preso as limitações da API do Docker (O Problema do Swarm) você tem total liberdade já que o Kubernetes não foi desenvolvido especialmente para o Docker, você pode trocar a sua estrutura de Docker para Rockets (Containers no CoreOS). Você pode escolher a simplicidade do Swarm ou o poder do Kubernetes.

Dentro do Kubernetes possuímos alguns termos para determinadas funções:

Minions: É o nome dado para cada host do cluster.

Kubelet: Agente que roda nos hosts do cluster.

Pods: É a menor unidade dentro de um cluster, nada mais é do que containers rodando dentro de seu cluster de Kubernetes. Pode ser um container rodando nginx, php, apache, etc…

Replication Controller: É o responsável por manter um número determinado de pods em execução. No RC é onde você diz quantos containers de nginx, php, apache você desejá que fiquem rodando, caso um caia, o RC cria outra instância automaticamente.

Services: É o responsável por atrelar uma faixa de IP para um determinado RC. Para que cada vez que o RC crie uma nova instância de pod o mesmo inicie com um IP determinado pelo service.

Namespace: Com o namespace você pode dividir seu Cluster de Kubernetes em dois ambientes, Produção e Teste, podendo limitar os recursos computacionais para ambos.

No proximo post vamos mostrar como podemos instalar e configurar o kubernetes para que você use em seu ambiente da melhor maneira possível.

Docker Swarm

Oi Pessoal,

Hoje queremos trazer para vocês mais uma das ferramentas que o Docker disponibiliza em seu ecossistema, chegou a hora de conhecermos o Docker Swarm. O Docker Swarm é uma ferramenta nativa do Docker que permite a criação de clusters de Docker, ou seja, podemos fazer com que diversos hosts de Docker estejam dentro do mesmo pool de recursos, facilitando assim o deploy de containers. É possível por exemplo criar um container sem necessariamente saber em qual host ele está, pois o Swarm disponibilidade uma API de integração, onde é possível realizar grande parte das atividades administrativas de um container. Quer ver na prática?

Requisitos:

  • Estar com a versão 1.6+ do Docker
  • Abrir a API do Docker para o Swarm Manager

 

Mãos a obra:

1 – Baixando a imagem oficial:

$ docker pull swarm

2 – Criando o cluster:

$ docker run --rm swarm create 
4765653423fdecsdfe875954a6e2h78ed # 

 

O retorno desse comando será o ID do Cluster, armazena essa informação pois será importante nas próximas etapas.

3 – Adicionando nós ao cluster:

$ docker run -d swarm join --addr=<node_ip:2375> token://4765653423fdecsdfe875954a6e2h78ed

4 – Configurando o Manager:

$ docker run -d -p <porta_manager>:2375 swarm manage token://4765653423fdecsdfe875954a6e2h78ed

Lembrando que <porta_manager> será a porta que você utilizará para se comunicar com o Swarm Manager, responsável pela administração do cluster, a arquitetura ficará da forma como a imagem abaixo:

5 – Verificando o Cluster:

$ docker -H tcp://ip:porta_manager> info

O retorno será algo parecido com isso:

Containers: 0 
Nodes: 3 
agent-2: 172.31.0.1:2375 
  └ Containers: 0 
  └ Reserved CPUs: 0 / 1 
  └ Reserved Memory: 0 B / 514.5 MiB 
agent-1: 172.31.0.2:2375 
  └ Containers: 0 
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 514.5 MiB 
agent-0: 172.31.0.3:2375 
  └ Containers: 0 
  └ Reserved CPUs: 0 / 1 
  └ Reserved Memory: 0 B / 514.5 MiB

Você pode enfrentar alguma dificuldade relacionada a TLS, principalmente se estiver apenas testando, para resolver isso basta executar: unset DOCKER_TLS_VERIFY, com isso não será verificado se os hosts possuem acesso via TLS ativado.

Para administrar seu cluster (criar containers, etc) basta utilizar o IP e Porta do Swarm Manage, dessa forma:

$ docker -H tcp://<manager_ip:manager_port> info 
$ docker -H tcp://<manager_ip:manager_port> run ... 
$ docker -H tcp://<manager_ip:manager_port> ps 

Para listar os nós que fazem parte do cluster, bata utilizar o comando abaixo:

$ docker run --rm swarm list token://4765653423fdecsdfe875954a6e2h78ed
172.31.0.1:2375 
172.31.0.2:2375 
172.31.0.3:2375

 

É claro que isso é apenas o início, tendo o cluster montado é possível criar filtros de identificação por tipo de serviço, isso é muito útil para criar containers com o mesmo tipo de serviço em um mesmo local sem a necessidade de saber onde. Mas isso é história para um próximo post

Fique atento as novidades do Blog, e ajude divulgando o mundodocker.com.br.

Abraço!

 

Docker Bench Security

Eai pessoal!

Os engenheiros do Docker disponibilizaram uma ferramenta para testes básicos de segurança para o ambiente Docker. Essa ferramenta nada mais é do que um container que executa um script e verifica se as melhores práticas e recomendações de segurança foram seguidas na instalação e configuração do serviço do Docker. Para executar rode o comando:

docker run -it --net host --pid host --cap-add audit_control -v /var/lib:/var/lib -v /var/run/docker.sock:/var/run/docker.sock -v /usr/lib/systemd:/usr/lib/systemd -v /etc:/etc --label docker_bench_security docker/docker-bench-security

Este comando retornará algo parecido com:

BenchDocker

Que é um report sobre como está seu ambiente, a cada procedimento para correção das falhas indicadas por este relatório, você deverá executar novamente o comando, pois ele analisará se a correção surtiu efeito ou não.

Lembrando que é recomendado que você execute esse container na versão 1.6 em diante do Docker.

Todos os testes realizados por esse script foram criados baseados em um estudo realizado pelo CISecurity (Center Of Internet Security), que indicam quais seriam as melhores formas de se proteger e aumentar a segurança de seu ambiente Docker.

Espero que tenha sido útil, tendo dúvidas ou precisando de ajuda para resolver algum ponto nos avise, e ajude divulgando o mundodocker.com.br!

 

Referências:

https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.0.pdf

https://github.com/docker/docker-bench-security

Understanding Docker Security and Best Practices

Utilizando API com Docker

Olá pessoal!

Hoje vamos mostrar como realizar as operações mais básicas do Docker através da API dele. Vamos ver como iniciar, parar, criar, excluir e coletar informações de containers através da API. Estarei utilizando a distribuição CentOS 7 em meu host onde vou criar os containers.

– Como habilito a API?

vim /etc/systemd/system/docker.service 

//Vamos alterar a linha que contém ExecStart=/usr/local/bin/docker -d -H fd:// por essa

ExecStart=/usr/local/bin/docker -d -H fd:// -H 0.0.0.0:4243

service docker restart

Agora estamos com nossa API habilitada e escutando na porta 4243.

– Iniciar

curl -X POST http://IPHost:4243/containers/IDContainer/start

– Parar

curl -X POST http://IPHost:4243/containers/IDContainer/stop

– Excluir

curl -X DELETE http://IPHost:4243/containers/IDContainer

– Criar

curl -X POST -H "Content-Type: application/json" http://IpHost:4243/containers/create -d '{
"Hostname":"",
   "User":"",
   "Memory":0,
   "MemorySwap":0,
   "AttachStdin":false,
   "AttachStdout":true,
   "AttachStderr":true,
   "PortSpecs":null,
   "Privileged":false,
   "Tty":false,
   "OpenStdin":false,
   "StdinOnce":false,
   "Env":null,
   "Dns":null,
   "Image":"busybox",
   "WorkingDir":""
}'

– Renomear

curl -X GET http://IPHost:4243/containers/IDContainer/rename?name=novo_nome

– Exibir containers que estão iniciado

curl -X GET http://IPHost:4243/containers/json

– Exibir todos os containers

curl -X GET http://IPHost:4243/containers/json?all=1

– Top

curl -X GET http://IPHost:4243/containers/IDContainer/top

– Stats

curl -X GET http://IPHost:4243/containers/IDContainer/stats

– Images

curl -X GET http://IPHost:4243/images/json?all=0

Por hoje era isso, fiquem atentos para as novidades e ajude divulgando o mundodocker.com.br!

Coleta de métricas no Docker Swarm

Oi Pessoal!

Queremos trazer para vocês hoje uma solução para coleta e visualização de métricas para o Docker Swarm. Um dos maiores desafios, principalmente para as equipes de operações, é saber quanto está sendo utilizado por cada container, OK, existem soluções na engine do Docker, como é o caso do docker stats, mas e quando você tem um diversos hosts, e eles estão em cluster e não tem definido quais containers estão em cada host, complicou né?

A intenção com este post é mostrar como é possível ter, de forma fácil, todas as informações de consumo de seu cluster, utilizando soluções simples, e que a maioria de vocês já deve ter visto. Para este lab vamos usar o Cadvisor, Influxdb e Grafana, vamos entender melhor onde cada um irá atuar neste ambiente.

Cadvisor

Como já vimos aqui no blog, o Cadvisor é uma ferramenta desenvolvida justamente para realizar a coleta de recursos de containers/aplicações dentro de um servidor. É possível estender seu uso através de integração com a API que essa ferramenta disponibiliza, e enviar os dados coletados para diversos backends, em nosso lab vamos utilizar o InfluxDB, que você verá logo abaixo o que é e como funciona.

 

InfluxDB

Para quem não conhece, o InfluxDB faz parte de um conjunto de soluções da empresa InfluxData, que tem seus produtos voltadas para analise, monitoramento e armazenamento de informações cronológicas. O InfluxDB é conhecido como um data series database, que serve justamente para armazenar dados em ordem cronológica.

 

Grafana

O Grafana talvez seja uma das mais completas ferramentas para criação e exibição de gráficos, e uma ferramenta extremamente flexível e adaptável, tendo como input diversos tipos de backend, o que facilita ainda mais o nosso lab 😉 . Você pode inclusive ter mais datasources e montar o seu dashboard unindo todas as essas informações, bacana né?

 

Ok, teoria é muito bonita, mas… vamos praticar?

Primeiramente você deve ter em execução o seu cluster, caso não tenha feito isso ainda, faça agora, caso tenha dúvidas, veja este post, onde mostramos na prática como fazer isso 🙂 . Certo agora vamos criar os serviços de coleta para o nosso cluster, para isso, você pode executar o seguinte passo-a-passo:

  •  Crie uma rede do tipo overlay para que seja possível a comunicação entra as ferramentas, e que essa comunicação seja realizada de forma isolada:
$ docker network create -d overlay --attachable coleta
  • Em um dos dos hosts (de preferência o menos utilizado), crie o servidor de Influx, que será utilizado como backend para as informações coletadas:
$ docker run -d --restart=always -v /data:/var/lib/influxdb --network coleta --name influx influxdb
  • Devemos criar a database dentro do influx para que seja possível salvar as informações:
$ docker exec -it influx influx -execute 'CREATE DATABASE cadvisor'
  • Ok, agora basta criar o serviço de coleta no cluster:
$ docker service create --name agentes --network coleta --mode global --mount type=bind,source=/,destination=/rootfs,readonly=true --mount type=bind,source=/var/run,destination=/var/run  --mount type=bind,source=/sys,destination=/sys,readonly=true  --mount type=bind,source=/var/lib/docker,destination=/var/lib/docker,readonly=true google/cadvisor -logtostderr -docker_only -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influx:8086

Se tudo correu bem, você deve terá criado um serviço do tipo global, ou seja, cada host de seu cluster terá um container desse tipo (Cadvisor), e todos eles enviarão os dados para o banco influx. Para ter certeza de que tudo correu bem, você pode executar o comando:

$ docker service ls

Dessa forma você visualizará os serviços que estão em execução, e terá ter certeza de que os containers iniciaram em todos os nós, o retorno do comando deverá ser algo parecido com isso:

$ docker service ls
ID           NAME    MODE   REPLICAS IMAGE                  PORTS
5ras37n3iyu2 agentes global 2/2      google/cadvisor:latest

Viu, tudo certo 🙂 Mas ainda não acabou, continuando:

  • A última etapa é subir nosso serviço de Grafana para podermos visualizar as informações que foram coletadas pelo Cadvisor, e armazenadas no InfluxDB, execute:
$ docker run -d --restart=always -v /data:/var/lib/grafana --network coleta --name grafana -p 80:3000 grafana/grafana

Simples né? Agora temos que acessar a interface do Grafana para podemos configurar e termos os gráficos que desejamos, acesse: http://ip-do-host/login, você visualizará a interface de acesso dele, como ilustrado abaixo:

Os dados de acesso default do Grafana são:

User: admin
Password: admin

Estando dentro da interface do Grafana, vá até “Source” e adicione uma nova fonte de dados, nela informe “InfluxDB”, conforme imagem abaixo:

Após clique em “save & test” para validar o acesso ao seu InfluxDB. Se tudo ocorrer conforme o planejado, você terá sucesso nessa adição, e em seguida deverá montar o gráfico baseado nas informações que estão no banco, para isso existem duas formas, uma mais complexa onde você precisará montar as querys e depois criar o gráfico com essas querys, ou importar um template pronto para isso, e neste caso eu agradeço ao Hanzel Jesheen, pela contribuição a comunidade, em ter criado o template e disponibilizado em seu github . Você pode baixar este arquivo, salvar em seu computador e depois ir até a área de Dashboard de seu Grafana e clicar em import, informe o caminho de onde salvou o template, escolha o source criado anteriormente e depois clique em “import”, conforme imagem abaixo:

Parabéns! Você acaba de montar seu sistema de coleta e visualização de recursos para todo o seu cluster! Indo até Dashboards – Cadvisor você terá uma visualização parecida com esta:

Bacana não?

A partir desse protótipo você pode evoluir seu ambiente para atender a sua demanda, em nosso lab a coleta é realizada pelo Cadvisor e enviada ao InfluxDB a cada 60 segundos, isso quer dizer que o gráfico tem um delay de 1 minuto entre a coleta e a visualização, para alguns isso é problema, para outros não. Outro ponto que você deve se atentar é: Quantos mais containers você tiver, mais poluído ficará o seu gráfico, isso por motivos óbvios, então talvez você precisa alterar o layout do dashboard. Ahhh não esqueça de trocar a senha do usuário admin do Grafana

Por hoje era isso gente, esperamos que isso ajude vocês, e continuaremos com alguns posts mais técnicos trazendo alguns soluções ou implementações legais utilizando Docker. Nos ajude divulgando o blog, e tendo dúvida nos avise!

Grande abraço!