基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现

讲正文开始前先回顾一下以往传统的代码部署方式。

通常运维人员在接到代码(新项目)上线的任务前都要做大量的准备工作,包括:物理主机、虚拟机、代码运行环境、数据库安装配置、各种帐号创建,、运行后期的系统监控、应用的日志收集,性能优化等一系列的工作。

想一想这个流程不是很复杂但是很繁琐,效率低下,如需要调试还需要给开发人员提供线上系统权限等等,细节没有注意的话,还会造成解决问题的难度等各种问题。

OK,说完以上的问题,那接下来就有相对应的解决方案。

方案大概的架构组成:

Jenkins+Gitlab+Harbor+Rancher+k8s

各个组件的功能描述

Jenkins

(1)下载gitlab中项目代码

(2)负载执行镜像的构建、上传下载

(3)部署到k8s集群

Gitlab

(1)项目代码以及配置

(2)Dockerfile文件

Harbor

这个是vmware公司开源的docker镜像仓库管理系统,比较方便管理维护镜像

(1)负责构建后镜像的存储

Rancher

容器编排管理工具

(1)更新stack/service

(2)实现服务的扩容缩容

k8s

(1)简化应用部署 (2)提高硬件资源利用率 (3)健康检查和自修复 (4)自动扩容缩容 (5)服务发现和负载均衡

架构图

基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第1张图片

架构图说明

项目开发语言是java,使用了比较流行的spring boot框架,manven更新源采用阿里云,编译生成jar文件

① 开发人员提交代码到gitlab

② 手动执行jenkins构建(或者gitlab钩子触发jenkins执行构建),下载最新版本的代码,代码里面包含Dockerfile

③ jenkins执行shell脚本:mvn编译生成jar文件。通过docker build 指令打包成镜像

④ 上传构建好的镜像push到harbor镜像仓库

⑤ jenkins远程到k8s master节点,更新service镜像地址,达到更升级容器的目的(也就是更新代码版本)。

以上流程完整的实现了CI/CD,这里主要是jenkins部分是关键位置之一。

环境说明

系统 ip 主机名 配置 版本
CentOS 7.6 10.212.20.94 k8s-master 2核4g Kubernetes1.18.1
CentOS 7.6 10.212.20.240 k8s-node01 2核4g Kubernetes1.18.1
CentOS 7.6 10.212.82.89 jenkins 2核4g 2.222.4
CentOS 7.6 10.212.82.90 gitlab 2核4g 10.5.1
CentOS 7.6 10.212.82.86 harbor 2核4g v2.0.0
CentOS 7.6 10.212.82.87 rancher 2核4g v2.4.3

关于k8s 1.18.1安装,请参考链接:

https://www.cnblogs.com/xiao987334176/p/12696740.html

关于jenkins安装,请参考链接:

https://www.cnblogs.com/xiao987334176/p/13032339.html

关于Gitlab和Harbor安装,请自行百度

关于rancher安装以及导入现有k8s集群,请参考链接:

https://www.cnblogs.com/xiao987334176/p/12965945.html

项目说明

基于Spring Boot/Spring Security/thymeleaf的通用后台管理系统

项目地址:

https://github.com/jonsychen/admin

此项目依赖于mysql,因此需要提前在Rancher里面部署mysql才行。

mysql部署

登录k8s-node01主机,创建数据目录
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第2张图片

mkdir \-p /data/mysql/data

访问Harbor后台,点击部署服务

端口映射

设置环境变量

TZ\=Asia/Shanghai
MYSQL\_ROOT\_PASSWORD\=abcd@1234

基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第3张图片

数据卷映射
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第4张图片

点击启动
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第5张图片

代码配置

下载代码:https://github.com/jonsychen/admin

解压之后,进入目录admin-master\src\main\resources

修改application-default.yaml,修改红色部分。

server:
  port: 8088
  compression:
    enabled: true
  connection\-timeout: 3000

debug: false

##登录记住我的token加密key
remember:
  key: yintong
##actuator config,actuator运行在一个独立的webappcontext中,see AnnotationConfigEmbeddedWebApplicationContext
management:
  context\-path: /management
  security:
    enabled: false

spring:
  application:
    name: admin
  datasource:
    url: jdbc:mysql://db\-mysql.default.svc.cluster.local:3306/admin?characterEncoding\=utf\-8
    username: root
    password: abcd@1234

说明:

port: 8088 项目运行的端口号

db-mysql.default.svc.cluster.local 表示db-mysql服务的svc地址。

格式说明:服务名.命令空间.default.svc.cluster.local ,其中服务名和命名空间是根据实际情况来的,后半部分是固定的。这一长串域名,会解析为svc地址。

password: abcd@1234 mysql的root用户密码

application-prod.yaml的配置修改同上。

在此项目的根目录创建dockerfile

FROM mayan31370/openjdk\-alpine\-with\-chinese\-timezone:8\-jdk
ADD admin\-0.1.0.jar /

EXPOSE 8088
ENTRYPOINT \[ "java","-jar","/admin-0.1.0.jar"\]

此时顶层目录结构如下:

\# tree \-L 1
.
├── dockerfile
├── etc
├── pom.xml
├── README.md
└── src

将此项目代码,提交到gitlab中。

sql导入

登录k8s-master节点,查看svc映射端口。因为使用Rancher部署mysql时,nodeport端口是随机的。

\# kubectl get svc
NAME                    TYPE        CLUSTER\-IP    EXTERNAL\-IP   PORT(S)          AGE
db\-mysql                ClusterIP   10.1.116.0    <none\>        3306/TCP         61s
db\-mysql\-nodeport       NodePort    10.1.86.36    <none\>        3306:31959/TCP   61s
kubernetes              ClusterIP   10.1.0.1      <none\>        443/TCP          20d

可以看到随机映射的端口是31959

使用navicat软件连接mysql
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第6张图片

新建数据库book

create database admin default character set utf8mb4 collate utf8mb4\_unicode\_ci;

进入book,执行项目中的sql文件,路径为:etc/ddl.sql

执行成功后,表如下:
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第7张图片

Harbor配置

新建一个项目java,访问级别是公开。注意:设置公开后,下载镜像不需要认证。
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第8张图片

推送镜像

进入jenkins主机,下载gitlab代码。

git clone ssh://[email protected]:/home/git/git\_storage/admin\-master

修改docker配置,增加Harbor库地址。

vim /etc/docker/daemon.json

增加insecure-registries

{"insecure-registries": \["192.168.10.122"\]}

重启服务

systemctl restart docker

登录Harbor,否则无法推送镜像

docker login 10.212.82.86:1180

进入项目目录,使用mvn编译代码

mvn \-f pom.xml clean package

推送镜像,执行命令:

cp dockerfile target/cd target
docker build \-t 10.212.82.86:1180/java/admin\-master:1 .
docker push 10.212.82.86:1180/java/admin\-master:1docker rmi 10.212.82.86:1180/java/admin\-master:1

admin-master部署

登录k8s-node01节点

修改docker配置,增加Harbor库地址。

vim /etc/docker/daemon.json

增加insecure-registries

{"insecure-registries": \["192.168.10.122"\]}

重启服务

systemctl restart docker

访问Rancher后台,点击部署服务
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第9张图片

端口映射
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第10张图片

点击启动
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第11张图片

等待几分钟,Running表示运行正常。
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第12张图片

登录k8s-master节点,查看svc映射端口。因为使用Rancher部署时,nodeport端口是随机的。

\# kubectl get svc
NAME                    TYPE        CLUSTER\-IP    EXTERNAL\-IP   PORT(S)          AGE
admin\-master            ClusterIP   10.1.10.23    <none\>        8088/TCP         10m
admin\-master\-nodeport   NodePort    10.1.238.46   <none\>        8088:31581/TCP   10m
db\-mysql                ClusterIP   10.1.116.0    <none\>        3306/TCP         61s
db\-mysql\-nodeport       NodePort    10.1.86.36    <none\>        3306:31959/TCP   61s
kubernetes              ClusterIP   10.1.0.1      <none\>        443/TCP          20d

可以看到nodeport映射的随机端口是31581

访问admin-master

http://10.212.20.94:31581/

输入用户名和密码,都是root
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第13张图片

首页效果如下:
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第14张图片

前面已经通过Rancher部署了mysql和admin-master,接下来演示一下,如何通过jenkins实现基于Pipeline,实现发布和回滚。

安装插件Git Parameter
在这里插入图片描述
新建一个job,名称为:test_admin,选择流水线。
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第15张图片
通用设置
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第16张图片

参数化构建
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第17张图片

Pipeline脚本
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第18张图片

完整代码如下:

env.CREDENTIALSID \= '7a294fc5-2b2b-4d2d-92ff-54324e1b032a'
env.BRANCHES \= 'master'
env.GIT\_URL \= 'ssh://[email protected]:/home/git/git\_storage/admin-master'
env.HARBOR\_PROJECT \= '10.212.82.86:1180/java/admin-master'
env.PROJECT \= 'admin-master'
env.K8S\_MASTER \= '10.212.20.94'
env.NAMESPACE \= 'default'
node {
   if (env.Status \== 'Deploy'){
       stage('code pull') {
           checkout(\[$class: 'GitSCM', branches: \[\[name: env.BRANCHES\]\],
           doGenerateSubmoduleConfigurations: false,
           userRemoteConfigs: \[\[credentialsId: env.CREDENTIALSID, url: env.GIT\_URL\]\]\])
       }
       stage('code Build') {
         sh 'mvn -f pom.xml clean package'
       }
       stage('docker push') {
         sh 'cd ${WORKSPACE} && cp dockerfile target'
         sh 'cd ${WORKSPACE}/target && docker build -t ${HARBOR\_PROJECT}:${BUILD\_NUMBER} .'
         sh 'docker push ${HARBOR\_PROJECT}:${BUILD\_NUMBER}'
         sh 'docker rmi ${HARBOR\_PROJECT}:${BUILD\_NUMBER}'
       }
       stage('k8s deploy') {
         sh 'ssh ${K8S\_MASTER} "kubectl -n ${NAMESPACE} set image deploy ${PROJECT} \*=${HARBOR\_PROJECT}:${BUILD\_NUMBER}"'
       }
   }else{
       stage('k8s rollback') {
           sh 'ssh ${K8S\_MASTER} "kubectl -n ${NAMESPACE} set image deploy ${PROJECT}\*=${HARBOR\_PROJECT}:${BUILD\_ID}"'
       }
   }
}

根据实际情况,修改红色文字参数,也就是全局变量。

说明:

7a294fc5-2b2b-4d2d-92ff-54324e1b032a 这个是jenkins全局凭据,针对gitlab设置的。
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第19张图片

点击构建
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第20张图片

直接点击构建
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第21张图片

构建成功后,效果如下:
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第22张图片

如果需要回滚到上一个版本,输入BUILD_ID。

由于最近成功一次的BUILD_ID是10,所以输入9

效果如下:
基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现_第23张图片

本文参考链接:

https://blog.51cto.com/andylhz2009/2053741

你可能感兴趣的:(基于Jenkins+Gitlab+Harbor+Rancher+k8s CI/CD实现)