Docker 1.12 Swarm集群实战(第四章)
文章目录
前情提要
懒, 没提要了, 前几章链接如下:
第四章 swarm集群运维
上一章中我们终于把docker币
, 跑在swarm
集群上了. 不过性能还是没有达到我们的预期, 经过性能测试我们发现所有的应用响应时间都在100ms
以上.
为什么呢
下面我们来一起看看 rng
和hasher
应用的源代码.
1 | [root@node01 ~]# cd orchestration-workshop/dockercoins/ |
每个应用的源码程序就在这几个目录中:
我们一起来看看rng
的源码:1
2
3
4
5
6
7
8
9[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
和worker
的也一样.1
2
3
4
5
6
7
8
9
10[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
...
1 | [root@node01 dockercoins]# cat worker/worker.py |
哈哈, 现在你知道100ms
延迟的原因了吧. 下面我们以worker
服务为例, 更新下源代码缩短下响应时间.
目的是 演示下当我们的应用代码更新的时候, 如何利用docker swarm
集群滚动更新我们的服务副本容器,要知道我们是有多个worker
副本容器的.
4.1 Rolling Updates
在swarm 集群
的环境下, 我们每个服务都会有多个容器副本, 如何在不停止应用的情况下滚动更新每个容器副本就十分重要了, docker swarm
集群为我们提供了方便的命令.
那么如果我们要发布一个新版本的worker
服务需要做什么呢:
- 更新
worker
服务的源代码, 缩短time.sleep(0.1)
到0.01
. - 重新build
worker
镜像, 使用一个新的tag版本. - push新镜像到我们本地的镜像仓库.
- 滚动更新
worker
服务, 使用新的镜像
在开始之前, 如果你一直跟着文章做的, 上一章为了性能测试我们已经把worker
服务副本scale成0
了, 我们先恢复成10
个副本.1
2
3
4
5
6
7[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
4.2 更新应用代码
下面我们来更新worker
服务的代码~/orchestration-workshop/dockercoins/worker/worker.py
把sleep
时间从0.1
改成0.01
.
1 | [root@node01 dockercoins]# cat worker/worker.py |
4.3 重新build, push镜像
重新build我们的worker
服务镜像, tag为v0.0.1
1
2
3
4
5
6
7[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镜像到本地镜像库1
[root@node01 dockercoins]# docker push localhost:5000/dockercoins_worker:v0.01
4.4 滚动更新worker
服务
为了跟踪查询我们worker
服务在滚动更新中的状态, 我们新开一个ssh
窗口连接node01
, 执行watch
命令, 监控worker
服务状态:
如下命令可以打开一个监控窗口, 每秒监控我们worker
服务的状态变化:
1 | [root@node01 ~]# watch -n1 "docker service ps worker -a | grep -v Shutdown.*Shutdown" |
下面我们有了新worker
服务的镜像v0.01
, 我们来滚动更新我们的10个worker
:
这里只用docker service update
命令, --update-parallelism
指定每次update的容器数量, --update-delay
每次更新之后的等待时间.--image
后面跟服务镜像名称1
2
3
4
5
6
7
8## 确认我们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
成功以后, 注意观察刚刚我们打开的监控窗口, 你会看到worker
会一次2
个容器副本的频率更新到v0.01
版本.
1 | [root@node01 ~]# docker service ls |
全部update完成后, 你可以看到我们的worker
镜像已经都更新到最新版v0.0.1
版本了.
在去看看我们的webui
每秒钟产生的docker币
约40个
了, 哈哈^_^
.
4.5 容器服务回滚
如果我们发现, 新版本worker
有问题希望回滚怎么办呢.
很简单, 跟上面更新的命令一样啊, 直接只用v0.1
版本的镜像就可以了.
上面我们演示了滚动更新, 如果你希望一次性都更新或者回滚呢, 更简单了, 不加参数就行了.
下面我们一次性回滚所有worker
服务到v0.1
版本1
2
3
4
5
6
7[root@node01 dockercoins]# docker service update worker --image localhost:5000/dockercoins_worker:v0.1
worker
[root@node01 dockercoins]# 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~~.
4.6 ELK日志平台
现在我们有了docker swarm
集群, 上面跑了docker币
应用, 以后我们还会有很多的应用跑在集群上面, 如何监控每个应用的运行状态呢.
所以我们需要一个日志平台, 用来收集分析展示, 所有swarm集群
上应用的日志.
在本小节我们就一起来搭建一个ELK日志平台, 什么是ELK stack?
ELK 主要有三个部分组成:
ElasticSearch
用来存储和索引日志.Logstash
用来接收, 发送, 过滤, 分隔日志.Kibana
用来搜索, 展示, 分析日志的UI我们在会
swarm集群
的每个节点使用syslog
协议发送日志到logstash, 存储在elasticsearch
中, 最后使用kibana
分析展示日志.
4.6.1 配置elasticsearch
创建一个overlay网络logging
用于ELK平台日志收集1
2[root@node01 ~]# docker network create --driver overlay logging
biucttiifbj9ak4eh5kn07zqq
创建ElasticSearch
服务1
2[root@node01 ~]# docker service create --network logging --name elasticsearch elasticsearch
8ts6wfiufj7gsj4cm34drb56x
4.6.2 配置Kibana
配置Kibana服务, 发布5601
端口, 用于UI访问.1
2[root@node01 ~]# docker service create --network logging --name kibana --publish 5601:5601 \
-e LOGSPOUT=ignore -e ELASTICSEARCH_URL=http://elasticsearch:9200 kibana
4.6.3 配置logstash
创建Logstash
服务, logstash需要一些配置去监听syslog
日志, 把他们发送到elasticsearch
中.1
2
3[root@node01 ~]# docker service create --network logging --name logstash \
-e LOGSPOUT=ignore logstash \
-e "$(cat ~/orchestration-workshop/elk/logstash.conf)"
Note
cat ~/orchestration-workshop/elk/logstash.conf
这个文件是git库里面带的logstash配置文件, 如果你的路径不同注意替换.
1 | [root@node01 ~]# docker service ps logstash |
下面一段用于验证logstash
服务, 由于docker hub 连接问题, 你可能很难pull到image, 确保你的service运行成功. 当然你也可以忽略下面一端. 有问题的话再回来验证.
验证logstash
服务:1
2
3
4
5
6
7
8
9
10[root@node01 ~]# CID=$(docker ps -q --filter label=com.docker.swarm.service.name=logstash)
[root@node01 ~]# docker logs --follow $CID
{:timestamp=>"2016-08-08T08:56:32.639000+0000", :message=>"Pipeline main started"}
{
"message" => "ok",
"host" => "57c83db57ba2",
"@version" => "1",
"@timestamp" => "2016-08-08T08:56:30.539Z"
}
^C
现在开启一个新的ssh
窗口, 我们测试下生成syslog
日志,发送到logstash
.
1 | [root@node01 ~]# docker service create --network logging --restart-condition none debian \ |
4.6.4 启动logspout服务
logspout
运行在docker
服务器节点上, 用于将docker
服务器上运行的容器日志输出到logstash
中.所以我们要在swarm集群
的每个节点上运行这个容器, 采用global模式
. 这里我们直接使用一个编译好的docker镜像来运行logspout
服务.
关于
logspout
的更多信息, 请访问 https://github.com/gliderlabs/logspout
设置日志logspout
, 将docker host日志输入到logstash
:1
2
3[root@node01 ~]# docker service create --network logging --name logspout --mode global \
--mount source=/var/run/docker.sock,type=bind,target=/var/run/docker.sock \
-e SYSLOG_FORMAT=rfc3164 gliderlabs/logspout syslog://logstash:51415
4.6.5 访问Kibana
前面我们配置了Kibana, 发布了5601
端口用于访问, 下面使用浏览器访问
http://192.168.33.101:5601/
点击Time-field name
选择@timestamp
, 点击Create
.
然后点击屏幕上面的Discover
.
下面你就能看见日志收集情况了, 为了方便查看我们再来配置下刷新时间.
点击右上角的Last 15 minutes
选择Last 1 Hour
, 点击Auto-refresh
选择5 seconds
.
配置下Fields, 在屏幕左边host
,logsource
,program
后面点击add
.
好了, kiban的简单配置就到完成了,最后你可以看到这样的效果:
注意日志的host
列显示日志来自swram集群
的哪个节点.logsource
列显示日志来日与那个容器, program
列显示的是容器的名字, 你可以看到我们的服务名字.message
列就是日志的内容了.
关于ELK日志平台还有很多内容, 你可以在kibana
上分析日志, 生成图表等等. 这里就不多介绍了.
最后
整个docker 1.12 swarm集群实战系列教程就结束了, 感谢大家的观看.
呃, 后面还有补充的第五章~