自建自动化持续集成方案
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
文章目录
前言
提微服务开发过程中,开发人员需要不断编码、编译、打包、上传、构建镜像、发布镜像、发布服务、自动化测试等一系列步骤,如何才能有效的减少各环节之间时间,减少开发者的工作量,形成一套自动化的体系?
以下内容的前提是基于微服务架构的开发,单体架构会简单很多,自行按需搭建即可。
一、组成部分
-
Jenkins – 用于建立构建任务
-
Gitlab、Github等git系代码仓库 – 本文不支持SVN体系下的自动化持续集成,如果你的代码库使用的SVN,只有以下两种选择
a. 不要浪费时间看下面的内容
b. 代码库切换到Git仓库 -
Maven仓库 – 自建Nexus,阿里云云效Maven,其他公共Maven仓库,建议使用自建Nexus
-
Docker仓库 – 自建Harbor,阿里云镜像仓库,Docker公共仓库,建议使用自建Harbor
-
Kubernetes集群 – 阿里云Kubernetes集群,自建Kubernetes集群+Kuboard,建议自建集群,个人观点是阿里云的不好用,不顺手
以上组件的选择根据自己公司的财务情况可分为以下两种
- 资产充足,毫无压力
建议所有组件都是自建方式,企业内部可见,使用灵活,各组件使用不受限制,可以最大化提供集成能力 - 财务紧张,运维能力有限
Git、Maven、Docker仓库都使用云上免费服务,已知阿里云都有免费的相关服务,其他服务商未调研。
二、流程步骤
1. 流程图
2. 安装组件
1. 安装Gitlab
sudo docker run --detach \
--hostname gitlab.example.com \
--publish 443:443 --publish 80:80 --publish 22:22 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/config:/etc/gitlab:Z \
--volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
--volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
gitlab/gitlab-ee:latest
英文不好的朋友,请自行百度中文搭建文章,没有任何难度。
2. 安装Maven仓库
mkdir -p /data/nexus-data && \
chown -R 200 /data/nexus-data && \
docker run -d \
-p 8081:8081 \
--name nexus \
-e INSTALL4J_ADD_VM_PARAMS="-Xms2g -Xmx2g -XX:MaxDirectMemorySize=3g" \
-v /data/nexus-data:/nexus-data \
sonatype/nexus3
英文不好的朋友,请自行百度中文搭建文章,没有任何难度。
3. 安装Harbor
- 打开下载地址 Harbor-Installer
安装文件分为在线和离线,在线方式安装时会自动下载镜像,离线方式安装过程中无任何网络交互,如下载不成功,请使用vpn. - 下载在线安装包 harbor-online-installer-v2.1.0
- 解压安装包并重命名harbor.yml.tmpl 为 harbor.yml
- 配置hostname, 注释掉https的配置(https自行配置)
- 运行安装文件
sh prepare
sh install.sh
Docker 默认使用Https协议
Https证书如何获取,请自行百度,本文不做说明
4. 安装Jenkins
5. 安装Kubernetes/Kuboard
3. 准备打包服务器
1. 安装Python3
yum install -y pyphon3
pip3 install requests
可选【修改Xml输出脚本】
执行以下脚本查看python安装路径
import sys
print(sys.path)
如图
修改文件 vim /usr/lib64/python3.6/xml/dom/minidom.py
改为
此操作的目的是,再修改pom.xml后,解决xml的格式问题
4. 编写脚本
1. Shell脚本
|____notify
| |____dingding.sh – 发送钉钉通知
|____docker
| |____push_server_image.sh – 推送docker镜像
|____maven
| |____update_release_version.sh – 发布Release版本
| |____update_dependencies_version.sh – 更新依赖服务版本号
| |____package.sh – 打包Jar
|____k8s
| |____deploy.sh – 发布到 Kuberneters
|____in_one
| |____push_image.sh – 编译->打包->推送镜像
|____es
| |____update_version.sh – 更新服务Release版本,方便引用服务自动更新
2. Jenkins任务脚本
#!/bin/sh
set -ex
DD_TOKEN="此处填写钉钉机器人Token"
ES_URL="此处填写ES的索引查询url"
IMAGE_REPOSITORY_URL="此处填写Docker镜像仓库地址"
MSG_REP="镜像仓库: xxx \n服务版本: xxx \n"
GIT_SCRIPT_URL="git@gitee.com:sean-framework/deploy.git"
TMP_DIR=~/tmp/git
mkdir -p ${TMP_DIR}
cd ${TMP_DIR}
space=${repository_git_ssh_url%/*}
space=${space##*/}
server_name=${repository_git_ssh_url##*/}
server_name=${server_name%.*}
branch=${ref##*/}
timeStamp=$(date +%s)
GIT_DIR=${TMP_DIR}/code/${timeStamp}
GIT_SCRIPT_DIR=${TMP_DIR}/script/${timeStamp}
declare -A phones
# 此处修改为开发人员对应的user_id,和 手机号, 通知是可以@
phones["1"]="18072978089"
at=false
#根据key找到对应的value
phone=${phones[$user_id]}
check() {
if [[ -z ${phone} ]]; then
errormsg="用户id:"${user_id}",账号:"${user_name}"---未配置手机号"
phone=18072978089
sh ${GIT_SCRIPT_DIR}/notify/dingding.sh -m "${errormsg}" -t "${DD_TOKEN}" -p ${phone}
fi
}
notify() {
msg="${msg}\n日志:http://此处为Jenkins地址/job/server_version/${BUILD_NUMBER}/console"
sh ${GIT_SCRIPT_DIR}/notify/dingding.sh -m "${msg}" -t "${DD_TOKEN}" -p ${phone}
}
# 根据自己的项目路径修改
if [[ ${space}s == servers ]] ; then
# 删除分支, 清除k8s容器
if [[ "${after}"s == 0000000000000000000000000000000000000000s ]]; then
if [[ ${server_name}s != octopuss ]]; then
set +e
echo "删除服务 ${server_name}-${branch//./}"
kubectl delete deploy ${server_name}-${branch//./} -n dev
exit 0
fi
else
mkdir -p ${GIT_DIR}
version=${branch}
if [[ ${branch}s != masters ]]; then
arg="-b ${branch}"
fi
#label
label="revision"
# 下载代码
git clone ${GIT_SCRIPT_URL} ${GIT_SCRIPT_DIR}
check
git clone ${arg} ${repository_git_ssh_url} ${GIT_DIR}
if [[ "${before}"s == 0000000000000000000000000000000000000000s ]]; then
# 新开分支,修改依赖版本号
echo "新开分支"
sh ${GIT_SCRIPT_DIR}/maven/update_dependencies_version.sh -b "${branch}" -l ${label} -d "${GIT_DIR}" -u "${ES_URL}"
echo "通知"
msg=${server_name}'新开分支['${branch}']\n依赖项目版本号已更新\n提交人:'${user_name}
notify
else
# Master分支,需要发布RELEASE版
if [[ ${branch}s == masters ]]; then
at=true
echo "修改版本为RELEASE"
set +e
sh ${GIT_SCRIPT_DIR}/maven/update_release_version.sh -d "${GIT_DIR}" -b "${branch}" -n "${server_name}" -l ${label} -u "此处为ES地址"
ret=$?
set -e
if [ $ret -ne 0 ]; then
exit 0
fi
cd ${GIT_DIR}
version=$(grep -m 1 ${label} pom.xml | awk -F ">" '{print $2}' | awk -F "<" '{print $1}')
msg="${MSG_REP}\n${server_name}[${version}]\nJar已发布到Maven仓库"
else
# 提交代码,上传maven仓库
echo "Maven打包"
set +e
sh ${GIT_SCRIPT_DIR}/maven/package.sh -d "${GIT_DIR}" -c "deploy"
ret=$?
set -e
if [ $ret -ne 0 ]; then
msg="${server_name}[${branch}]打包失败!\n提交人:${user_name}"
notify
exit 0
fi
cd ${GIT_DIR}
version=$(grep -m 1 ${label} pom.xml | awk -F ">" '{print $2}' | awk -F "<" '{print $1}')
msg="${server_name}[${version}]\nJar已发布到Maven仓库"
fi
if [[ ${server_name}s != octopuss ]]; then
echo "构建镜像"
set +e
sh ${GIT_SCRIPT_DIR}/docker/push_server_image.sh -d "${GIT_DIR}" -n "${server_name}" -v "${branch}" -j "${server_name}-server.jar" -r "${IMAGE_REPOSITORY_URL}" -c "${after}"
ret=$?
set -e
if [ $ret -ne 0 ]; then
msg="${server_name}[${branch}]构建镜像失败!\n提交人:${user_name}"
notify
exit 0
fi
msg="${msg}\n镜像已上传到Docker仓库"
echo "部署"
set +e
sh ${GIT_SCRIPT_DIR}/k8s/deploy.sh -n "${server_name}" -v "${branch}" -r "${IMAGE_REPOSITORY_URL}"
ret=$?
set -e
if [ $ret -ne 0 ]; then
msg="${server_name}[${branch}]部署失败!\n提交人:${user_name}"
notify
exit 0
fi
msg="${msg}\n开发环境已部署成功"
fi
msg="${msg}\n提交人:${user_name}"
echo "通知"
set +e
notify
set -e
fi
set +e
rm -fr ${GIT_DIR}
rm -fr ${GIT_SCRIPT_DIR}
set -e
fi
fi
3. ES索引
5. 串联各个组件
- 创建钉钉机器人
- 添加SSH remote hosts
- 创建Jenkins Jos
- 配置Generic Webhook Trigger插件
- 配置任务名
- 添加SSH构建步骤
- 配置Gitlab Webhook
总结
关注公众号获取一手资料