Docker – Device mapper

Olá pessoal,

No primeiro post da série falamos sobre AUFS e hoje vamos falar um pouco sobre Device Mapper.

Origem

No começo o Docker era suportado apenas em distribuições Ubuntu, Debian e usavam AUFS para o seu armazenamento. Depois de algum tempo o Docker começou a se popularizar e as pessoas começaram a querer utilizar Docker com RedHat, porêm o AUFS era suportado apenas em sistemas (Debian,Ubuntu).

Então os engenheiros da Redhat baseados no código do AUFS decidiram desenvolver uma tecnologia própria de armazenamento baseado no já existente “Device mapper”. Então os engenheiros da RedHat colaboraram com o “Docker inc” para contribuir com um novo driver de armazenamento para containers. Então o Docker foi reprojetado para fazer a conexão automática com o dispositivo de armazenamento baseado em Device Mapper.

Layers

O Device Mapper armazena cada imagem e container em seu disco virtual, esses discos virtuais são dispositivos do tipo Copy-on-Write no nível de bloco e não a nível de arquivo. Isso significa que ao invés do Device Mapper copiar todo um arquivo para o seu dispositivo, ele vai copiando por blocos o que o torna muito rápido comparado ao AUFS. No processo de criação de uma imagem com o Device Mapper é criado um pool e em cima desse pool é criado um dispositivo base que é a partir dele que as imagens são construídas, a partir dai temos as imagens base do Docker que a cada modificação vão criando camadas de snapshots a cima da camada anterior. Conforme a imagem abaixo:

https://docs.docker.com/engine/userguide/storagedriver/images/two_dm_container.jpg

Read

Quando um container deseja ler algum arquivo que está nas camadas anteriores o Device Mapper cria um ponteiro na camada do container referenciando a camada da imagem onde possui esses dados colocando transferindo esse bloco para a memória do container.

Write

Quando o Docker faz uma alteração no arquivo utilizando Device Mapper esse arquivo é copiado apenas o que sera modificado cada bloco de modificação copiado é de no máximo 64KB. Por exemplo na escrita de um arquivo de 40KB de novos dados para o container o Device Mapper aloca um único bloco de 64KB para o container, caso a escrita seja de um arquivo maior que 64KB então o Device Mapper aloca mais blocos para realizar essa gravação.

O Device Mapper já é padrão nas em algumas distribuições do linux como:

  • RedHat/Centos/Fedora
  • Ubuntu 12.04 e 14.04
  • Debian

Docker e Device Mapper

O Device Mapper atribui novos blocos para um container por meio de uma operação chamada “Allocate-on-Demand”, isso significa que cada vez que uma aplicação for gravar em algum lugar novo dentro do container, um ou mais blocos vazios dependendo do tamanho de gravação terão que ser localizados a partir do pool mapeado para esse container. Como os blocos são de 64KB então muitas gravações pequenas podem sofrer com problemas de performance, pois acaba causando lentidões nas operações. Com isso aplicações que gravam arquivos pequenos sequencialmente podem ter performance piores com Device Mapper do que com AUFS.

Legal né? Se gostou nos ajude divulgando o blog.

Grande abraço!

 

Docker – AUFS

Olá pessoal,

AUFS foi o primeiro controlador de armazenamento em uso com Docker, como beneficio tem uma história longa com Docker. É muito estável, tem grandes implementações no mundo real e possui forte apoio da comunidade, o AUFS possui diversas características que acabam o tornando uma boa escolha para uso com Docker. Entre elas estão:

  • Tempo de inicialização do container rápido
  • Uso eficiente de armazenamento
  • Uso eficiente de memória

Apesar de ter uma ampla capacidade de caracteristicas com Docker, algumas distribuições não possuem suporte ao AUFS, pois ele não está incluído na linha principal do Kernel Linux, no caso do RHEL não é suporte AUFS.

Os tópicos seguintes demonstram algumas características do AUFS e como ele se relaciona com o Docker:

 

Layers de Imagens:

AUFS é um sistema de unificação de arquivos, isso quer dizer que ele leva vários diretórios em um único host linux, colocando um sobre o outro e fornece uma visão unificada desses arquivos para conseguir isso o AUFS usa uma união de montagem.

O AUFS driver de storage do Docker implementa Layers de imagens utilizando usando a união do sistema montado. Abaixo podemos ver um exemplo de Layers, onde para o cliente é apresentado a união de todas elas:

 

layer1

 

Utilizando arquivos:

O Docker utiliza a tecnologia de “AUFS CoW”  para conseguir compartilhar a imagem e minimizar o uso de disco. Como o AUFS trabalha em nível de arquivos então todos os dados são copiados por inteiros para a camada superior mesmo que modificando uma pequena parte do arquivo, isso faz com que dependendo do tamanho de arquivo que será copiado acabe penalizando um pouco o desempenho do container, pois um arquivo muito grande demorará algum tempo para que seja copiado. Ou também a imagem possui uma grande quantidade de camadas e o arquivo que você deseja utilizar está na primeira camada da imagem.

A ordem de procura é de cima para baixo, então caso seja a primeira vez que o usuário irá utilizar aquele arquivo, então o Docker vai procurar esse arquivo nas suas camadas abaixo e copiar todo o seu conteúdo para a camada gravável do container. Porém o arquivo só é copiado na primeira vez, após isso o esse arquivo já está na ultima camada então todas as demais operações são rápidas.

Deletando arquivos:

O driver do AUFS exclui um arquivo de dentro do container colocando um arquivo whiteout na camada gravável do container. O arquivo whiteout obscurece a existência do arquivo nas camadas inferiores de imagem:

 

 

layers2

 

 

Você pode adicionar o driver AUFS no seu daemon docker editando o arquivo de conf do docker e adicionando:

DOCKER_OPTS="--storage-driver=aufs"
systemctl restart docker

 

Então ta pessoal esse é nosso primeiro post dessa série que vai mostrar para vocês os drivers de armazenamento nativos do Docker.

 

Docker Overlay

Oi Pessoal,

Como vimos nesse post, é possível utilizar plugins diversos para resolver o desafio da rede, e mostramos nesse post um pouco da teoria de como usar o driver de overlay, hoje queremos mostrar isso na prática, e para isso, nada melhor do que colocar a mão na massa, certo?  Claro, mas antes precisamos entender um pouco de teoria, e lá vamos nós.

Se você estiver utilizando o Swarm, não é necessário configurar um serviço de chave-valor externo, pois o próprio Swarm faz o controle e persistência das informações de rede que você utiliza. E você deve ter cuidado, pois se quiser utilizar o Overlay com um serviço externo de chave-valor, o modo de cluster via Swarm fica impossibilitado.

Veja abaixo uma tabela com algumas informações relevantes sobre o funcionamento do Overlay:

ProtocoloPortaDescrição
udp4789Data plane (VXLAN)
tcp/udp7946Control plane

Ou seja, você deve cuidar para que em seus firewalls essas portas estejam liberadas, caso contrario a comunicação entre os nós não ocorrerá, o que impossibilitará o funcionando do Overlay.

Veja abaixo os principais parâmetros que você deve ter atenção:

OpçãoDescrição
--cluster-store=PROVIDER://URL
Endereço do seu servidor/serviço de chave-valor
--cluster-advertise=HOST_IP|HOST_IFACE:PORT
IP ou interface do host que será utilizado para comunicação do cluster
--cluster-store-opt=KEY-VALUE OPTIONS
Configuração opicional, onde é possível definir regras de monitoramento dos hosts e validação TLS

Ok Cristiano, entendi tudo isso, mas como vamos testar, qual será o ambiente de laboratório que vamos seguir? Vamos lá, para exemplificar como será o ambiente que vamos montar, segue abaixo uma imagem onde ilustra o funcionamento do Docker com o serviço de chave-valor, todos os hosts consultam esse serviço para identificar quais redes existem e qual bloco/ip deve ser alocado por container. Veja:

Engine on each host

Vamos colocar a mão na massa?

Dependências/Configuração

Você deve ter um serviço de chave valor, no qual o Docker persistirá as informações de rede que você criar, em nosso lab utilizamos o Consul dentro de um container Docker, rodando em um server a parte dos que participarão do ambiente multi-host, para isso executamos:

[root@consul ~]# docker run -d  -p "8500:8500"  -h "consul"  progrium/consul -server -bootstrap

Dessa forma iniciamos um container com Consul, mapeando a porta 8500 do host para o container, ou seja, para ter acesso ao serviço do Consul basta acessar ip-do-host:8500. Agora vamos ao nosso ambiente de Docker.

Nos hosts de Docker (obviamente você já tem o Docker instalado, mas se quiser saber como instalar, veja esse post 😉 ) você precisará configurar o daemon para consultar o Consul e buscar as informações de rede, em nosso laboratório utilizamos o CentOS, com isso, o arquivo a ser modificado é o: /lib/systemd/system/docker.service, e deixamos da seguinte forma:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --cluster-advertise=eth0:2376 --cluster-store=consul://ip-do-consul:8500
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target

Feito isso, basta reiniciar o serviço e seguirmos para o próximo passo.

Utilização/Testes

Agora que você já definiu um serviço de chave-valor a ser consultado, basta você criar a sua rede com o driver Overlay, para isso:

[root@docker01 ~]# docker network create --driver overlay rede1

Você pode definir ainda qual o bloco de ip que deseja para essa rede, caso não faça essa definição, o Docker associará um bloco automaticamente para você. Fácil certo? Basta testarmos, para isso vamos validar em todos os hosts se ambos estão visualizando a mesma rede, execute esse comando em qualquer outro host:

[root@docker01 ~]# docker network ls

Será retornando algo como isso:

NETWORK ID          NAME                DRIVER
64507d0be843f        rede1               overlay
d0bdae8fbe7bd        bridge              bridge
1c0eb8f68962d        none                null
3412c2496d0eb        host                host
697102a22e8d2        docker_gwbridge     bridge

 Vamos utilizar essa rede, crie os containers em pelo menos 2 hosts, informando essa nova rede, veja:

[root@docker01 ~]# docker run -it --net=rede1 centos /bin/bash

Agora basta pingar ou acessar os serviços entre os containers que estão nessa mesma rede.

Dessa forma você pode definir uma rede diferente por grupo de containers, e pode ainda isolar essas redes utilizando o método VXLAN, para isso deve passar como parâmetro na criação da rede o seguinte argumento: –opt “com.docker.network.driver.overlay.vxlanid_list=257″, esse parâmetro fará com que essa rede receba uma vlan, ou seja, todo o trafego direcionado a essa rede receberá uma identificação, impossibilitando que outros containers que não estejam nessa vlan tenha acesso a esse trafego. 

Legal né? Se gostou nos ajude divulgando o blog.

Grande abraço!

Auto Complete para Docker

Olá!

Hoje o post será um pouco diferente dos que geralmente publicamos, queremos mostrar para vocês como é possível utilizar a funcionalidade de auto complete do shell para os comandos Docker. Mas para que isso? Simples, facilidade e agilidade na execução de comandos, quem aqui nunca apertou o tab depois de digitar ‘./conf’? Então, você deve sentir falta dessa facilidade quando se utiliza os subcomandos do docker, certo? Queremos mostrar pra vocês como resolver isso.

Como você já viu aqui, existem diversos subcomandos do docker, e cada um possui diversos parâmetros que podem ser utilizados, com o docker –help você poderá visualizar as opções disponíveis.

Mas isso é chato algumas vezes, é mais fácil começar a digitar docker run --vol...[tab][tab]e deixar o autocomplete fazer o trabalho:

$ docker run --volume
--volume         --volume-driver  --volumes-from

#vamosinstalar?

No Mac OS X

O processo é simples, estando no Mac OS X temos que instalar o auto completion usando o brew:

$ brew install bash-completion

E em seguida adicionar as linhas em nosso arquivo de profile ($HOME/.bash_profile ou /Users//.bash_profile)

if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi

Você pode executar os seguintes comandos, que devem ser utilizados nesta sequência:

$ echo "if [ -f $(brew --prefix)/etc/bash_completion ]; then" | tee -a $HOME/.bash_profile
$ echo "    . $(brew --prefix)/etc/bash_completion" | tee -a $HOME/.bash_profile
$ echo "fi" | tee -a $HOME/.bash_profile

Atenção: Se não temos o homebrew instalado, veja em http://brew.sh/ mais informações de como instala-lo e utiliza-lo.

 
No Linux

No Linux, como sempre, é mais simples, basta instalar via gerenciador de pacotes da sua distribuição. Se for Debian like (Ubuntu, Mint, etc) usamos o apt-get:

$ sudo apt-get install bash-completion

Se for Red Hat like (RHEL, CentOS, Fedora, etc) então usamos yum:

$ sudo yum install bash-completion

Completion do Docker Engine

O arquivo está disponível em https://github.com/docker/docker/blob/master/contrib/completion/bash/docker portanto sempre que fizer uma atualização é recomendável que você baixe novamente esse arquivo para refletir os comandos e parâmetros novos disponibilizados pelo Docker.

Ao baixar devemos colocá-lo na pasta /etc/bash_completion.d/ se estivermos no Linux, se estivermos em um Mac OS X:  $(brew --prefix)/etc/bash_completion.d.

No Mac OS X
$ curl -L https://raw.githubusercontent.com/docker/docker/master/contrib/completion/bash/docker > $(brew --prefix)/etc/bash_completion.d/docker
No Linux
$ curl -L https://raw.githubusercontent.com/docker/docker/master/contrib/completion/bash/docker > /etc/bash_completion.d/docker

Completion do Docker Compose

De maneira similar o arquivo está disponível emhttps://github.com/docker/compose/blob/master/contrib/completion/bash/docker-compose . Reforçamos que sempre que fizer uma atualização é bom baixar novamente esse arquivo para refletir os comandos e parâmetros novos disponibilizados pelo Docker Compose.

Ao baixar também devemos colocá-lo na pasta /etc/bash_completion.d/ se estivermos no Linux ou devemos acrescentar a pasta do homebrew antes se estivermos em um Mac OS X: $(brew --prefix)/etc/bash_completion.d.

No Mac OS X
$ curl -L https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose > $(brew --prefix)/etc/bash_completion.d/docker-compose
No Linux
$ curl -L https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

Completion do Docker Machine

O processo é praticamente o mesmo porém o docker-machine possui 3 arquivos de auto complete. Os arquivos estão disponíveis em https://github.com/docker/machine/tree/master/contrib/completion/bash .

Como dito anteriormente devemos colocá-los na pasta /etc/bash_completion.d/ se estivermos no Linux ou devemos acrescentar a pasta do homebrew antes se estivermos em um Mac OS X: $(brew --prefix)/etc/bash_completion.d.

Como são mais arquivos recomendo utilizarmos um loop para baixarmos todos em sequência utilizando apenas um comando.

No Mac OS X
machineVersion=`docker-machine --version | tr -ds ',' ' ' | awk 'NR==1{print $(3)}'`
files=(docker-machine docker-machine-wrapper docker-machine-prompt)
for file in "${files[@]}"; do
  curl -L https://raw.githubusercontent.com/docker/machine/v$machineVersion/contrib/completion/bash/$file.bash > `brew --prefix`/etc/bash_completion.d/$file
done
unset machineVersion
No Linux
machineVersion=`docker-machine --version | tr -ds ',' ' ' | awk 'NR==1{print $(3)}'`
files=(docker-machine docker-machine-wrapper docker-machine-prompt)
for file in "${files[@]}"; do
  curl -L https://raw.githubusercontent.com/docker/machine/v$machineVersion/contrib/completion/bash/$file.bash > /etc/bash_completion.d/$file
done
unset machineVersion

Observe que:

  1. Se você utilizar alguma versão específica de uma dessas ferramentas basta baixar os arquivos da pasta correspondente.  Por exemplo o docker engine, da maneira que mostramos vamos pegar o arquivo que está na branch master, atualmente versão 1.12.1, para pegar na versão 1.11.0 por exemplo o arquivo fica em https://github.com/docker/docker/blob/v1.11.0/contrib/completion/bash/docker
  2. O Docker disponibiliza alguns arquivos de completion para outros shells. O Docker Engine disponibiliza bash, zsh, fish e powershell como podemos ver em https://github.com/docker/docker/tree/master/contrib/completion .
  3. O Docker Compose e o Docker Machine disponibilizam apenas para bash e zshcomo vemos nas urls https://github.com/docker/compose/tree/master/contrib/completionhttps://github.com/docker/machine/tree/master/contrib/completion .

E era isso por hoje pessoal, agradecimento especial ao @wsilva pela dica. Já sabe, ajude divulgando o blog, e tendo dúvidas ou sugestões deixa ai nos comentários 😉

Abraço!

Fonte: http://dumpscerebrais.com/2016/09/auto-complete-para-docker-engine-machine-e-compose/

Troubleshooting e dicas de Docker

Olá pessoal,

Já faz mais de 1 ano que criamos esse blog e hoje resolvemos fazer um post referente a como solucionar algumas dificuldades e problemas que tivemos no começo, visto que trabalhamos a mais de 2 anos já com Docker, tivemos muitos problemas que queremos demonstrar para vocês.

Instalando a versão mais recente

A maioria das pessoas que acabam por usar Ubuntu, Centos, RedHat ou qualquer outra distribuição utiliza seus próprios comandos para realizar a instalação do Docker, com yum ou apt-get. Mas a forma de utilizar as versões mais recentes são essas:

Versão oficial para se utilizar em produção:

curl -sSL https://get.docker.com/ | sh

Versão que se encontra ainda em fase de testes:

curl -fsSL https://test.docker.com/ | sh

Versão alpha que está em constante desenvolvimento:

curl -fsSL https://experimental.docker.com/ | sh

 Como remover todos os containers parados:

docker rm $(docker ps -a -q)

 Sincronizar o relógio do host com o container:

Isso é um dos principais problemas que as pessoas acabam encontrando as vezes.

Para Centos (Na hora de criar o container mapeia o diretório do host com o do container)

docker run -v /etc/localtime:/etc/localtime:ro centos date

Para Ubuntu (Na hora da criar o container passa como variável o timezone(tz)

docker run -e "TZ=America/Salvador" ubuntu date

 Comunicação entre containers:

Por padrão no Docker a comunicação entre os containers na mesma rede é liberado através de IP interno. Mas caso você queira que os containers não se comuniquem diretamente basta mudar na hora da criação da rede colocar icc=false.

docker network create -o com.docker.network.bridge.enable_icc=false rede_isolada

Montando volumes com services:

Quando criamos um container simples com docker run, existe a opção do -v onde podemos passar como parâmetro o nosso volume, porém com a implementação do services no Docker 1.12 ficou um pouco mais complicado na hora de passar um volume para o serviço:

Como você pode ver na opção “type” temos o “bind” que seria um diretório em nosso host:

docker service create --mount type=bind,source=/diretoriohost,target=/diretoriocontainer imagem

E também temos a opção volume que é passado o volume que é criado com “docker volume create…..

docker service create --mount type=volume,source=meuvolume,target=/diretoriocontainer imagem

 Docker commit e volume:

O comando “docker commit” gera uma imagem do nosso container, porém ele NÃO vai armazenar os dados do volume que estão atrelados a aquele container. Então o docker commit não irá servir de backup para os seus dados que estão no volume.

Não rode containers com –privileged

Com a opção de –privileged o container consegue facilmente acessar diversas áreas do seu host na qual podem ser cruciais caso alguém ache alguma brecha de segurança em sua aplicação.

Um processo para cada container.

Não instale pacotes desnecessários em seus containers, se você quer ter um container para apache, só instale o apache nele. Quer ter o PHP também? então suba outro container.

Cuidado com as regras de IPTABLES

Como o Docker trabalha com toda a sua parte de redes através de iptables, é bem provável que se você fizer alguma manutenção em seu firewall e editar alguma regra errada, toda a sua estrutura de Docker pode parar de funcionar por algum problema.

Coloque o diretório do docker em outro disco:

O docker utiliza o caminho “/var/lib/docker” para colocar todos os seus arquivos de instalação e também toda a sua estrutura de containers, volumes e mais outros recursos que ele utiliza. Então não deixe esse diretório no mesmo disco do seu SO.

Gostaram do post? Deixe seu feedback e novamente, nos ajudem divulgando o blog.

Grande abraço!

Docker Service

Oi Pessoal,

Hoje queremos trazer em detalhes para vocês uma das features implementadas no Docker 1.12 (que foi lançado no último dia 29), e que já mencionamos aqui, que é o Docker Service. Para quem ainda não leu o nosso post sobre as novidades do Docker 1.12, o Docker Service é uma feature que foi incorporada pela engine Docker em sua última versão e que permite ao administrador criar e administrar sua stack de serviço dentro de um cluster Swarm, sem precisar utilizar uma segunda ferramenta para isso. Ela é parte integrante de uma série de melhorias que permitiram ao Docker 1.12 ter a camada de orquestração nativa em sua engine.

Mas afinal, como isso me ajuda? Bem, nas versões anteriores do Docker, para você ter algum tipo de orquestração você teria que utilizar uma série de ferramentas, como por exemplo: Docker Swarm, Docker Compose isso sem falar, que, se você quisesse provisionar isso em larga escala mesmo, o recomendado era utilizar Kubernetes, Mesos ou alguma outra forma de orquestração mais adequada. Agora está tudo dentro da própria engine do Docker, o que permite você ter maior controle sob o que está utilizando, e claro, permite você manipular esse ambiente de forma mais simples.

Para serviço especificamente, foi adicionado o sub-comando: docker service, e dentro dele alguns itens, veja:

  1. docker service create: Possibilita a criação de sua stack de serviço, é ele o que você mais vai ver hoje ;)
  2. docker service inspect: Verifica as informações sobre seu serviço e retorna informações sobre parametro utilizados para inicialização do mesmo, imagem utilizada, etc.
  3. docker service ls: Lista todos os serviços que você tem criado, e lhe retorna informações sobre nome, quantidade de replicas, etc.
  4. docker service rm: Remove o serviço desejado do cluster
  5. docker service ps: 2° comando mais útil, retorna para você o status de cada container que atende um serviço, é muito parecido com o docker ps, com a diferença de lhe trazer apenas informações sobre os container que fazem parte de um serviço criado, você pode ainda utilizar filtros para ter um retorno mais simplificado.
  6. docker service scale: Com o scale é possível realizar o escalonamento de seu serviço, é possível você aumentar a quantidade de containers que atenderão o seu serviço.
  7. docker service update: Comando que lhe permite realizar modificações no serviço criado, através dele é possível modificar informações sobre quantidade de memória, cpu, dentre muitas outras coisas em seu serviço.

Tudo certo com a teoria? Então vamos a prática :), nosso problema: Queremos criar uma stack para nosso ElasticSearch, nosso objetivo é escalar esse ambiente quantas vezes eu quiser e atualiza-lo de forma consistente.

Primeiro temos que criar nosso service:

docker service create --replicas 1 --update-delay 10s --update-parallelism 1 --name elasticsearch elasticsearch

O que isso quer dizer? Vamos lá:

  • Replicas – Número de containers que eu quero criar nesse momento, deve ser no mínimo um (por motivos óbvios);
  • Update-delay – Quando for realizado uma procedimento de atualização do ambiente, qual será a cadência de atualização dos containers.
  • Update-parallelism – Quantidade de containers que desejamos atualizar por vez
  • Name – Nome do serviço e por último a imagem que vamos utilizar para esse serviço.

O retorno do comando será algo parecido com isso:

docker-service1

Certo, meu serviço está criado, como escalono ele agora? Fácil, olha o print 🙂

docker-service2

Note que para escalar, basta executar o comando: docker service scale $(seu-servico)=numero. Agora vamos atualizar o nosso ambiente, certo? Muito fácil, basta executar o comando: docker service update, com ele é possível modificar diversos atributos do serviço, como por exemplo: Portas publicadas, limites de recursos, número de replicas, imagem, politica de escalonamento, etc.

Em nosso exemplo vamos atualizar a imagem que nosso serviço utiliza, veja que quando criamos, a imagem utilizada era a elasticsearch:latest, agora queremos testar a última versão do elasticsearch, que está em alpha (no dia da criação desse post) que é a 5.0, para isso basta executar: docker service update –image elasticsearch:5.0 elasticsearch, veja o que aconteceu:

docker-service3

Veja que nosso serviço não foi atualizado de uma vez só, esse processo foi sendo realizado conforme os containers iam sendo atualizados, isso devido a nossa politica de update que definimos na criação do serviço. Com o update você pode realizar diversas ações, veja mais em: docker service update –help, ele lhe mostrará todas as opções disponíveis.

Como removemos um serviço? Bem, você já deve ter imaginado como: docker service rm nome_do_servico.

Ahh, você se lembra que falamos aqui que no Docker 1.12 era possível criar um serviço distribuído dentro Swarm e acessá-lo de qualquer lugar? Pois bem, quando você criar um serviço você pode especificar qual será a porta publica dele, no exemplo acima não utilizamos isso, mas você pode definir (através do parâmetro -p) que a porta 8080 seja a porta de seu serviço, com isso todo o trafego enviado para a porta 8080 nos ips de seus nós do cluster de Swarm será redirecionado para os containers que atendam esse serviço. Lembrando que para você criar um serviço distribuído é necessário ter um cluster de Swarm ativo.

Gostaram do post? Deixe seu feedback e novamente, nos ajudem divulgando o blog.

Grande abraço!

 

Docker e Jenkins para build de aplicações

Olá pessoal,

Hoje queremos demonstrar para vocês como podemos utilizar Docker e Jenkins para o build de aplicações de forma rápida e fácil, primeiro vamos entender como é o ambiente de diversas empresas de TI hoje e você que estiver lendo este post possivelmente estará se identificando com isso.

Hoje diversas empresas utilizam a ferramenta Jenkins para build e deploy de aplicações, muitas vezes (Se não forem todas) essa maquina de Jenkins é compartilhada entre diversos times, Java, PHP, Python, Rails e NodeJS acabam utilizando. O que deixa essa máquina com ferramentas desnecessárias para as equipes, sobrecarregando o sistema e qualquer problema acaba parando todas as equipes.

Porém existem alguns casos mais organizados que a maquina onde irá ocorrer o build será uma máquina para cada equipe, o que torna o processo um pouco melhor, porém sempre que sair uma nova versões de softwares alguém precisa ficar atualizando essa máquina, o que pode acabar por muitas vezes impactando em prazos do projeto.

Então existe o que acreditamos que seja a melhor solução que seria a utilização de containers para o build de suas aplicações. mas porque usar containers?

  • Só dependências para aquela aplicação
  • Fácil manutenção
  • Ambiente de produção e local iguais.
  • Escabilidade

Então visto o porque que devemos utilizar containers para realizar o build, vamos mostrar como podemos utilizar essas duas ferramentas em sincronia.

Primeiramente vamos até as configurações do nosso repositório e clicar em “WebHooks & Services:4

Vamos até “Add Service” e adicionar o “Jenkins (Github Plugin)”
5
Agora em nosso servidor com Docker instalado, vamos iniciar o container que terá o Jenkins Master instalado.

############# SERVIDOR1 #################
docker run -p 8080:8080 -p 50000:50000 -d jenkins

Iniciado, agora vamos até o nosso browser e digitar http://ipserver:8080 e vamos fazer a configuração base do Jenkins.

1

Para pegar a senha você irá executar

docker exec idcontainer cat /var/jenkins_home/secrets/initialAdminPassword

Na pŕoxima página você pode escolher a opção de usar os plugins recomendados, então depois irá pedir para você criar um usuário.

2

Feito isso agora estamos na página inicial do jenkins.

3

Esse será nosso servidor de Jenkins Master que sera o responsável por avisar e mandar rodar alguns comandos no nosso servidor onde estará o Docker. Para isso, vamos acessar o servidor 2 e realizar a instalação do Jenkins:

############# SERVIDOR2 #################
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install jenkins -y
sudo yum install java -y 
sudo service jenkins start/stop/restart
sudo chkconfig jenkins on
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload
sudo yum install java-1.7.0-openjdk -y

Após realizar a instalação do servidor2, vamos até o nosso servidor de Jenkins Master e adicionar o outro nó nele, colocando o IP e a forma pela qual o agente fosse instalado: Para isso você deve ir até “Gerenciar Jenkins” >> “Gerenciar nós”

6

Após isso você irá clicar em novo nó, colocar o ip desse novo servidor e clicar na opção de “Permanent” e OK. Após isso irá aparecer algo parecido com a tela abaixo então, você tera que fazer download do slave.jar, ir até o outro servidor e executar o comando do java que é mostrado na imagem abaixo, porem com as suas configurações.

7

Feito isso, vamos até a tela da esquerda na opção de configurações e configurar parecido com a imagem abaixo: A parte mais importante dessa tela é a configuração do “rótulo” que é o apelido que vamos dar a esse servidor, e também o “uso” que estamos dizendo que vamos executar esse servidor apenas como jobs.

8

Agora vamos até a página inicial do nosso jenkins e então criar o nosso build. Vamos até “Novo Build”

9

Após selecionar “Novo Build” vamos até a opção de configuração:

10

Vamos colocar o nome do nosso servidor de slave na opção de “Restringe onde este projeto pode ser executado”

11

Abaixo vamos colocar o nosso caminho do “GitHub” e também de qual branch irá baixar o código.

12

Vamos marcar  a opção de “Build when a change is pushed to github” e também a opção de quanto em quanto tempo vamos ir consultar o nosso “SCM”.

14

Em nosso ultimo passo, vamos colocar os comandos que iremos executar em nosso servidor. Vamos criar uma imagem a partir do Dockerfile que está em nosso GitHub e após isso vamos iniciar o container com essa imagem.

15

Então por hoje era isso pessoal, espero que tenham gostado do post e gostaríamos que vocês interagissem através de comentários propondo novos posts e arquiteturas que vocês gostariam que a gente fizesse com Docker. Em breve teremos mais posts nesse estilo.

Obrigado!

Referências: https://www.docker.com/sites/default/files/RA_CI%20with%20Docker_08.25.2015.pdf

: https://jenkins.io/solutions/docker/

: https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins