ansible 修改文件变量_Jenkins+ansible+pipeline自动化构建

假如我们有几十个Java项目,Python,node项目,安卓,IOS等各种项目,

而且又分为测试,预上线,正式等多个环境,不同环境的配置是不一样的,有的项目还可能同时有多个配置文件,

所以项目上线更新也是一个很大的工程,所以我们可以借助与Jenkins等CI/CD工具简化这个工作,需要上线时,只需要点下构建就行,由于上线这个过程可以保证没问题,所以这个上线权限可以直接交给开发人员。

大概思路:

我们可以给每个项目的配置文件创建一套配置模板,关键进行抽成模板语言变量,所有环境(测试,预上线,正式)共用这一套模板,构建时根据配置和模板渲染成配置文件进行替换,问题就是开发需要更新配置文件,需要在模板中添加,开发本地测试提到Git上的配置文件是不起作用的。

给每个环境创建一个配置文件(test.yml,release.yml,main.yml),

每一类项目创建一个playbook模板,项目的所有服务命名,配置文件位置文件名,启动方式,pom.xml等尽量统一。

playbook中定义所有动作:更新配置文件-打包(mvn, yarn,npm,go build, gradlew)-上传到服务器-重启服务

注,根据情况,playbook中可以添加你想添加的操作(比如上传到OSS,钉钉通知等),我们的服务管理用的是supervisord,所以服务器重启借助了supervisorctl

1.准备环境

  • 安装jenkins+ansible
  • 配置ansible服务器与其他服务器ssh密钥通信
ssh-keygenssh-copy-id server1

# 仅供说明,请根据实际情况配置

  • 安装ansible插件
0cdafff9fb1c53ad73b99d06e95fabd7.png
  • 安装gitlab插件
39d1170d6dc2c3970a0a8d17c30f067f.png

2. 配置

凭据-系统-全局凭据-添加凭据

类型选择 SSH Username with private key

ec90240e5dadfbc86158cdc0c140a85f.png

添加两个凭据,1个ansible用,一个Git用,Private Key选择ssh的私钥文件

注,由于我们Git使用的是自己搭建的gitlab服务器,通过ssh拉取代码,所以添加两个同样的凭据,可以根据实际情况调整。

3. 从Git拉取代码

stage('拉取代码') {   //def branch = input message: 'input branch name for this job', ok: 'ok', parameters: [string(defaultValue: 'develop', description: 'branch name', name: 'branch')]  // 可以手动输入分支   git branch: "develop", credentialsId: 'f16ff4e6-98f', url: "${registry}"   // credentialsId配置上面添加的Git凭据}

4. ansible配置

stage('执行构建') {  ansiblePlaybook(  credentialsId: 'b260876f6b0',  // 配置上面添加的ansible凭据  disableHostKeyChecking: true,  installation:"ansible",  inventory: "/etc/ansible/inventory/hosts", // 指定ansible inventory  playbook: "/etc/ansible/playbook/${playbook_template}", // 指定playbook  extras: "-e job_name=${JOB_NAME} -e jenkins_home=${JENKINS_HOME} -e configfile=${configfile} -e proj=${proj} -e inventory=${inventory}",  // 传递参数  ) }

5.创建一个流水线项目

8aa83b2b6b478862c81ad05b3bef1d1d.png

注,如果需要划分权限,可借助Role-based Authorization Strategy插件,项目命名也要规范,test-*对应测试环境,release-*对应预上线环境,main-*对应生产环境,方便后续的授权。

6.配置项目

  • General-描述:添加项目描述,可备注项目访问地址,端口,等信息
  • 高级项目选项-显示名称:可以配置一个更可读的名称
  • 流水线-Pipeline Script:Pipeline脚本

脚本如下,可先定义变量,然后其他项目可以使用复制功能,或者调用Jenkins API批量创建,只需要修改变量就行。

node {    def branch = "develop"   // Git 分支    def proj = 'app'   //项目名称    def configfile = 'test.yml'  //配置文件    def inventory = '192.168.1.1,server-app1,server-group'  //主机组或者主机列表    def playbook_template = "app.yml"    def registry = "git@git.example.com/app/app.git"  // Git仓库地址    stage('拉取代码') { // for display purposes       //def branch = input message: 'input branch name for this job', ok: 'ok', parameters: [string(defaultValue: 'develop', description: 'branch name', name: 'branch')]        git branch: "${branch}", credentialsId: 'f16ff4e65284698f', url: "${registry}"    }     stage('执行构建') {         ansiblePlaybook(        credentialsId: 'b260897f776f6b0',        disableHostKeyChecking: true,        installation:"ansible",        inventory: '/etc/ansible/inventory/hosts',        playbook: "/etc/ansible/playbook/${playbook_template}",        extras: "-e job_name=${JOB_NAME} -e jenkins_home=${JENKINS_HOME} -e proj=${proj} -e configfile=${configfile} -e inventory=${inventory} -e branch=${branch}",         )    }}

参数说明:

  • branch:定义Git分支,不同分支对应不同环境
  • proj:项目名称,所有环境名称一致,playbook中会用到,可以根据这个名称构建指定项目,拷贝包或文件到指定目录,作为supervisorctl重启服务的名称
  • configfie:配置文件,里面定义端口,调用地址,MySQL,MongoDB,Redis,ES,kafka地址账号等配置信息,对应不同环境
  • inventory:主机组或者主机列表,可以同时更新多台服务器,多个主机用逗号隔开,主机名和主机组名称为ansible inventory/hosts的里面配置名称
  • playbook_template:playbook的模板,不同项目操作不同(java,node,andriod),可以定义多个playbook模板,然后传入不同参数执行。
  • registry:项目的Git地址,每个项目都是可变的,所以要抽出来。

注意:

修改credentialsId为自己的credentialsId,

可以使用def继续增量变量,但extras也要同步增加,在playbook中才能使用,不同playbook的extras根据实际情况调整

7. playbook的配置片段

主机和变量文件配置

- hosts: "{{ inventory }}"  // 这个对应的是pipeline的inventory变量  gather_facts: false  vars_files:    - /etc/ansible/host_vars/common.yml // 定义一些公共变量如proxy_host,template_dir

更新配置文件,template_local是一个自定义的模块,可以用template模块代替

      - name: update properties configure file        run_once: true        delegate_to: "{{ proxy_host }}"        template_local:            template_dir: "{{ template_dir }}/{{ proj }}"            src_template_file: "{{ item }}.properties"            dest_template_file: "{{ jenkins_home }}/workspace/{{ job_name }}/{{ proj }}/src/main/resources/config/{{ item }}.properties"            var_file: /etc/ansible/host_vars/{{ configfile }} // configfile 对应Pipeline中的configfile        with_items:            - application            - common

mvn 打包

      - name: mvn package        run_once: true        delegate_to: "{{ proxy_host }}"        shell: cd "{{ jenkins_home }}/workspace/{{ job_name }}/"  && mvn -U -pl {{ proj }} -am clean package  // 仅打包指定项目

node编译,这个编译是在Jenkins服务器上,所以除了第一次,之后执行yarn install会很快

      - name: build node for andriod        run_once: true        delegate_to: "{{ proxy_host }}"        shell: export PATH=$PATH:/data/apps/node/  && cd "{{ jenkins_home }}/workspace/{{ job_name }}/node " && yarn install  && yarn build

apk打包

      - name: build apk package        run_once: true        delegate_to: "{{ proxy_host }}"        shell: cd "{{ jenkins_home }}/workspace/{{ job_name }}/Android/platforms/android/"  && bash gradlew  debug

jar包上传服务器进行更新

      - name: copy jar to remote        copy:          src: "{{ jenkins_home }}/workspace/{{ job_name }}/{{ proj }}/target/{{ jar_version.stdout }}" // jar_version是写的另一个插件解析pom.xml获取jar/war的名字          dest: "/data/apps/{{ proj }}/"          backup: yes  // 开启备份

更新静态文件,这种HTML/css/js项目更新前需要备份的话,可先执行个shell拷贝

      - name: rsync files to remote        delegate_to: "{{ proxy_host }}"        synchronize:            src: "{{ jenkins_home }}/workspace/{{ job_name }}/html/"            dest: /data/apps/{{ proj }}/app/            dest_port: "{{ ansible_port }}"            checksum: yes            delete: yes            recursive: yes            rsync_opts:              - "--exclude=.svn*"              - "--exclude=.git"

重启服务

      - name: restart service        shell: supervisorctl restart "{{ proj }}"

借助when可以根据分支来做备份(正式环境才备份)

      - name: backup app dir        become: yes        become_method: sudo         become_user: root        shell: cd /data/{{ proj }}/app && cp -r  dist dist_{{ build_time }}        when: branch == "master"  

docker容器镜像更新

     - name: stop log service        shell: "[[ $(docker ps -a | grep {{ item }} | wc -l) -eq 1 ]] &&  docker stop {{ item }} && docker rm {{ item }} || echo 0"         with_items:            - log-normal            - log-video            - log-judge      - name: start log service        shell: "docker run -d --name={{ item }} -v /data/apps/{{ item }}/conf:/conf -v /data/logs/trace:/data/logs/trace -v /etc/localtime:/etc/localtime harbor.aliyuncs.com/app/{{ repo }}"        with_items:            - log-normal            - log-video            - log-judge

使用template模块自动生成Dockerfile和deplyment.yml

ansible服务器需要能跟镜像仓库和k8s集群通信

- name: generate Dockerfile && deployment.yml        run_once: true        delegate_to: "{{ proxy_host }}" // 这个要为ansible服务器IP或者127.0.0.1        template:            src: "{{ template_dir }}/docker/{{ item }}" // 提前创建好Dockerfile和deployment.yml模板            dest: "{{ jenkins_home }}/workspace/{{ job_name }}/{{ item }}"        with_items:            - Dockerfile            - deployment.yml

注,如果执行playbook使用的是普通用户,一些操作需要给予sudo权限

become: yes

become_method: sudo

become_user: root

playbook执行报错,开发人员可以直接在Jenkins上查看错误信息

c10ed03b6a1bfde730f7c6e0d42e65ac.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值