jenkins+ansible+docker+svn自动发布

文章目录

    • 前期准备
      • 地址说明
      • 思路
      • docker
      • maven自动打包配置文件
    • 创建jenkins自由项目
    • 制造项目容器
    • 配置ansible
    • 客户端运行容器

前期准备

软件: svn + jenkins + ansible + docker + harbor

  • jenkins+svn自动发布:思路查看
  • docker
  • harbor: 安装及使用说明
  • jenkins: 安装, 持续集成相关说明

地址说明

服务 地址 版本
docker-ce 192.168.9.10 19.03.11
ansible 192.168.9.15 2.9.10
jenkins 192.168.9.15:8080 2.244 \ jdk:1.181
harbor 192.168.9.62:20443
svn\gitxx 192.168.9.X

思路

  • 检查
  1. 检查打包之后是否生成了war包,一般下情况只有一个
  2. 检查历史版本的war包是否存在,如果不存在,则说明输入的版本也是错误的
  • 回滚
  1. 获取最新的war包 ${WORKSPACE}/target目录下
  2. 获取上一版的war包,通过doscard old builds保存的构建最大个数,目录如下
 -  jenkins_build_path=${JENKINS_HOME}/jobs/${JOB_NAME}/modules/com*/builds # job归档war包 固定路径
 -  jenkins_build_war=${jenkins_build_path}/${BUILD_NUMBER}/archive/com\*/\*\*/\*\*/\*.war # 返回war包名称
  1. 获取之后覆盖最新的target目录下的war包,以及 构建时的版本war包
  2. 最终在target中的就是历史版本war包或最新的war包,通过release_id手动输入
  3. 返回这个target/xx.war包
  • 容器
  1. 容器分为三个
    • 基础容器(基础的java软件, 系统要使用的字符集, 以及各种依赖包)
    • 项目容器(通过tomcat配置好文件,并且获取war包解压到webapps下,手动解压 unzip 源.war -d 保存目录)
    • 存储容器 (用于指定项目下的upload目录以及tomcat的日志) 用于后续容器使用
  2. 先在服务端做好 基础容器、项目容器
 -  将项目容器下的upload推送至客户端,如果存在则不需要,或者直接使用NAS或其它存储
 -  获取存储容器目录upload\logs是否存在,不存在则创建
 -  服务端的 项目容器\基础容器必须推送至服务端
  1. 在客户端运行存储容器(upload\logs) 然后 通过 volume-form指定对应的目录直接挂载
  2. 运行容器

docker

安装来源

  1. 安装: yum install -y yum-utils device-mapper-persistent-data lvm2

  2. 添加源: yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

  3. 更新或安装

yum makecache fast
yum -y install docker-ce
# 启动命令: systemctl restart docker 这一步等配置好镜像加速在执行
  1. 镜像加速,指定存储类型
]# cat /etc/docker/daemon.json 
{
  "registry-mirrors": [
  	# docker 镜像加速站点
      "https://kfwkfulq.mirror.aliyuncs.com",
      "https://2lqq34jg.mirror.aliyuncs.com",
      "https://pee6w651.mirror.aliyuncs.com",
      "https://registry.docker-cn.com",
      "http://hub-mirror.c.163.com"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  # 这里是自定义的仓库地址,后续看自己的harbor改对应地址即可
  "insecure-registries": ["192.168.9.62:20443"], 
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  # 指定存储类型,  相关资料直接搜 k8s docker overlay2 存储
  "storage-driver": "overlay2",   
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}

PS: "insecure-registries": ["192.168.9.62:20443"] 忽略https错误问题

  1. 版本
]# docker version
Client: Docker Engine - Community
 Version:           19.03.11
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        42e35e61f3
 Built:             Mon Jun  1 09:13:48 2020
 OS/Arch:           linux/amd64
 Experimental:      false

maven自动打包配置文件

pom.xml, 详见可参考 jenkins+maven动态打包配置文件, 参考2

<build>
    <finalName>gmonitor</finalName>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources${package.environment}</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>8</source>
                <target>8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <package.environment></package.environment>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <package.environment>-test</package.environment>
        </properties>
    </profile>
</profiles>

  1. build段中的resources

    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            # 指定profie中设置的参数,选择目录文件
            <directory>src/main/resources/${package.environment}</directory>
            # 动态指定配置文件
            <filtering>true</filtering>
        </resource>
        <resource>
        	# src/main/java不管是那一个都需要有
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
    
  2. build段中的 plugins

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            # 指定编译时的编译版本,用utf8跟 jdk8编译
            <configuration>
                <source>8</source>
                <target>8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
    
  3. profile

    <profiles>
        <profile>
            <id>dev</id>
            <properties>
           		# 默认就是 resource下的配置文件
                <package.environment></package.environment>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <id>test</id>
            <properties>
            	# 动态指定 resource-test。。。
                <package.environment>-test</package.environment>
            </properties>
        </profile>
    </profiles>
    
    # 每次添加时只需要添加这个,  并且添加一个 resource-名称的目录,并且将文件复制进去 
        <profile>
            <id>名称</id>
            <properties>
            	# 动态指定 resource-test。。。
                <package.environment>-名称</package.environment>
            </properties>
        </profile>
    

    jenkins+ansible+docker+svn自动发布_第1张图片

jenkins+ansible+docker+svn自动发布_第2张图片
clean install -Ptest package -Dmaven.test.skip=true

创建jenkins自由项目

只保留四个版本, 注意: 这里是jenkins:8080, 安装看参考文档

jenkins+ansible+docker+svn自动发布_第3张图片

点击部署时的提示说明,后续会有展示
jenkins+ansible+docker+svn自动发布_第4张图片

添加svn或者git的帐户,用于下载版本

jenkins+ansible+docker+svn自动发布_第5张图片
clean compile install -Ptest -Dmaven.test.skip=true -P参数 可查看maven打包配置说明
jenkins+ansible+docker+svn自动发布_第6张图片

脚本
jenkins+ansible+docker+svn自动发布_第7张图片


jenkins_release_id=${release_Id}       # jenkins中传递的值
date_time=`date +%Y%m%d%H%M%S`         # 打包时间

# 工作的tomcat版本,后续说明为啥这么使用
webapps=/data/docker/conf/apache-tomcat-8.5.56/webapps/   

project_name=gmonitor2                # 项目的名称
container_port=23232                  # 容器的端口
docker_register="192.168.9.62:20443/test"  # docker register仓库远程地址
docker_build_name=${docker_register}/${project_name}:v6.0.${BUILD_NUMBER}.${date_time}

pro_name_target="${WORKSPACE}/target"  # 项目 target 路径
current_war=`/usr/bin/find  ${pro_name_target} -maxdepth 1 -name *.war`  # 获取war包

jenkins_build_path=${JENKINS_HOME}/jobs/${JOB_NAME}/modules/com*/builds # job归档war包 固定路径
jenkins_build_war=${jenkins_build_path}/${BUILD_NUMBER}/archive/com*/**/**/*.war # 返回war包名称

################    检查点 - 1   ################
# 获取war包,如果小于1个 说明没有,直接退出
[ `ls ${current_war} | wc -l` -lt 1 ] && exit 10 && echo "无war包,请重新打包"

################    检查点 - 2   ################
# 检查是否存在 该归档,如否则直接打主干
if [ -n "${jenkins_release_id}" ];then  # 不为空时检查
    for i in `find ${jenkins_build_path} -maxdepth 1 -type d `;do
        if [ ${jenkins_release_id} == `basename $i` ];then
            echo "=================== 回滚中 =================== "
            # 步骤: 1、获取归档war包, 2、还原当前打包的war包, 3、还原target下的war包
            archive_war=${jenkins_build_path}/${jenkins_release_id}/archive/com*/**/**/*.war
            echo ${jenkins_build_war} ${current_war} | xargs -n 1 cp -v ${archive_war}
            echo "=================== 回滚完成================== "
        fi
    done
fi

echo "开始制作容器..........请等待............."
rm -rf ${webapps}/* &>/dev/null  # 清空 tomcat中的内容 
echo "解压包中............请等待................" 
unzip ${current_war} -d ${webapps}/ &>/dev/null  # 将war包解压到tomcat中

cd /data/docker/conf
docker build -t ${docker_build_name} . &>/dev/null

echo "================== docker完成 =================="

docker images ${docker_build_name}

echo "================== 推送至仓库中 =================="
docker push ${docker_build_name} &>/dev/null    # 推送到仓库中, 注意需要先登陆
echo "================== 推送完成 =================="

# .ymal是放在9.15 ansible的服务端中,需要与其它机器必须免密钥登陆
ansible-playbook /data/docker/conf/checkUpload.yaml -e "{'name':'${project_name}'}"

# dockerRun.sh是在ansible客户端上的脚本, 需要传递三个参数
ansible docker  -a "bash -x /data/website/dockerRun.sh ${project_name} ${docker_build_name} ${container_port}"

制造项目容器

严重警告: 必须先登陆到仓库: docker login 192.168.9.62:20443 , 这一步必须通过!!!!!

思路: 项目中有upload,开发上传的图片直接放在这目录下, 还有logs,以及项目需要分开

  1. 创建基础容器
    jenkins+ansible+docker+svn自动发布_第8张图片
base_docker]# ls
apache-tomcat-8.5.56  Dockerfile  fonts.conf  jdk-8u181-linux-x64.tar.gz  wqy-zenhei.ttc
[root@cat2 base_docker]# cat Dockerfile 
FROM centos:centos7.8.2003

MAINTAINER [email protected]

# 说明版本
LABEL jdk-version=8u181 character-fonts=wqy-zenhei tomcat-version=8.5.56

# 容器中的jdk版本
ADD jdk-8u181-linux-x64.tar.gz /data/

WORKDIR /data

RUN sed -i '13'd /etc/yum.conf \
    && yum install -y kde-l10n-Chinese glibc-common fontconfig ttmkfdir \
    && yum clean all \
    && mkdir /usr/share/fonts/wqy-zenhei -p \
    && mkdir /etc/fonts/ -p

# 字符集, 根据项目需求了
COPY wqy-zenhei.ttc /usr/share/fonts/wqy-zenhei/  
COPY fonts.conf /etc/fonts/

# 最后运行bash不让它退出
CMD ["/bin/bash"]

# 注意啊 这个只是基础容器   最后通过 docker build 制造
  1. 获取war包之后,解压到tomcat中, 然后将tomcat在COPY到容器中
# 这里的内容是在 jenkins 打包之后执行shell的时候运行的
###########################   忽略开始 ###########################
echo "开始制作容器..........请等待............."
rm -rf ${webapps}/* &>/dev/null  # 清空 tomcat中的内容 
echo "解压包中............请等待................" 
unzip ${current_war} -d ${webapps}/ &>/dev/null  # 将war包解压到tomcat中
###########################   忽略结束 ###########################


#####################  制造 开始 #####################
conf]# cat Dockerfile  # 查看 Dockerfile
# 这里是基础镜像的名称,  注意啊,  一直要 docker push到仓库中
FROM 192.168.9.62:20443/test/centos-character:7.8.2003-zh

COPY apache-tomcat-8.5.56 /data/tomcat/

ENV JAVA_HOME=/data/jdk1.8.0_181
ENV CATALINAME_HOME=/data/tomcat
ENV CATALINAME_VERSION=8.5.56
ENV PATH=$JAVA_HOME/bin:$CATALINAME_HOME/bin:$PATH
ENV LC_ALL=zh_CN.UTF-8
ENV TZ='Asia/Shanghai'

EXPOSE 8080
CMD ["run.sh"]

#####################  制造 结束 #####################

jenkins+ansible+docker+svn自动发布_第9张图片

  1. 最后将容器push到harbor上
# 这里的内容是在 jenkins 打包之后执行shell的时候运行的
###########################   忽略开始 ###########################
cd /data/docker/conf
docker build -t ${docker_build_name} . &>/dev/null
echo "================== docker完成 =================="
docker images ${docker_build_name}
echo "================== 推送至仓库中 =================="
docker push ${docker_build_name} &>/dev/null    # 推送到仓库中, 注意需要先登陆
echo "================== 推送完成 =================="
###########################   忽略结束 ###########################

docker build -t 这里打包的是第2步的脚本,
docker push 将镜像直接推到仓库中

# 注意:  一定要先登陆  docker login 192.168.9.62:20443 
  1. 基础容器 跟项目容器就完成了, 后续 会将 项目容器 跟upload/logs容器通过volume-form结合起来运行

配置ansible

思路: 先检查客户端是否有upload\logs目录, 没有就创建它或推送 upload

# 注意: 这里是在9.15上, 安装直接使用yum 即可
]# cat /etc/ansible/hosts   # 直接使用ansible/hosts在使用时就不用指定 -i了
[docker]
192.168.9.10

# 注意:  先在服务端上生成
]# ssh-keygen
]# ssh-copy-id [email protected]   免密钥登陆,  推送给需要运行的机器

# 这里的内容是在 jenkins 打包之后执行shell的时候运行的
###########################   忽略开始 ###########################
# .ymal是放在9.15 ansible的服务端中,需要与其它机器必须免密钥登陆
ansible-playbook /data/docker/conf/checkUpload.yaml -e "{'name':'${project_name}'}"
###########################   忽略结束 ###########################

conf]# cat checkUpload.yaml 
---
- name: check docker upload
  hosts: docker
  remote_user: root
  gather_facts: no
  vars:
    filedir: "/data/website/{{ name }}/upload"
  tasks:
  - name: test
    shell: test -e {{filedir}}
    ignore_errors: true
    register: shellSyntex
  - block:
      - name: create logs
        file:
          path: "/data/website/{{ name }}/logs"
          state: directory
      - name: copy upload
        copy:
          src: "/data/docker/conf/apache-tomcat-8.5.56/webapps/upload/"
          dest:  "/data/website/{{ name }}/upload"
    when: shellSyntex.rc != 0
...

客户端运行容器

思路:

  1. 先检查 名称_upload的容器是否存在,
  2. 然后将这个 upload容器 与先前上传的镜像 通过 volumes-from 挂载
# 注意: 这里是在 9.10上操作

# 这里的内容是在 jenkins 打包之后执行shell的时候运行的
###########################   忽略开始 ###########################
# dockerRun.sh是在ansible客户端上的脚本, 需要传递三个参数
ansible docker  -a "bash -x /data/website/dockerRun.sh ${project_name} ${docker_build_name} ${container_port}"
###########################   忽略结束 ###########################

]# cat dockerRun.sh 
#!/bin/bash
#
# 第一个值: 项目名称
# 第二个值: harbor仓库的名称
# 第三个值: 端口号
# 执行:   bash  xx.sh projectName, containerName, port

project_name=$1
container_harbor_name=$2
container_port=$3
project_mount_name="${project_name}_upload"
local_upload="/data/website/${project_name}/upload"
local_log="/data/website/${project_name}/logs"
tomcat_upload="/data/tomcat/webapps/upload"
tomcat_log="/data/tomcat/logs"

#  检查基础容器 upload和logs
/usr/bin/docker ps | grep ${project_mount_name}
if [ $? -ne 0 ];then
    /usr/bin/docker run -d --name=${project_mount_name} \
                        -v ${local_upload}:${tomcat_upload} \
                        -v ${local_log}:${tomcat_log} \
                        --network=bridge --memory 256m \
                        --privileged --restart=on-failure:10 \
                        centos:7.6.1810 tail -f /dev/null
fi

# 运行该脚本说直接说明容器需要重新创建
/usr/bin/docker stop ${project_name}; /usr/bin/docker rm ${project_name}

# 下载镜像
/usr/bin/docker pull ${container_harbor_name}

# --name:指定名称  --volumes-from:挂载基础容器   端口 xx:8080
/usr/bin/docker run -d --name=${project_name} \
                    --volume /etc/localtime:/etc/localtime:ro \
                    -p ${container_port}:8080 \
                    --network=bridge --memory 2048m \
                    --memory-reservation 2000m \
                    --privileged --restart=on-failure:10 \
                    --volumes-from ${project_mount_name} ${container_harbor_name}
# 最终在打印结果
/usr/bin/docker ps | grep ${1}*

# 最后运行起来长这样
]# docker ps
IMAGE            command                PORTS                     NAMES
镜像名称          忽略                  0.0.0.0:23232->8080/tcp   gmonitor2
centos:7.6.1810   "tail -f /dev/null"    忽略 没有端口            gmonitor2_upload

你可能感兴趣的:(linux)