要求将某项目的部署方式转变为docker的方式,并和jenkins相结合,主要组件有自身的两个服务(bill-api ,bill-backend)以及mysql、mq、redis

2016-04-18

  1. 先申请了2台机器,因为只是demo,所以提出要debian7 3.18内核的,配置的话2x2 4G或以上就可以

  2. 得到2台机器106和107
    在jenkins节点机器上ping和telnet一下,访问正常
    jenkins机器138

  3. 安装docker-1.9.1

 1     apt-get update
 2     apt-get install -y apt-transport-https
 3 
 4     echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list
 5 
 6     apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
 7 
 8 
 9     apt-get update
10     apt-get install -y lxc-docker-1.9.1
 
  1. 开远程端口,允许远程访问
    DOCKER_OPTS='-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock'
    service docker restart
 

尝试一下127.0.0.1:2375/info,若有信息返回说明正常

  1. 权限控制

使用蜂巢的镜像仓库,由于线上采用了帐号权限控制,若使用线上的仓库,只能在安装有docker的机器用自己的帐号先docker login一下,否则会拉取失败

 docker login –u [你的蜂巢账号] –p [你的蜂巢密码] –e [你的邮箱] hub.c.163.com
 

目前难点
1.服务的编译、打包、写dockfile方式全需要自己搞定
2.需调研远程docker调用方式并进行coding
https://github.com/docker/docker-py

2016-04-19

尝试使用了docker api的方式,优点是易于编写和标准化,缺点难以通用,最后改用了命令行方式,有兴趣的同学也可采用docker api的方式去做

在jenkins节点机安装docker.py

准备好冒烟代码

1 import sys
2 from docker import Client
3 cli = Client(base_url='tcp://10.180.194.106:2375',version='1.21',timeout=10)
4 resp=cli.containers()
5 print str(resp);
 

1.安装docker.py,前先安装pip

apt-get update
apt-get install python-pip -y
 

2.安装docker-py

pip install docker-py
 

3.用冒烟代码跑一下,若出现
ImportError: No module named ipaddress
就表示少了模块,使用pip安装

pip install ipaddress

 

 

本机配置了下python+pycharm环境

1.安装docker-py插件

注意version必须和目标的docker server匹配

Server:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      linux/amd64

 

 

一个基础的部署脚本如下

 1 import sys
 2 import time
 3 from docker import Client
 4 
 5 
 6 
 7 #docker server
 8 url = "10.180.194.107:2375"
 9 #docker client need match # docker server
10 version = "1.21"
11 #image
12 image = "hub.c.163.com/cloud163/qademo:mysql"
13 
14 #init cli
15 cli = Client(base_url='tcp://' + url, version=version, timeout=30)
16 try:
17     resp = cli.create_container(image=image, detach=True, environment=["MYSQL_ROOT_PASSWORD=ncetest","MYSQL_USER=root","PASSWORD=123456"])
18     print(resp)
19     containerId = resp['Id']
20 
21 except Exception,e:
22     print "create container fail:" + str(e)
23     cli.remove_container(container=containerId)
24     sys.exit()
25 time.sleep(5)
26 resp = cli.start(container=containerId)
27 try:
28     resp = cli.start(container=containerId)
29 except Exception,e:
30     print "start container fail:" + str(e)
31     #cli.remove_container(container=containerId)
32     #sys.exit()
33 
34 time.sleep(5)
35 
36 
37 try:
38     resp = cli.inspect_container(containerId)
39     status = (resp['State']['Status'])
40     if status != "running":
41         raise Exception("container not running")
42 
43 
44 except Exception,e:
45     print "inspect container fail:" + str(e)
46     cli.remove_container(container=containerId)
47     sys.exit()

 

 

使用了一下,如果是自己使用足够方便,但是要提供给别人用,很难通用,使用上不够灵活,需要自己封装,所以采用更简单docker -H 方式

2016-04-20

为了方便推广,采用docker -H方式,使用上和本地命令行一样

  1. jenkins机器上安装docker
    按上文的脚本安装docker,然后冒烟
    #  docker -H 10.180.194.107:2375 images
    REPOSITORY                                      TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    registry.hz.netease.com/nce2cntr/hzmali_mysql   latest              7424a1b1aebd        4 months ago        247.2 MB
    hub.c.163.com/cloud163/qademo                   mysql               7424a1b1aebd        4 months ago        247.2 MB
 

远程调用无问题

  1. 编写部署脚本
    基本逻辑是停掉老服务,删除老服务,最后启动新服务
    对于mysql、rabbitmq和redis来说只要运行即可

上传了3个组件镜像到镜像仓库

hub.c.163.com/cloud163/qademo:mysql 
hub.c.163.com/cloud163/qademo:rabbitmq3 
hub.c.163.com/cloud163/qademo:redis

 

基本运行方式

docker run -d xxx --name xxxx

使用--name唯一标识了一个容器,利用--name进行操作无需获取container id

ps:
部署完可以自己定义一些初始化操作,或者手动登录去进行初始化
由于docker -H pull 镜像用的是ci节点机器,所以节点机器需要有拉取权限,需要docker login一下

3.构建服务镜像
发现jenkins server 内核太老了:
” level=warning msg=”Your Linux kernel version 3.2.73 can be unstable running docker. Please upgrade your kernel to 3.10.0.”
本来想构建是在节点机器上做,现在只能去目标机器上去做了,相当于节点机仅仅是使用了docker cli

基本逻辑:环境准备->用dockerfile构建->push镜像->清理

1.环境准备这块涉及拉代码什么的,每个项目不同,  
2.dockerfile构建则是根据构建服务的规则写dockerfile,每个项目不同
3.构建完成后推送镜像
4.清理镜像,这部分暂时未做

4.简单将流程贯穿起来

SA(静态代码检查)>unitTest(单测)->build image(构建镜像)>deploy image(部署镜像)>apiTest(接口测试)

后续工作:
1.各job间参数和变量未进行优化处理
2.代码编译需要在节点机上自己安装编译环境
3.代码拉取以及dockerfile构建还未进行编写
4.老镜像清理这块还未做
5.一些实现细节待优化

2016-04-28

服务的代码是用java写的,使用tomcat运行,有现成的build.xml,所以dockerfile也比较简单,如

    FROM hub.c.163.com/nce2/tomcat:or7_7.0.62
    ADD compressed /webroot
 
  1. 开通代码权限

确保ci节点机器上有配置自己的密钥,可以拉取代码

  1. 构建环境安装
    将ant、maven、jdk等,上传到ci的节点机器上,未来的构建也可以放到一个构建的镜像中去做,无需每次都去安装环境

ps:
我突然想到了一个更轻的方案,使用容器做虚拟机,安装好agent,使用现有的部署工具和平台进行部署,即可无缝迁移到容器方式

2016-04-29

1.目前build.xml和dockerfile都是放在ci节点机器的/home/script下面然后copy到当前workspace,后续可以直接放到代码目录下面

2.暂时根据bill-api服务做了一个构建任务,主逻辑:

 1 #!/bin/bash
 2 dockerfilepath="/home/script"
 3 shopt -s  expand_aliases 
 4 alias docker="docker -H $addr"
 5 . ~/.bash_profile
 6 
 7 
 8 cd $WORKSPACE
 9 
10 #git pull
11 echo "git pull"
12 
13 #get git version
14 if [ $version -eq 0 ];then
15 echo "use latest version"
16 version=`git log|head -1|cut -d " " -f 2`
17 echo "get latest version:"$version
18 else
19 echo "use user version"
20 git checkout -f $version
21 fi
22 
23 
24 #compile
25 cp -p /home/script/$buildfile ./build.xml
26 
27 echo "compile and build"
28 
29 # can use -D to transinto param
30 #/bin/bash -c ant1.7.0_64 -f  build.xml -Dconf=$conf
31 ant1.7.0_64 -f  build.xml -Dconf=$conf
32 
33 
34 #make image url
35 image=$registry":"${name}_${version}
36 
37 #build
38 echo "#### docker build $tag ####"
39 cp -p $dockerfilepath/$dockerfile ./dockerfile
40 docker build -f ./dockerfile -t $image ./
41 
42 #push
43 image_no=`docker images|grep $registry |grep -c ${name}_${version}`
44 if [ $image_no -eq 0 ];then
45 echo "docker build fail"
46 exit -1
47 fi 
48 echo "#### docker push $image ####"
49 docker push $image
 

在部署和运行的job中,docker run的部分需要自己定义需要-p开放想要的端口、-e传入指定的环境变量、-v配置需要挂载到本地的路径,其中端口对外开放的配置(docker run -p xxx:yyy)根据实际服务对外访问来进行配置和开启

做pipieline和单构建任务类似,需要做的是在构建镜像的job执行完成后将镜像名称传递给deploy的job,变量的传递可以采用文件传递