Docker进阶:服务配置
当使用Docker Swarm模式时,我们可以通过命令docker service create
向Swarm集群部署应用服务。Swarm集群中的管理节点将服务描述视为应用服务所需的状态。其次,所有服务相关的命令,即docker service
,一定要在管理节点上运行(管理节点负责Swarm集群中的服务管理和任务编排)。
本文目录:
创建服务
Swarm集群中最简单创建服务的方式就是指定所要创建的服务镜像就可以,即命令docker service create <IMAGE>
。当执行创建服务命令后,Swarm编排器则向可用节点分派服务任务。一个任务其实就是一个基于指定镜像生成的容器。比如,创建一个nginx web服务。
# 在管理节点上
# --name参数用于指定服务的名称
$ docker service create --name myweb nginx
l3w3x4df6tnia8qql64mkdm1s
# 查看Swarm集群中的服务
$ docker service ls
ID NAME MODE REPLICAS IMAGE
l3w3x4df6tni myweb replicated 1/1 nginx:latest
当然,我们也可以在部署服务时指定容器中将要运行的指令,其命令为docker service create <IMAGE> <COMMAND>
。
$ docker service create --name myalpine ping www.bing.com
服务配置
当创建一个服务时,我们通过修改配置选项对服务进行限制,命令docker service create --help
可以查看创建服务的帮助信息。
配置服务的运行环境
我们可以通过以下参数配置服务的运行环境:
- –env参数可以指定环境变量
- –workdir参数可以指定容器中的工作目录
- –user参数可以指定用户名或者UID
# 通过不同的参数配置服务
$ docker service create --name myservice \
--env MYSERVICE=/usr/local/service
--workdir /tmp
--user subond
alpine ping www.baidu.com
配置服务规模和位置
前面的介绍中,我们讲到Swarm模式中有两种服务类型:复制服务(replicated service)和全局服务(global service)。对于复制服务类型,我们可指定–replicas参数来创建一定数量的服务任务,从而将任务分派到可用节点上;而对于全局服务,调度器则在每一个可用节点上均部署一个任务,–mode参数可以指定全局服务。具体如下:
# 在具有一个管理节点(manager)和一个工作节点(worker1)的Swarm集群中,部署一个具有两个副本的nginx web服务
# 在节点manger
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
34y77dgnqon4soj2kqyb65a9y * manager Ready Active Leader
nxb55hhu8kwp272z21xi9dhyy worker1 Ready Active
$ docker service create --name myweb1 --replicas 3 nginx
xpmhprvzqtl1fi0mdveowjdoa
# 创建成功
# docker service ls
ID NAME MODE REPLICAS IMAGE
xpmhprvzqtl1 myweb1 replicated 2/2 nginx:latest
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27aa642e7786 nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." 59 seconds ago Up 58 seconds 80/tcp myweb1.1.ei5mappmkkcdhbnk6gv3tcgrf
# 在节点worker1
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
245a257c56d5 nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." About a minute ago Up About a minute 80/tcp myweb1.2.y2am04ermd2b8d3qevfeyzn67
# 我们的可以看到在两个节点上均有一个myweb1服务
# 接下来,我们再部署一个myweb2服务,与myweb1不同的是,myweb2是全局服务
# 在manager节点上
$ docker service create --name myweb2 --mode global nginx
yfbd525ztbqpa688ego4u0de8
$ docker service ls
ID NAME MODE REPLICAS IMAGE
xpmhprvzqtl1 myweb1 replicated 2/2 nginx:latest
yfbd525ztbqp myweb2 global 2/2 nginx:latest
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a99dca94917 nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." About a minute ago Up About a minute 80/tcp myweb2.34y77dgnqon4soj2kqyb65a9y.rush02tpvachu294flrklw32p
27aa642e7786 nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." 8 minutes ago Up 8 minutes 80/tcp myweb1.1.ei5mappmkkcdhbnk6gv3tcgrf
# 在worker1节点上
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a00f5c5ce9b nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." About a minute ago Up About a minute 80/tcp myweb2.nxb55hhu8kwp272z21xi9dhyy.on9e6cr8obz3y51e84b3s72z4
245a257c56d5 nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." 8 minutes ago Up 8 minutes 80/tcp myweb1.2.y2am04ermd2b8d3qevfeyzn67
# 接下来,我们将工作节点worker2加入Swarm集群
$ 在worker2节点上
$ docker swarm join \
--token SWMTKN-1-1omg2k2e92snxv3wlja3komux5wan4hynn80ikkma2s9rd5cxz-9hq2vf8n0jysukytfqpavd8j7 \
172.28.128.3:2377
This node joined a swarm as a worker.
# 在manager节点上
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
34y77dgnqon4soj2kqyb65a9y * manager Ready Active Leader
nxb55hhu8kwp272z21xi9dhyy worker1 Ready Active
v0rmad0igl7xwn8alop33j3fu worker2 Ready Active
# 在worker2节点上
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
356da4542dd5 nginx@sha256:12d30ce421ad530494d588f87b2328ddc3cae666e77ea1ae5ac3a6661e52cde6 "nginx -g 'daemon ..." 40 seconds ago Up 39 seconds 80/tcp myweb2.v0rmad0igl7xwn8alop33j3fu.5wa1pg01i73u3a1feb73ht5p5
# 可以看到worker2上具有myweb2的服务,而不具备myweb1服务
# 这是复制服务和全局的模式的重要区别
配置发布端口
当创建Swarm服务时,有两个方式将服务的端口发布到Swarm群外的主机端口上:
- 依靠路由网络。当我们发布一个服务端口时,无论节点上是否运行着服务的任务,Swarm都会在每个节点的目标端口上访问该服务。
- 直接在运行该服务任务的节点上发布服务端口。Docker1.13及其更高版本支持该功能。
第一种:依靠路由网络发布端口
我们可以通过参数–publish :发布服务的端口。Swarm使得服务在每个节点的目标端口均可达。如果外部主机连接到Swarm集群中的任何一个节点,都可以通过路由网络将其路由到服务任务所在的节点上。外部主机不要知道服务任务所在的ip和内部使用的服务端口就可以与服务进行交互。
例如,我们在一个具有3个节点的Swarm集群中运行一个具有2个副本的nginx web服务,并将发布端口设为8080。那么,在任何一个节点上可以使用8080端口上的nging服务。
# 在manger节点上部署nginx web服务,并发布8080端口
$ docker service create --name myweb --replicas 2 --publish 8080:80 nginx
# 通过检查,我们发现在manager节点和worker2节点均有myweb任务
# 在worker1节点请求nginx服务
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
...
</body>
</html>
外部主机上,使用任何一个节点的ip均可以访问到nginx服务,如下图:
第二种:在Swarm节点上发布端口
通过指定mode=host来进行参数–publish的设定,我们可以将发布端口指定到每个运行服务任务的Swarm节点上。
主要注意的是:如果使用mode=host直接在Swarm节点上发布服务的端口,并且还设置published=,则会创建一个隐式限制,只能在给定的群组节点上为该服务运行一个任务。 另外,如果使用mode=host,并且在docker服务创建时不使用–mode=global标志,那么将难以知道哪些节点正在运行服务,以便将工作路由到它们。
接下来,我们创建一个全局服务类型的nginx web服务,并将发布端口指定为8090。
# 在manager节点上
$ docker service create --name mynginx --mode global --publish mode=host,target=80,published=8090 nginx
# 这样我们可以在Swarm任何一个节点上访问到8090端口上的nginx服务,即使新加入的节点。
- 原文作者:Kevin
- 原文链接:http://www.subond.com/post/2017-05-01_docker_swarm5/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。