Docker 1.12 Swarm Mode集群实战(第四章 Swarm集群运维)

前情提要

Docker 1.12 Swarm Mode集群实战(第一章)

Docker 1.12 Swarm Mode集群实战(第二章)

Docker 1.12 Swarm Mode集群实战(过渡篇)之Registry和Image

Docker 1.12 Swarm Mode集群实战(第三章)

第四章 Swarm集群运维

上一章中我们终于把docker币, 跑在swarm集群上了。不过性能还是没有达到我们的预期, 经过性能测试我们发现所有应用的响应时间都在100ms以上。

为什么呢?

下面我们来一起看看 rng和hasher应用的源代码.

[root@node01 ~]# cd orchestration-workshop/dockercoins/

[root@node01 dockercoins]# ls

...  hasher  ports.yml  rng  webui  worker

进入dockercoins应用的目录, 你会看到 hasher, rng, webui,worker几个目录。Docker币每个应用的源码程序就在这几个目录中

我们一起来看看rng的源码:

[root@node01 dockercoins]# cat rng/rng.py

...

def rng(how_many_bytes):

    # Simulate a little bit of delay

    time.sleep(0.1)

    return Response(

        os.read(urandom, how_many_bytes),

        content_type="application/octet-stream")

...

哈哈, 看到了没。time.sleep(0.1)每个请求会自动延迟100ms响应.

hasher的也一样

[root@node01 dockercoins]# cat hasher/hasher.rb

...

post '/' do

    # Simulate a bit of delay

    sleep 0.1

    content_type 'text/plain'

    "#{Digest::SHA2.new().update(request.body.read)}"

end

...

worker的也一样

[root@node01 dockercoins]# cat worker/worker.py

...

def work_once():

    log.debug("Doing one unit of work")

    time.sleep(0.1)

    random_bytes = get_random_bytes()

    hex_hash = hash_bytes(random_bytes)

    if not hex_hash.startswith('0'):

        log.debug("No coin found")

        return

    log.info("Coin found: {}...".format(hex_hash[:8]))

    created = redis.hset("wallet", hex_hash, random_bytes)

    if not created:

        log.info("We already had that coin")

...

哈哈, 现在明白了100ms延迟的原因了吧,这是来自程序猿朋友开的一个玩笑.^_^

下面我们以worker服务为例, 更新下源代码缩短下响应时间。主要目的是演示下当我们的应用代码更新的时候, 如何利用docker swarm集群滚动更新和回滚我们的多个服务副本容器。

Rolling Updates

在swarm集群的环境下, 我们每个服务都会有多个容器副本, 如何在不停止应用的情况下滚动更新每个容器副本就十分重要了, 好在docker swarm集群为我们提供了方便的命令。

那么如果我们要发布一个新版本的worker服务需要做什么呢?

更新worker服务的源代码, 缩短time.sleep(0.1)到0.01.

重新buildworker镜像, 使用一个新的tag版本.

push新镜像到我们本地的镜像仓库.

滚动更新worker服务, 使用新的镜像

在开始之前, 因为上一章为了性能测试我们已经把worker服务副本scale成0了, 那么我们先恢复成10个副本。

[root@node01 dockercoins]# docker service ls

ID            NAME      REPLICAS  IMAGE                                   COMMAND

...

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

... 

[root@node01 dockercoins]# docker service scale worker=10

worker scaled to 10

更新应用代码

下面我们来更新worker服务的代码

~/orchestration-workshop/dockercoins/worker/worker.py

把sleep时间从0.1改成0.01

[root@node01 dockercoins]# cat worker/worker.py

...

def work_once():

    log.debug("Doing one unit of work")

    time.sleep(0.01)

    random_bytes = get_random_bytes()

    hex_hash = hash_bytes(random_bytes)

    if not hex_hash.startswith('0'):

        log.debug("No coin found")

        return

    log.info("Coin found: {}...".format(hex_hash[:8]))

    created = redis.hset("wallet", hex_hash, random_bytes)

    if not created:

        log.info("We already had that coin")

...

重新build,push镜像

[root@node01 dockercoins]# docker build -t localhost:5000/dockercoins_worker:v0.01 worker

[root@node01 dockercoins]# docker images

REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE

localhost:5000/dockercoins_worker   v0.01               a9cb198fcb8c        21 seconds ago      80.5 MB

...

localhost:5000/dockercoins_worker   v0.1                bef5d2dc4bd0        7 days ago          80.5 MB

...

Note:我们新build镜像tag不一样, 为方便区分本例我们以sleeptime作为版本号。新的TAG是v0.0.1.

Push镜像到本地镜像库

[root@node01 dockercoins]# docker push localhost:5000/dockercoins_worker:v0.01

滚动更新worker服务

为了跟踪查询我们worker服务在滚动更新中的状态, 我们新开一个ssh窗口连接node01, 执行watch命令, 监控worker服务状态:

[root@node01 ~]# watch -n1 "docker service ps worker -a | grep -v Shutdown.*Shutdown"

如上命令可以打开一个监控窗口, 每秒监控我们worker服务的状态变化:

下面我们有了新worker服务的镜像v0.01, 我们来滚动更新我们的10个worker:

确认我们当前的worker服务的版本为v0.1

[root@node01 dockercoins]# docker service ls

ID            NAME      REPLICAS  IMAGE                                   COMMAND

...

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

## 滚动更新我们`worker`, 每次更新2个副本容器, 延迟`5s`

[root@node01 dockercoins]# docker service update worker --update-parallelism 2 --update-delay 5s --image localhost:5000/dockercoins_worker:v0.01

worker

这里只用docker service update 命令

–update-parallelism指定每次update的容器数量

–update-delay 每次更新之后的等待时间

–image后面跟服务镜像名称

成功以后, 注意观察刚刚我们打开的监控窗口, 你会看到worker会一次2个容器副本的频率更新到v0.01版本.

[root@node01 ~]# docker service ls

ID            NAME      REPLICAS  IMAGE                                    COMMAND

...

d7g0estex65u  worker    10/10     localhost:5000/dockercoins_worker:v0.01

...

全部update完成后, 你可以看到我们的worker镜像已经都更新到最新版v0.0.1版本了.

在去看看我们的webui每秒钟产生的docker币约40个了, 哈哈^_^.

回滚worker服务

如果我们发现, 新版本worker有问题希望回滚怎么办呢.

很简单, 跟上面更新的命令一样啊, 直接只用v0.1版本的镜像进行回滚就可以了.

上面我们演示了滚动更新, 如果你希望一次性都更新或者回滚呢, 更简单了, 不加参数就行了.

[root@node01 ~]# docker service update worker --image localhost:5000/dockercoins_worker:v0.1

worker

[root@node01 ~]# docker service ls

ID            NAME      REPLICAS  IMAGE                                   COMMAND

...

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

...

可以看到一次性将所有的worker服务全都回滚到v0.1版本了.

好了,后面可以自己折腾下了, 尝试scale下几个服务, 尝试更新下rng和hasher几个应用, 看看最多能挖到每秒多少docker币,嘿嘿!!!

当然这不是比特币哈, 挖了再多也不能用来买东西, 哈哈, have fun~~.

至此《Docker 1.12 Swarm Mode集群实战》已完篇,感谢大家的观看!

特别鸣谢:小张烤茄  作者:祥旭 

分享到:更多 ()