zoukankan      html  css  js  c++  java
  • 某项目docker化持续集成日记

    某项目docker化持续集成日记

    要求将某项目的部署方式转变为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,变量的传递可以采用文件传递

     
     
  • 相关阅读:
    Azure ARM (8) ARM Template
    Azure ARM (7) ARM Template
    Azure ARM (6) ARM Template简单介绍
    HBase集群安装过程中的问题集锦
    修改linux最大文件句柄数
    Hadoop 2.2.0部署安装(笔记,单机安装)
    sqoop安装部署(笔记)
    HIVE部署安装(笔记)
    防盗链Nginx设置图片防盗链,设置无效的请仔细看红字
    postgresql 内存分配
  • 原文地址:https://www.cnblogs.com/opama/p/5536879.html
Copyright © 2011-2022 走看看