关闭

尝试docker1.12内置swarm

标签: docker1.12 docker sw
3203人阅读 评论(2) 收藏 举报
分类:

自从Dockercon 2016发布Docker 1.12版本以来, 经历了几个RC版本后Docker 1.12终于迎来了第一个稳定版.


Docker 1.12展露了docker一统生态的野心。docker engine集成swarmkit, 使得你可以不用安装额外的软件包, 就可以用简单的命令创建和管理docker swarm集群。

同时集成了swarm集群的安全特性和K-V存储, 你现在也不需要额外去部署etcd或者consul等应用。


1.在所有节点上安装docker1.12

 

## 添加docker repo文件

tee /etc/yum.repos.d/docker.repo <<-'EOF'

[dockerrepo]

name=Docker Repository

baseurl=https://yum.dockerproject.org/repo/main/centos/7/

enabled=1

gpgcheck=1

gpgkey=https://yum.dockerproject.org/gpg

EOF

## 安装 docker package

yum install docker-engine -y

## 启动docker

systemctl start docker

systemctl enable docker

## 检查docker版本

docker -v

Docker version 1.12.0, build 8eab29e


2.在node1节点上安装docker-compose:

 

curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

docker-compose -v

docker-compose version 1.8.0, build f3628c7


3.通过docker-compose启动应用

  前提是cd到 docker-compose.yml执行

  docker-compose up

使用Control+C停止应用,我们使用-d参数后台启动应用.

# docker-compose ps   //查看运行情况

# docker-compose logs  //查看应用日志

docker-compose logs --tail 10 --follow  //#滚动输出应用日志, 每个容器输出最新10行

注意:日志滚动输出的时候按Ctrl+S暂停, Ctrl+Q 继续输出, Ctrl+C退出

docker-compose down  //停止应用

4.通过Scale up扩展应用

docker-compose ps

# 可以看到我们现在只有一个worker服务

# 增加到2个 worker服务, 使用如下命令

# docker-compose scale worker=2

Creating and starting dockercoins_worker_2 ... done


5.应用的瓶颈

当我们扩展worker为10发现性能并没有提升上去,原因是我们所有的应用都是跑在一台服务器上,多个work节点导致服务器资源竞争,所以几遍增加work节点也不能改善性能,另外也可能是其他节点导致的瓶颈。

瓶颈问题解决:针对第一个work节点的话,我们可以建立docker集群环境,使得worker节点可以分布在不同虚拟机上运行,针对后面其他节点瓶颈问题可以建立多个相关节点来消除瓶颈。

6.创建swarm集群

Docker Engine 1.12及后续版本集成了SwarmKit编排服务,即Swarm Mode。它将服务对象引入到docker中,提供swarm集群管理的原生支持并实现scaling、rolling update、service discovery、load balance、routing mesh等特性。

基本概念

  • 节点(Node)为swarm集群中的一个Docker Engine实例。其中管理节点(Manager Node)负责swarm集群管理并向工作节点分配任务;工作节点(Work Node)接受并执行来自管理节点的Task。简单可理解为一个Node就是一台Docker宿主机,管理节点为领导,工作节点为小兵。

    需要注意的是领导也会干小兵的活儿,真是个好领导啊...而且小兵也可以根据需求随时提拔成领导,真是个好团队啊...

  • 服务(Service)是对在worker nodes所运行一组任务的定义,它是整个swarm的核心,一个Service由多个任务组成。

  • 任务(Task)包含Docker容器和容器中运行的命令或应用,它是swarm中被调度的最小单元。简单可理解为一个Task就是一个容器。


Swarm Mode下主要使用三组新的命令行工具创建和管理一个Swarm集群:

  • docker swarm:开启swarm模式; 加入Swarm集群; 配置集群参数

  • docker node: 查询集群节点信息; 提升/移除一个管理节点; 管理swarm节点主机

  • docker service: 创建管理service


 在node1上初始化swarm集群:
  #docker swarm init --advertise-addr 192.168.0.2
  备注:
  • 你只需要在一个node上初始化swarm集群, 其他node加入这个集群就行了, 所以以上命令只需要在node01上运行。

  • --advertise-addr参数, 后面跟你swarm集群的通讯地址, 这里是node01的IP地址。

  • 命令输出的提示很人性化吧,在需要的管理/工作节点复制粘贴运行即可加入到swarm集群中

  

 #docker swarm join \

--token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-3e8p1ojarz8rdq1rx0ves1a9o \

192.168.0.2:2377     //将node1以manager角色加入swarm集群

 #docker info   //检查node1 docker swarm mode信息

 #docker node ls //查看swarm集群node列表

 #docker swarm join \

--token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-4l4b6o7q1wnjyiwsubkpffkkn \

192.168.0.2:2377  //将其他节点加入到集群

 如果你不记得初始化后提示加入swarm集群的命令和密钥也没关系,可以使用如下方式查看worker节点和manager节点的加入命令

            # docker swarm join-token worker

            # docker swarm join-token manager

 注意:为了swarm集群的高可用,避免单点故障可以多建立几个manager节点

  # docker node promote node02 node03  //提升node02和node03节点为manager节点

 此时通过docker node ls可以看到  node1是Leader节点, node02和node03是Reachable节点,这是可以通过node02和node03上面管理整个swarm集群。


7.在Swarm集群运行Service

  

有了Docker Swarm集群,我们如何把我们的应用跑在Swarm集群上呢?

很简单, 将我们原来我们使用的docker run命令替换成docker service create就行了,命令后面的格式和选项全都一样。

docker service create --name ping-google alpine ping 8.8.8.8  //在swarm集群上, 启动一个alpine镜像来执行ping 8.8.8.8命令(如果出错,swarm集群会不断帮你重试启动容器,直到成功为止)

   docker service ps <Service ID or Name>命令可以查看服务到底跑在哪个节点服务器上
 。扩展(Scale)服务

    前面ping-google服务只有一个容器,现在我们想Scale服务到10个副本,可以使用

      docker service scale <Service ID or Name>=<replicas No.>

      如#docker service scale ping-google=10    

       # docker service ls

        ID            NAME         REPLICAS  IMAGE   COMMAND

        9cyy6xrk2n0w  ping-google  1/10      alpine  ping 8.8.8.8

    这里REPLICAS显示的1/10表示这个service一共有10个副本,现在成功运行了一个,集群正在启动其他副本 

     #dockerr service ps ping-goole  //查看service进程

       等所有的副本都启动成功了, 你会看到swarm集群会自动编排10个副本到5台docker宿主机上,而且每个节点会启动2个容器。

    。开发一个服务端口       

        跟我们在单机使用docker一样, 你可以将你容器的端口暴露到主机网络中,从而使得跑在容器中的应用能够被外部访问。

       swarm集群的service端口暴露还有如下特性:

  • 公共的端口会暴露在每一个swarm集群中的节点服务器上.

  • 请求进如公共端口后会负载均衡到所有的sevice实例上.

       发布端口的参数跟单机环境一样是-p, 就是把docker run -p替换成docker service create -p就行

       #docker service create --name search --publish 9200:9200 --replicas 7 elasticsearch   //创建一个elasticsearch服务, 发布9200端口

       可以使用watch docker service ps search监控service创建过程

       

       注意DESIRED STATE列, 一个service副本的创建过程,会经历以下几个状态:

  • accepted 任务已经被分配到某一个节点执行

  • preparing 准备资源, 现在来说一般是从网络拉取image

  • running 副本运行成功

  • shutdown 呃, 报错,被停止了…

        当一个任务被终止stoped or killed.., 任务不能被重启, 但是一个替代的任务会被创建.

        

         测试服务端口:

# curl localhost:9200

{

  "name" : "Rachel Grey",

  "cluster_name" : "elasticsearch",

  "version" : {

    "number" : "2.3.4",

    "build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f",

    "build_timestamp" : "2016-06-30T11:24:31Z",

    "build_snapshot" : false,

    "lucene_version" : "5.5.0"

  },

  "tagline" : "You Know, for Search"

}

        反复执行这个命令, 你会看到name会改变, 请求会被分发到不同的service副本.


  。删除服务

     使用docker service rm <Service ID or Name> 命令删除服务

     docker service ls -q | xargs docker service rm  //删除所有servcie


 8.在Swarm集群上运行应用
    为了让我们的应用跑在swram集群上,我们要解决容器间的网络通信问题。单节点场景中,我们应用所有的容器都跑在一台主机上, 所以容器之间的网络是内部互通的。
   

     那我们该如何保证不同主机上的容器网络互通呢?

     不用担心,swarm集群已经帮我们解决了这个问题了,那就是overlay network.

     在docker 1.12以前, swarm集群需要一个额外的key-value存储(consul, etcd etc)来同步网络配置, 保证所有容器在同一个网段中。

     在docker 1.12中已经内置了这个存储并且集成了overlay networks的支持。至于overlay network的细节, 就不多介绍了。

    。创建一个overlay network

        docker network create --driver overlay test  //创建一个名为test的overlay network

        #docker network ls  //查看docker network列表

          在网络列表中你可以看到dockercoins网络的SCOPE是swarm, 表示该网络是在整个swarm集群生效的, 其他一些网络是local, 表示本机网络.

          你只需要在manager节点创建overlay network即可, swarm集群会自动配置到其他的节点。当overlay network在manager节点创建完毕后再查看其他节点的网络状态,可以看到各节点的test网络已经创建了.:

                  如:ssh node03 docker network ls

        。在网络上运行容器

            直接使用--network <network name>参数, 在指定网络上创建service.

            docker service create --network test --name redis redis

            docker service create --network test --name hasher localhost:5000/dockercoins_hasher:v0.1 //创建hasher服务

            docker service rm webui  //删除webui

            docker service create --network test --name webui -p 8000:80 localhost:5000/dockercoins_webui:v0.1

            好了, 现在你可以用浏览器访问http://192.168.0.2:8000/index.html 就能看到我们熟悉的webui了.事实上, 你可以通过访问swarm集群中的所有节点(192.168.0.2 - 192.168.0.6)的8000端口来访问到我们的webui.

        。扩展(Scaling)应用

           两种方式:

                          》docker service scale worker=10

                          》通过修改服务的属性来实现

                               # docker service inspect rng   //查询service属性

                                     “Mode": {

                                                            "Replicated": {

                                                                   "Replicas": 1

                                                                 }

                                    #docker service update rng --replicas 5  //更新rng服务属性


                  #docker service ls  //查看服务

          。找程序瓶颈

             docker service create --network test --name debug --mode global alpine sleep 1000000000

                启动一个临时容器, debug使用alpine镜像, 连接到test网络中.

  • --mode globle 是啥意思呢?global模式的service, 就是在swarm集群的每个节点创建一个容器副本, 所以如果你想让一个service分布在集群的每个节点上,可以使用这个模式.

  • sleep 1000000000是为啥呢?因为懒, 想保持这个容器, 方便我们debug.

       

          随便进入某个节点中的debug容器,安装性能测试工具:curl,ab和drill  -------#apk add --update curl apache2-utils drill

          

3.4.1 负载均衡模式

检查rng服务

/ # drill rng

;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 16923

;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:

;; rng. IN A

;; ANSWER SECTION:

rng. 600 IN A 10.0.0.6

....

可以看到rng服务的IP地址是10.0.0.6。我们一共有5个rng服务, 为啥只有一个IP地址呢?其实这个IP地址是swarm集群分配给所有rng服务负载均衡的VIP(Virtual IP).


swarm集群负载均衡service有两种方式—VIP和DNSRR:

  • VIP模式每个service会得到一个virtual IP地址作为服务请求的入口。基于virtual IP进行负载均衡.

  • DNSRR模式service利用DNS解析来进行负载均衡, 这种模式在旧的Docker Engine下, 经常行为诡异…所以不推荐.


如何查看service的负载均衡模式呢:

docker service inspect rng

...

            "EndpointSpec": {

                "Mode": "vip"

            }

        },

        "Endpoint": {

            "Spec": {

                "Mode": "vip"

            },

            "VirtualIPs": [

                {

                    "NetworkID": "396fwpd5ja6azh93dshalmxro",

                    "Addr": "10.0.0.6/24"

                }

            ]

        },

...


指定一个service的模式, 可以在创建service的时候使用如下命令:

docker service create --endpoint-mode [vip|dnssrr] <service name>


修改一个service的模式, 使用如下命令:

docker service update --endpoint-mode [vip|dnssrr] <service name>


3.4.2 rng服务压力测试

介绍完负载均衡模式, 下面使用ab对我们的rng服务进行简单的压力测试.
测试之前, 我们要关掉所有的worker服务, 避免worker服务影响测试结果.

docker service scale worker=0

worker scaled to 0

docker service ls

ID            NAME      REPLICAS  IMAGE                                   COMMAND

...

d7g0estex65u  worker    0/0       localhost:5000/dockercoins_worker:v0.1


回到我们的debug容器中

a.模拟一个客户端,发送50个请求给rng服务

/ # ab -c 1 -n 50 http://rng/10

This is ApacheBench, Version 2.3 <$Revision: 1748469 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking rng (be patient).....done

Server Software:        Werkzeug/0.11.10

Server Hostname:        rng

Server Port:            80

Document Path:          /10

Document Length:        10 bytes

Concurrency Level:      1

Time taken for tests:   5.386 seconds

Complete requests:      50

Failed requests:        0

Total transferred:      8250 bytes

HTML transferred:       500 bytes

Requests per second:    9.28 [#/sec] (mean)

Time per request:       107.716 [ms] (mean)

Time per request:       107.716 [ms] (mean, across all concurrent requests)

Transfer rate:          1.50 [Kbytes/sec] received

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        1    2   0.6      1       3

Processing:   103  106   1.5    106     110

Waiting:      102  105   1.2    105     109

Total:        104  107   1.7    107     112

WARNING: The median and mean for the initial connection time are not within a normal deviation

        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)

  50%    107

  66%    108

  75%    108

  80%    108

  90%    110

  95%    110

  98%    112

  99%    112

 100%    112 (longest request)


b.模拟50个并发客户端, 发送50个请求

/ # ab -c 50 -n 50 http://rng/10

This is ApacheBench, Version 2.3 <$Revision: 1748469 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking rng (be patient).....done

Server Software:        Werkzeug/0.11.10

Server Hostname:        rng

Server Port:            80

Document Path:          /10

Document Length:        10 bytes

Concurrency Level:      50

Time taken for tests:   1.105 seconds

Complete requests:      50

Failed requests:        0

Total transferred:      8250 bytes

HTML transferred:       500 bytes

Requests per second:    45.23 [#/sec] (mean)

Time per request:       1105.436 [ms] (mean)

Time per request:       22.109 [ms] (mean, across all concurrent requests)

Transfer rate:          7.29 [Kbytes/sec] received

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        7    9   1.3      9      12

Processing:   103  590 313.4    627    1087

Waiting:      103  589 313.3    626    1087

Total:        115  599 312.2    637    1095

Percentage of the requests served within a certain time (ms)

  50%    637

  66%    764

  75%    869

  80%    946

  90%   1050

  95%   1092

  98%   1095

  99%   1095

 100%   1095 (longest request)

可以看出,单个客户端的时候rng的响应时间平均107.716ms, 多并发情况下增加到大约1000ms+.


3.4.3 hasher服务压力测试

hasher的服务测试稍微复杂点, 因为hasher服务需要POST一个随机的bytes数据.
所以我们需要先通过curl制作一个bytes数据文件:

/ # curl http://rng/10 > /tmp/random


a.模拟单客户端,发送50个请求给hasher服务

/ # ab -c 1 -n 50 -T application/octet-stream -p /tmp/random http://hasher/

This is ApacheBench, Version 2.3 <$Revision: 1748469 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking hasher (be patient).....done

Server Software:        thin

Server Hostname:        hasher

Server Port:            80

Document Path:          /

Document Length:        64 bytes

Concurrency Level:      1

Time taken for tests:   5.323 seconds

Complete requests:      50

Failed requests:        0

Total transferred:      10450 bytes

Total body sent:        7250

HTML transferred:       3200 bytes

Requests per second:    9.39 [#/sec] (mean)

Time per request:       106.454 [ms] (mean)

Time per request:       106.454 [ms] (mean, across all concurrent requests)

Transfer rate:          1.92 [Kbytes/sec] received

                        1.33 kb/s sent

                        3.25 kb/s total

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        1    1   0.4      1       3

Processing:   103  105   0.8    105     107

Waiting:      103  104   0.8    104     107

Total:        104  106   1.0    106     109

Percentage of the requests served within a certain time (ms)

  50%    106

  66%    106

  75%    106

  80%    107

  90%    108

  95%    108

  98%    109

  99%    109

 100%    109 (longest request)


b.模拟50个并发客户端, 发送50个请求

/ # ab -c 50 -n 50 -T application/octet-stream -p /tmp/random http://hasher/

This is ApacheBench, Version 2.3 <$Revision: 1748469 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking hasher (be patient).....done

Server Software:        thin

Server Hostname:        hasher

Server Port:            80

Document Path:          /

Document Length:        64 bytes

Concurrency Level:      50

Time taken for tests:   0.345 seconds

Complete requests:      50

Failed requests:        0

Total transferred:      10450 bytes

Total body sent:        7250

HTML transferred:       3200 bytes

Requests per second:    144.95 [#/sec] (mean)

Time per request:       344.937 [ms] (mean)

Time per request:       6.899 [ms] (mean, across all concurrent requests)

Transfer rate:          29.59 [Kbytes/sec] received

                        20.53 kb/s sent

                        50.11 kb/s total

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        5   10   4.8      8      17

Processing:   131  214  71.5    238     323

Waiting:      126  207  72.2    231     322

Total:        147  224  67.2    246     328

Percentage of the requests served within a certain time (ms)

  50%    246

  66%    249

  75%    252

  80%    314

  90%    324

  95%    328

  98%    328

  99%    328

 100%    328 (longest request)

从结果可以看出, 单客户端hasher平均响应时间106.454ms, 50并发平均响应时间344.937ms.
hasher服务并发响应时间也慢, 不过比rng的1000+ms却好太多…




            

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:245902次
    • 积分:3505
    • 等级:
    • 排名:第10119名
    • 原创:107篇
    • 转载:57篇
    • 译文:1篇
    • 评论:15条
    最新评论