Docker e DevOps

Olá pessoal!

Hoje vamos ao post um pouco mais voltado ao conceito e ideias que fazem do Docker uma tecnologia/solução tão inovadora, eficiente e claro popular.

Precisamos entender, antes de tudo, como a vida de um profissional pode ser, primeiro temos o mundo das empresas que adotam o método tradicional de trabalho, nessa empresa o horário é fixo, as decisões demoradas, e geralmente as ideias que você pode ter estão descritas em um manual interno.

Geralmente essas empresas demoram a reagir ao mercado, ou seja, algo novo demora a ser posto em prática, e as mudanças são vistas como um problema.

Temos outro mundo, a de empresas que vêem em mudanças um forma de ganhar espaço no mercado, onde ideias novas e desafios são um requisito para se trabalhar, você é instigado a ver as coisas de uma outra perspectiva, pois deve se manter sempre a frente do que vem em seguida.

Um os grandes entraves em ambas as empresas é a diferenciação que há entre as equipes de desenvolvimento e infra-estrutura, elas não se conversam, e o que uma propõe é um problema para a outra. Isso leva apenas a um lugar: Estagnação, pois não colaboração entre elas para criar ou resolver algo que seja vital para a empresa.

blue devops_4

Felizmente essa percepção está sendo mudada, em seu lugar surgiu um novo conceito de trabalho, que serve para ambas as empresas que mencionei acima, o conceito de DevOps. Mas o que ser isso cacique?

DevOps é uma metodologia, que incentiva uma maior integração entre as diferentes áreas da empresa, ou seja, em vez de cada um fazer uma coisa, as equipes tendem a se integrar em prol de uma objetivo comum, seja um projeto ou a resolução de um problema.

Para que isso seja possível, existem diversas ferramentas que auxiliam o desenvolvimento conjunto de projetos, desde base de conhecimento até orquestração de serviços. É nesse sentido em que o Docker auxilia, tanto o pessoal de Dev, quanto o pessoal de Ops. O Docker permite que o desenvolvedor tenha todo o seu ambiente de desenvolvimento e teste totalmente agnóstico da infraestrutura.  Da mesma forma que permite ao analista de infraestrutura realizar ou configurar o ambiente de produção de uma maneira muito mais segura e eficiente, pois basta replicar o ambiente de homologação (que já foi testado pelo desenvolvedor) no ambiente de produção, e isso sem se preocupar nas diferenças nos ambiente, pois é o mesmo ambiente.

Outro beneficio que o Docker proporciona é a agilidade no deploy das aplicações, pois não é necessário subir uma instância ou instalar um servidor todo apenas para testar algo, basta criar um container e subir sua aplicação.

Nos próximos posts nós iniciaremos alguns tutoriais que explicarão melhor como podemos integrar de forma mais eficiente o Docker a outras ferramentas, permitindo criar um ecossistema completo de desenvolvimento e integra continua, tendo em vista os benefícios tanta para Dev quanto Ops.

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.

O que são Capabilities

Olá!

Hoje vamos ver algumas features de segurança que pertencem não apenas ao Docker, mas sim ao LXC, são as capabilities.

Em sistemas Unix like, há basicamente duas categorias de processos: processos privilegiados, que executam com ID 0 (superusuário) e os não-privilegiados, que executam com ID maior que 0.

Basicamente os processos privilegiados ignoram todas as verificações de permissões de kernel, enquanto os processos não-privilegiados estão sujeitos a algumas checagens para sua correta execução, normalmente: UID efetivo (usuário dono do arquivo/binário, etc), GID efetivos (grupo dono do arquivo/binário, etc) ou lista de grupo suplementar (mais conhecidas como ACL’s – Access Control List).

Do kernel 2.2 em diante o Linux dividiu as formas tradicionais de privilégios associados ao superusuários em unidades diferentes, conhecidas como capacidades, que podem ser habilitadas e desabilitadas independentemente umas das outras. Essas capacidades são atribuídas por thread, ou seja, threads do mesmo processos podem ter suas capacidades de execução modificadas.

 No Docker é possível modificar essas capacidades, habilitando ou desabilitando conforma sua necessidade, vale lembrar que todo container executa de forma não privilegiada, ou seja, ele tem sua execução restrita, quando é adicionada uma capacidade a execução de um container, é dado o privilegio para que o mesmo possa executar alguma ação como root, isso pode ser um problema de segurança, dependendo do seu ambiente.

Vamos ver algumas capacidades que podem ser atribuídas a um container, e que são normalmente utilizadas:

CAP_SETPCAP Modifica capacidades de um processo
CAP_SYS_MODULE Insere ou remove módulos do kernel
CAP_SYS_RAWIO Modifica memória do Kernel
CAP_SYS_PACCT Configura quota de processo
CAP_SYS_NICE Modifica prioridade do processo
CAP_SYS_RESOURCE Sobrescreve os limites de recursos
CAP_SYS_TIME Modifica a hora de sistema
CAP_SYS_TTY_CONFIG Configura interface tty
CAP_AUDIT_WRITE Escreve logs de auditoria
CAP_AUDIT_CONTROL Configura auditoria dos subsistema
CAP_MAC_OVERRIDE Ignora politicas de MC do Kernel
CAP_MAC_ADMIN Configuração de MAC
CAP_SYSLOG Modifica o comportamento de logs
CAP_NET_ADMIN Configura funções de rede
CAP_SYS_ADMIN Possibilita execução totalmente privilegiada.

Agora, para habilitar alguma capacidade (ou CAP) no Docker, pode ser utilizado o parâmetro: –cap-add=NOMEDACAP, algo parecido com isso:

docker run --cap-add=NOMEDACAP -i -t --rm centos /bin/bash

Para remover alguma CAP basta adicionar o parâmetro –drop-cap, ficaria assim:

docker run --cap-add=ALL --cap-drop=NET_ADMIN -i -t --rm centos /bin/bash

Seguindo os parâmetros acima, todas as CAPs serão habilitadas para este container, menos a CAP NET_ADMIN, com isso todas as demais operações serão permitidas ao container, menos as operações de rede, como modificação de ip, configurações de rotas, etc.

Por hoje era isso, fiquem atentos para as novidades!

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.

Administrando um Container

Olá Pessoal!

Hoje vamos fazer algo um pouco mais avançado no Docker, aprenderemos um pouco mais sobre os comandos no Docker, e como podem nos ajudar. Antes vamos definir um plano de ação: Temos um container com Apache dentro, precisamos saber:

1 – Como saber quais containers possuo?

2 – Quais foram os últimos logs desse container?

3 – Em que porta está executando o container?

4 – Que comando tenho que executar para parar e iniciar o container?

5 – Como sei que o container está no ar?

FÁCIL:

Para criar/iniciar um container você pode utilizar o seguinte comando:

docker run -d -p 80:80 httpd

Esse comando fará com que seja iniciado um container utilizando uma imagem pronta do Apache, caso a imagem não seja encontrada localmente, o próprio Docker realizará o download dessa imagem através de seus repositórios oficiais. Ele atribuirá a porta 80 do host para o container, ou seja, quando acesso a porta 80 do host, o que será apresentado é o site que encontra-se dentro do container.

Podemos ainda, mapear uma pasta do host para dentro do container, isso fará com que o container compartilhe com o host uma determinada pasta, veja o comando:

docker run -d -p 80:80 -v /var/www/html:/var/www/html httpd

Por padrão, a pasta mapeada recebe permissão de leitura e escrita, mas é possível fazer com que esse mapeamento seja somente leitura, para isso basta adicionar :ro no final, veja:

docker run -d -p 80:80 -v /var/www/html:/var/www/html:ro httpd

Isso fará com que o container não possa adicionar ou escrever dentro da pasta compartilhada. Agora voltando ao nosso plano de ação, visto que já sabemos como iniciar um container.

1 – Como saber quais containers possuo?

Você pode executar o comando: docker ps -a, isso fará com que seja listado todos os containers que você possui no host onde está sendo executado o comando (ou onde está apontando o Docker Client)

2 – Quais foram os últimos logs desse container?

Na listagem do comando acima, poderá ser visto o id do container, tendo essa informação, basta executar o comando: docker logs containerid . Esse comando retornará na tela os últimos eventos ocorridos dentro do container (mais para frente veremos a diferença nos outputs de logs para um container)

3 – Em que porta está executando o container?

A forma mais simples de saber isso é executando o comando: docker ps, esse comando retornará várias informações dos containers que estão running no momento, entre essas informações podemos capturar em qual porta do host o container está ‘ouvindo’.

4 – Que comando tenho que executar para parar e iniciar o container?

Isso é simples, docker stop e docker start, há opções mais drásticas como docker kill, mas esse último é recomendado apenas em último caso, pois o mesmo fará com que o container seja parado de forma abrupta, podendo causar o corrompimento do filesystem do mesmo.

5 – Como sei que o container está no ar?

O comando docker ps retornará apenas os containers que estão ativos, é claro que apenas isso não quer dizer que sua aplicação/ambiente está funcionando corretamente, um forma de testar isso é acessando seu ambiente de fora, por exemplo, no comando que executamos acima: docker run -d -p 80:80 httpd o mesmo fará com que seja alocado a porta 80 do host para o container, isso quer dizer que caso eu acesse: http://ipdohost estarei acessando na verdade a porta 80 que está dedicada ao container, com isso estarei acessando o site que encontra-se dentro do container, o site acessou? Perfeito, seu container está no ar.

Espero que essas dicas o ajudem a entender um pouco mais o funcionamento de um container, essas são algumas tarefas administrativas que possivelmente serão as mais utilizadas durante o seu convívio com o Docker. Dúvidas, sugestões? nos mande um mensagem e vamos conversando.

Grande Abraço!

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.

O que é Dockerfile

Olá!

Como mencionado neste post, o Docker possui alguns recursos que permitiram sua popularização pelo mundo a fora, além da API de integração, o Docker permite que possamos criar imagens a partir de um arquivo de definição, esse arquivo chama-se Dockerfile.

Vamos lá. Como explicado anteriormente em alguns posts, uma imagem nada mais é do que um ambiente totalmente encapsulado e pronto para ser replicado onde desejar. Podemos montar esse ambiente através de um container que esteja em execução (Exportando o mesmo), ou através da criação a partir do Dockerfile, que nada mais é do que um arquivo de definição onde é possível realizar ou preparar todo ambiente a partir de um script de execução. Em resumo, o Dockerfile é um arquivo texto com instruções, comandos e passos que você executaria manualmente, basicamente o Docker executa uma receita de bolo.

Através do comando docker build, o Docker realizar a execução desses passos e no final da execução ele encapsula cada layer gerada para dentro da imagem. Mas o Dockerfile deve seguir uma ordem ou formatação correta para que o build seja feito de forma certa, por exemplo, o formato do texto deve respeitar: INSTRUÇÃO argumento, onde INSTRUÇÃO é o comando que o build deve executar, e argumento são as instruções que deve fato serão feitas, por exemplo:

RUN yum update

Onde:

RUN: É a instrução;

yum update: Argumento que será executado.

Abaixo podemos visualizar todas as opções de instruções disponíveis:

  • FROM: Informa a partir de qual imagem será gerada a nova imagem, lembrando que em poucos casos (Veremos em posts futuros), uma imagem será gerada se um imagem base;
  • MAINTAINER: Campo opcional, que informa o nome do mantenedor da nova imagem;
  • RUN: Especifica que o argumento seguinte será executado, ou seja, realiza a execução de um comando;
  • CMD: Define um comando a ser executado quando um container baseado nessa imagem for iniciado, esse parâmetro pode ser sobrescrito caso o container seja iniciado utilizando alguma informação de comando, como: docker run -d imagem comando, neste caso o CMD da imagem será sobrescrito pelo comando informado;
  • LABEL: Adiciona metadados a uma imagem, informações adicionais que servirão para identificar versão, tipo de licença, ou host, lembrando que a cada nova instrução LABEL é criada uma nova layer, o Docker recomenda que você não use muitas LABEL. É possível realizar filtragens posteriormente utilizando essas LABEL.
  • EXPOSE: Expõem uma ou mais portas, isso quer dizer que o container quando iniciado poderá ser acessível através dessas portas;
  • ENV: Instrução que cria e atribui um valor para uma variável dentro da imagem, isso é útil para realizar a instalação de alguma aplicação ou configurar um ambiente inteiro.
  • ADD: Adiciona arquivos locais  ou que estejam em uma url, para dentro da imagem.
  • COPY: Copia arquivos ou diretórios locais para dentro da imagem.
  • ENTRYPOINT: Informa qual comando será executado quando um container for iniciado utilizando esta imagem, diferentemente do CMD, o ENTRYPOINT não é sobrescrito, isso quer dizer que este comando será sempre executado.
  • VOLUME: Mapeia um diretório do host para ser acessível pelo container;
  • USER: Define com qual usuário serão executadas as instruções durante a geração da imagem;
  • WORKDIR: Define qual será o diretório de trabalho (lugar onde serão copiados os arquivos, e criadas novas pastas);
  • ONBUILD: Define algumas instruções que podem ser realizadas quando alguma determinada ação for executada, é basicamente como uma trigger.

Veja abaixo um exemplo de Dockerfile completo:


# VERSION 0.1

FROM ubuntu
RUN echo foo > bar
# Saida parecida com ===> 907ad6c2736f

FROM ubuntu
RUN echo moo > oink
# Saida parecida com ===> 695d7793cbe4

EXPOSE 5900

# Você terá duas imagens, 907ad6c2736f com /bar, e 695d7793cbe4 com
# /oink.


Basta copiar esse código acima em um arquivo chamado Dockerfile e em seguir executar o comando: docker build -t minhaimagem . . E pronto, será criada uma imagem com o nome de minhaimagem, basta usa-la para o que precisar.

Nos próximos posts veremos como criar uma imagem mais complexa, iremos montar um ambiente completo para um site em WordPress, e aprendermos um pouco mais sobre outros recursos do docker build.

Fique atento, e tendo dúvidas já sabe, nos mande uma mensagem, abraço!

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.

Como Funciona o Filesystem no Docker?

Olá pessoal!

Para você que está começando a ler nossos posts agora, sugiro que leia antes esseesse link que explicam o que é o Docker e como ele funciona. Hoje nós abordaremos um dos assuntos mais importantes dentro do Docker: O Filesystem.

O sistema de arquivos do Docker é chamado de layered, ou seja, é um sistema de arquivo em camadas, o que isso quer dizer?

Um sistema de arquivo comum, possui basicamente duas camadas:

bootfs: Onde ficam o sistema de Boot do sistema e o Kernel.

rootfs: Inclui o sistema de arquivo do sistema, incluindo a arquitetura de diretório, em sistemas unix-like: /dev, /proc, /bin, /etc, /lib, /usr, e /tmp assim como os arquivos de configuração e binários do sistema.

Quando o sistema é iniciado ele carrega o rootfs primeiramente em modo somente leitura, verifica sua integridade e em seguida remonta-o como leitura/escrita e assim fica disponível para o usuário/aplicação.

No Docker temos essa arquitetura também, mas com um diferencial, a camada de escrita que o processo/aplicação visualiza não é o mesmo rootfs base, e sim uma camada de abstração do rootfs, isso é o que faz com que um container torne-se portável, pois as modificações realizadas não são aplicadas ao sistema origem do container, e sim na camada a qual o sistema visualiza.

Para ficar mais claro, veja na figura abaixo como é um sistema tradicional:

    docker-filesystems-generic1

 

Agora veja como é o filesystem no docker:

 

docker-filesystems-multiroot

 

 

Como podem notar o bootfs em vez de ser único por sistema/container, é compartilhado entre eles, mas o rootfs é isolado por camadas, ou seja, o que deve ser em comum entre o host e container é compartilhado via AUFS, que monta uma camada de leitura/escrita em cima do filesystem em somente leitura, isso garante que modificações feitas dentro do container não afetem o sistema de arquivos do host.

A imagem abaixo ilustra melhor como funciona essas camadas:

docker-filesystems-busyboxrw

Um detalhe nessa arquitetura é que a cada modificação e commit do container é gerada uma nova camada, ou seja, digamos que eu inicie um container a partir de uma imagem do Debian, e instale o serviço apache dentro desse container, quando eu for transformar esse container em uma imagem, essa imagem possuirá a primeira camada que é do sistema Debian, e uma camada adicional que refere-se a instalação do serviço apache. Na imagen abaixo podemos visualizar melhor esse ambiente.

 

docker-filesystems-multilayer-update

Lembrando que uma imagem pode ser utilizada diversas vezes, ou seja, há compartilhamento da imagem entre os containers, mas os containers depois de iniciados são isolados uns dos outros, na imagem abaixo podemos visualizar essa arquitetura.docker-filesystem

Como podemos notar, há o compartilhamento das camadas inferiores, pois elas fazem parte da imagem que originou o container, e a camada de escrita, que faz parte do container rodando, é isolada para cada container.

Por hoje é isso, veremos em breve um pouco mais sobre filesystem no Docker, e algumas outras questões relacionadas a essa arquitetura. Ficou com dúvida? Gostaria de saber mais? Algum feedback a nos dar? Deixe sua mensagem e vamos conversando.

Abraço!

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.

O que é Docker?

Olá!

Iniciamos agora uma série de posts técnicos que lhe ajudarão a entender o funcionamento do Docker, e como cada componente é utilizado dentro desta plataforma.

Primeiro temos que definir o que não é Docker. Docker não é um sistema de virtualização tradicional. Enquanto em um ambiente de virtualização tradicional nós temos um S.O. completo e isolado, dentro do Docker nós temos recursos isolados que utilizando bibliotecas de kernel em comum (entre host e container), isso é possível pois o Docker utiliza como backend o nosso conhecido LXC.

Abaixo podemos ver uma figura que ilustra essa diferença.

lxc-vm

 

Docker é uma plataforma Open Source escrito em Go, que é uma linguagem de programação de alto desempenho desenvolvida dentro do Google, que facilita a criação e administração de ambientes isolados.

Mas por que que o Docker é tão legal?

O Docker possibilita o empacotamento de uma aplicação ou ambiente inteiro dentro de um container, e a partir desse momento o ambiente inteiro torna-se portável para qualquer outro Host que contenha o Docker instalado.

Isso reduz drasticamente o tempo de deploy de alguma infraestrutura ou até mesmo aplicação, pois não há necessidade de ajustes de ambiente para o correto funcionamento do serviço, o ambiente é sempre o mesmo, configure-o uma vez e replique-o quantas vezes quiser.

Outra facilidade do Docker é poder criar suas imagens (containers prontos para deploy) a partir de arquivos de definição chamados Dockerfiles (veremos isso melhor em posts futuros).

Não podemos nos esquecer também de que o Docker utiliza como backend default o LXC, com isso é possível definir limitações de recursos por container (memória, cpu, I/O, etc.)

Para ficar um pouco mais claro, podemos ver na imagem abaixo a diferença em se utilizar o LXC puro e o Docker.

lxc_vs_docker

 

Como o Docker faz isso?

Como ele trabalha utilizando cliente e servidor (toda a comunicação entre o Docker Daemon e Docker client é realizada através de API), basta apenas que você tenha instalado o serviço do Docker em um lugar, e aponte em seu Docker Client para esse servidor. A plataforma do Docker em si utilizada alguns conjuntos de recursos, seja para a criação ou administração dos containers, entre esses conjuntos podemos destacar a biblioteca libcontainer, que é responsável pela comunicação entre o Docker Daemon e o backend utilizado, é ela a responsável pela criação do container, e é através dela que podemos setar os limites de recursos por container.

Podemos ver na imagem abaixo como é o Workflow dentro do Docker.

libcontainer intro

 

 

Ficou com dúvidas? Ótimo! nos mande suas dúvidas para que possamos conversar mais sobre essa tecnologia. E aguardem, nos próximos posts explicaremos melhor cada um dos componentes do Docker, e claro traremos algumas aplicações práticas dele 😉

Até Mais!

 

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.

O que é Container?

Olá Pessoal,

Este é nosso primeiro post aqui no Blog, antes de começar a falar sobre o que é Docker, Containers, DevOps e afins gostaríamos de agradecer a você que chegou até nós e agora está lendo um pouco sobre o que é esse mundo.

Você já deve ter ouvido falar em Containers ou no mínimo, Docker, bom o que é tudo isso afinal de onde veio essa história de container?

O projeto LXC (Linux Container) nasceu em agosto de 2008, no inicio, o site oficial trazia a seguinte frase: LXC, chroot com esteroides. O objetivo do projeto era ser uma alternativa a já consolidada tecnologia de chroot, sendo um meio termo entre máquina virtual e chroot, possibilitando a criação de um ambiente mais próximo possível de uma instalação Linux sem a necessidade de  um kernel separado.

Através do chroot é possível encapsular um sistema inteiro dentro de uma estrutura de diretório, fazendo com que o sistema hospede não acesse nada além daquilo que é definido dentro dessa arquitetura. Isso é muito útil pois elimina a sobrecarga de uma máquina virtual inteira para executar um processo ou serviço simples.

Voltando ao LXC, algumas das features do LXC são:

Kernel Namespaces:

Possibilita a abstração de processos dentro do kernel, isso quer dizer que um processo ou grupo de processo é isolado dentro do kernel, podendo visualizar os pontos de montagem, id de processos, id de usuário, hostname e fila de processo, isolados de outros processos ou grupo de processo.

Apparmor and SELinux:

Responsável por carregar politicas de acesso no host, isso quer dizer que são definidas regras de acesso a determinados arquivos/diretórios dentro do host, isso garante que em uma possível brecha de segurança, um container não consiga visualizar ou executar algo malicioso no host.

Seccomp policies:

Realiza uma filtragem das chamadas de sistema (syscall) e aceita ou não essa chamada. Como o host e container compartilham do mesmo kernel, é necessário algumas politicas especificas a nível de interface do kernel para que o hóspede não consiga escalar privilégios dentro do sistema host.

Chroots (pivot_root):

Responsável pelo mapeamento de diretórios e ponto de montagem do sistema container, é a chamada de sistema que cria a árvore de diretórios que o container terá acesso.

Kernel Capabilities:

Todos os sistema UNIX dividem os processos em duas grandes categorias, processo privilegiados  (sendo executados como root) e processos não privilegiados (executados com usuário comum), por padrão todo container executa comando não privilegiados, ou seja, um processo dentro de um container é executado como root dentro do host (mesmo que este esteja como root dentro do container). Sendo assim, a partir do kernel 2.2  foram inseridos dispositivos que possibilitam ao container executar de forma privilegiados alguns comandos, para esses dispositivos foi dado o nome de Capabilities ou CAP.

Cgroups:

Ou Control Groups, é responsável pelo controle de uso dos recursos por processo/grupo de processo, podendo assim executar diferentes containers com diferentes limites de uso (memória, cpu, I/O).

Devido a essas características é que chamamos de container todo sistema criado utilizando essa tecnologia, pois o sistema fica “enjaulado” dentro de uma caixa de recursos alocados exclusivamente para ele, e claro limitado a esses recursos. Abaixo há uma imagem ilustrando a diferença entre uma máquina virtual comum e um sistema em containers.

 

 

Ótimo, já sabemos um pouco sobre o que é e de onde vieram os containers, agora temos outras dúvidas:

O que é o docker afinal?

No que os containers podem me ajudar?

Ok, ok, vamos responder a essas e muitas outras dúvidas em nossos próximos posts, fiquem atentos e caso tenham dúvidas ou quiserem conversar um pouco mais sobre esse mundo, deixem suas mensagens!

Entusiasta Open Source, seu principal foco é ir atrás de ideias novas e torna-las realidade através de soluções simples e eficientes, o menos é mais, e o dividir é multiplicar.