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

发布时间:2020-06-16 14:16:26编辑:admin阅读(3277)

    一、概述

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

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

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

    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)服务发现和负载均衡

     

    架构图

    1.png

     

    架构图说明

    项目开发语言是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.94k8s-master2核4gKubernetes1.18.1
    CentOS 7.6 10.212.20.240k8s-node012核4gKubernetes1.18.1
    CentOS 7.6 10.212.82.89jenkins2核4g2.222.4
    CentOS 7.6 10.212.82.90gitlab2核4g10.5.1
    CentOS 7.6 10.212.82.86harbor2核4gv2.0.0
    CentOS 7.6 10.212.82.87rancher2核4gv2.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才行。

     

    三、Rancher操作

    mysql部署

    登录k8s-node01主机,创建数据目录

    mkdir -p /data/mysql/data

     

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

    1.png

    端口映射

    1.png

     

     

    设置环境变量

    TZ=Asia/Shanghai
    MYSQL_ROOT_PASSWORD=abcd@1234

     

    1.png

     

     

    数据卷映射

    1.png

     

     点击启动

     1.png

     

     

    代码配置

    下载代码: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

    1.png

     

     

    新建数据库book

    create database admin default character set utf8mb4 collate utf8mb4_unicode_ci;

     

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

    执行成功后,表如下:

    1.png

     

     

    Harbor配置

    新建一个项目java,访问级别是公开。注意:设置公开后,下载镜像不需要认证。

    1.png

     

     

    推送镜像

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

    git clone ssh://git@10.212.20.94:/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后台,点击部署服务

    1.png

     

     端口映射

    1.png

     

     点击启动

    1.png

     

     

     等待几分钟,Running表示运行正常。

    1.png

     

     

    登录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

    1.png


    首页效果如下:

    1.png

     

    四、jenkins操作

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

    安装插件Git Parameter 

    1.png

     

    新建一个job,名称为:test_admin,选择流水线。

    1.png

     

    通用设置

     1.png

     

    参数化构建

    1.png

     

    Pipeline脚本

    1.png

     

     

    完整代码如下:

    env.CREDENTIALSID = '7a294fc5-2b2b-4d2d-92ff-54324e1b032a'
    env.BRANCHES = 'master'
    env.GIT_URL = 'ssh://git@10.212.20.94:/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设置的。

    1.png

     

     

    点击构建

    1.png

     

     

    直接点击构建

    1.png

     

    构建成功后,效果如下:

    1.png

     

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

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

    1.png

     

    效果如下:

    1.png

     

     

    本文参考链接:

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


关键字