阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

初创公司利用Docker持续集成部署

114次阅读
没有评论

共计 24798 个字符,预计需要花费 62 分钟才能阅读完成。

【编者的话】Docker 技术炙手可热,但是对于初创企业如何利用 Docker 这门新技术来解决内网开发或者测试环境的快速部署,解放运维并提高工作效率,尤其在创业之初人力资源不足的情况下,更为重要。为此我和公司一位开发同学一起研究的关于 Docker 快速部署应用的解决方案架构,下面是整个方案部署的步骤,由于资源有限过程中有问题还望大家指正交流,谢谢!

架构图

初创公司利用 Docker 持续集成部署

 

部署说明:

初创公司利用 Docker 持续集成部署

注意:
1. 平台部署以虚拟机为基础,除 DNS 服务器系统为 CentOS6.5 之外,所有虚拟机系统为 Centos7.0。
2. VM 系统需要设置 selinux 为允许或者关闭,以及关闭默认系统防火墙。

安装过程:(dns-registry-zk-mesos-marathon-consul-nginx-consul-template)

1)安装 docker 软件,部署说明中需要 docker 环境的都需要先安装软件,命令如下:

systemctl stop firewalld;systemctl disable firewalld
setenforce 0
sed -i s/^SELINUX=enforcing/SELINUX=permissive/ /etc/selinux/config
#设置 Selinux 为允许或者直接关闭。
yum install docker -y
vi /etc/sysconfig/docker
OPTIONS='--selinux-enabled --insecure-registry docker.smart.com'
#添加 docker 仓库信任
systemctl start docker
#启动 docker 服务 

2)配置 DNS 解析 smart.com 区域文件

DNS 服务器配置过程略。

192.168.10.200 docker.smart.com
#解析仓库域名服务器
echo nameserver 192.168.10.86 >>/etc/resolv.conf
#修改所有服务器域名服务器地址

3)配置 Docker 仓库

/data/docker/registry
#创建 docker 运行映射目录
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
#运行 registry 服务
docker push docker.smart.com/base/registry
#将本地镜像推送到仓库
curl http://docker.smart.com/v1/search
#查看仓库中的相关镜像(可以使用 Python json 模块转换 | python -m json.tool)
(可以按照此方法将 Jenkins、nginx、zookeeper 等镜像拉下来并推送到 docker.smart.com 仓库)

4)配置 zookeeper

mkdir /data/docker/zookeeper/conf -p
#创建配置文件映射目录(统一将 docker 运行的软件配置文件放到这个目录)

  • cat /data/docker/zookeeper/conf/zoo.cfg
    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
  • /data/docker/zookeeper/data/myid
    echo "1" > /data/docker/zookeeper/data/myid
  • 如果 myid 与 zoo.cfg 配置文件中的 server.x 相同则后边只能写 0.0.0.0,2888 为 zk 通讯端口,3888 为选举端口, 这里 3 个 zk 组成一个集群。

5)配置 mesos-master 和 mesos-slave

rpm -i http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
yum -y install mesos 
mesos-master --ip=192.168.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
#启动 master

  • 这里 –ip 为本机 –hostname 也为本机主机名 –quorum 做为有效果结点数, 值为(N+1) / 2,N 是 master 节点数, 配置 log_dir 主要是为了查看 mesos 日志。
mesos-slave --ip=192.168.10.136 --hostname=192.168.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
#启动 slave 首次启动均在前台,没有问题可以使用 nohup 放到后台。

 

  • ip 每个主机取值不相同
    hostname 默认会是主机名,但很多情况不能访问,所以使用主机 IP
    如果要在 WEB UI 上看到日志,需要配置 log_dir 属性
    executor_registration_timeout 容器执行的超时时间,如果 docker pull 的时候非常耗时,可能会导致这里超时.

6)配置 marathon 平台

  • marathon 平台需要依赖 mesos 相关库文件和 Java 环境所以需要安装 mesos 和 java
    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=192.168.10.124" >>  /etc/profile
    source /etc/profile
    #IP 为本机的 IP 地址
    bin/start --master zk://zk1.paas.smart.com:2181,zk2.paas.smart.com:2181,zk3.paas.smart.com:2181/mesos   --zk zk://zk1.paas.smart.com:2181,zk2.paas.smart.com:2181,zk3.paas.smart.com:2181/marathon --hostname 192.168.10.124 --framework_name smart
    #启动服务,hostname 为主机 IP 或本机主机名

7)配置 consul 集群

  • 需要部署 consul 的节点,mesos-master 和 mesos-slave
    # 将 consul 可执行文件放到 /usr/bin 目录下
    mkdir /usr/local/consul/conf
    #创建 consul 配置文件目录
    cat /usr/local/consul/conf/config.conf
    {
    "datacenter": "diliPAAS"
    ,"data_dir": "/usr/local/consul/data"
    ,"log_level": "INFO"
    ,"node_name": "master1"
    ,"server": true
    ,"retry_join":["192.168.10.210","192.168.10.184","192.168.10.152","192.168.10.136"]
    ,"rejoin_after_leave":true
    ,"client_addr":"192.168.10.203"
    }
    #retry_join IP 为各个 consul 节点的 IP,client_addr 为本机 IP 地址,server 为工作模式。
    consul agent -node=master1 -server -bootstrap -data-dir=/usr/local/consul/data -dc=diliPAAS
    #前台首次启动命令,需要指定 consul 相关数据存放目录,当启动其他 consul 之后可以使用如下命令启动
    nohup consul agent -config-file=config.conf >consul.out&
    consul members -rpc-addr=192.168.10.210:8400
    #查看 consul 集群情况,其中 rpc-addr 为任意节点 consul IP. 

8)nginx 配置

  • 因为我们的 nginx 和 DNS 配置是通过 consul-template 生成配置文件的,我们先把 nginx 起来然后配置 consul-template 通过模板生成最新的配置文件。
    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 仓库中拉去。

9. 配置 consul-template 来动态发现注册服务。

  • 配置 nginx 的服务发现和注册
cat /data/docker/nginx/conf/nginx.conf.tmpl
#nginx 配置模板文件
{{$model:="test"}}
worker_processes 1;

events {
worker_connections 65535;
}

http {

#lua_code_cache off;
client_max_body_size 1G;
server_names_hash_bucket_size 64;
    upstream marathon {
            server 192.168.10.186:8080;
            server 192.168.10.124:8080;
    }

    server {
            server_name marathon1.paas.smart.com;
            listen 80;
            location / {
                    proxy_pass http://marathon;
            }
    }

    upstream registry {
            server 192.168.10.200:80;
    }

    server {
            server_name docker.smart.com;
            listen 80;
            location / {
                    proxy_pass http://registry;
            }
    }


############################loop
{{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="192.168.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        192.168.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":"192.168.10.86"

,"zk1.paas":"192.168.10.160"
,"zk2.paas":"192.168.10.150"
,"zk3.paas":"192.168.10.209"
,"master1.paas":"192.168.10.203"
,"master2.paas":"192.168.10.210"
,"docker":"192.168.10.200"
,"cms":"192.168.6.54"
,"supplier":"192.168.6.54"
,"user":"192.168.6.54"
,"www":"192.168.6.54"
,"manweb":"192.168.6.54"
,"passport":"192.168.6.54"
,"authcode":"192.168.6.54"
,"shop":"192.168.6.54"
,"manage":"192.168.6.54"
,"upload":"192.168.6.53"
,"chat":"192.168.6.53"
,"csc":"192.168.6.53"
,"titan":"192.168.6.53"
,"orders":"192.168.6.53"
,"static":"192.168.6.53"
"smart.json" 51L, 1157C
,"mapi.pay":"192.168.6.53"
,"pay2":"192.168.6.53"
,"sso":"192.168.6.54"
,"group-admin":"192.168.6.54"
,"group":"192.168.6.54"
,"group-orders":"192.168.6.54"
,"img0":"192.168.6.153"
,"img1":"192.168.6.153"
,"img2":"192.168.6.153"
,"img3":"192.168.6.153"
,"img4":"192.168.6.153"
,"img5":"192.168.6.153"
,"img6":"192.168.6.153"
,"img7":"192.168.6.153"
,"img8":"192.168.6.153"
,"img9":"192.168.6.153"
,"cashier.pay":"192.168.6.53"
,"schedule":"192.168.4.14"
,"dp":"192.168.4.211"
,"apd":"192.168.6.54"
,"marathon":"192.168.10.177"
,"jenkins":"192.168.10.161"
,"leader.paas":"192.168.10.177"
}
#添加 consul-template 更新 DNS 的配置文件
cat /usr/local/consul-template/bind.conf
consul="192.168.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="www"
#BUILD_NUMBER="1"
#sysDir="/data/docker/jenkins/workspace/www/diligrp-website-web/target/diligrp-website-web"
sysName=${JOB_NAME}
HOST=root@192.168.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
#sysTmp=$(find / -name ${filename:=*.war})
#sysDir=${sysTmp/'.war'/}
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": "192.168.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} 

更多 Docker 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm 

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm 

Ubuntu 使用 VNC 运行基于 Docker 的桌面系统  http://www.linuxidc.com/Linux/2015-08/121170.htm

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm 

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm 

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm 

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

平台部署遇到的一些坑:

  1. 系统防火墙问题,docker 的防火墙和系统的防火墙是独立管理的,可以关闭系统防火墙。
  2. 系统 selinux 问题,如果 selinux 设置为强制会影响 docker 系统权限,需改成允许或者禁用。3. 平台 VM 是基于 cloudstack 搭建的,这里 cloudstack 的安全组也是一个坑,需要将相关端口开放。4. consul 第一个节点启动的时候需要带参数并指定 bootstrap 参数,然后在其他节点启动之后可以正常使用配置文件启动。
  3. 在部署平台之前先规划好相关主机名和 DNS 解析。
  4. 平台启动顺序为先启动 zk 然后 mesos 然后 marathon,不然会导致 marathon 与 mesos 通讯异常。
  5. 在启动 nginx 时 - v 参数后边接 nginx 相关配置目录不要接文件,尤其是需要配置 ssl 的时候。
    8.jenkins 由于跑在 docker 里,所以在推送脚本的时候需要进入 docker 做下与 Docker Build 的 ssh 信任关系。
  6. 在使用 yum 安装 mesos 的时候可能会由于 linux 7 下 systemctl 服务创建开机自动启动服务,需要 disable 掉。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2015-09/123026p2.htm

平台使用

任务从一次 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 任务
    初创公司利用 Docker 持续集成部署
  2. marathon 平台部署
    初创公司利用 Docker 持续集成部署
  3. 服务访问
    初创公司利用 Docker 持续集成部署

 

  • 后记:使用此平台能快速部署应用,易于扩展,从任务发布到访问服务不过短短几分钟,这在创业公司或者内部测试完全能满足需求,但是如果要落地到企业生产环境还有很多地方需要改进。

  1. Jenkins 编译构建流程需要拆分,不能每次发布同一款项目都需要重新编译拉包等,效率低下且不合理。
  2. Docker 的 iptables 网络部分需要重新设计,靠 iptables 的 NAT 转发效率有限,虽然解决了服务发现的问题。
  3. 没有比较细致的权限控制,平台安全性缺少。
  4. Docker APP 应用监控以及平台相关资源监控报警缺少。(Docker 监控目前可以介入监控宝)
  5. APP 应用的弹性伸缩目前是人为控制,不能根据业务需求创建。
  6. 平台部署相对流程比较多,易于扩展性不足。
    (后台 consul-UI)
    初创公司利用 Docker 持续集成部署 

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-09/123026.htm

【编者的话】Docker 技术炙手可热,但是对于初创企业如何利用 Docker 这门新技术来解决内网开发或者测试环境的快速部署,解放运维并提高工作效率,尤其在创业之初人力资源不足的情况下,更为重要。为此我和公司一位开发同学一起研究的关于 Docker 快速部署应用的解决方案架构,下面是整个方案部署的步骤,由于资源有限过程中有问题还望大家指正交流,谢谢!

架构图

初创公司利用 Docker 持续集成部署

 

部署说明:

初创公司利用 Docker 持续集成部署

注意:
1. 平台部署以虚拟机为基础,除 DNS 服务器系统为 CentOS6.5 之外,所有虚拟机系统为 Centos7.0。
2. VM 系统需要设置 selinux 为允许或者关闭,以及关闭默认系统防火墙。

安装过程:(dns-registry-zk-mesos-marathon-consul-nginx-consul-template)

1)安装 docker 软件,部署说明中需要 docker 环境的都需要先安装软件,命令如下:

systemctl stop firewalld;systemctl disable firewalld
setenforce 0
sed -i s/^SELINUX=enforcing/SELINUX=permissive/ /etc/selinux/config
#设置 Selinux 为允许或者直接关闭。
yum install docker -y
vi /etc/sysconfig/docker
OPTIONS='--selinux-enabled --insecure-registry docker.smart.com'
#添加 docker 仓库信任
systemctl start docker
#启动 docker 服务 

2)配置 DNS 解析 smart.com 区域文件

DNS 服务器配置过程略。

192.168.10.200 docker.smart.com
#解析仓库域名服务器
echo nameserver 192.168.10.86 >>/etc/resolv.conf
#修改所有服务器域名服务器地址

3)配置 Docker 仓库

/data/docker/registry
#创建 docker 运行映射目录
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
#运行 registry 服务
docker push docker.smart.com/base/registry
#将本地镜像推送到仓库
curl http://docker.smart.com/v1/search
#查看仓库中的相关镜像(可以使用 Python json 模块转换 | python -m json.tool)
(可以按照此方法将 Jenkins、nginx、zookeeper 等镜像拉下来并推送到 docker.smart.com 仓库)

4)配置 zookeeper

mkdir /data/docker/zookeeper/conf -p
#创建配置文件映射目录(统一将 docker 运行的软件配置文件放到这个目录)

  • cat /data/docker/zookeeper/conf/zoo.cfg
    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
  • /data/docker/zookeeper/data/myid
    echo "1" > /data/docker/zookeeper/data/myid
  • 如果 myid 与 zoo.cfg 配置文件中的 server.x 相同则后边只能写 0.0.0.0,2888 为 zk 通讯端口,3888 为选举端口, 这里 3 个 zk 组成一个集群。

5)配置 mesos-master 和 mesos-slave

rpm -i http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
yum -y install mesos 
mesos-master --ip=192.168.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
#启动 master

  • 这里 –ip 为本机 –hostname 也为本机主机名 –quorum 做为有效果结点数, 值为(N+1) / 2,N 是 master 节点数, 配置 log_dir 主要是为了查看 mesos 日志。
mesos-slave --ip=192.168.10.136 --hostname=192.168.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
#启动 slave 首次启动均在前台,没有问题可以使用 nohup 放到后台。

 

  • ip 每个主机取值不相同
    hostname 默认会是主机名,但很多情况不能访问,所以使用主机 IP
    如果要在 WEB UI 上看到日志,需要配置 log_dir 属性
    executor_registration_timeout 容器执行的超时时间,如果 docker pull 的时候非常耗时,可能会导致这里超时.

6)配置 marathon 平台

  • marathon 平台需要依赖 mesos 相关库文件和 Java 环境所以需要安装 mesos 和 java
    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=192.168.10.124" >>  /etc/profile
    source /etc/profile
    #IP 为本机的 IP 地址
    bin/start --master zk://zk1.paas.smart.com:2181,zk2.paas.smart.com:2181,zk3.paas.smart.com:2181/mesos   --zk zk://zk1.paas.smart.com:2181,zk2.paas.smart.com:2181,zk3.paas.smart.com:2181/marathon --hostname 192.168.10.124 --framework_name smart
    #启动服务,hostname 为主机 IP 或本机主机名

7)配置 consul 集群

  • 需要部署 consul 的节点,mesos-master 和 mesos-slave
    # 将 consul 可执行文件放到 /usr/bin 目录下
    mkdir /usr/local/consul/conf
    #创建 consul 配置文件目录
    cat /usr/local/consul/conf/config.conf
    {
    "datacenter": "diliPAAS"
    ,"data_dir": "/usr/local/consul/data"
    ,"log_level": "INFO"
    ,"node_name": "master1"
    ,"server": true
    ,"retry_join":["192.168.10.210","192.168.10.184","192.168.10.152","192.168.10.136"]
    ,"rejoin_after_leave":true
    ,"client_addr":"192.168.10.203"
    }
    #retry_join IP 为各个 consul 节点的 IP,client_addr 为本机 IP 地址,server 为工作模式。
    consul agent -node=master1 -server -bootstrap -data-dir=/usr/local/consul/data -dc=diliPAAS
    #前台首次启动命令,需要指定 consul 相关数据存放目录,当启动其他 consul 之后可以使用如下命令启动
    nohup consul agent -config-file=config.conf >consul.out&
    consul members -rpc-addr=192.168.10.210:8400
    #查看 consul 集群情况,其中 rpc-addr 为任意节点 consul IP. 

8)nginx 配置

  • 因为我们的 nginx 和 DNS 配置是通过 consul-template 生成配置文件的,我们先把 nginx 起来然后配置 consul-template 通过模板生成最新的配置文件。
    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 仓库中拉去。

9. 配置 consul-template 来动态发现注册服务。

  • 配置 nginx 的服务发现和注册
cat /data/docker/nginx/conf/nginx.conf.tmpl
#nginx 配置模板文件
{{$model:="test"}}
worker_processes 1;

events {
worker_connections 65535;
}

http {

#lua_code_cache off;
client_max_body_size 1G;
server_names_hash_bucket_size 64;
    upstream marathon {
            server 192.168.10.186:8080;
            server 192.168.10.124:8080;
    }

    server {
            server_name marathon1.paas.smart.com;
            listen 80;
            location / {
                    proxy_pass http://marathon;
            }
    }

    upstream registry {
            server 192.168.10.200:80;
    }

    server {
            server_name docker.smart.com;
            listen 80;
            location / {
                    proxy_pass http://registry;
            }
    }


############################loop
{{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="192.168.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        192.168.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":"192.168.10.86"

,"zk1.paas":"192.168.10.160"
,"zk2.paas":"192.168.10.150"
,"zk3.paas":"192.168.10.209"
,"master1.paas":"192.168.10.203"
,"master2.paas":"192.168.10.210"
,"docker":"192.168.10.200"
,"cms":"192.168.6.54"
,"supplier":"192.168.6.54"
,"user":"192.168.6.54"
,"www":"192.168.6.54"
,"manweb":"192.168.6.54"
,"passport":"192.168.6.54"
,"authcode":"192.168.6.54"
,"shop":"192.168.6.54"
,"manage":"192.168.6.54"
,"upload":"192.168.6.53"
,"chat":"192.168.6.53"
,"csc":"192.168.6.53"
,"titan":"192.168.6.53"
,"orders":"192.168.6.53"
,"static":"192.168.6.53"
"smart.json" 51L, 1157C
,"mapi.pay":"192.168.6.53"
,"pay2":"192.168.6.53"
,"sso":"192.168.6.54"
,"group-admin":"192.168.6.54"
,"group":"192.168.6.54"
,"group-orders":"192.168.6.54"
,"img0":"192.168.6.153"
,"img1":"192.168.6.153"
,"img2":"192.168.6.153"
,"img3":"192.168.6.153"
,"img4":"192.168.6.153"
,"img5":"192.168.6.153"
,"img6":"192.168.6.153"
,"img7":"192.168.6.153"
,"img8":"192.168.6.153"
,"img9":"192.168.6.153"
,"cashier.pay":"192.168.6.53"
,"schedule":"192.168.4.14"
,"dp":"192.168.4.211"
,"apd":"192.168.6.54"
,"marathon":"192.168.10.177"
,"jenkins":"192.168.10.161"
,"leader.paas":"192.168.10.177"
}
#添加 consul-template 更新 DNS 的配置文件
cat /usr/local/consul-template/bind.conf
consul="192.168.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="www"
#BUILD_NUMBER="1"
#sysDir="/data/docker/jenkins/workspace/www/diligrp-website-web/target/diligrp-website-web"
sysName=${JOB_NAME}
HOST=root@192.168.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
#sysTmp=$(find / -name ${filename:=*.war})
#sysDir=${sysTmp/'.war'/}
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": "192.168.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} 

更多 Docker 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm 

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm 

Ubuntu 使用 VNC 运行基于 Docker 的桌面系统  http://www.linuxidc.com/Linux/2015-08/121170.htm

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm 

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm 

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm 

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

平台部署遇到的一些坑:

  1. 系统防火墙问题,docker 的防火墙和系统的防火墙是独立管理的,可以关闭系统防火墙。
  2. 系统 selinux 问题,如果 selinux 设置为强制会影响 docker 系统权限,需改成允许或者禁用。3. 平台 VM 是基于 cloudstack 搭建的,这里 cloudstack 的安全组也是一个坑,需要将相关端口开放。4. consul 第一个节点启动的时候需要带参数并指定 bootstrap 参数,然后在其他节点启动之后可以正常使用配置文件启动。
  3. 在部署平台之前先规划好相关主机名和 DNS 解析。
  4. 平台启动顺序为先启动 zk 然后 mesos 然后 marathon,不然会导致 marathon 与 mesos 通讯异常。
  5. 在启动 nginx 时 - v 参数后边接 nginx 相关配置目录不要接文件,尤其是需要配置 ssl 的时候。
    8.jenkins 由于跑在 docker 里,所以在推送脚本的时候需要进入 docker 做下与 Docker Build 的 ssh 信任关系。
  6. 在使用 yum 安装 mesos 的时候可能会由于 linux 7 下 systemctl 服务创建开机自动启动服务,需要 disable 掉。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2015-09/123026p2.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计24798字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中