标签(空格分隔): docker
---
| 主机角色 | 服务类型 | 主机IP | 安装环境| 安装软件
| -------- | -----: | :----: |
| Marathon1 |marathon-HA | 10.28.10.186 | VM |marathon/mesos
|Marathon2|marathon-HA|10.28.10.124|VM|marathon/mesos
|Mesos-Master1|mesos-master/consul-server|10.28.10.186|VM|mesos/consul
|Mesos-Master2|mesos-master/consul-server|10.28.10.124|VM|mesos/consul
|Mesos-Slave1|mesos-slave/consul-agent|10.28.10.184|VM|mesos/consul/docker
|Mesos-Slave2|mesos-slave/consul-agent|10.28.10.152|VM|mesos/consul/docker
|Mesos-Slave3|mesos-slave/consul-agent|10.28.10.136|VM|mesos/consul/docker
|Jenkins|jenkins|10.28.10.161|Docker|jenkins images/docker
|Docker Registry|images 存储|10.28.10.200|Docker|docker registry images/docker
|Docker Building|生成任务镜像|10.28.10.130|Docker|docker
|Docker-Zookeeper-1|分布式协调|10.28.10.160|Docker|zookeeper images/docker
|Docker-Zookeeper-2|分布式协调|10.28.10.150|Docker|zookeeper images/docker
|Docker-Zookeeper-3|分布式协调|10.28.10.209|Docker|zookeeper images/docker
|DNS|Docker 内部域名服务|10.28.10.86|VM|bind server/consul-template
|NGINX|Docker 内部和外部代理以及负载均衡|10.28.10.177|Docker|nginx images/consul-template
注意:
1.平台部署以虚拟机为基础,除DNS服务器系统为Centos6.5之外,所有虚拟机系统为Centos7.0。
2.VM系统需要设置selinux为允许或者关闭,以及关闭默认系统防火墙。
1.安装docker软件,部署说明中需要docker环境的都需要先安装软件,命令如下:
systemctl stop firewalld;systemctl disable firewalld
setenforce 0
sed -i s/^SELINUX=enforcing/SELINUX=permissive/ /etc/selinux/config
yum install docker -y
vi /etc/sysconfig/docker
OPTIONS='--selinux-enabled --insecure-registry docker.smart.com'
systemctl start docker
2.配置DNS解析smart.com区域文件
DNS服务器配置过程略。
10.28.10.200 docker.smart.com
echo nameserver 10.28.10.86 >>/etc/resolv.conf
3.配置Docker仓库
```
/data/docker/registry
docker pull index.alauda.cn/juqkai/registry
docker tag index.alauda.cn/juqkai/registry docker.smart.com/base/registry
docker run -d --restart=always -p 80:5000 -v /data/docker/registry:/tmp/registry-dev docker.smart.com/juqkai/registry
docker push docker.smart.com/base/registry
curl http://docker.smart.com/v1/search
(可以按照此方法将Jenkins、nginx、zookeeper等镜像拉下来并推送到docker.smart.com仓库)
4.配置zookeeper
mkdir /data/docker/zookeeper/conf -p
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
clientPort=2181
server.1=0.0.0.0:2888:3888
server.2=zk2.paas.smart.com:2888:3888
server.3=zk3.paas.smart.com:2888:3888
echo "1" > /data/docker/zookeeper/data/myid
5.配置mesos-master和mesos-slave
rpm -i http://repos.mesosphere.io/el/ ... h.rpm
yum -y install mesos
mesos-master --ip=10.28.10.203 --hostname=master1.paas.smart.com --work_dir=/var/lib/mesos --quorum=1 --log_dir=/var/log/mesos --port=5050 --zk_session_timeout=120secs --zk=zk://zk1.paas.smart.com:2181,zk2.paas.smart.com:2181,zk3.paas.smart.com:2181/mesos
mesos-slave --ip=10.28.10.136 --hostname=10.28.10.136 --log_dir=/var/log/mesos --containerizers=docker,mesos --master=zk://zk1.paas.smart.com:2181,zk2.paas.smart.com:2181,zk3.paas.smart.com:2181/mesos --executor_registration_timeout=5mins
ip每个主机取值不相同
hostname默认会是主机名,但很多情况不能访问,所以使用主机IP
如果要在WEB UI上看到日志,需要配置log_dir属性
executor_registration_timeout容器执行的超时时间,如果docker pull的时候非常耗时,可能会导致这里超时.
6.配置marathon平台
rpm -i http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
yum -y install mesos marathon java
echo "export LIBPROCESS_IP=10.28.10.124" >> /etc/profile
source /etc/profile
8.nginx配置
mkdir /data/docker/nginx/conf/
#创建nginx配置映射目录,ssl等文件也放在这个目录
docker run -d --name nginx -p 80:80 -v /data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf index.alauda.cn/library/nginx
#从灵雀云拉的镜像运行,如果之前拉过并push到仓库,可以从我们之前放到docker.smart.com仓库中拉去。
events {
worker_connections 65535;
}
http {
#lua_code_cache off;
client_max_body_size 1G;
server_names_hash_bucket_size 64;
upstream marathon {
server 10.28.10.186:8080;
server 10.28.10.124:8080;
}
server {
server_name marathon1.paas.smart.com;
listen 80;
location / {
proxy_pass http://marathon;
}
}
upstream registry {
server 10.28.10.200:80;
}
server {
server_name docker.smart.com;
listen 80;
location / {
proxy_pass http://registry;
}
}
{{range services}}
{{$nameArr := .Name | split "-"}}
{{if gt (len $nameArr) 1}}
{{if eq $model (index $nameArr 1)}}
{{$name := (index $nameArr 0)}}
{{if service .Name }}
upstream {{.Name}} { {{range service .Name}}
server {{.Address}}:{{.Port}};#{{range .Tags}}{{.}},{{end}}{{end}}
}
server {
server_name {{$name}}.smart.com;
listen 80;
location / {
proxy_pass http://{{.Name}};
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
{{if eq $name "passport"}}
upstream {{.Name}}ssl { {{range service .Name}}
server {{.Address}}:{{.Port}};{{end}}
}
server {
server_name {{$name}}.smart.com;
listen 443;
ssl on;
ssl_certificate smart_server.pem;
ssl_certificate_key smart_server.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://{{.Name}}ssl;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
{{end}}
{{end}}
{{end}}
{{end}}
{{end}}
}
#nginx配置文件模板文件内容
mkdir -p /usr/local/consul-template/
#创建consul-template 配置文件目录
cat nginx.tmpl.conf
consul="10.28.10.203:8500"
template {
source="/data/docker/nginx/conf/nginx.conf.tmpl"
destination="/data/docker/nginx/conf/nginx.conf"
command="docker exec nginx nginx -s reload >> /dev/null"
}
#其中consul中的IP为mesos-master
nohup consul-template -config=./nginx.tmpl.conf &
#启动consul-template更新nginx服务
```
配置DNS的consul-template服务
```
cat /var/named/smart.com.zone.tmp
#DNS区域文件模板
{{$model:="test"}}
$TTL 1D
@ IN SOA @ rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS @
A 127.0.0.1
AAAA ::1
@ IN NS ns.smart.com.
{{$ips:=file "/var/named/smart.json" |parseJSON}}
{{range services}}
{{$nameArr := .Name | split "-"}}
{{if gt (len $nameArr) 1}}
{{if eq $model (index $nameArr 1)}}
{{$name := (index $nameArr 0)}}
{{$name}} IN A 10.28.10.177
{{end}}
{{end}}
{{end}}
{{range $k,$v := $ips}}{{$kn := $k|regexReplaceAll "$" "-"|regexReplaceAll "$" $model}}{{$sk := service $kn}}{{$l:=len $sk}}{{if $l}}{{else}}
{{$k}} IN A {{$v}}{{end}}{{end}}
#由于系统需要调用外部资源所以增加外部固定资源DNS A记录 smart.json
cat /var/named/smart.json
{
"ns":"10.28.10.86"
,"zk1.paas":"10.28.10.160"
,"zk2.paas":"10.28.10.150"
,"zk3.paas":"10.28.10.209"
,"master1.paas":"10.28.10.203"
,"master2.paas":"10.28.10.210"
,"docker":"10.28.10.200"
,"cms":"10.28.6.54"
,"supplier":"10.28.6.54"
,"user":"10.28.6.54"
,"www":"10.28.6.54"
,"manweb":"10.28.6.54"
,"passport":"10.28.6.54"
,"authcode":"10.28.6.54"
,"shop":"10.28.6.54"
,"manage":"10.28.6.54"
,"upload":"10.28.6.53"
,"chat":"10.28.6.53"
,"csc":"10.28.6.53"
,"titan":"10.28.6.53"
,"orders":"10.28.6.53"
,"static":"10.28.6.53"
"smart.json" 51L, 1157C
,"mapi.pay":"10.28.6.53"
,"pay2":"10.28.6.53"
,"sso":"10.28.6.54"
,"group-admin":"10.28.6.54"
,"group":"10.28.6.54"
,"group-orders":"10.28.6.54"
,"img0":"10.28.6.153"
,"img1":"10.28.6.153"
,"img2":"10.28.6.153"
,"img3":"10.28.6.153"
,"img4":"10.28.6.153"
,"img5":"10.28.6.153"
,"img6":"10.28.6.153"
,"img7":"10.28.6.153"
,"img8":"10.28.6.153"
,"img9":"10.28.6.153"
,"cashier.pay":"10.28.6.53"
,"schedule":"10.28.4.14"
,"dp":"10.28.4.211"
,"apd":"10.28.6.54"
,"marathon":"10.28.10.177"
,"jenkins":"10.28.10.161"
,"leader.paas":"10.28.10.177"
}
#添加consul-template更新DNS的配置文件
cat /usr/local/consul-template/bind.conf
consul="10.28.10.184:8500"
template {
source="/var/named/smart.com.zone.tmp"
destination="/var/named/smart.com.zone"
command="chown root.named /var/named/smart;/etc/init.d/named restart"
}
nohup consul-template -config=./bind.conf >dns.out &
#运行DNS的consul-template服务
```
10.配置Jenkins
jenkins服务提供拉取代码并本地编译然后推送到Docker Build服务器。
```
docker run -it --rm -p 80:8080 -v /data/docker/jenkins:/var/jenkins_home -v /data/docker/jenkins/maven:/home/anonymous/.m2 docker.smart.com/base/jenkins
cat /data/docker/jenkins/upload_file
#jenkins 编译完成之后推送脚本
#!/bin/bash
dcpu=${cpu:="0.4"}
dmem=${mem:="512"}
dins=${ins:="1"}
model="test"
sysName=${JOB_NAME}
HOST=root@10.28.10.130
sysTmp=$(find ${WORKSPACE} -name ${filename:=.war})
sysDir=${sysTmp/'.war'/}
echo "war path: ${sysDir}"
upload_file()
{
ssh -nq $HOST "[ -d /tmp/${sysName} ] && rm -rf /tmp/${sysName} >>/dev/null ; mkdir -p /tmp/${sysName}"
ssh -nq $HOST "mkdir -p /tmp/${sysName} "
scp -r ${sysDir}/* $HOST:/tmp/${sysName}
ssh -nq $HOST "sh /usr/bin/Docker_Build ${sysName} ${BUILD_NUMBER} ${dcpu} ${dmem} ${dins} ${model}"
}
upload_file
11.配置Docker Build服务
Docker Build其实就是将Jenkins服务器推过来的源码包利用Dockfile
生成 docker 镜像。
cat /usr/bin/Docker_Build
#!/bin/bash
cpu=$3
mem=$4
ins=$5
sysName=$1
BUILD_NUMBER=$2
model=$6
sysDir=/tmp/$1
echo "war path: ${sysDir}"
if [ ! -f "${sysDir}/Dockerfile" ]; then
#дDockerfile
echo "FROM docker.smart.com/base/tomcat
RUN rm -rf /usr/local/tomcat/webapps/ROOT/*
ADD ./ /usr/local/tomcat/webapps/ROOT
" > ${sysDir}/Dockerfile
fi
dockerPath=docker.smart.com/front/$sysName:${BUILD_NUMBER}
cd ${sysDir}
docker build -t ${dockerPath} .
docker push ${dockerPath}
curl -X DELETE -H "Content-Type: application/json" http://marathon1.paas.smart.com/v2/apps/ ${model}/${sysName}
sleep 20
if [ ! -f "${sysDir}/app_marathon.json" ]; then
cat << EOF >${sysDir}/app_marathon.json
{"id": "/${model}/${sysName}","container": {"docker":{"image":"${dockerPath}","network": "BRIDGE","parameters":[{"key":"dns", "value": "10.28.10.86"}],"portMappings": [{"containerPort": 8080}]}},"cpus": ${cpu},"mem": ${mem},"instances": ${ins}}
EOF
fi
curl -X POST -H "Content-Type: application/json" http://marathon1.paas.smart.com/v2/apps -d@${sysDir}/app_marathon.json
sleep 5
cd /
rm -rf ${sysDir}
```
平台部署遇到的一些坑:
1.系统防火墙问题,docker的防火墙和系统的防火墙是独立管理的,可以关闭系统防火墙。
2.系统selinux问题,如果selinux设置为强制会影响docker系统权限,需改成允许或者禁用。
3.平台VM是基于cloudstack搭建的,这里cloudstack的安全组也是一个坑,需要将相关端口开发。
4.consul第一个节点启动的时候需要带参数并指定bootstrap参数,然后在其他节点启动之后可以正常使用配置文件启动。
5.在部署平台之前先规划好相关主机名和DNS解析。
6.平台启动顺序为先启动zk然后mesos然后marathon,不然会导致marathon与mesos通讯异常。
7.在启动nginx时-v参数后边接nginx相关配置目录不要接文件,尤其是需要配置ssl的时候。
8.jenkins由于跑在docker里,所以在推送脚本的时候需要进入docker做下与Docker Build 的ssh信任关系。
9.在使用yum安装mesos的时候可能会由于linux 7下systemctl服务创建开机自动启动服务,需要disable掉。
> * 任务从一次Jenkins构建开始,Jenkins从代码仓库(svn,git)拉取代码并编译(配置mvn服务),编译完成之后通过upload_file脚本将*.war包推送到Docker Build服务器,Build服务器使用Docker_Build脚本生成Dockfile文件并building成相应的app镜像推送到docker.smart.com仓库,同时通过RESTful接口通知marathon平台,marathon平台从mesos-master请求部署任务,mesos-master返回具体部署服务器slave信息;marathon通过slave docker Damon进程部署app任务。consul服务更新app相关IP和端口然后consul-template服务分别将IP和服务端口更新到DNS和nginx配置文件reload服务,最后用户就可以直接访问app服务,整个任务完成。
1.Jenkins构建app任务
2.marathon平台部署
3.服务访问
后记:使用此平台能快速部署应用,易于扩展,从任务发布到访问服务不过短短几分钟,这在创业公司或者内部测试完全能满足需求,但是如果要落地到企业生产环境还有很多地方需要改进。
1.Jenkins编译构建流程需要拆分,不能每次发布同一款项目都需要重新编译拉包等,效率低下且不合理。
2.Docker的iptables网络部分需要重新设计,靠iptables的NAT转发效率有限,虽然解决了服务发现的问题。
3.没有比较细致的权限控制,平台安全性缺少。
4.Docker APP应用监控以及平台相关资源监控报警缺少。(Docker监控目前可以介入监控宝)
5.APP应用的弹性伸缩目前是人为控制,不能根据业务需求创建。
6.平台部署相对流程比较多,易于扩展性不足。
(后台consul-UI)