转载

9. 在Docker Swarm集群中运行Java EE应用

Docker Swarm是Docker的原生集群。它允许你使用全套的Docker工具来创建和访问一批Docker主机。Docker Swarm提供标准的Docker API,任何可以与Docker后台通信的工具都能够使用Swarm将其扩展到多个主机上。

9.1 Docker Swarm关键组件

9. 在Docker Swarm集群中运行Java EE应用

Swarm Manager:Docker Swarm有一个管理者,是一台预先准备的Docker主机,作为所有管理工作的唯一入口。它策划和调度整个集群的容器。当前仅允许集群中有一个管理者的实例。这是一个高可用架构的单点故障,在未来的Swarm版本中将会允许其他的管理者,参见 #598 。

Swarm Nodes:容器被部署在节点上。每一个Swarm节点能够被管理者访问,每一个节点必须监听相同的TCP端口。每一个节点运行一个Docker Swarm代理,用来注册使用的Docker后台,监控和更新后端发现的节点状态。容器运行在一个节点上。

Scheduler Strategy:不同的调度策略(紧密,宽松(默认),随机)用来选择运行容器的最佳节点。默认的策略是的运行容器的节点数最少。通过不同类型的过滤器,比如限制条件和相似性,用来考虑一个合适的调度算法。

Node Discovery Service:Swarm默认使用本机的发现服务,以Docker Hub为基础,通过令牌来发现集群中的节点。但是etcd,consul,和ZooKeeper也能够作为服务发现。这是特别有用的如果不能访问因特网,或者你在一个封闭网络内运行。一个新的服务发现后台能够这样被创建,主机服务发现在防火墙内部是有用的,就像 #660 讨论的。

Standard Docker API:Docker Swarm提供了标准的Docker API,因此任何能够和单一Docker主机通信的工具将能无缝扩展到多个主机。这就意味着如果你在shell脚本中使用Docker CLI来配置多个Docker主机,同样的CLI将会和Swarm集群通信,然后Docker Swarm将会作为代理在集群中运行。

9.2. 创建一个Docker Swarm集群

1. 创建Swarm最简单的方式是,使用正式的Docker镜像:

From Internet

docker run --rm swarm create

From Instructor

docker run --rm classroom.example.com:5000/swarm create

这个命令返回一个发现令牌,文档中使用TOKEN来标记它,它是一个唯一的集群ID。它将在随后的创建master和节点的时候使用。集群ID由Docker Hub的发现服务返回。

它显示如下输出:

Unable to find image 'swarm:latest' locally
latest: Pulling from swarm
55b38848634f: Pull complete
fd7bc7d11a30: Pull complete
db039e91413f: Pull complete
1e5a49ab6458: Pull complete
5d9ce3cdadc7: Pull complete
1f26e949f933: Pull complete
e08948058bed: Already exists
swarm:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:0e417fe3f7f2c7683599b94852e4308d1f426c82917223fccf4c1c4a4eddb8ef
Status: Downloaded newer image for swarm:latest
1d528bf0568099a452fef5c029f39b85

最后一行就是TOKEN。

注意:确保记录下这个集群ID,因为之后不会再显示。这个问题将在 #661 中被修复。

Swarm完全集成在Docker Machine中,所以最简单的方式是像下面这样:

From Internet

docker-machine create -d virtualbox --swarm --swarm-master --swarm-discovery token://<token> swarm-master

From Instructor

docker-machine create -d virtualbox --virtualbox-boot2docker-url=http://classroom.example.com:8082/downloads/boot2docker.iso --engine-insecure-registry=classroom.example.com:5000 --swarm --swarm-master --swarm-discovery token://<token> swarm-master

使用前面步骤中的TOKEN替换对应的内容。

--swarm 在machine中配置swarm, --swarm-mster 配置创建的machine作为Swarm master。Swarm master和Docker Hub上的服务进行通信,通知它一个master在集群中被创建了。

  1. 连接刚刚创建的master,获取相关信息:

    {{{

    eval "$(docker-machine env swarm-master)"

    docker info

    }}}

注意:如果你使用Windows,使用 docker-machine env swarm-master 命令,复制输出内容到编辑器中,用SET替换所有的EXPORT,去掉所有的引号和重复的/ 。

输出内容如下:

docker info
Containers: 2
Images: 7
Storage Driver: aufs
Root Dir: /mnt/sda1/var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 11
Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.0.5-boot2docker
Operating System: Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015
CPUs: 1
Total Memory: 996.2 MiB
Name: swarm-master
ID: DLFR:OQ3E:B5P6:HFFD:VKLI:IOLU:URNG:HML5:UHJF:6JCL:ITFH:DS6J
Debug mode (server): true
File Descriptors: 22
Goroutines: 36
System Time: 2015-07-11T00:16:34.29965306Z
EventsListeners: 1
Init SHA1:
Init Path: /usr/local/bin/docker
Docker Root Dir: /mnt/sda1/var/lib/docker
Username: arungupta
Registry: https://index.docker.io/v1/
Labels:
provider=virtualbox
  1. 创建Swarm节点:

    {{{

    #From Internet

    docker-machine create -d virtualbox --swarm --swarm-discovery token://<TOKEN> swarm-node-01

From Instructor

docker-machine create -d virtualbox --virtualbox-boot2docker-url= http://classroom.example.com:8 ... r.iso --engine-insecure-registry=classroom.example.com:5000 --swarm --swarm-discovery token://<TOKEN> swarm-node-01

}}}

使用早先的集群ID替换TOKEN。

节点会和Docker Hub上的服务通信,并加入之前创建的集群。通过 --swarm-discovery token://... 的方式来指定。让我们来创建第二个节点:

From Internet

docker-machine create -d virtualbox --swarm --swarm-discovery token://<TOKEN> swarm-node-02

From Instructor

docker-machine create -d virtualbox --virtualbox-boot2docker-url=http://classroom.example.com:8082/downloads/boot2docker.iso --engine-insecure-registry=classroom.example.com:5000 --swarm --swarm-discovery token://<TOKEN> swarm-node-02

使用早先的集群ID替换TOKEN。

  1. 显示创建的所有节点

    {{{

    docker-machine ls

    }}}

显示的输出如下:

docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
lab virtualbox Running tcp://192.168.99.101:2376
swarm-master * virtualbox Running tcp://192.168.99.102:2376 swarm-master (master)
swarm-node-01 virtualbox Running tcp://192.168.99.103:2376 swarm-master
swarm-node-02 virtualbox Running tcp://192.168.99.104:2376 swarm-master

存在集群中的machine会出现一个集群名字在SWARM列下,否则是一个空白。例如“lab”和“summit2015”是独立的machine,而其他的所有machine是“swarm-master”集群的一部分。Swarm master同样在SWARM列中定义为(master)。

  1. 连接Swarm集群,查看相关信息:

    {{{

    eval "$(docker-machine env --swarm swarm-master)"

    docker info

    }}}

输出如下显示:

docker info
Containers: 4
Images: 3
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
swarm-master: 192.168.99.102:2376
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.022 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
swarm-node-01: 192.168.99.103:2376
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.022 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
swarm-node-02: 192.168.99.104:2376
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.022 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
CPUs: 3
Total Memory: 3.065 GiB

这里有3个节点,一个Swarm master,2个Swarm节点。总共有4个容器运行在集群中,1个Swarm代理运行在master和节点上,以及一个swarm-agent-master运行在master上。

  1. 显示集群中的所有节点:

    {{{

    docker run swarm list token://<TOKEN>

    }}}

输出显示如下:

docker run swarm list token://1d528bf0568099a452fef5c029f39b85
192.168.99.103:2376
192.168.99.104:2376
192.168.99.102:2376

9.3. 部署Java EE应用到Docker Swarm集群

现在有了一个完整的集群,我们需要部署Java EE应用到集群中。

Swarm检查节点中发布的部署,唯一要做的是,我们需要按照在 部署Java EE7应用(容器链接方式) 中说过的一样来部署应用。

  1. 启动MySQL服务器:

    {{{

    #From Internet

    docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -p 3306:3306 -d mysql

From Instructor

docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -p 3306:3306 -d classroom.example.com:5000/mysql

}}}

-e 定义数据库启动时的环境变量,来允许我们通过这个用户和密码访问数据库。

  1. 启动WildFly并部署Java EE7 应用:

    {{{

    #From Internet

    docker run -d --name mywildfly --link mysqldb:db -p 8080:8080 arungupta/wildfly-mysql-javaee7

From Instructor

docker run -d --name mywildfly --link mysqldb:db -p 8080:8080 classroom.example.com:5000/wildfly-mysql-javaee7

}}}

这里使用之前说过的 Docker容器链接 。

  1. 检查集群状态:

    > docker info
    Containers: 7
    Images: 5
    Role: primary
    Strategy: spread
    Filters: affinity, health, constraint, port, dependency
    Nodes: 3
    swarm-master: 192.168.99.102:2376
    └ Containers: 2
    └ Reserved CPUs: 0 / 1
    └ Reserved Memory: 0 B / 1.022 GiB
    └ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
    swarm-node-01: 192.168.99.103:2376
    └ Containers: 2
    └ Reserved CPUs: 0 / 1
    └ Reserved Memory: 0 B / 1.022 GiB
    └ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
    swarm-node-02: 192.168.99.104:2376
    └ Containers: 3
    └ Reserved CPUs: 0 / 1
    └ Reserved Memory: 0 B / 1.022 GiB
    └ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
    CPUs: 3
    Total Memory: 3.065 GiB

“swarm-node-02”运行了3个容器,让我们看看运行的容器内容:

eval &quot;$(docker-machine env swarm-node-02)&quot;
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35325d730c97 arungupta/wildfly-mysql-javaee7 &quot;/opt/jboss/wildfly/ 57 seconds ago Up 56 seconds 0.0.0.0:32768->8080/tcp rafael_mywildfly_1
dd3525575b12 mysql &quot;/entrypoint.sh mysq 57 seconds ago Up 56 seconds 3306/tcp rafael_mysqldb_1
e9f655cbcb4b swarm:latest &quot;/swarm join --adver 27 minutes ago Up 27 minutes 2375/tcp swarm-agent

1.访问应用:

curl http://$(docker-machine ip swarm-node-02):8080/employees/resources/employees

查看输出内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><collection><employee><id>1</id><name>Penny</name></employee><employee><id>2</id><name>Sheldon</name></employee><employee><id>3</id><name>Amy</name></employee><employee><id>4</id><name>Leonard</name></employee><employee><id>5</id><name>Bernadette</name></employee><employee><id>6</id><name>Raj</name></employee><employee><id>7</id><name>Howard</name></employee><employee><id>8</id><name>Priya</name></employee></collection>

9.4. 使用Docker Compose部署Java EE应用到Docker Swarm集群中

使用Docker Compose管理多个容器 解释了多个容器经验怎样通过Docker Compose来简单的启动。

  1. 连接“swarm-node-02”:
    eval "$(docker-machine env swarm-node-02)"
  2. 停止MySQL和WildFly容器:
    docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f
    docker ps -a | grep mysql | awk '{print $1}' | xargs docker rm -f
  3. 使用 docker-compose.yml 文件来启动容器
    docker-compose up -d
    Creating wildflymysqljavaee7_mysqldb_1...
    Creating wildflymysqljavaee7_mywildfly_1...
  4. 检查集群中运行的容器:
    eval "$(docker-machine env --swarm swarm-master)"
    docker info

查看输出内容:

docker info
Containers: 7
Images: 5
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
swarm-master: 192.168.99.102:2376
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.022 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
swarm-node-01: 192.168.99.103:2376
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.022 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
swarm-node-02: 192.168.99.104:2376
└ Containers: 3
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.022 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.0.5-boot2docker, operatingsystem=Boot2Docker 1.7.0 (TCL 6.3); master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015, provider=virtualbox, storagedriver=aufs
CPUs: 3
Total Memory: 3.065 GiB

  1. 再次连接“swarm-node-02”:

    {{{

    eval "$(docker-machine env swarm-node-02)"

    }}}

查看当前运行的容器列表:

docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35325d730c97 arungupta/wildfly-mysql-javaee7 "/opt/jboss/wildfly/ 57 seconds ago Up 56 seconds 0.0.0.0:32768->8080/tcp rafael_mywildfly_1
dd3525575b12 mysql "/entrypoint.sh mysq 57 seconds ago Up 56 seconds 3306/tcp rafael_mysqldb_1
e9f655cbcb4b swarm:latest "/swarm join --adver 27 minutes ago Up 27 minutes 2375/tcp swarm-agent
  1. 检查日志

    {{{

    docker-compose logs

    }}}

使用 https://github.com/javaee-samp ... es/55 增加容器可视化。

原文链接: 9. Java EE Application on Docker Swarm Cluster

正文到此结束
Loading...