zoukankan      html  css  js  c++  java
  • Jenkins+Rancher+Harbor+Gitlab部署应用到生产环境

    Jenkins结合rancher进行项目的持续集成,这个流程其实跟之前的java项目、React项目、安卓项目的持续集成都差不多。但是相较之前的项目部署来说,在流程上多了很多的步骤,需要注意的地方比较多,所以在这里以部署一个java的demo项目进行演示和记录。

    一、环境准备

    本次实验的主机系统全部为CentOS Linux release 7.6.1810 (Core)

    1、需要用到的服务

    应用版本
    Jenkins 2.213
    Gitlab 11.9.9
    Rancher 2.3.5
    Harbor 1.10.0

    2、准备rancher-cli

    要想Jenkins能远程控制rancher,需要借助rancher-cli这个工具来实现。具体的配置方法可以参考:rancher-cli的使用

    3、准备rancher存储类(StrongClass)

    在k8s中,关于存储的概念有3个:PV、PVC、StrongClass,在规划存储之前,最好想了解下这三个概念,可以参考下这篇文章:Kubernetes PV与PVC

    前面已经搭建了一个3个节点的rancher集群,因为考虑应用的日志问题,所以这里准备一个存储类用于应用日志目录的挂载。

    首先进入到将要部署应用的集群中,点击应用商店,选择启动,搜索nfs,点击进去并拉到页面最下方点击启动进行安装,操作流程如下图:
    在这里插入图片描述

    部署完成后,可以在集群的工作负载中看到对应的服务。
    在这里插入图片描述
    在这里做一个小小的规划:后续所有应用的日志都通过这个nfs服务进行汇总到一台主机这个nfs共享目录中,这样开发人员在点击jenkins进行部署完成之后,不需要知道这中间复杂的过程,直接去一个统一的位置查看日志就行了。

    所以我打算将rancher集群中的node2(192.168.0.52)/data目录共享出来(当然比较好的做法是单独的挂载一块容量较大的硬盘到/data目录)

    注意:这个nfs共享的分区需要使用xfs格式,否则后期可能会出现pod挂载失败的报错。报错的内容如下:

    Unable to mount volumes for pod "isj-eureka-57fb65b885-wf77q_isj(b0b0594f-715e-11e9-884a-0050568fa4d0)": timeout expired waiting for volumes to attach or mount for pod "isj"/"isj-eureka-57fb65b885-wf77q". list of unmounted volumes=[eureka]. list of unattached volumes=[eureka default-token-9wmpb]
    
    • 1

    接着来对刚才在应用商店部署的nfs服务进行一些调整,来满足上面的这个小小规划的需求。点击右边三个小点,选择升级,然后更改一些配置信息。
    在这里插入图片描述

    这里修改了两个地方:

    1)主机调度:让pod绑定在node2(192.168.0.52)上。

    2)数据卷:卷名可以自定义,主机路径改成我们预设的/data目录。

    调整之后,点击最下方的升级就生效了,这样一个nfs的存储类就创建完成了。后续需要用到存储的时候,可以直接从这个存储类中划分,非常方便。

    4、添加持久卷声明(PVC)

    上面的存储类配置之后不能直接应用,还需要添加持久卷声明(PVC)才能用。

    来到集群的PVC栏目中,点击添加PVC
    在这里插入图片描述
    配置如下:
    在这里插入图片描述
    名称:可以自定义。
    命名空间:我这里是根据项目来规划命名空间的,所以选择demo。如果没有项目的命名空间,可以新建一个。
    来源:选择使用存储类创建新的持久卷(PV)
    存储类:选择刚才创建的nfs-provisioner
    容量:因为这里上面nfs共享的分区的空间不大,我这里就限制为20G。

    点击创建,就能在PVC列表中看到一个20G大小的PVC了,后面的应用部署将会用到这个PVC。

    二、相关服务安装

    需要用到的各个服务的详细安装这里就不讲了,有需要的可以直接点击参考一下:

    三、正式配置

    先来整理下思路:首先在Jenkins上将代码克隆下来,进行编译打包,然后编写Dockerfile来构建镜像并将镜像推送到私服,接着就可以在rancher中部署项目了。

    按照上面的思路,就可以一步步的把一个应用给部署好了。

    1、克隆代码,构建镜像

    Jenkins想必都是很熟悉的了,我这里选择了一个自由风格的项目进行配置(我个人比较爱用自由风格的)。废话不多说,直接上Jenkins的配置。
    在这里插入图片描述
    其实这就是一般Jenkins的配置,这里就不讲了。

    我这里要说的是在构建中的执行shell中要写的脚本,将需求具体化成步骤:

    1)到项目的$WORKSPACE目录中去执行打包命令。
    2)进入到target目录编写Dockerfile。
    3)打镜像,并推送到Harbor上。

    注意:如果不是用的Harbor的默认自带项目library的话,需要先在的Harbor上创建项目,我这里是在Harbor新建一个demo项目。

    先暂时到这里吧,上面步骤的shell脚本如下:

    #!/bin/bash
    source /etc/profile
    
    ##set color##
    echoRed() { echo $'e[0;31m'"$1"$'e[0m'; }
    echoGreen() { echo $'e[0;32m'"$1"$'e[0m'; }
    echoYellow() { echo $'e[0;33m'"$1"$'e[0m'; }
    ##set color##
    
    # 设置变量
    project="demo"
    version=`date +%Y%m%d%H%M%S`
    port=9001
    echo -------------------------------------
    
    # mvn打包
    cd $WORKSPACE
    mvn clean install -DskipTests=true
    if [ $? -eq 0 ];then
        echoGreen "mvn package is success!"
    else
        echoRed "mvn package is Failed!" && exit 1
    fi    
    sleep 2
    
    # 进入target目录
    cd  $WORKSPACE/target/ && mv $project-0.0.1-SNAPSHOT.jar app.jar
    
    # 创建docker镜像
    cat > run.sh << EOF
    #!/bin/bash
    source /etc/profile
    java -jar /opt/app.jar --server.port=${port}
    EOF
    chmod +x run.sh
    cat >Dockerfile << EOF
    FROM 192.168.0.153/public/jdk:1.8
    MAINTAINER wc <123@qq.com>
    ENV LANG en_US.UTF-8
    ADD   app.jar /opt
    ADD   run.sh  /
    EXPOSE 9001
    ENTRYPOINT [ "sh", "-c", "/run.sh" ]
    EOF
    
    # 编译镜像
    echoGreen "开始构建当次镜像!"
    docker build -t 192.168.0.153/demo/$project:$version .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    好了,Jenkins执行下构建,构建完成之后去Harbor上看一眼。
    在这里插入图片描述
    最下面这个镜像就是刚才推送到Harbor上的。

    2、部署应用

    好了,镜像已经打好了,下面的步骤就是要在rancher中进行应用的部署了,因为rancher集成了很友好的UI界面,所以常规应用的部署直接在UI中操作就可以了。

    进入到集群中,在工作负载中点击部署服务,配置见下图:
    在这里插入图片描述
    1:定义将要部署应用的名称,这里最好与上面脚本中$project的值相等,便于脚本上下文的调用。

    2:填入刚才生成的镜像的地址。

    3:选择应用要用的命名空间,如果没有想要的,可以新建一个。

    4:端口名称,自定义即可。

    5:填入容器中应用的端口。

    6:填入将要映射出来的端口,建议合理规划一下映射的端口。

    7:通过端口检查来做健康检查,后面的时间可以根据应用初始化情况进行合理调整。

    8:在添加卷中选择使用现有PVC,卷名自定义即可。

    9:选择之前创建的PVC。

    10:根据自己的需求挂载容器目录,我这里把应用的日志目录挂载出来。

    11:定义挂载在持久卷中的目录名称。

    然后点击启动,就完成应用的部署了。稍等一会,就可以在工作负载中看到这个刚部署的应用了。
    在这里插入图片描述
    部署完成之后,可以访问下试试,点击应用名称下边的端口,就可以直接跳转访问。
    在这里插入图片描述
    再来看看应用的日志情况:
    在这里插入图片描述

    接着去我们一开始配置的存储类对应的节点(192.168.0.52)上看看是否有日志文件。

    [root@node2 demo]# pwd
    /data/pvc-33ac32cb-ff71-412b-98e5-bd4b5e16751f/demo
    [root@node2 demo]# ls
    demo.log
    
    • 1
    • 2
    • 3
    • 4

    可以看到日志和一开始预期的一样出现了,其中pvc-33ac32cb-ff71-412b-98e5-bd4b5e16751f就是上面创建的持久卷声明(PVC)的名称,demo是刚才在rancher上部署应用时定义的。

    3、完善脚本

    OK,上面的都没问题。这样就完成了一个应用的部署,剩下的事情就是把刚才的shell脚本补充完整(刚才的shll脚本只写到推送镜像到Harbor为止),达到一键部署的效果。

    这里之后的shell脚本的完整内容如下:

    #!/bin/bash
    source /etc/profile
    
    ##set color##
    echoRed() { echo $'e[0;31m'"$1"$'e[0m'; }
    echoGreen() { echo $'e[0;32m'"$1"$'e[0m'; }
    echoYellow() { echo $'e[0;33m'"$1"$'e[0m'; }
    ##set color##
    
    # 设置变量
    project="demo"
    version=`date +%Y%m%d%H%M%S`
    port=9001
    harbor_user="admin"
    harbor_pwd="Harbor12345"
    harbor_host="192.168.0.153"
    echo ----------------------------------------------
    
    # mvn打包
    cd $WORKSPACE
    mvn clean install -DskipTests=true
    if [ $? -eq 0 ];then
        echoGreen "mvn package is success!"
    else
        echoRed "mvn package is Failed!" && exit 1
    fi    
    sleep 2
    
    # 进入target目录
    cd  $WORKSPACE/target/ && mv $project-0.0.1-SNAPSHOT.jar app.jar
    
    # 创建docker镜像
    cat > run.sh << EOF
    #!/bin/bash
    source /etc/profile
    java -jar /opt/app.jar --server.port=${port}
    EOF
    chmod +x run.sh
    cat >Dockerfile << EOF
    FROM 192.168.0.153/public/jdk:1.8
    MAINTAINER wc <123@qq.com>
    ENV LANG en_US.UTF-8
    ADD   app.jar /opt
    ADD   run.sh  /
    EXPOSE 9001
    ENTRYPOINT [ "sh", "-c", "/run.sh" ]
    EOF
    
    # 编译镜像
    echoGreen "开始构建本次镜像!"
    docker build -t $harbor_host/demo/$project:$version .
    [ $? != 0 ] && echoRed "请注意,打镜像时出错,故而退出!" && exit 1
    
    # 登录远程Harbor仓库
    echoGreen "开始登录远程Harbor仓库!"
    docker login -u $harbor_user -p $harbor_pwd $harbor_host
    [ $? != 0 ] && echoRed "请注意,登录Harbor时出错,故而退出!" && exit 1
    
    # 上传到docker私服
    echoGreen "开始push新镜像到私服!"
    docker push $harbor_host/demo/$project:$version
    [ $? != 0 ] && echoRed "请注意,在执行push上传时出错,故而退出!" && exit 1
    docker rmi $harbor_host/demo/$project:$version
    
    # 更新镜像
    echoGreen "开始将新镜像部署到远端!"
    rancher kubectl set image deployment/$project $project=192.168.0.153/demo/$project:$version -n demo
    [ $? != 0 ] && echoRed "请注意,在执行镜像更新时出错,故而退出!" && exit 1
    echoGreen "部署完成!"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    这里先说一下,因为应用时放在单独的容器中执行的,所以jar包的名称无关紧要,我这里直接把jar包的名称改为app.jar,这样在写dockerfile和运行的时候都是用的app.jar这个名称,以后即使不同的项目,都不需要对shell脚本中的jar包名称进行更改了。

    把上面这个shell脚本放到Jenkins的执行shell中,然后再点击一下构建,看看是不是能把新构建的镜像部署到rancher中去。

    查看Jenkins的控制台输出,可以看到流程一切顺利。
    在这里插入图片描述
    然后来看rancher这边,可以看到新的应用已经开始部署了。
    在这里插入图片描述

    因为之前在rancher中配置应用时使用的缩放/升级策略滚动: 先启动新Pod,再停止旧Pod,所以整个部署过程是不会影响到业务的正常访问的。

    再来谈谈规范化的问题,整个过程中都在考虑规范化的问题,以后再新增应用的时候,直接Jenkins复制Job,仅仅需要更改一些git仓库的地址,以及shell脚本中的一些变量的值,然后rancher上复制应用,对应的更改一些地方,一个新的应用的部署就这么完成了, 其实并不复杂。

    参考文章:
    http://www.eryajf.net/2746.html
    https://i4t.com/4467.html

  • 相关阅读:
    My97 DatePicker 的jQuery插件
    UITableView 的 delegate2个基本方法
    你还在使用myImage = [UIImage imageNamed:@"icon.png"];吗
    自动生成数学题型三 (框架Struts2)题型如 a+b=c(a、b、c都为分数)
    自动生成数学题型二(框架struts2)题型如((a+b)*c=d)
    自动生成数学题型一 (框架Struts2) 题型如(a+b=c)
    创业团队应具备的要素
    在服务器中linux的centos系统如何封ip
    创业成功:必须具备的12个要点
    PHP+mysqli如何连接MySQL数据库,MySQL, Improved
  • 原文地址:https://www.cnblogs.com/ExMan/p/13955183.html
Copyright © 2011-2022 走看看