MYF

Get Started, Part 3: Services

参考文档:Get Started, Part 3: Services

Prerequisites

  • 安装Docker1.13以上版本
  • 搞定Docker Compose,在Mac或者Windows的docker中,这个已经预先安装好了,你可以直接开始。在Linux系统中,你需要直接安装。在之前的没有Hyper-V的Windows 10系统中,使用Docker Toolbox。
  • 阅读Part 1
  • 阅读Part 2学会如何创建conatiner
  • 确认你已经发布在publishing it to a registry节中创建的了friendlyhelloimage,我们这节需要使用这个。
  • 确认你的image像被部署的容器一样运行正常,运行这个命令,将usernamerepo,和tag换成你的:docker run -p 80:80 username/repo:tag,然后访问http://localhost/

Introduction

在Part 3中,我们将要扩张我们的应用,同时启动负载均衡(load-balancing)。想要这么做,我们必须在分布式应用上向上一个层级:service

  • Stack
  • Services(你在这里)
  • Container(在Part 2中已经介绍了)

About services

在分布式应用中,app不同的部分(pieces)叫做service。比如,如果你想做一个视频分享网站,这可能包括在数据库中存储应用数据,一个将视频在用户上传之后进行转码的服务,一个前端的服务等等。

Service是“产品中的容器”。一个service只运行一个image,但是管理了image运行的方式——使用什么端口,有多少个container的复制品需要运行从而service达到从需要的容量。Scale一个serviece改变容器实例的数量,分配更多的运算资源。

幸运的是,通过docker平台想要定义、运行、scale各种服务非常简单,只需要写一个docker-compose.yml文件。

Your first docker-compse.yml file

一个docker-compose.yml文件十一个YAML文件,在其中定义了在production中Docker容器如何运行。

将这个文件保存为docker-compose.yml在任何你想要的地方。确保你已经将part 2中的image推送了,同时对于下面的YAML文件替换username/repo:tag为你自己的image信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# filename: docker-compose.yml
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "80:80"
networks:
- webnet
networks:
webnet:

这个docker-compose.yml文件告诉Docker以下几件事情:

  • 把我们之前上传的image给pull下来
  • 运行这个image的5个实例作为一个service,叫做web,限制每一个最多用10%的CPU和50MB的RAM
  • 如果其中一个fail了,立刻重启containers
  • 将主机的80端口映射到web的80端口
  • 指示web的container来分享80端口通过一个叫做webnet的负载均衡网络。在内部,容器自身通过一个转瞬即逝的端口来发布到80端口。
  • 使用默认的设置来定义webnet网络

Run your new load-balanced app

在我们使用docker stack deploy命令前,我们先运行:

1
2
3
4
5
6
7
8
[root@centos-s-1vcpu-1gb-sfo2-01 docker]# docker swarm init --advertise-addr 123.45.67.234
Swarm initialized: current node (uokt7cupzqo0y5u3glmj11uhw) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-1zk9xtopyusryowiyd5r42zfip0nppbyxfc8hjjfw8hjoma34v-dat294y134bzkmnm2v4k0k154 123.45.67.234:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

注意:我们进入了Part 4中的命令的意义,如果你不运行这句话,你会遇到报错——“this node is not a swarm manager”

现在我们来运行他。你需要给你的app其一个名字,这里我们设置其为getstartedlab

1
docker stack deploy -c docker-compose.yml getstartedlab

我们单一的service stack正在运行着5个我们部署的image的容器实例在主机上。让我们来看一下,获取service的ID:

1
2
3
[root@centos-s-1vcpu-1gb-sfo2-01 docker]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
u0rekntjyshs getstartedlab_web replicated 5/5 manyfun711/get-started:part2 *:80->80/tcp

查看web服务的输出,考虑你的app名称。尽管你给他起名和例子中的一样都叫getstartedlab_web。这个service ID也被列出来了,同时还有副本的数量,image名称,以及暴露的端口。

一个单独的容器在一个服务中运行称为一个task。每一个Task有独立的ID随着数值上升,最大到达replicas的数量,也就是你在docker-compose.yml中定义的那样。列出你你的服务中的task:

1
2
3
4
5
6
7
[root@centos-s-1vcpu-1gb-sfo2-01 docker]# docker service ps getstartedlab_web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ekla2kc1fbdw getstartedlab_web.1 manyfun711/get-started:part2 centos-s-1vcpu-1gb-sfo2-01 Running Running 12 minutes ago
5e8p56tjzrfg getstartedlab_web.2 manyfun711/get-started:part2 centos-s-1vcpu-1gb-sfo2-01 Running Running 12 minutes ago
1ltvyby9xw0y getstartedlab_web.3 manyfun711/get-started:part2 centos-s-1vcpu-1gb-sfo2-01 Running Running 12 minutes ago
hyrfnsl4qxve getstartedlab_web.4 manyfun711/get-started:part2 centos-s-1vcpu-1gb-sfo2-01 Running Running 12 minutes ago
rj4vr5yh4lvt getstartedlab_web.5 manyfun711/get-started:part2 centos-s-1vcpu-1gb-sfo2-01 Running Running 12 minutes ago

当你列出系统中所有的容器的时候,Tasks也可以显示出来,尽管并不是按照service分类的。

1
docker container ls -q

你可以运行curl -4 http://localhost一行多次,或者打开浏览器访问这个地址然后刷新多次。不管哪种方式,container的ID都会改变,表明这有负载均衡。对于每一个请求,这5个task中的一个会被选中,使用轮转法(round-robin fashion)的方式来响应。container的ID匹配的上你之前命令(docker container ls -q)的输出。

运行在Windows 10?
Windows 10的PowerShell应该已经有了curl,但是你不能抓一个像Git Bash一样的linux的仿真器,或者下载wget for windows。

Slow response times?
这取决于你的网络环境配置,可能会花上30s对于containers来响应http请求。这不代表Docker或者swarm的性能,而是一个没满足的Redis依赖,我们在后面的教程中会说。目前来说,访客计数器因为相同的原因无法工作,我们还没有将服务添加到持久化数据中(persist data)。

Scale the app

你可以规模化你的应用通过更改docker-compose.yml文件中的replicas的值,保存更改,然后重新运行docker stack deploy命令:

1
docker stack deploy -c docker-compose.yml getstartedlab8

Docker展现了一个in-place的更新,不需要破坏stack或者kill掉任何containers;

现在,我们重新执行docker container ls -q来看看部署的实例被重新配置了。如果你增加了replica的数量,更多的task,也就是说更多的container会被启动。

Take down the app and the swarm

关掉app和swarm

将app关掉使用docker stack rm指令

1
docker stack rm getstartedlab

关掉集群

1
docker swarm leave --force

想要使用docker来简历你的app非常容易。你已经在如何使用container进行生产上进行了一大步了。接下来,你将学习如何运行这个app在一个真正的swarm在一系列docker机器上。

注意:类似的Compose files用于定义Docker的应用,并且可以被上传到Docker Cloud云上,或者任何提供Docker Enterprise Edition的硬件或云

Recap and cheat sheet (optional)

1
2
3
4
5
6
7
8
docker stack ls                                            # List stacks or apps
docker stack deploy -c <composefile> <appname> # Run the specified Compose file
docker service ls # List running services associated with an app
docker service ps <service> # List tasks associated with an app
docker inspect <task or container> # Inspect task or container
docker container ls -q # List container IDs
docker stack rm <appname> # Tear down an application
docker swarm leave --force # Take down a single node swarm from the manager