Soluções | Mundo Docker
Soluções onde o Docker pode ser utilizado.
January 30, 2019 January 30, 2019 Wellington SilvaLeave a comment
Post incialmente públicado em: https://dumpscerebrais.com/2019/01/migrando-do-docker-swarm-para-o-kubernetes
Começamos 2019 e ficou bem claro que o Docker Swarm perdeu para o Kubernetes na guerra de orquestradores de contêineres.
Não vamos discutir aqui motivos, menos ainda se um é melhor que outro. Cada um tem um cenário ótimo para ser empregado como já disse em algumas das minhas palestras sobre o assunto. Mas de uma maneira geral se considerarmos o requisito evolução e compararmos as duas plataformas então digo que se for construir e manter um cluster de contêineres é melhor já começarmos esse cluster usando Kubernetes.
O real objetivo desse artigo é mostrar uma das possíveis abordagens para que nossas aplicações hoje rodando num cluster Docker Swarm, definidas e configuradas usando o arquivo docker-compose.yml possam ser entregues também em um cluster Kubernetes.
Já é meio comum a comparação entre ambos e posso até vir a escrever algo por aqui mas no momento vamos nos ater a um detalhe simples: cada orquestrador de contêineres cria recursos próprios para garantir uma aplicação rodando. E apesar de em alguns orquestradores recursos terem o mesmo nome, como o Services do Docker Swarm e o Services do Kubernetes eles geralmente fazem coisas diferente, vem de conceitos diferentes, são responsáveis por entidades diferentes e tem objetivos diferentes.
O Kompose, uma alternativa
O kompose é uma ferramenta que ajuda muito a converter arquivos que descrevem recursos do Docker em arquivos que descrevem recursos do Kubernetes e até dá para utilizar diretamente os arquivos do Docker Compose para gerir recursos no Kubernetes. Também tenho vontade de escrever sobre ele, talvez em breve, já que neste artigo vou focar em como ter recursos do Docker Swarm e do Kubernetes juntos.
Sempre gosto de passar o contexto para as pessoas entenderem como, quando e onde foram feitas as coisas, assim podemos compreender as decisões antes de pré-julgarmos.
Na Dockercon européia de 2017, a primeira sem o fundador Solomon Hykes, foi anunciado e demostrado como usar um arquivo docker-compose.yml para rodar aplicações tanto num cluster Docker Swarm quanto num cluster Kubernetes usando a diretiva Stacks.
A demostração tanto na Dockercon quanto no vídeo acima foram sensacionais. Ver que com o mesmo comando poderíamos criar recursos tanto no Docker Swarm quanto no Kubernetes foi um marco na época. O comando na época:
docker stack deploy --compose-file=docker-compose.yml stackname
Só tinha um problema, isso funcionava apenas em instalações do Docker Enterprise Edition ($$$) ou nas novas versões do Docker for Desktop que eram disponíveis apenas para OSX e Windows.
Aí você pergunta: Como ficaram os usuário de Linux nessa história, Wsilva?
Putos, eu diria.
Assim como outros também tentei fazer uma engenharia reversa e vi que o bootstrap desse Kubernetes rodando dentro do Docker for Mac e Windows era configurado usando o Kubeadm. Fucei, criei os arquivos para subir os recursos Kubernetes necessários e quase consegui fazer rodar mas ainda me faltava descobrir como executar o binário responsável por extender a api do Kubernetes com os parâmetros certos durante a configuração de um novo cluster, todas as vezes que rodei tive problemas diferentes.
Até postei um tweet a respeito marcando a Docker Inc mas a resposta que tive foi a que esperava: a Docker não tem planos para colocar suporte ao Compose no Linux, somente Docker for Desktop e Enterprise Edition.
Ainda bem antes de tentar fazer isso na mão, lá na Dockercon de 2018 (provavelmente também escreverei sobre ela) tive a oportunidade de ver algumas palestras sobre extender a API do Kubernetes, sobre como usaram Custom Resource Definition na época para fazer a mágica de interfacear o comando docker stack antes de mandar a carga para a API do Kubernetes ou para a API do Docker Swarm e também conversei com algumas pessoas no conference a respeito.
A desculpa na época para não termos isso no Docker CE no Linux era uma questão técnica, a implementação dependeria muito de como o Kubernetes foi instalado por isso que no Docker para Desktop e no Docker Enterprise, ambientes controlados, essa bruxaria era possível, mas nas diversas distribuíções combinadas com as diversas maneiras de criar um cluster Kubernetes seria impossível prever e fazer um bootstrap comum a todos.
Docker ainda pensando no Open Source?
Na Dockercon européia de 2018, praticamente um ano depois do lançamento do Kubernetes junto com o Swarm finalmente foi liberado como fazer a API do Compose funcionar em qualquer instalação de Kubernetes. Mesmo sem as instruções de uso ainda mas já com os fontes do instalador disponíveis (https://github.com/docker/compose-on-kubernetes) era possível ver que a estrutura tinha mudado de Custom Resource Definition para uma API agregada e relativamente fácil de rodar em qualquer cluster Kubernetes como veremos a seguir.
Para rodarmos essa API do Compose no Mac e no Windows, assim como no final de 2017, basta habilitar a opção Kubernetes na configuração conforme a figura e toda a mágica vai acontecer.
No Linux podemos trabalhar com o Docker Enterprise Edition ou com o Docker Community Edition.
Para funcinar com o Docker Community Edition primeiramente precisamos de um cluster pronto rodando kubernetes e podemos fazer teoricamente em qualquer tipo de cluster. Desde clusters criados para produção com Kops – (esse testei na AWS e funcionou), ou Kubespray, ou em clusteres locais como esse que criei para fins educativos: https://github.com/wsilva/kubernetes-vagrant/ (também funcionou), ou Minikube (também funcionou, está no final do post), ou até no saudoso play with kubernetes (também funcionou) criado pelo nosso amigo argentino Marcos Nils.
Para verificar se nosso cluster já não está rodando podemos checar os endpoints disponíveis filtrando pela palavra compose:
$ kubectl api-versions | grep compose
Para instalar a api do Compose em um cluster Kubernetes precisamos do etcd operator rodando e existem maneiras de instalar com e sem suporte a SSL. Mais informações podem ser obtidas nesse repositório.
Neste exemplo vamos utilizar o gerenciador de pacotes Helm para instalar o etcd operator.
Primeiro criamos o namespace compose em nosso Kubernetes:
$ kubectl create namespace compose
Em seguida instalmos ou atualizamos o Helm.
Se estivermos utilizando OSX, podemos instalar de maneira simples com homebrew.
Error: kubernetes-helm 2.11.0 is already installed
To upgrade to 2.12.3, run `brew upgrade kubernetes-helm`
$ brew upgrade kubernetes-helm
==> Upgrading 1 outdated package:
kubernetes-helm 2.11.0 -> 2.12.3
==> Upgrading kubernetes-helm
==> Downloading https://homebrew.bintray.com/bottles/kubernetes-helm-2.12.3.moja
==> Pouring kubernetes-helm-2.12.3.mojave.bottle.tar.gz
?  /usr/local/Cellar/kubernetes-helm/2.12.3: 51 files, 79.5MB
No Linux podemos optar por gerenciadores de pacotes ou instalar manualmente baixando o pacote e colocando em algum diretório do PATH:
$ curl -sSL https://storage.googleapis.com/kubernetes-helm/helm-v2.12.1-linux-amd64.tar.gz -o helm-v2.12.1-linux-amd64.tar.gz
$ tar -zxvf helm-v2.12.1-linux-amd64.tar.gz
x linux-amd64/tiller
$ cp linux-amd64/tiller /usr/local/bin/tiller
$ cp linux-amd64/helm /usr/local/bin/helm
Estamos em 2019 então todos os clusters Kubernetes já deveriam estar rodando com RBAC (Role Base Access Control) por questões de segurança. Para isso devemos criar uma Service Account em nosso cluster para o tiller.
$ kubectl --namespace=kube-system create serviceaccount tiller
$ kubectl --namespace=kube-system \
create clusterrolebinding tiller \
Neste exemplo fizemos o bind para o role cluster admin, mas seria interessante criar uma role com permissões mais restritas definindo melhor o que o helm pode ou não fazer em nosso cluster Kubernetes.
Instalamos o etcd operator:
$ helm install --name etcd-operator \
stable/etcd-operator \
--namespace compose
Monitoramos até os pods responsáveis pelo etcd operator estarem de pé:
$ watch kubectl get pod --namespace compose
Com etcd operator de pé podemos matar o watch loop com ctrl+c.
Próximo passo vai ser subir um cluster etcd usando o operator:
$ cat > compose-etcd.yaml <<EOF
apiVersion: "etcd.database.coreos.com/v1beta2"
kind: "EtcdCluster"
name: "compose-etcd"
namespace: "compose"
version: "3.2.13"
$ kubectl apply -f compose-etcd.yaml
Monitoramos novamente até os pods responsáveis pelo nosso etcd cluster estarem de pé:
Com etcd cluster rodando podemos matar o watch loop com ctrl+c.
Em seguida baixamos diretamente do GitHub e executamos o instalador da API do Compose.
Se estivermos utilizando OSX:
$ curl -sSLO https://github.com/docker/compose-on-kubernetes/releases/download/v0.4.18/installer-darwin
chmod +x installer-darwin
./installer-darwin \
-namespace=compose \
-etcd-servers=http://compose-etcd-client:2379 \
-tag=v0.4.18
$ curl -sSLO https://github.com/docker/compose-on-kubernetes/releases/download/v0.4.18/installer-linux
chmod +x installer-linux
./installer-linux \
Vamos checar se os pods estão rodando novamente com watch loop:
watch kubectl get pod --namespace compose
Após todos os pods rodando usamos o ctrl+c para parar o watch loop e em seguida podemos verificar se agora temos os endpoints do compose:
Sucesso. Agora vamos baixar um arquivo docker compose de exemplo do repositório da própria Docker:
curl -sSLO https://github.com/docker/compose-on-kubernetes/blob/master/samples/docker-compose.yml
Para ver o conteudo do arquivo podemos usar um editor de texto ou o simples cat docker-compose.yml no terminal mesmo.
Agora vamos usar o docker para criar os recursos no kubernetes, como se estivessemos fazendo um deployment em um cluster de Docker Swarm mesmo:
$ docker stack deploy \
--orchestrator=kubernetes \
--compose-file docker-compose.yml \
minha-stack
Podemos usar tando o kubectl como o docker cli para checar os status:
NAME        SERVICES  PORTS    STATUS                        CREATED AT
demo-stack  3         web: 80  Available (Stack is started)  2019-01-28T20:47:38Z
$ docker stack ls \
--orchestrator=kubernetes
NAME           SERVICES      ORCHESTRATOR      NAMESPACE
demo-stack     3             Kubernetes        default
Podemos pegar o ip da máquina virtual rodando minikube com o comando minikube ip e a porta do serviço web-published e acessar no nosso navegador.
No próprio repositório temos uma matriz de compatibilidade entre as funcionalidades no Docker Swarm e funcionalidades no Kubernetes: https://github.com/docker/compose-on-kubernetes/blob/master/docs/compatibility.md
Se você está pensando em migrar seus workloads de clusters de Docker Swarm para clusters de Kubernetes você pode optar tanto pelo Kompose quanto pelo Docker Compose no Kubernetes.
Optando pelo Compose no Kubernetes podemos usar o Docker for Mac ou Docker for Windows, basta habilitar nas configurações a opção de cluster Kubernetes.
Se estiver no Linux pode optar por seguir os passos acima ou pagar pelo Docker Enterprise Edition.
Veja como cada uma dessas opções se adequa melhor aos seus processos e divirta-se.
wfsilva.com
April 12, 2017 April 12, 2017 Cristiano DiedrichLeave a comment
January 18, 2017 February 16, 2017 Cristiano Diedrich4 Comments
Viu, não deixamos passar nada 😉
E os logs?
July 13, 2016 July 13, 2016 Cristiano Diedrich2 Comments
Oi Pessoal, tranquilo?
Uma das coisas que atormentam tanto a vida do pessoal de Dev quanto de Ops é saber o que está acontecendo com o seu ambiente. Como se resolve isso? Existem duas formas, que devem sempre trabalhar juntas, são elas: Monitoramento, para saber que vai dar problema antes do problema ocorrer :), e Gerencia de logs, para saber, depois de ocorrer algum problema, o que aconteceu com sua aplicação ou ambiente que ocasionou o comportamento inesperado.
Essa mesma abordagem deve ser utilizada quando se trabalha com containers também, para monitoria você já viu aqui e aqui algumas formas de como pode ser feito esse monitoramento. Para a gerencia de logs você deve pensar antes qual será a criticidade dessas informações para o debug de sua aplicação e resolução de algum imprevisto, outro ponto é: como preciso ou como gostaria de visualizar essas informações. Tendo resolvido essas duas questões você pode então optar:
Utilizar o comando docker logs: Com isso você terá as informações do que está sendo enviando para a console do container, ou seja,somente irá visualizar aquilo que estiver passando na console, você deve fazer com que sua aplicação envie as informações necessárias para a console do container. Caso sua aplicação salve o debug em arquivo de log você não conseguirá visualizar de forma fácil essa informação.
Utilizar plugins de log: Utilizando plugins você pode fazer com que qualquer log do container seja enviado para um serviço externo, isso garante que você poderá ter acesso a qualquer informação (seja do container ou app) de um único lugar.
O que vamos ver hoje é como você pode utilizar alguns dos plugins de logs mais conhecidos, isso é claro na prática 🙂
Um dos drivers de log mais fácil de se utilizar, com ele você pode enviar tanto o stderr quanto o stout para o serviço de logs externo, para isso basta você rodar:
docker run --log-driver=fluentd
É claro que você precisa passar alguns parâmetros, como por exemplo: "–log-opt fluentd-address=" onde você define qual será o destino de seus logs, geralmente será um host onde estará rodando o servidor Fluentd ou o endereço que esse serviço lhe fornecer. Por padrão a tag de busca será o id do container, com isso, quando você precisar consultar algum log deverá faze-lo pelo id do container que desejar.
O Splunk é talvez uma das ferramentas para gerenciamento de log mais completo que se pode ter, e da mesma forma que o Fluentd, você precisa apenas definir esse driver como sendo de log:
docker run --log-driver=splunk
Você precisa definir algumas coisas antes, veja a lista:
splunk-token: Token utilizado para autenticação do container na API http;
splunk-url: Endereço do servidor de Splunk disponível, seja ele local ou na solução de cloud da Splunk;
splunk-source: Origem do log (se não definido ele coletará tudo);
splunk-sourcetype: Tipo do log (app, debug, etc);
splunk-index: Índice para os logs;
splunk-capath: Caminho do certificado;
splunk-caname: Nome para validação do certificado, por padrão ele pega pelo nome do splunk-url;
splunk-insecureskipverify: Desativa a verificação ssl para o seu host Splunk;
tag: Identificação do log na base, no caso do Docker você pode definir qualquer informação do container como tag, por exemplo: ID, Nome, Região, etc;
labels: Facilita a consulta do log posteriormente, você pode por exemplo consultar logs do container x que pertence a região Sul;
env: Pode classificar por Dev, Test, Prod etc.
docker run --log-driver=splunk --log-opt splunk-token=SEUTOKENAQUI --log-opt splunk-url=https://servidor-splunk:8088 --log-opt splunk-capath=/etc/cert/cacert.pem --log-opt splunk-caname=SplunkDefaultCert --log-opt tag="{{.Name}}/{{.FullID}}" --log-opt labels=location --log-opt env=TESTE --env "TESTE=false" --label location=sul nginx
Claro que não poderia faltar a opção de enviar seus logs para o CloudWatch da AWS, e é o mais simples de se utilizar, por um motivo: Basta você ter conta na AWS e ativar o CloudWatch, não é necessário contratar um serviço cloud de terceiro ou subir um servidor de log local. Veja como você pode utiliza-lo:
docker run --log-driver=awslogs --log-opt awslogs-region=sa-east-1
Você deve definir para qual grupo de log deseja enviar os logs do container, e tenha cuidado pois dependendo do tipo de logs e quantidade, pode prejudicar a visualização do mesmo, então preste atenção no formato de log que estará enviando:
docker run --log-driver=awslogs --log-opt awslogs-region=sa-east-1 --log-opt awslogs-group=MeuGrupodeLog nginx
A autenticação é bem simples, você montar o seguinte volume: aws:~/.aws, dentro dessa pasta deve ter um arquivo chamado credentials com o seu AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, e AWS_SESSION_TOKEN Lembre-se que o usuário utilizado para isso deve ter no mínimo as seguintes permissões: logs:CreateLogStream e logs:PutLogEvents.
Espero ter ajudado, tenho alguma dúvida pode nos enviar por e-mail ou deixe nos comentários. E nos ajude divulgando o blog 😉
'); is_agreed = false; } } else { is_agreed = true; } if (isvalidName == true && isvalidEmail == true && is_agreed == true) { jQuery(".AjaxLoader").show(); jQuery('#mysuccess_msg').html(''); jQuery('#mysuccess_msg').hide(); jQuery('#myerror_msg').html(''); jQuery('#myerror_msg').hide(); var name = ""; if (jQuery('#yourname').length > 0) { name = jQuery("#yourname").val(); } var nonce = 'ddb1533d71'; var url = 'https://www.mundodocker.com.br/wp-content/plugins/email-subscribe/'; var email = jQuery("#youremail").val(); var str = "action=store_email&email=" + email + '&name=' + name + '&is_agreed=' + is_agreed + '&sec_string=' + nonce; jQuery.ajax({ type: "POST", url: 'https://www.mundodocker.com.br/wp-admin/admin-ajax.php', data: str, async: true, success: function (msg) { if (msg != '') { var result = msg.split("|"); if (result[0] == 'success') { jQuery(".AjaxLoader").hide(); jQuery('#mysuccess_msg').html(result[1]); jQuery('#mysuccess_msg').show(); setTimeout(function () { jQuery.fancybox_ns.close(); }, 2000); } else { jQuery(".AjaxLoader").hide(); jQuery('#myerror_msg').html(result[1]); jQuery('#myerror_msg').show(); } } } }); } } var interval_62b8a0311f09f = setInterval(function() { if(document.readyState === 'complete') { clearInterval(interval_62b8a0311f09f); /* if ( jQuery.browser.msie && jQuery.browser.version >= 9 ) { jQuery.support.noCloneEvent = true }*/ var htmlpopup = jQuery("#formFormEmail").html(); jQuery("#formFormEmail").remove(); jQuery('body').on('click', '.shownewsletterbox', function () { jQuery.fancybox_ns({ 'overlayColor': '#000000', 'hideOnOverlayClick': false, 'padding': 10, 'autoScale': true, 'showCloseButton': true, 'content': htmlpopup, 'transitionIn': 'fade', 'transitionOut': 'elastic', 'width': 560, 'height': 360 }); }); } }, 100);