Docker服务,堆栈和分布式应用程序捆绑

两周前宣布了Docker 1.12的第一个发布候选版本 。 此版本计划了几个新功能。

该博客将展示如何从Docker Compose创建分布式应用程序捆绑包,并将其作为Docker堆栈以Docker Swarm模式部署。 非常感谢@friism帮助我理解这些概念。

让我们先来看一下这些功能:

  • 内置编排 :典型的应用程序是使用Docker Compose文件定义的。 该定义由多个容器组成,并部署在多个主机上。 这样可以避免单点故障(SPOF),并保持应用程序的弹性。 多个编排框架(例如Docker Swarm,Kubernetes和Mesos)使您可以编排这些应用程序。 但是,这正是应用程序的重要特性,Docker Engine现在具有内置的编排。 在以后的博客中,有关此主题的更多详细信息。
  • 服务 :可以使用docker service create命令轻松创建复制,分布式和负载平衡的服务。 提供了应用程序的“所需状态”,例如运行3个Couchbase容器,并且自我修复的Docker引擎确保群集中正在运行许多容器。 如果某个容器发生故障,则将启动另一个容器。 如果某个节点发生故障,则该节点上的容器将在另一个节点上启动。 有关更多信息,请参见后面的博客。
  • 零配置安全性 :Docker 1.12随附经过相互认证的TLS,可为现存集群中每个参与节点的通信提供认证,授权和加密。 有关更多信息,请参见后面的博客。
  • Docker堆栈和分布式应用程序捆绑包 :分布式应用程序捆绑包(DAB)是一种多服务可分发映像格式。 进一步阅读以获取更多详细信息。

到目前为止,您可以获取一个Dockerfile并使用Dockerfile docker build命令Dockerfile创建映像。 可以使用docker run命令启动容器。 通过多次给出该命令,可以轻松启动多个容器。 或者,您也可以使用Docker Compose文件并使用docker-compose scale命令docker-compose scale容器。

码头工人生命周期

图像是单个容器的可移植格式。 分布式应用程序捆绑包 (DAB)是Docker 1.12中引入的新概念,是一种可移植的格式,用于多个容器。 然后可以在运行时将每个捆绑软件部署为堆栈

docker-stack-lifecycle

docker.com/dab上了解有关DAB的更多信息。

为了简单起见,可以得出一个类比:

Dockerfile->图片->容器

Docker Compose->分布式应用程序捆绑-> Docker Stack

让我们使用一个Docker Compose文件,从中创建一个DAB,并将其部署为Docker Stack。

重要的是要注意,这是1.12-RC2中的实验功能。

从Docker Compose创建分布式应用程序捆绑包

Docker Compose CLI添加了一个新的bundle命令。 可以找到更多详细信息:

docker-compose bundle --help
Generate a Docker bundle from the Compose file.
 
Local images will be pushed to a Docker registry, and remote images
will be pulled to fetch an image digest.
 
Usage: bundle [options]
 
Options:
    -o, --output PATH          Path to write the bundle file to.
                               Defaults to ".dsb".

现在,让我们采用Docker Compose定义并从中创建一个DAB。 这是我们的Docker Compose定义:

version: "2"
services:
  db:
    container_name: "db"
    image: arungupta/oreilly-couchbase:latest
    ports:
      - 8091:8091
      - 8092:8092 
      - 8093:8093 
      - 11210:11210
  web:
    image: arungupta/oreilly-wildfly:latest
    depends_on:
      - db
    environment:
      - COUCHBASE_URI=db
    ports:
      - 8080:8080

该Compose文件将启动WildFly和Couchbase服务器。 Java EE应用程序已在WildFly服务器中预先部署,该服务器连接到Couchbase服务器,并允许使用REST API执行CRUD操作。

该文件的来源位于: github.com/arun-gupta/oreilly-docker-book/blob/master/hello-javaee/docker-compose.yml

用它生成一个应用程序包:

docker-compose bundle
WARNING: Unsupported key 'depends_on' in services.web - ignoring
WARNING: Unsupported key 'container_name' in services.db - ignoring
Wrote bundle to hellojavaee.dsb

depends_on仅在两个服务之间创建依赖关系,并使它们以特定顺序启动。 这只能确保启动Docker容器,但容器中的应用程序可能需要更长的时间才能启动。 因此,此属性只能部分解决问题。 container_namecontainer_name一个特定的名称。 依赖于特定的容器名称是紧密耦合的,并且不允许缩放容器。 因此,暂时可以忽略这两个警告。

此命令使用Compose项目名称(即目录名称)生成文件。 因此,在本例中,将生成hellojavaee.dsb文件。 在RC3中,此文件扩展名已重命名为.dab

生成的应用程序包如下所示:

{
  "services": {
    "db": {
      "Image": "arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c", 
      "Networks": [
        "default"
      ], 
      "Ports": [
        {
          "Port": 8091, 
          "Protocol": "tcp"
        }, 
        {
          "Port": 8092, 
          "Protocol": "tcp"
        }, 
        {
          "Port": 8093, 
          "Protocol": "tcp"
        }, 
        {
          "Port": 11210, 
          "Protocol": "tcp"
        }
      ]
    }, 
    "web": {
      "Env": [
        "COUCHBASE_URI=db"
      ], 
      "Image": "arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914", 
      "Networks": [
        "default"
      ], 
      "Ports": [
        {
          "Port": 8080, 
          "Protocol": "tcp"
        }
      ]
    }
  }, 
  "version": "0.1"
}

该文件提供了应用程序中包含的服务的完整描述。 我不太确定Distributed Application Bundle是否是最合适的名称,请在#24250中进行讨论。 如果可以在这里支持其他容器格式,例如Rkt,甚至VM,那就太好了。 但就目前而言,Docker是唯一受支持的格式。

在Docker中初始化Swarm模式

如上所述,“所需状态”现在由Docker Swarm维护。 现在,它已经被移植到Docker Engine中了。

Docker Swarm概念也在不断发展,可以在Swarm模式下的关键概念中阅读。 稍后将发布有关此内容的更详细的博客。

但对于此博客,现在添加了新命令docker swarm

docker swarm --help
 
Usage:    docker swarm COMMAND
 
Manage Docker Swarm
 
Options:
      --help   Print usage
 
Commands:
  init        Initialize a Swarm
  join        Join a Swarm as a node and/or manager
  update      Update the Swarm
  leave       Leave a Swarm
  inspect     Inspect the Swarm
 
Run 'docker swarm COMMAND --help' for more information on a command.

在Docker Engine中初始化Swarm节点(作为工作程序):

docker swarm init
Swarm initialized: current node (ek9p1k8r8ox7iiua5c247skci) is now a manager.

可以使用docker swarm inspect命令找到有关此节点的更多详细信息。

docker swarm inspect
[
    {
        "ID": "1rcvu7m9mv2c8hiaijr7an9zk",
        "Version": {
            "Index": 1895
        },
        "CreatedAt": "2016-07-01T23:52:38.074748177Z",
        "UpdatedAt": "2016-07-02T04:54:32.79093117Z",
        "Spec": {
            "Name": "default",
            "AcceptancePolicy": {
                "Policies": [
                    {
                        "Role": "worker",
                        "Autoaccept": true
                    },
                    {
                        "Role": "manager",
                        "Autoaccept": false
                    }
                ]
            },
            "Orchestration": {
                "TaskHistoryRetentionLimit": 10
            },
            "Raft": {
                "SnapshotInterval": 10000,
                "LogEntriesForSlowFollowers": 500,
                "HeartbeatTick": 1,
                "ElectionTick": 3
            },
            "Dispatcher": {
                "HeartbeatPeriod": 5000000000
            },
            "CAConfig": {
                "NodeCertExpiry": 7776000000000000
            }
        }
    }
]

输出显示该节点只是一个工作程序,而不是管理程序。 如果群集只有一个节点,这可能很好。 但是,多节点群集至少应具有一个管理器。

部署Docker堆栈

使用docker deploy命令创建堆栈:

docker deploy -f hellojavaee.dsb hellojavaee
Loading bundle from hellojavaee.dsb
Creating network hellojavaee_default
Creating service hellojavaee_db
Creating service hellojavaee_web

#24249中所述,可以肯定地简化命令用法。

请参阅服务列表:

docker service ls
ID            NAME             REPLICAS  IMAGE                                                                                                COMMAND
2g8kmrimztes  hellojavaee_web  1/1       arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914    
46xhlb15cc60  hellojavaee_db   1/1       arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c

输出显示两个服务WildFly和Couchbase正在运行。 服务也是Docker 1.12中引入的新概念。 有什么让您拥有“理想状态”,而Docker Engine便为您提供了这种理想状态。

docker ps显示正在运行的容器的列表:

CONTAINER ID        IMAGE                                                                                                 COMMAND                  CREATED             STATUS              PORTS                                                        NAMES
622756277f40        arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c   "/entrypoint.sh /opt/"   3 seconds ago       Up 1 seconds        8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp   hellojavaee_db.1.19enwdt6i5m853m5675tx3z29
abf8703ed713        arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914     "/opt/jboss/wildfly/b"   3 seconds ago       Up 1 seconds        8080/tcp                                                     hellojavaee_web.1.70piloz6j4zt06co8htzisgyl

在Couchbase容器启动并运行之前,WildFly容器启动。 这意味着Java EE应用程序尝试连接到Couchbase服务器并失败。 因此,应用程序永远无法成功启动。

自我修复Docker服务

Docker Service维护应用程序的“期望状态”。 在我们的情况下,期望的状态是确保用于服务的一个(只有一个)容器正在运行。 如果我们删除容器而不是服务,则该服务将自动再次启动容器。

按照以下方式卸下容器:

docker rm -f abf8703ed713

注意,您必须给-f因为容器已经在运行。 Docker 1.12自愈机制启动并自动重启容器。 现在,如果您再次列出容器

CONTAINER ID        IMAGE                                                                                                 COMMAND                  CREATED             STATUS                  PORTS                                                        NAMES
db483ac27e41        arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914     "/opt/jboss/wildfly/b"   1 seconds ago       Up Less than a second   8080/tcp                                                     hellojavaee_web.1.ddvwdmojjysf46d4n3x4g8uv4
622756277f40        arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c   "/entrypoint.sh /opt/"   26 seconds ago      Up 25 seconds           8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp   hellojavaee_db.1.19enwdt6i5m853m5675tx3z29

这表明新的容器已启动。

检查WildFly服务:

docker service inspect hellojavaee_web
[
    {
        "ID": "54otfi6dc9bis7z6gc6ubynwc",
        "Version": {
            "Index": 328
        },
        "CreatedAt": "2016-07-02T01:36:35.735767569Z",
        "UpdatedAt": "2016-07-02T01:36:35.739240775Z",
        "Spec": {
            "Name": "hellojavaee_web",
            "Labels": {
                "com.docker.stack.namespace": "hellojavaee"
            },
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914",
                    "Env": [
                        "COUCHBASE_URI=db"
                    ]
                }
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 1
                }
            },
            "Networks": [
                {
                    "Target": "epw57lz7txtfchmbf6u0cimis",
                    "Aliases": [
                        "web"
                    ]
                }
            ],
            "EndpointSpec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 8080
                    }
                ]
            }
        },
        "Endpoint": {
            "Spec": {},
            "Ports": [
                {
                    "Protocol": "tcp",
                    "TargetPort": 8080,
                    "PublishedPort": 30004
                }
            ],
            "VirtualIPs": [
                {
                    "NetworkID": "9lpz688ir3pzexubkcb828ikg",
                    "Addr": "10.255.0.5/16"
                },
                {
                    "NetworkID": "epw57lz7txtfchmbf6u0cimis",
                    "Addr": "10.0.0.4/24"
                }
            ]
        }
    }
]

Swarm为服务分配了一个随机端口,或者可以使用docker service update命令手动更新。 在我们的情况下,容器的端口8080映射到主机上的30004端口。

验证申请

检查应用程序是否已成功部署:

curl http://localhost:30004/books/resources/book
[{"books":0}]

向应用程序添加一本新书:

curl -v \
&qt; -H "Content-Type: application/json" \
&qt; -X POST -d '{
&qt;   "isbn": "978-1-4919-1889-0",
&qt;   "name": "Minecraft Modding with Forge",
&qt;   "cost": 29.99
&qt; }' \
&qt; http://localhost:30004/books/resources/book
*   Trying ::1...
* Connected to localhost (::1) port 30004 (#0)
&qt; POST /books/resources/book HTTP/1.1
&qt; Host: localhost:30004
&qt; User-Agent: curl/7.43.0
&qt; Accept: */*
&qt; Content-Type: application/json
&qt; Content-Length: 92
&qt; 
* upload completely sent off: 92 out of 92 bytes
<HTTP/1.1 200 OK
<Connection: keep-alive
<X-Powered-By: Undertow/1
<Server: WildFly/10
<Content-Type: application/octet-stream
<Content-Length: 88
<Date: Sat, 02 Jul 2016 01:39:49 GMT
<
* Connection #0 to host localhost left intact
{"name":"Minecraft Mhttp://localhost:30004/books/resources/book-1-4919-1889-0"}

再次验证书籍:

curl http://localhost:30004/books/resources/book
[{"books":{"name":"Minecraft Modding with Forge","cost":29.99,"id":"1","isbn":"978-1-4919-1889-0"}}, {"books":1}]

github.com/arun-gupta/oreilly-docker-book/tree/master/hello-javaee上了解有关此Java EE应用程序的更多信息。

该博客展示了如何从Docker Compose创建分布式应用程序捆绑包,并在Docker Swarm模式下将其作为Docker Stack部署。

翻译自: https://www.javacodegeeks.com/2016/07/docker-services-stack-distributed-application-bundle.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值