自从Dockercon 2016发布Docker 1.12版本以来, 经历了几个RC版本后Docker 1.12终于迎来了第一个稳定版.
Docker 1.12展露了docker一统生态的野心。docker engine集成swarmkit, 使得你可以不用安装额外的软件包, 就可以用简单的命令创建和管理docker swarm集群。
同时集成了swarm集群的安全特性和K-V存储, 你现在也不需要额外去部署etcd或者consul等应用。
以Docker最新版1.12为基础,介绍了docker编排使用的最新情况,希望大家能有所所收获。(推荐直接观看视频讲解)
本系列文章主要分以下几个章节:
第一章 环境准备
主要准备实验环境, 安装docker, 使用docker-compose运行我们的示例应用docker币。
第二章 创建swarm集群
使用集成的SwarmKit配置docker swarm集群,创建swarm service等。
第三章 在swarm上部署app
集群环境部署app,解决单节点的性能瓶颈。同时涵盖部署本地registry, overlay network介绍
第四章 swarm集群运维
swarm集群的操作和管理
VM Hostname 和 IP地址如下:”node01″ => “192.168.33.101”,”node02″ => “192.168.33.102”,
"node03" => "192.168.33.103", "node04" => "192.168.33.104", "node05" => "192.168.33.105"
1.1 使用Vagrant创建实验环境什么是vagrant?
简单说vagrant是一个命令行的虚拟机操作和编排工具,支持各种虚拟化引擎。可以帮助我们快速搭建实验环境。
具体细节请看Vagrant官方网站http://vagrantup.com/
1.1.1 安装 Vagrant
下载安装 Oracle VM Virtualbox
https://www.virtualbox.org/wiki/Downloads
下载安装 Vagrant.
https://www.vagrantup.com/downloads.html
1.1.2 创建实验环境
打开window命令行工具:
新建一个目录:
>mkdir docker-workshop >cd docker-workshop
# 初始化一个vagrant 配置文件
>vagrant init A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant.
你会发现目录下面多了一个 Vagrantfile
文件. 编辑这个文件替换成如下内容:
## files: Vagrantfile # -*- mode: ruby -*- # vi: set ft=ruby : hosts = { "node01" => "192.168.33.101", "node02" => "192.168.33.102", "node03" => "192.168.33.103", "node04" => "192.168.33.104", "node05" => "192.168.33.105" } Vagrant.configure("2") do |config| hosts.each do |name, ip| config.vm.define name do |machine| machine.vm.box = "bento/centos-7.2" machine.vm.box_check_update = false machine.ssh.insert_key = false machine.vm.hostname = name machine.vm.network :private_network, ip: ip machine.vm.synced_folder ".", "/vagrant", disabled: true machine.vm.provider "virtualbox" do |v| v.name = name v.customize ["modifyvm", :id, "--memory", 512] end end end end
NOTE 你可以根据你环境的总内存情况调整每台VM的内存. 修改
v.customize ["modifyvm", :id, "--memory", 512]
.默认为每台VM 512MB.
使用vagrant up
命令,启动实验环境:
>vagrant up Bringing machine 'node01' up with 'virtualbox' provider... Bringing machine 'node02' up with 'virtualbox' provider... Bringing machine 'node03' up with 'virtualbox' provider... Bringing machine 'node04' up with 'virtualbox' provider... Bringing machine 'node05' up with 'virtualbox' provider... ....
NOTE 第一次启动vagrant会从网络下载VM镜像, 所以速度较慢. 请耐心等待:)
验证VM启动状态
>vagrant status Current machine states: node01 running (virtualbox) node02 running (virtualbox) node03 running (virtualbox) node04 running (virtualbox) node05 running (virtualbox)
ssh登录实验环境VM的两种方法:
方法一:
使用vagrant ssh <nodename>
命令直接在window终端登录VM:
> vagrant ssh node01 [vagrant@node01 ~]$
方法二:
使用ssh客户端远程登录
vagrant ssh-config <nodename>
查看每台VM的登录配置.
> vagrant ssh-config node01 Host node01 HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile C:/Users/xiangxu/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL
以上, 你可以使用任意ssh客户端(如xshell),使用 vagrant
用户和密钥C:/Users/xxx/.vagrant.d/insecure_private_key
登录node01。其中ip地址可以使用192.168.33.101,
也可以使用配置文件的127.0.0.1
的2222
端口。
1.1.3 其他vagrant命令介绍
vagrant一些常用命令如下:
vagrant halt # 关闭VM
vagrant up # 启动VM
vagrant destroy #删除VM
vagrant status # VM 状态
vagrant -h # vagrant 帮助
1.2 系统环境准备
host
列表, 安装ntp
, 配置所有节点密钥登录.以下命令请在所有节点执行, 以
node01
为例子:#切换至root用户$ sudo su -#设置root用户密码
# echo rootpassword | passwd --stdin root
#更新系统
# yum update -y # 安装ntp时间同步 # yum install ntp -y # 启动ntp服务, 配置开机启动 # systemctl start ntpd # systemctl enable ntpd
# 配置hosts文件
# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 192.168.33.101 node01 192.168.33.102 node02 192.168.33.103 node03 192.168.33.104 node04 192.168.33.105 node05
配置所有节点密钥互信(在node01
可以免密码登录各节点)
只在node01
上执行:
# 生成sshkey # ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: cd:84:03:a2:06:df:e4:ca:d1:0d:73:80:48:cd:3f:28 root@node01 The key's randomart image is: +--[ RSA 2048]----+ |ooo.*.o | |.o.O * . . | | = * . o . | | E + o = | | + . S o | | | | | | | | | +-----------------+
# 发布sshkey到各个节点
# ssh-copy-id node01 The authenticity of host 'node01 (192.168.33.101)' can't be established. ECDSA key fingerprint is 3b:6f:e4:72:5e:72:f3:76:b9:d0:7e:0e:dd:83:9f:5a. Are you sure you want to continue connecting (yes/no)? yes ... root@node01's password: #输入root用户密码 Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'node01'" and check to make sure that only the key(s) you wanted were added. # ssh-copy-id node02 ... # ssh-copy-id node03 ... # ssh-copy-id node04 ... # ssh-copy-id node05
测试密钥登录
# for N in $(seq 1 5); do ssh node0$N hostname; done; node01 node02 node03 node04 node05
1.3 安装docker 1.12在所有节点上安装docker 1.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
在node01上安装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
1.4 运行docker币应用
1.4.1 下载docker币应用配置
你可以从github库中,得到所有关于这个workshop的文档和配置.
https://github.com/jpetazzo/orchestration-workshop
在node01
上下载这个github库.
#安装git
# yum install git -y
# 克隆git 库
# git clone https://github.com/jpetazzo/orchestration-workshop.git
# 进入dockercoins应用目录
# cd orchestration-workshop/dockercoins
# 可以看到 dockercoins应用的`docker-compose`文件
# ls docker-compose.yml docker-compose.yml-portmap hasher webui docker-compose.yml-ambassador docker-compose.yml-scaled-rng ports.yml worker docker-compose.yml-logging docker-compose.yml-v2 rng
NOTE 该github库中包含了workshop的详细文档和配置,部署脚本和PPT等。有基础的同学可以自己先看看。
1.4.2 docker币应用介绍
查看 docker币的docker-compose文件
# cat docker-compose.yml version: "2" services: rng: build: rng ports: - "8001:80" hasher: build: hasher ports: - "8002:80" webui: build: webui ports: - "8000:80" volumes: - "./webui/files/:/files/" redis: image: redis worker: build: worker
docker币应用一共有4个服务,分别对应4个目录rng
, hasher
, webui
, worker
:
详情可进入对应目录查看Dockerfile
.
rng
是一个web service 生成随机的bytes数据.hasher
是一个计算POST数据hash值的web service.worker
作为工作节点后台调用rng
生成随机bytes数据, 然后将数据post到hasher服务计算hash值, 如果hashe值开头为0
.则产生一个docker币
.并将docker币
保存到redis数据库中.webui
一个web接口来监控整个系统.读取redis
数据库中的docker币
数量
1.4.3 运行docker币应用
你可以直接使用如下命令运行docker币应用。docker-compose
会自动pull镜像和build镜像 然后启动应用:
# docker-compose up由于某些你懂的原因, 可能导致你的网络连接docker hub的时候不稳定, 导致docker pull镜像失败…所以你也可以把需要的镜像事先给pull下来.
# docker pull python:alpine # docker pull ruby:alpine # docker pull redis # docker pull node:4-slim # 检查所需的images # docker images REPOSITORY TAG IMAGE ID CREATED SIZE python alpine 0298711f3095 12 days ago 73.04 MB node 4-slim 6585f7b67838 4 weeks ago 207.9 MB ruby alpine c872d09a2f2e 5 weeks ago 126 MB redis latest 4465e4bcad80 6 weeks ago 185.7 MB
NOTE 如果pull镜像的时候报网络连接错误, 可以反复执行多试几遍.
手工build docker币应用镜像:
# docker-compose build ... # 根据每个应用目录下的Dockerfile build应用镜像, 需要一会儿.... # build完成后, 你可以使用 docker image命令查看镜像 # docker images REPOSITORY TAG IMAGE ID CREATED SIZE dockercoins_webui latest c2d09bb0c442 About a minute ago 212.2 MB dockercoins_rng latest ff1d886f2fa3 2 minutes ago 83.53 MB dockercoins_hasher latest 9d361dbaf589 2 minutes ago 310.6 MB dockercoins_worker latest bef5d2dc4bd0 8 minutes ago 80.5 MB ...
启动 docker币应用:
# docker-compose up启动以后你可以看见应用日志, 一直滚动…
使用Control+C
停止应用,我们使用-d
参数后台启动应用.
# docker-compose up -d Starting dockercoins_rng_1 Starting dockercoins_worker_1 Starting dockercoins_hasher_1 Starting dockercoins_redis_1 Starting dockercoins_webui_1
查看应用运行情况:
# docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------ dockercoins_hasher_1 ruby hasher.rb Up 0.0.0.0:8002->80/tcp dockercoins_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp dockercoins_rng_1 python rng.py Up 0.0.0.0:8001->80/tcp dockercoins_webui_1 node webui.js Up 0.0.0.0:8000->80/tcp dockercoins_worker_1 python worker.py Up
查看应用日志:
# docker-compose logs
# 滚动输出应用日志, 每个容器输出最新10行
# docker-compose logs --tail 10 --follow
TIP 日志滚动输出的时候按
Ctrl+S
暂停,Ctrl+Q
继续输出,Ctrl+C
退出.
访问webui监控程序运行:
从上面docker-compose ps
命令, 我们可以看到应用的port映射.
浏览器访问 http://192.168.33.101:8000打开应用的webui.
你会看到下面的页面:
从webui可以看到我们的docker币程序每秒可以产生约4个docker币.
worker
服务负责产生docker币。那么我们可以尝试scale up worker
服务.
# docker-compose ps # 可以看到我们现在只有一个worker服务 # 增加到2个 worker服务, 使用如下命令 # docker-compose scale worker=2 Creating and starting dockercoins_worker_2 ... done # docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------ dockercoins_hasher_1 ruby hasher.rb Up 0.0.0.0:8002->80/tcp dockercoins_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp dockercoins_rng_1 python rng.py Up 0.0.0.0:8001->80/tcp dockercoins_webui_1 node webui.js Up 0.0.0.0:8000->80/tcp dockercoins_worker_1 python worker.py Up dockercoins_worker_2 python worker.py Up
好了, 现在我们有2个worker服务了.
再看web
ui
浏览器界面, 发现现在我们每秒可以产出8个docker币了。
WoW~ 这么简单, 让我们再来更多的docker币吧.
# 再增加8个worker节点. # docker-compose scale worker=10 # docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------- dockercoins_hasher_1 ruby hasher.rb Up 0.0.0.0:8002->80/tcp dockercoins_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp dockercoins_rng_1 python rng.py Up 0.0.0.0:8001->80/tcp dockercoins_webui_1 node webui.js Up 0.0.0.0:8000->80/tcp dockercoins_worker_1 python worker.py Up dockercoins_worker_10 python worker.py Up dockercoins_worker_2 python worker.py Up dockercoins_worker_3 python worker.py Up dockercoins_worker_4 python worker.py Up dockercoins_worker_5 python worker.py Up dockercoins_worker_6 python worker.py Up dockercoins_worker_7 python worker.py Up dockercoins_worker_8 python worker.py Up dockercoins_worker_9 python worker.py Up
可以看到我们现在有10个worker
节点了, 那理论上来说我们可以每秒产生40个docker币
.
看看我们的webui
注意, 每秒产生的docker币数量.
OMG~ 为什么现在每秒至产生约10个docker币而不是40?
8个docker币
, 但是10个worker节点每秒也只产生10个docker币。
为什么呢?1.因为我们现在所有的应用都是跑在一台服务器上node01
, 10个worker node造成服务器资源竞争, 所以增加worker节点也不能改善性能。2.因为我们有10个worker
节点, 只有一个rng
, hasher
节点, 所以瓶颈有可能发生在rng
和hasher
节点。我们可以简单测试下rng
,hasher
节点的负载,使用httping
工具, 测试rng
, hasher
延迟.
## 安装 httping # yum install epel-release -y # yum install httping -y
测试rng
延迟, docker-compose ps
命令可以看到rng
应用映射到本地8001
端口:
# httping -c 10 localhost:8001 PING localhost:8001 (/): connected to 127.0.0.1:8001 (159 bytes), seq=0 time=782.49 ms connected to 127.0.0.1:8001 (159 bytes), seq=1 time=821.42 ms connected to 127.0.0.1:8001 (159 bytes), seq=2 time=775.34 ms connected to 127.0.0.1:8001 (159 bytes), seq=3 time=697.87 ms connected to 127.0.0.1:8001 (159 bytes), seq=4 time=866.71 ms connected to 127.0.0.1:8001 (159 bytes), seq=5 time=838.10 ms connected to 127.0.0.1:8001 (159 bytes), seq=6 time=775.62 ms connected to 127.0.0.1:8001 (159 bytes), seq=7 time=770.14 ms connected to 127.0.0.1:8001 (159 bytes), seq=8 time=758.90 ms connected to 127.0.0.1:8001 (159 bytes), seq=9 time=776.65 ms --- http://localhost:8001/ ping statistics --- 10 connects, 10 ok, 0.00% failed, time 17872ms round-trip min/avg/max = 697.9/786.3/866.7 ms
测试hasher
延迟, 8002
端口:
# httping -c 10 localhost:8002 PING localhost:8002 (/): connected to 127.0.0.1:8002 (210 bytes), seq=0 time= 3.85 ms connected to 127.0.0.1:8002 (210 bytes), seq=1 time= 24.33 ms connected to 127.0.0.1:8002 (210 bytes), seq=2 time= 9.28 ms connected to 127.0.0.1:8002 (210 bytes), seq=3 time= 4.11 ms connected to 127.0.0.1:8002 (210 bytes), seq=4 time= 1.94 ms connected to 127.0.0.1:8002 (210 bytes), seq=5 time= 2.23 ms connected to 127.0.0.1:8002 (210 bytes), seq=6 time= 1.28 ms connected to 127.0.0.1:8002 (210 bytes), seq=7 time= 2.47 ms connected to 127.0.0.1:8002 (210 bytes), seq=8 time= 2.41 ms connected to 127.0.0.1:8002 (210 bytes), seq=9 time= 2.15 ms --- http://localhost:8002/ ping statistics --- 10 connects, 10 ok, 0.00% failed, time 10062ms round-trip min/avg/max = 1.3/5.4/24.3 ms
以上结果可以看出, rng
节点延迟较大800ms
+ , 所以瓶颈有可能出现在rng
节点。
如何解决瓶颈?
针对原因1:
我们可以建立docker集群环境, 使得worker节点可以分布在不同虚拟机上运行。
针对原因2:
我们可以scale out
rng节点,建立多个rng
节点消除瓶颈。
其实上面两条差不多意思, 主要的性能问题在第二条, 就是要scale out
横向扩展我们的应用,这里就需要用到集群。
所以下一章, 我们会引入docker swarm集群,
介绍在docker 1.12下如何基于集成在Docker Engine的SwarmKit快速搭建Swarm集群。
最终轻松scale out
我们的应用,解决性能瓶颈,造出更多的Docker币。:)
下一章开始之前, 清理现在的环境
我们开始下一章之前, 先要停止现在的docker币应用, 使用如下命令.
# docker-compose down
评论前必须登录!
注册