《基于Jenkins的持续集成部署(CI/CD)》中简单的介绍了最基础的持续集成部署的实践案例,但是在工作生产中我们的服务需要更敏捷、更稳定、更全面的功能,因此我们一直在改进持续集成部署流程,直到我们遇到了
Rancher
先简要说明一下大致流程:
1. 提交代码至gitlab代码仓库
2. 配置jenkins集成编译任务
3. 部署rancher服务
改进背景
在最初的基于jenkins持续集成部署流程中,我们按标准说只能算是做到了简单的持续集成自动化,对于部署、发布(灰度)、运维来说基本还是靠手工,对于线上环境来说,系统功能的升级迭代过程就容易出现问题,影响客户体验-
升级意见
docker swarm
使用docker compose
对服务应用做编排,同时使用docker swarm对服务做集群负载均衡,并且docker swarm是通过docker生态进行的服务负载,运维复杂度与学习成本相对较低。在微服务项目中,都是分布式的业务实现,因此普通应用用不上docker compose。最初考虑就是使用docker swarm服务做负载以保证服务的稳定性,但是docker swarm对于服务运维与服务监控上存在不足,并且与其替代品k8s对比起来,docker swarm功能相对较弱,因此此意见被搁置k8s
在研究容器服务的负载工具时,最被推崇的就是k8s了,我也尝试了k8s的集群搭建与使用,结合k8s dashboard
能够很方便的对服务进行负载配配置,同时k8s提供了更强大的网络配置与更强大的监控管理,因此此选项被作为了升级的优先备选项,直到有一天在开源中国看到了一篇关于Rancher的文章,描述着说如何轻松的管理ks集群,当时就只是点击了收藏,直到有一次公司内部技术分享,隔壁部门就单独分享了此应用,因此就立马对进行了实践,发现它基于k8s对所有的功能进行了界面化管理,极大的降低了运维成本
k8s vs docker:https://blog.csdn.net/qq_36609501/article/details/93138036rancher
什么也不说了,一款用了就不想换的容器服务管理工具,尽管最近又开始流行Podman + Buildah + Skopeo
,先观察看看吧
-
环境
- Gitlab:项目代码仓库
- Jenkins:持续集成部署任务管理工具
- Rancher:服务集群负载管理工具
- Docker:容器环境
编译准备
参照《基于Jenkins的持续集成部署(CI/CD)》,这里就不重复描述了-
任务准备
这里主要分享一下jenkins任务的改造细节:配置
丢弃旧的构建(Discard old builds Strategy)
:用于清理已构建历史记录的自动清除,节省jenkins构建环境的空间暂用配置
构建参数(This project is parameterized)
:由于我们的gitlab的代码标签版本号使用{version}-{branch},因此我们为了任务的更方便的构建,我们将版本和分支参数配置为了参数构造,这个功能建议配置上,后期升级时构建方便很多配置
Source Code Management
代码路径(Repositories
),配置分支(Branches to build
):refs/tags/${version}-${branch}
-
配置
Build Environment
-
Delete workspace before build starts
:构建之前删除工作空间 -
Add timestamps to the Console Output
: 控制台打印浏览器时间戳
-
配置
Build
,选择Gradle
版本与任务命令:-x test buildDocker
-
配置
执行shell
#!/bin/bash set +v echo 版本号:${version} echo 分支:${branch} echo 代码标签:refs/tags/${version}-${branch} # -------------------项目配置------------------- # 项目名称 PROJECT_NAME=${projectName} # 项目包路径 PROJECT_PACKAGE=${packageName} # 项目版本 PROJECT_VERSION=${version} # 项目分支 PROJECT_BRANCH=${branch} # -------------------编译配置------------------- # 远端仓库地址 MIRROR_WAREHOUSE=${MIRROR_WAREHOUSE} # 远端仓库组织 MIRROR_WAREHOUSE_ORG=${MIRROR_WAREHOUSE_ORG} # 远端仓库用户 MIRROR_WAREHOUSE_USER=${MIRROR_WAREHOUSE_USER} # 远端仓库密钥 MIRROR_WAREHOUSE_PWD=${MIRROR_WAREHOUSE_PWD} # 编译后镜像名,项目包路径/项目名称:项目版本(多环境下同一项目版本号生成的镜像名一致,极端情况下可能会出现镜像交叉问题) JENKINS_IMAGE_NAME=${PROJECT_PACKAGE}/${PROJECT_NAME}:${PROJECT_VERSION} # 远端仓库镜像名,远端仓库地址/远端仓库组织/项目名称:项目版本-项目分支 WAREHOUSE_IMAGE_NAME=${MIRROR_WAREHOUSE}/${MIRROR_WAREHOUSE_ORG}/${PROJECT_NAME}:${PROJECT_VERSION}-${PROJECT_BRANCH} # -------------------运行配置------------------- # 将镜像标记为远程仓库名 docker tag ${JENKINS_IMAGE_NAME} ${WAREHOUSE_IMAGE_NAME} # 登录远程仓库 docker login -u ${MIRROR_WAREHOUSE_USER} -p ${MIRROR_WAREHOUSE_PWD} ${MIRROR_WAREHOUSE} # 推送镜像至远程仓库 docker push ${WAREHOUSE_IMAGE_NAME} echo 镜像推送完成:${WAREHOUSE_IMAGE_NAME} # 清理构建镜像(可选) #docker rmi -f ${JENKINS_IMAGE_NAME} #docker rmi -f ${WAREHOUSE_IMAGE_NAME}
配置
Post-build Actions
,编译后删除工作空间(Delete workspace when build is done
)
*以上仅为个人使用案例,建议根据各自情况进行调整,以上配置的目的只要是利用jenkins编译java代码生成镜像,同时上传至镜像仓库
-
部署准备
-
配置镜像仓库认证。在rancher集群首页点击
执行kubectl命令行
,输入jenkins中配置的镜像仓库配置kubectl create secret docker-registry secret-name --namespace=default \ --docker-server=http://${MIRROR_WAREHOUSE} --docker-username=${MIRROR_WAREHOUSE_USER} \ --docker-password=${MIRROR_WAREHOUSE_PWD}
之前一致没找到配置私有仓库认证的地方,误以为是在集群的私有仓库配置,后来发现此处的私有仓库配置的作为是:给集群配置私有仓库地址,并在开始构建集群时通过此镜像仓库拉取所需的全部镜像,包含rancher自身运行环境必须的镜像,如rancher/rke-tools等,之前也有想过基于此模式的实现方案:1.将所需镜像推送至华为云镜像仓库(rancher);2.自建私有镜像仓库并支持公开镜像仓库的转发(可行性未知),当然现在都不用了
-
-
部署服务
名称
服务名称,名称不能重复,且有最大字符限制
-
类型
一般的微服务应用,直接选择Deployment
,如果应用需要固定IP那么设置类型为StatefulSet
StatefulSet详解:https://www.cnblogs.com/xzkzzz/p/9871837.html
区别详解:https://www.cnblogs.com/weifeng1463/p/10284122.html -
Docker镜像
${MIRROR_WAREHOUSE}/${MIRROR_WAREHOUSE_ORG}/${projectName}:{version}-{branch}
命名空间
默认使用default
就好了-
端口映射
- HostPort:仅部署的主机的此端口可访问,适用于指定IP部署的上级微服务,如网关、注册中心的能够
- NodePort:集群所有主机可访问,适用于指定IP部署,但默认端口范围有限制,且默认为随机(可在集群中修改配置),多用于附加端口用于服务接口调试
- 集群IP:集群内网IP,适用于底层微服务
- L4层负载均衡器:暂未深入研究
-
环境变量
#APP_OPTIONS --eureka.client.service-url.defaultZone=http://192.168.1.1:8761/eureka/ --spring.cloud.config.label=beta --eureka.instance.ip-address=${spring.cloud.client.ipAddress} #--eureka.instance.ip-address=${spring.cloud.client.ipAddress},这个配置是为了兼容之前在项目bootstrap.yml文件中已配置固定IP,使用此配置可使用集群内部的IP替换掉bootstrap.yml文件中配置的IP #JAVA_OPTIONS -Duser.timezone=GMT+8 -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8
主机调度
可配置为随机主机部署或指定主机,一般上级微服务需要指定主机被集群外部访问的都需要设定指定主机
*当同一集群中想实现自定义规则部署时,首先对主机点击升级
并配置键值对
,然后在主机调度中配置相应规则即可,规则配置详解:https://my.oschina.net/u/3330830/blog/1938975-
数据卷
如果我们的服务需要存储数据,如mysql或微服务日志文件等,rancher提供了多种方式数据管理方式,推荐使用PVC进行数据存储,可实现Pod数据共享
-
缩放/升级策略
这个和服务类型有关,当类型设置为Deployment
时:
当类型设置为StatefulSet
时:
此功能用于对服务节点调整时,服务的更新策略,比如对服务升级时,旧服务可设置在新服务启动后60秒后再关闭,而不能马上关闭,保证服务的稳定性
-
更多
节点调整
提供快速的节点增加/删除功能
提供快速的节点克隆/升级/重新部署功能主机监控,
Prometheus
+Grafana
自动对集群主机及服务进行全方位的监控,并嵌入rancher结合使用十分方便,功能强大-
日志
容器日志查看
集成多种日志收集工具
告警
支持各种指标的告警,指标相当丰富指令
集群kubectl
指令
服务容器shell
指令
......