问题导读:
1.怎样搭建HAProxy负载均衡服务器?
2.怎样配置Swarm集群? 3.怎样在Docker上运行Spark?
开放容器组织(Open Container Project, OCP)由Docker公司和CoreOS,加上一些顶牛的大公司,如Google,IBM,Microsoft,EMC,Amazon,思科,华为等等,在Linux基金会的支持下于2015年6月份创立的一个统一容器标准的组织。
许多厂商会在Docker和CoreOS之间犹豫不决,观望对工业界来说是个明智之举也是个掣肘之举,谁也不敢冒进。统一标准,意义重大。
OCP的一大产物就是runC,它跟docker一样也是用来大量生产和运行容器(containers)的,不过它是遵循OCP规范的,它与Docker的另一个不同在于它不需要守护进程,只需要一个配置文件一个开放的文件夹,一个进程就可以跑。不过docker镜像可以用runC来运行。
下面是runC官网给出的示例,我感觉要比网上其他博客和教程说得清晰:
这样这个容器就运行起来了,不过它就不需要与daemon打交道了。不过在这之前我们仍然用到了docker hub,以及docker技术这个生态圈。我想这样引入runC的愿景就是
Docker来,run Docker;其它containers来,run 其它。
当然runC仍处于研制阶段,现在还不能看出和实践出它的魅力。Docker依旧是宠儿。
MSP
Managed Service Provider (MSP)
管理服务(managed service)是云计算最古老的形式之一。如IBM可以为很多IT公司的服务(如电子邮件公司和应用APP公司)提供管理安全服务。
我的一个朋友在经营一家互联网APP和Web公司,他的业务核心是为普通人提供优质的互联网服务,对于后台系统和信息系统的管理,如果交给MSP,会变得 cost-efficient,同时MSP可以根据他公司的业务情况提供架构和存储方面的建议。
个人感觉还是中小企业比较青睐MSP。
新的服务领域永远都是管理服务提供商(MSP)最关心的问题。
我们是否可以在MSP上引入Docker?这里要问一个问题:
MSP追求容器密度和TPS吗?
我们这里进行的Docker场景化就是基于MSP的,希望我们可以看到不一样的东西,通过接下来看似漫无目的的探索。
Hopefully!
HAProxy
“HAProxy(High Available Proxy)是基于四层和七层的高可用负载均衡代理服务器,配置简单、支持多达上万条并发请求。很多web站点都用HAProxy来作为七层负载均衡解决方案”
友情链接
这个是HAProxy官方给出的架构图。
下面是使用HAProxy的探索。
安装配置HAProxy:
[mw_shl_code=bash,true]#cd /usr/local/src
#wget http://www.haproxy.org/download/ ... oxy-1.7-dev0.tar.gz (截止到2015/11/5 这是最新版本)
#tar xf haproxy-1.7-dev0.tar.gz
#cd haproxy-1.7-dev0
#make TARGET=linux26 ARCH=x86_64
#TARGET是指定内核版本(我的内核是3.10,这里也选择linux26),ARCH指定CPU架构,我使用的是64bit系统
#make install[/mw_shl_code]
创建配置文件和启动文件:
[mw_shl_code=bash,true]#mkdir /etc/haproxy
#cp examples/haproxy.init /etc/init.d/haproxy
#chmod +x /etc/init.d/haproxy
#ln -s /usr/local/sbin/haproxy /usr/sbin/ (创建启动文件)
#mkdir /usr/share/haproxy[/mw_shl_code]
编辑配置文件:
[mw_shl_code=bash,true]vim /etc/haproxy/haproxy.cfg[/mw_shl_code]
[mw_shl_code=bash,true]global
log 127.0.0.1 local0 #日志输出配置,所有日志都记录在本机,通过local0输出
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096 #最大连接数
chroot /usr/share/haproxy #改变当前工作目录
uid 99 #所属用户的uid
gid 99 #所属运行的gid
daemon #以后台形式运行haproxy
#debug
#quiet
defaults
log global
mode http
#默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
option httplog
option dontlognull
option redispatch
#当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
option abortonclose
#当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
retries 3 #两次连接失败就认为是服务器不可用
maxconn 2000 #默认的最大连接数
#timeout http-keep-alive 10s
# timeout queue 1m
contimeout 5000 #连接超时
clitimeout 50000 #客户端超时
srvtimeout 50000 #服务器超时
timeout check 5s #心跳检测超时
stats refresh 30s #统计页面自动刷新时间
stats uri /stats #统计页面url
stats realm baison-test-Haproxy #统计页面密码框上提示文本
stats auth admin:admin123 #统计页面用户名和密码设置
stats hide-version #隐藏统计页面上HAProxy的版本信息
frontend www
bind *:80
#这里建议使用bind *:80的方式,要不然做集群高可用的时候有问题,vip切换到其他机器就不能访问了
acl web hdr(host) -i x1.x2.x3.x4
#acl后面是规则名称,-i是要访问的域名,如果访问x1.x2.x3.x4这个域名就分发到下面的webserver 的作用域。
use_backend webserver if web
backend webserver #webserver作用域
mode http
balance roundrobin
#banlance roundrobin 轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数
#option httpchk /index.html
server web01 x5.x6.x7.x8:22212 check inter 2000 fall 3 weight 30
server web01 x8.x9.xa.x8:22213 check inter 2000 fall 3 weight 20
server web01 xb.xc.xd.xe:22214 check inter 2000 fall 3 weight 10[/mw_shl_code]
最后启动服务并查看:
[mw_shl_code=bash,true]/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg[/mw_shl_code]
浏览器访问: x1.x2.x3.x4/stats
Cluster with Swarm
参考
第一步,安装swarm
[mw_shl_code=bash,true]# docker pull swarm[/mw_shl_code]
验证
[mw_shl_code=bash,true]# docker run --rm swarm -v[/mw_shl_code]
出现
[mw_shl_code=bash,true]swarm version 0.4.0 (d647d82)[/mw_shl_code]
成功!
如果出现不成功,就一直重复执行命令,甚至可以reboot系统,暴力一些。如果还不行,我采取的方法是在已经有swarm镜像的机器上使用命令docker save 和 docker load对镜像进行tar打包然后传到要安装swarm的机器上进行load,反正一直折腾吧,直到ok为止,O(∩_∩)O哈哈~
ubuntu install docker 通过Docker源安装最新版本
[mw_shl_code=bash,true]# apt-get install apt-transport-https
# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
# bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
# apt-get update
# apt-get install lxc-docker[/mw_shl_code]
On swarm master node (123 REHL docker 1.8.2)
[mw_shl_code=bash,true]<REHL>
# vim /usr/lib/systemd/system/docker.service
<Enter vim>
#ExecStart=/usr/bin/docker daemon -H fd://
# for swarm using
ExecStart=/usr/bin/docker -d -H 0.0.0.0:2375 -H unix:///var/run/docker.sock
<Exit vim>
# systemctl daemon-reload
# service docker restart[/mw_shl_code]
On swarm other nodes (110 Ubuntu docker 1.7.1, 64 Ubuntu docker 1.8.1)
[mw_shl_code=bash,true]<Ubuntu>
DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock" (vim /etc/default/docker)
# service docker restart[/mw_shl_code]
Notes:
1) docker -d 启动一个后台daemon进程
2) 运行Docker守护进程时,可以用-H标志调整守护进程绑定监听接口的方式。
3) 关于/var/run/docker.sock
当Docker软件包安装完毕后,默认会立即启动Docker守护进程。守护进程监听/var/run/docker.sock“这个Unix套接字文件,来获取来自客户端的Docker请求
如果出现/var/run/docker.sock的报错,解决方法是尝试用root用户身份去操作
Docker 集群管理需要使用服务发现功能。
这里我们不选择DockerHub 提供的服务发现功能(因为经过实践检验,会出现问题,在join时会出现fatal的错误导致无法使用DockerHub提供的服务发现),而是使用本地文件。
第一步:
On 123(swarm manager),把集群中各个机器的ip写入到管理节点上的一个文件中,示例如下
[mw_shl_code=bash,true]# echo ip1:2375 >> cluster
# echo ip2:2375 >> cluster
# echo ip3:2375 >> cluster
# cat cluster
ip1:2375
ip2:2375
ip3:2375[/mw_shl_code]
第二步:
[mw_shl_code=bash,true]# docker run -d -p 2376:2375 -v $(pwd)/cluster:/tmp/cluster swarm manage file:///tmp/cluster[/mw_shl_code]
出现
c36af6dd8b0279f4c5c2f49570563f2d61c1a5e23cd630e81d91b444039c9b00
docker ps后发现
[mw_shl_code=bash,true]CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
c36af6dd8b02 swarm “/swarm manage file:/” 37
seconds ago Up 36 seconds 0.0.0.0:2376->2375/tcp
mad_yalow[/mw_shl_code]
可以看到,此时整个集群已经启动成功。
接下来的就可以在任何一台安装了docker的机器上面通过命令使用集群,如在64机器上运行
[mw_shl_code=bash,true]# docker -H swarm_manager_ip:2376 info[/mw_shl_code]
就会显示集群中的机器信息。
Spark on Docker
只需执行
[mw_shl_code=bash,true]# docker pull sequenceiq/spark:1.5.1[/mw_shl_code]
就会得到spark on docker的image,然后运行
[mw_shl_code=bash,true]# docker run -it -p 8088:8088 -p 8042:8042 -h sandbox sequenceiq/spark:1.5.1 bash[/mw_shl_code]
就会启动容器,我们就在机器上用docker来运行spark了。
[mw_shl_code=bash,true]# docker run -it -p 8088:8088 -p 8042:8042 -h sandbox sequenceiq/spark:1.5.1 bash
/
Starting sshd: [ OK ]
Starting namenodes on [sandbox]
sandbox: starting namenode, logging to /usr/local/hadoop/logs/hadoop-root-namenode-sandbox.out
localhost: starting datanode, logging to /usr/local/hadoop/logs/hadoop-root-datanode-sandbox.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /usr/local/hadoop/logs/hadoop-root-secondarynamenode-sandbox.out
starting yarn daemons
starting resourcemanager, logging to /usr/local/hadoop/logs/yarn–resourcemanager-sandbox.out
localhost: starting nodemanager, logging to /usr/local/hadoop/logs/yarn-root-nodemanager-sandbox.out[/mw_shl_code]
Docker Hub
自己特制了一个ubuntu镜像,其中包含着jdk1.7和JMeter,用作测试,现在准备将它推送到自己的Docker Hub上:
在Docker Hub上注册自己的账户,我的username是qiushan。这里我同时创建了一个repository,叫ubuntuj。
在本地机器上,通过docker commit在本地构建了所需的镜像并命名为ubuntu/jmeter,标签为v1。
先运行docker images命令,找到镜像ubuntu/jmeter的ID为b12279f9de5a,然后运行下面命令:
[mw_shl_code=bash,true]docker tag b12279f9de5a qiushan/ubuntuj:v1[/mw_shl_code]
其实这就指定了之后我们push该镜像的目的地,因为之前我们在注册docker hub的时候已经构建了一个repository叫ubuntuj在qiushan下。
登录docker hub:
[mw_shl_code=bash,true]docker login --username=qiushan --password=****** --email=xxxxxx[/mw_shl_code]
显示Succeed后,开始push:
[mw_shl_code=bash,true]docker push qiushan/ubuntuj[/mw_shl_code]
等待上传成功。
成功后在docker hub上就可以看到这个镜像了,之后就可以通过pull命令来随时随地下载它:
[mw_shl_code=bash,true]docker pull qiushan/ubuntuj[/mw_shl_code]
在本地我们已经build好一个镜像叫mymongodb,我们如果不想采用上述方式将镜像上传到docker hub,可以将镜像保存成tar包,存在本地或上传到github,要重新build镜像时,就把这个tar包用docker load 命令加载即可。
打成tar包:
[mw_shl_code=bash,true]docker save mymongodb > mymongodb.tar
# 其中 mymongodb是镜像名[/mw_shl_code]
加载tar包生成镜像:
[mw_shl_code=bash,true]docker load < mymongodb.tar[/mw_shl_code]
Tips
获取容器的id,我们都知道docker ps后可以看到正在运行容器的container id等信息,不过还有一个容器id是出现在/var/lib/docker中,那里存在正在运行和已经exited的容器的信息,我们有时需要remove那些已经不在的容器,可那里只有这些容器的id(好长一串数字和字母),怎么来确定删除的不是正在运行的容器呢,通过下面的命令来定位:
[mw_shl_code=bash,true]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ee3e662bd12 mymongodb:latest "mongod" 20 minutes ago Up 20 minutes 0.0.0.0:32770->27017/tcp mongo_001[/mw_shl_code]
这是只有一个容器在运行,
[mw_shl_code=bash,true]# docker inspect -f '{{.Id}}' 4ee3e662bd12
4ee3e662bd122c7fb299ce04e98f0dc30ba03a9c4bc44d4cc54bde81c7d87c4a[/mw_shl_code]
运行docker inspect后,出现下面一长串,那就是这个容器的id。在/var/lib/docker目录下删除这个长串以外的就可以了。
Spark Job Server
Swagger
API提供者想用Swagger来表述他的REST API。
StrongLoop
Kubernetes
这是官方给出的架构图:
|