前情提要
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集群实战》已完篇,感谢大家的观看!
特别鸣谢:小张烤茄 作者:祥旭
swarmkit 具备多租户控制么?
其中服务调度支持指定节点和CPU亲和性么
其中对资源的控制似乎元没有没有docker run控制粒度细吧?
https://docs.docker.com/engine/reference/commandline/service_create/
创建不同的service可实现租户的隔离;服务基于节点的调度可使用约束来界定(未亲测);资源控制的功能有,但确实没有docker run的细粒度高。