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

  • 相关阅读:
    Delphi XE5 android 蓝牙通讯传输
    Delphi XE5 android toast
    Delphi XE5 android openurl(转)
    Delphi XE5 如何设计并使用FireMonkeyStyle(转)
    Delphi XE5 android 捕获几个事件
    Delphi XE5 android listview
    Delphi XE5 android 黑屏的临时解决办法
    Delphi XE5 android popumenu
    Delphi XE5 android 获取网络状态
    Delphi XE5 android 获取电池电量
  • 原文地址:https://www.cnblogs.com/ExMan/p/13955183.html
Copyright © 2011-2022 走看看