背景
前文我们设置了jenkins 的pipeline,并且接受调用方传过来的参数,现在我们实现具体的CD操作,也就是把产物传到目标机器,并且停止老应用,启动新应用。
一般而言CD会包含以下的步骤
- 登录目标机器
 
- 备份原有文件
 
- 下载目标文件
 
- 停止原有进程
 
- 启动新的进程
 
而具体每一步,根据公司自己的要求,又会有所不同,例如有些公司会做一些健康检查,检查目标应用有没有成功启动。或者是在停止应用之前,做一些优雅上下线的操作。
由于我们公司使用的是阿里云的oss来存储产物的,所以就会涉及到含有AK的配置文件的发送,为了安全起见,配置文件是不能留在机器上面的,所以会有配置文件的复制以及删除。
启动命令根据各公司要求而异吧
由于打包的动作不频繁,所以打包跟分发的pipeline进行了区分
分发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
   |  def TARGET_HOST = params.TARGET_HOST def WORKER_URL = params.WORKER_URL def WORK_SPACE = "/tmp/workspace/pangu-agent/"+currentBuild.number node{     stage("创建文件夹"){          sh "mkdir -p "+ WORK_SPACE     }     ws(WORK_SPACE){
          stage("生成临时host文件"){                      tmpHost = ""             tmpHost += "[tmp]\n"             String[] hosts = TARGET_HOST.split(",")             for(String host:hosts){                 tmpHost += host                 tmpHost += "\n"             }             writeFile file:WORK_SPACE+'/tmpInventory',text:tmpHost         }
 
          stage("安装探针"){         ansiblePlaybook colorized: true, installation: "Ansible", playbook: "/sharedata/pangu-agent.yml",                 dynamicInventory:true,                 inventory:WORK_SPACE+'/tmpInventory',                 extraVars: [ 				hosts: TARGET_HOST,                 worker_url: WORKER_URL,                 oss_config: "/opt/platform/myConfig",                 source_url: "oss://ggj-private/pangu-agent/pangu-agent.jar",                 dest_path: "pangu-agent.jar"                 ]     }     }      }
 
  | 
 
ansible的执行playbook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
   | --- - hosts: "{{hosts}}"        //目标机器信息   remote_user: "root"       //ansible执行任务时候的角色   gather_facts: False       //不收集fact信息   vars:                     //一些下面会用到的参数,因人而异     worker_url: "{{worker_url}}"     oss_config: "{{oss_config}}"     source_url: "{{source_url}}"     dest_path: "{{dest_path}}"     jvm_params: " -Xss256K -Xmx100M -XX:MaxRAM=128M -Xint -XX:ParallelGCThreads=1 -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+StartAttachListener "   tasks:     - name: copy oss config             //从jenkins机器上面复制oss配置文件过去       copy: src={{ oss_config }} dest=/tmp/oss_config owner=root group=root mode=0644              //设置文件的属性
      - name: check agent_exist       stat: 'path=/opt/platform/pangu-agent.jar'       register: exist_result            //检查机器上面是否已经有老的产物存在,如果存在,下面就会进行备份
      - name: back previous version       copy:         src: /opt/platform/pangu-agent.jar         dest: /opt/platform/pangu-agent.bak.jar         follow: yes                     //该选项为覆盖的意思         remote_src: yes                 //设置操作为远程的地址,如果不设置,则会任务从jenkins的机器复制文件到目标机器       when: exist_result.stat.exists    //只有老的产物存在的时候,才会执行
      - name: oss get file       shell: /opt/platform/ossutil64 --config-file /tmp/oss_config cp -f {{source_url}}  /tmp/{{dest_path}}      //oss下载文件,本地如果存在,强行覆盖
 
      - name: copy agent file             //将产物移动到目标位置       copy:         src: /tmp/{{dest_path}}         dest: /opt/platform/pangu-agent.jar         follow: yes         remote_src: yes
      - name: remove oss config           //删除配置文件       file: path=/tmp/oss_config state=absent     //ansible的file模块,absent表示删除文件
      - name: get previous thread       shell: source /etc/profile; jps -l|grep pangu-agent|awk '{print $1}'       register: pid           //查找当前存在的进程,如果存在,后面再进行kill操作,这里需要由source /etc/profile来让环境变量生效,不然的话会导致jps等命令找不到,因为这些属于后续设置的环境变量
      - debug: var=pid.stdout_lines[0]    //打印一下,看看当前有没有存在进行
      - name: kill previous thread       shell: kill -9 {{pid.stdout_lines[0]}}       when: pid.stdout_lines|length !=0     //如果pid.stdout_lines的length为0,说明没有进程,反之则说明有进程存在       - name: start agent       shell: source /etc/profile; nohup java -jar {{jvm_params}} -Dregister.target-url={{worker_url}} /opt/platform/pangu-agent.jar > /logs/agent.log 2>&1 &
   |