Primeira versão candidata do Docker 1.12 foi anunciado em duas semanas atrás. Vários novos recursos são
planejado para esta versão.
Este blog mostrará como criar um Aplicativo distribuído Bundle do Docker Compose e implante-o como Docker Stack em Docker Swarm Modo. Muito obrigado a @friismo por me ajudar a entender esses conceitos.
Vamos dar uma olhada nos recursos primeiro:
- Orquestração integrada: Um aplicativo típico é definido usando um arquivo Docker Compose. Essa definição consiste em vários contêineres e é implantada em vários hosts. Isso evita o ponto único de falha (SPOF) e mantém seu aplicativo
resiliente. Várias estruturas de orquestração, como Docker Swarm, Kubernetes e Mesos, permitem orquestrar esses aplicativos. No entanto, como essa é uma característica tão importante do aplicativo, o Docker Engine agora tem orquestração integrada.
Mais detalhes sobre esse tópico em um blog posterior. - Serviço: Um serviço replicado, distribuído e com balanceamento de carga pode ser facilmente criado usando
serviço docker createcomando. Um "estado desejado" do aplicativo, como a execução de 3 contêineres do Couchbase, é fornecido e o comando
O mecanismo de autocorreção do Docker garante que muitos contêineres estejam em execução no cluster. Se um contêiner for desativado, outro contêiner será iniciado. Se um nó for desativado, os contêineres desse nó serão iniciados em um nó diferente. Mais sobre isso em um próximo
blog. - Segurança de configuração zero: O Docker 1.12 vem com TLS mutuamente autenticado, fornecendo autenticação, autorização e criptografia para as comunicações de todos os nós que participam do enxame, prontos para uso. Mais sobre isso em
em um blog posterior. - Pilha do Docker e pacote de aplicativos distribuídos: O Distributed Application Bundle, ou DAB, é um formato de imagem distribuível de vários serviços. Leia mais para obter mais detalhes.
Até o momento, você pode pegar um Dockerfile e criar uma imagem a partir dela usando o construção de docas comando. Um contêiner pode ser iniciado usando o comando execução do docker comando. Vários contêineres podem ser iniciados facilmente com o comando
esse comando várias vezes. Ou você também pode usar o arquivo Docker Compose e aumentar a escala dos seus contêineres usando o comando escala do docker-compose comando.

A imagem é um formato portátil para um único contêiner. Pacote de aplicativos distribuídosou DAB, um novo conceito introduzido no Docker 1.12, é um formato portátil para vários contêineres. Cada pacote pode ser implantado como
a Pilha em tempo de execução.
Saiba mais sobre o DAB em docker.com/dab. Para simplificar, aqui está uma analogia que pode ser feita:
Dockerfile -> Imagem -> Contêiner
Docker Compose -> Pacote de aplicativos distribuídos -> Docker Stack
Vamos usar um arquivo Docker Compose, criar um DAB a partir dele e implantá-lo como um Docker Stack.
É importante observar que esse é um recurso experimental na versão 1.12-RC2.
Criar um pacote de aplicativos distribuídos a partir do Docker Compose
O Docker Compose CLI adiciona um novo feixe comando. Mais detalhes podem ser encontrados:
|
1 2 3 4 5 6 7 8 9 10 11 |
doca-compor feixe --ajuda Gerar a Docker feixe de o Compor arquivo. Local imagens vontade ser empurrado para a Docker registro, e remoto imagens vontade ser puxado para buscar e imagem resumo. Uso: feixe [opções] Opções: -o, --saída PATH Caminho para escrever o feixe arquivo para. Padrões para ".dsb". |
Agora, vamos pegar uma definição do Docker Compose e criar um DAB a partir dela. Aqui está nossa definição do Docker Compose:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
versão: "2" serviços: db: nome_do_contêiner: "db" imagem: arungupta/oreilly-couchbase:mais recente portos: - 8091:8091 - 8092:8092 - 8093:8093 - 11210:11210 web: imagem: arungupta/oreilly-mosca selvagem:mais recente depende_de: - db ambiente: - COUCHBASE_URI=db portos: - 8080:8080 |
Esse arquivo Compose inicia um servidor WildFly e um servidor Couchbase. Um aplicativo Java EE é pré-implantado no servidor WildFly que se conecta ao servidor Couchbase e permite executar operações CRUD usando a API REST. A fonte desse arquivo está em:
github.com/arun-gupta/oreilly-docker-book/blob/master/hello-javaee/docker-compose.yml. Gere um pacote de aplicativos com ele:
|
1 2 3 4 |
doca-compor feixe AVISO: Sem suporte chave 'depends_on' em serviços.web - ignorando AVISO: Sem suporte chave 'nome_do_contêiner' em serviços.db - ignorando Escreveu feixe para hellojavaee.dsb |
depende_de apenas cria dependência entre dois serviços e os faz iniciar em uma ordem específica. Isso só garante que o contêiner do Docker seja iniciado, mas o aplicativo dentro do contêiner pode demorar mais para iniciar. Portanto, esse atributo apenas
resolve parcialmente o problema. nome_do_contêiner fornece um nome específico para o contêiner. Depender de um nome de contêiner específico é um acoplamento rígido e não permite dimensionar o contêiner. Portanto, ambos os avisos podem ser ignorados,
por enquanto. Esse comando gera um arquivo usando o nome do projeto Compose, que é o nome do diretório. Portanto, no nosso caso, hellojavaee.dsb é gerado. Essa extensão de arquivo foi renomeada para .dab no RC3. O código gerado
pacote de aplicativos é semelhante:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
{ "serviços": { "db": { "Imagem": "arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c", "Redes": [ "default" ], "Portas": [ { "Porto": 8091, "Protocolo": "tcp" }, { "Porto": 8092, "Protocolo": "tcp" }, { "Porto": 8093, "Protocolo": "tcp" }, { "Porto": 11210, "Protocolo": "tcp" } ] }, "web": { "Env": [ "COUCHBASE_URI=db" ], "Imagem": "arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914", "Redes": [ "default" ], "Portas": [ { "Porto": 8080, "Protocolo": "tcp" } ] } }, "versão": "0.1" } |
Esse arquivo fornece uma descrição completa dos serviços incluídos no aplicativo. Não tenho certeza se Distributed Application Bundle é o nome mais apropriado; discuta isso em #24250. Ele
seria ótimo se outros formatos de contêineres, como o Rkt, ou mesmo VMs, pudessem ser suportados aqui. Mas, por enquanto, o Docker é o único formato compatível.
Inicializar o modo Swarm no Docker
Conforme mencionado acima, o "estado desejado" agora é mantido pelo Docker Swarm. E isso já está incorporado ao Docker Engine. Os conceitos do Docker Swarm também evoluíram e podem ser lidos em Conceitos-chave do modo Swarm. A
um blog mais detalhado sobre isso será publicado posteriormente. Mas para este blog, um novo comando enxame de docas foi adicionado:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
doca enxame --ajuda Uso: doca enxame COMANDO Gerenciar Docker Enxame Opções: --ajuda Imprimir uso Comandos: inicial Inicializar a Enxame unir-se Aderir a Enxame como a nó e/ou gerente atualização Atualização o Enxame sair Sair a Enxame inspecionar Inspecionar o Enxame Executar 'docker swarm COMMAND --help' para mais informações em a comando. |
Inicialize um nó do Swarm (como um gerenciador) no Docker Engine:
|
1 2 |
doca enxame inicial Enxame inicializado: atual nó (ek9p1k8r8ox7iiua5c247skci) é agora a gerente. |
Mais detalhes sobre esse nó podem ser encontrados em inspeção de nó doca autocomando.
A saída detalhada é detalhada, mas a seção relevante é:
|
1 2 3 4 5 |
"Especificação": { "Função": "gerente", "Associação": "aceito", "Disponibilidade": "ativo" }, |
A saída mostra que o nó é um gerente. Em um cluster de nó único, esse nó também atuará como um trabalhador.
Mais detalhes sobre o cluster podem ser obtidos usando o comando inspeção de enxame de docas comando.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
doca enxame inspecionar [ { "ID": "1rcvu7m9mv2c8hiaijr7an9zk", "Versão": { "Índice": 1895 }, "CreatedAt": "2016-07-01T23:52:38.074748177Z", "UpdatedAt": "2016-07-02T04:54:32.79093117Z", "Especificação": { "Nome": "default", "AcceptancePolicy" (Política de aceitação): { "Políticas": [ { "Função": "trabalhador", "Autoaceitação": verdadeiro }, { "Função": "gerente", "Autoaceitação": falso } ] }, "Orquestração": { "TaskHistoryRetentionLimit": 10 }, "Jangada": { "SnapshotInterval": 10000, "LogEntriesForSlowFollowers": 500, "HeartbeatTick": 1, "ElectionTick": 3 }, "Despachante": { "HeartbeatPeriod": 5000000000 }, "CAConfig": { "NodeCertExpiry": 7776000000000000 } } } ] |
Política de aceitação mostra que outros trabalhador Os nós podem entrar nesse cluster, mas um gerente precisa de aprovação explícita.
Implantar uma pilha do Docker
Crie uma pilha usando implantação de docas comando:
|
1 2 3 4 5 |
doca implantação -f hellojavaee.dsb hellojavaee Carregamento feixe de hellojavaee.dsb Criação de rede hellojavaee_default Criação de serviço hellojavaee_db Criação de serviço hellojavaee_web |
O uso do comando certamente pode ser simplificado, conforme discutido em #24249. Veja a lista de serviços:
|
1 2 3 4 |
doca serviço ls ID NOME RÉPLICAS IMAGEM COMANDO 2g8kmrimztes hellojavaee_web 1/1 arungupta/oreilly-mosca selvagem@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914 46xhlb15cc60 hellojavaee_db 1/1 arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c |
A saída mostra que dois serviços, WildFly e Couchbase, estão em execução. Serviços também é um novo conceito introduzido no Docker 1.12. É isso que dá a você o
"estado desejado", e o Docker Engine trabalha para fornecer isso a você. docker ps mostra a lista de contêineres em execução:
|
1 2 3 |
CONTAINER ID IMAGEM COMANDO CRIADO STATUS PORTOS NOMES 622756277f40 arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c "/entrypoint.sh /opt/" 3 segundos atrás Para cima 1 segundos 8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp hellojavaee_db.1.19enwdt6i5m853m5675tx3z29 abf8703ed713 arungupta/oreilly-mosca selvagem@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914 "/opt/jboss/wildfly/b" 3 segundos atrás Para cima 1 segundos 8080/tcp hellojavaee_web.1.70piloz6j4zt06co8htzisgyl |
O contêiner WildFly é iniciado antes que o contêiner do Couchbase esteja em funcionamento. Isso significa que o aplicativo Java EE tenta se conectar ao servidor Couchbase e falha. Portanto, o aplicativo nunca é inicializado com êxito.
Serviço do Docker com autocorreção
O Docker Service mantém o "estado desejado" de um aplicativo. No nosso caso, o estado desejado é garantir que um, e somente um, contêiner para o serviço esteja em execução. Se removermos o contêiner, e não o serviço, o serviço será
iniciar automaticamente o contêiner novamente. Remova o contêiner como:
|
1 |
doca rm -f abf8703ed713 |
Observe que você deve dar -f porque o contêiner já está em execução. Os mecanismos de autocorreção do Docker 1.12 entram em ação e reiniciam automaticamente o contêiner. Agora, se você listar os contêineres novamente:
|
1 2 3 |
CONTAINER ID IMAGEM COMANDO CRIADO STATUS PORTOS NOMES db483ac27e41 arungupta/oreilly-mosca selvagem@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914 "/opt/jboss/wildfly/b" 1 segundos atrás Para cima Menos do que a segundo 8080/tcp hellojavaee_web.1.ddvwdmojjysf46d4n3x4g8uv4 622756277f40 arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c "/entrypoint.sh /opt/" 26 segundos atrás Para cima 25 segundos 8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp hellojavaee_db.1.19enwdt6i5m853m5675tx3z29 |
Isso mostra que um novo contêiner foi iniciado. Inspecione o serviço WildFly:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
doca serviço inspecionar hellojavaee_web [ { "ID": "54otfi6dc9bis7z6gc6ubynwc", "Versão": { "Índice": 328 }, "CreatedAt": "2016-07-02T01:36:35.735767569Z", "UpdatedAt": "2016-07-02T01:36:35.739240775Z", "Especificação": { "Nome": "hellojavaee_web", "Rótulos": { "com.docker.stack.namespace": "hellojavaee" }, "TaskTemplate": { "ContainerSpec": { "Imagem": "arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914", "Env": [ "COUCHBASE_URI=db" ] } }, "Modo": { "Replicado": { "Réplicas": 1 } }, "Redes": [ { "Alvo": "epw57lz7txtfchmbf6u0cimis", "Aliases": [ "web" ] } ], "EndpointSpec": { "Modo": "vip", "Portas": [ { "Protocolo": "tcp", "TargetPort": 8080 } ] } }, "Ponto de extremidade": { "Especificação": {}, "Portas": [ { "Protocolo": "tcp", "TargetPort": 8080, "PublishedPort": 30004 } ], "VirtualIPs": [ { "NetworkID": "9lpz688ir3pzexubkcb828ikg", "Addr": "10.255.0.5/16" }, { "NetworkID": "epw57lz7txtfchmbf6u0cimis", "Addr": "10.0.0.4/24" } ] } } ] |
O Swarm atribui uma porta aleatória ao serviço, ou isso pode ser atualizado manualmente usando Atualização do serviço de docker comando. No nosso caso, a porta 8080 do contêiner é mapeado para 30004 no host.
Verificar o aplicativo
Verifique se o aplicativo foi implantado com êxito:
|
1 2 |
enrolar http://localhost:30004/books/resources/book [{"livros":0}] |
Adicione um novo livro ao aplicativo:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
enrolar -v > -H "Content-Type: application/json" > -X POST -d '{ > "isbn": "978-1-4919-1889-0", > "name": "Minecraft Modding with Forge", > "cost": 29.99 > }' > http://localhost:30004/books/resources/book * Tentando ::1... * Conectado para localhost (::1) porto 30004 (#0) > POST /livros/recursos/livro HTTP/1.1 > Anfitrião: localhost:30004 > Usuário-Agente: enrolar/7.43.0 > Aceitar: */* > Conteúdo-Tipo: aplicativo/json > Conteúdo-Comprimento: 92 > * carregar completamente enviado desligado: 92 fora de 92 bytes < HTTP/1.1 200 OK < Conexão: manter-vivo < X-Alimentado-Por: Undertow/1 < Servidor: WildFly/10 < Conteúdo-Tipo: aplicativo/octeto-fluxo < Conteúdo-Comprimento: 88 < Data: Sábado, 02 Julho 2016 01:39:49 GMT < * Conexão #0 para o host localhost permaneceu intacto {"name" (nome):"Minecraft Mhttp://localhost:30004/books/resources/book-1-4919-1889-0"} |
Verifique os livros novamente:
|
1 2 |
enrolar http://localhost:30004/books/resources/book [{"livros":{"name" (nome):"Modificação do Minecraft com o Forge","custo":29.99,"id":"1","isbn":"978-1-4919-1889-0"}}, {"livros":1}] |
Saiba mais sobre esse aplicativo Java EE em github.com/arun-gupta/oreilly-docker-book/tree/master/hello-javaee.
Este blog mostrou como criar um pacote de aplicativos distribuídos a partir do Docker Compose e implantá-lo como Docker Stack no modo Docker Swarm.
Referências de serviço e pilha do Docker
- Criação de serviço do Docker
- Livro GRATUITO da O'Reilly: Docker para desenvolvedores Java
- Couchbase em contêineres
- Portal do desenvolvedor do Couchbase
- Faça perguntas sobre @couchbasedev ou Stackoverflow

