docker + jenkins+git 搭建自动化部署详解。


  

       首先说下为什么要写这篇文章,网上基于jenkins自动话部署的文章很多,但是大多基于官方镜像做的,官方的latest版本的镜像部分插件不可用,笔者结合工作实际情况和本着学习的态度打算从零开始搭建一套自动化部署环境,记录这个过程中遇到的问题和如何解决问题。

    本文重点介绍jenkins,自建jenkins镜像,以及jenkins如何在docker容器中运行,jenkins和docker私有仓库又是怎么玩的。docker说明、安装和git说明、安装,maven说明、安装,gitlab说明,安装。在本文中不会特别详细的介绍。

本文部分引用 网上51CTO图片 。


背景说明

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

先来了解一下比较典型的java项目发布工作流程:

1.java项目开发 >> 2.提交项目代码到(git或svn) >> 3. 拉取项目代码(jenkins或手动) >> 4.编译项目代码(jenkins或手动) >> 5.发布java项目,并运行java项目 >> 6.测试

在来看看用docker+jenkins+git发布java项目流程又是怎样的呢:

1.java项目开发 >> 2.提交项目代码git容器 >> 3.jenkins容器拉取项目代码 >> 4.maven编译构建项目 >> 5.jenkins发布项目到tomcat容器 >> 6.测试

看到上面的流程后,在没有jenkins的情况下这些步骤都是手工完成的,有了Jenkins的帮助,在这6步中,除了第1步,后续的5步都是自动化完成的。当你完成了提交,Jenkins会自动运行你的编译脚本,编译成功后,再运行你的测试脚本,这一步成功后,接着它会帮你把新程序发布出去,特别的,在最后一步,你可以选择手动发布,或自动发布。

1、 环境描述

1、服务器部署信息

服务器主机名IP运行服务

jenkins服务器:jenkins192.168.154.128 安装docker、 运行jenkins容器、gitlab、jdk、maven,docker私有库

app 服务器docker 192.168.154.128  安装docker、创建镜像运行java项目 gateway

说明:

本文中完全是模拟生产环境中服务器的规划:git单独部署、jenkins单独部署。如果你没有这么多服务器,可以把git服务器和jenkins服务器放在一起来测试。前提是不要搞晕了就可以。

gateway是 springcloud 的gateway,基于springboot和maven 


2、版本信息

名称版本软件包说明

服务器 Centos 7 及内核信息

docker 版本:


JDK环境 1.8.211 


maven 版本信息:  apache-maven-3.6.1-bin.tar.gz

jenkins 采用2.150 版本 的war包,下载地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.150/jenkins.war

registry最新版本docker hub下载最新registry镜像docker私有仓库


3、 准备工作

   3.1  JDK的安装

            这里就不介绍了。通过rpm包的免配置自动安装或者tar.gz包配置安装网上有很多文章 。

   3.2 docker 的安装

    安装下一些必要的系统工具:

```

    sudo  yum install -y yum-utils device-mapper-persistent-data lvm2

```


    添加阿里的yum的源:

```

    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

```


    更新 yum缓存 :

```

    sudo yum makecache fast

```


    安装docker :

```
    sudo yum -y install docker-ce

```


    docker 启动: 

```

    sudo systemctl start docker 

```


    docker 设置开机自启动:

```

    sudo systemctl enable docker.service

```


    3.3 docker 私有仓库安装(不使用私库可以无视)

   sudo  docker search register 

选第一个镜像就好 

拉取镜像:

sudo docker  pull register 

 这里就可以通过 docker images 查询本地镜像


然后通过该镜像启动一个容器:

```

sudo docker run  -d -p 5000:5000  -v /opt/data/registry:/tmp/registry   --name register register 

```

说明这里是将本地的 /opt/data/registry  挂载到 容器的 /tmp/registry ,防止容器删除的时候, 容器里面的镜像会丢失。

将本地镜像push到私库:

```

sudo docker tag nginx 192.168.154.128:5000/nginx

```

这里注意。因为Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。

这个问题解决方法:

首先找到 docker.service  文件 

```

find / -name  docker.service 

```


然后修改docker.service 文件

vim /usr/lib/systemd/system/docker.service

加一条这句话:--insecure-registry 192.168.154.128:5000



sudo docker push 192.168.154.128:5000/nginx

如果我们要查询私库中的所有镜像可以用如下:curl -XGET http://registry:5000/v2/_catalog


3.4 jenkins 安装

 所有准备jenkins 需要的tar包和war包:
apache-ant-1.9.14-bin.tar.gz

apache-maven-3.6.1-bin.tar.gz

apache-tomcat-9.0.21.tar.gz

git-2.14.2.tar.gz

jdk-8u211-linux-x64.tar.gz 

jenkins.war


然后编写Dockerfile 

代码如下:

```
FROM centos:7

USER root

# author info

MAINTAINER wupeng 513943544@qq.como

#安装一些必要的系统工具:

# install git

ADD git-2.14.2.tar.gz /opt/

RUN yum install -y  gcc gcc-c++ automake autoconf libtool make curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker

# 切换上下文

WORKDIR /opt/git-2.14.2

RUN ./configure --prefix=/usr/local/git \

    && make && make install \

    && ln -s /usr/local/git/bin/git /usr/sbin/git

# install jdk

ADD jdk-8u211-linux-x64.tar.gz  /opt/

ENV JAVA_HOME /opt/jdk1.8.0_211

ENV CLASSPATH .:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

ENV PATH $JAVA_HOME/bin:$PATH

# install maven

ADD apache-maven-3.6.1-bin.tar.gz /opt/

ENV MAVEN_HOME /opt/apache-maven-3.6.1

ENV PATH $MAVEN_HOME/bin:$PATH

RUN mkdir -p /var/jenkins_home

ENV JENKINS_HOME /var/jenkins_home

ADD apache-tomcat-9.0.21.tar.gz /opt/

# startup tomcat

ADD jenkins.war /opt/apache-tomcat-9.0.21/webapps

CMD /opt/apache-tomcat-9.0.21/bin/catalina.sh run 

CMD systemctl start docker

# expose memcached port

EXPOSE 8080

```



ps:想在dockerfile里面加上安装docker,结果测试发现容器是不能用systemctl 的,导致docker 启动不了,不过没关系,不装docker,可以用宿主机的docker 完成push到私库的操作。


然后通过docker build 创建镜像

dcoker build -t jenkins_2.150 -f /home/Dockerfile .

注意 . 别漏掉了。

 

创建成功。

将镜像运行成容器:

```

docker run -d -p 8080:8080 -p 50000:50000 -v /soft/jenkins/jenkins_home:/var/jenkins_home -v /etc/localtime:/etc/localtime --name jenkins_2.150 jenkins:2.150

```


查询容器 :

docker ps 


验证docker jenkins 环境是否正常。

进入容器 :
```

docker exec -it jenkins_2.150 /bin/bash

```

验证 jdk 和maven git docker是否正常。

其他都没问题。 然后查看 jenkins 是否正常,退出容器,然后docker logs -f jenkins_2.150 

可以看到jenkins的 初始化密码:

这里需要注意,jenkins 官方的源下载插件的时候,各种被墙,所以这里修改成清华大学的源。

修改文件在:

/soft/jenkins/jenkins_home/hudson.model.UpdateCenter.xml

这个目录就是之前启动容器的时候挂载的目录,然后找到这个文件。

https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

然后 重启docker 容器

docker restart jenkins_2.150 

然后登陆到jenkins 

http://192.168.154.128:8080/jenkins

密码就是之前 打印 的密码,如果找不到 ,直接查看下面路径的初始密码 

cat /var/jenkins_home/secrets/initialAdminPassword 

此路径是jenkins容器内部的路径,可以直接看挂载的jenkins_home

登录之后,选择第一个,安装建议的插件。



部分插件装不成功的插件, 直接过也没事, 进去之后还能针对性安装,接下来基本操作, 不细说了。安装好了 重启下容器。

4、gitlab 配置

4.1创建测试项目

创建gateway 项目,然后把本地测试项目push到gitlab仓库,具体操作省略,gitlab有详细步骤。

4.2 配置ssh key

进入jenkins 容器。 然后配置git user.name 和 user.email 。然后生成ssh key 配置上即可。






生成ED25519 SSH key 

ssh-keygen-ted25519-C"email@example.com" 这里邮箱填配置的邮箱 配置 git config --global  user.email  "email@example.com"

生成之后默认在是 ~/.ssh/目录下面。 然后cat 下, 把内容复制gitlab里面即可。记得是公钥 !

5、Jenkins 配置

        首先这里说下jenkins 做了写什么。
       Jenkins 主要是在git仓库拉取代码,然后在本地 mvn package  成jar 包 然后用已经写好的Dockerfile  docker build 成 镜像,然后用 push 到本地的私库。之后再调用ssh 到appService 去从 私库里面pull 镜像, 然后再运行成容器。目的明确之后, 在来做这套就很好解决。

5.1、安装插件

    这里说下,Jenkins需要安装下面这个插件才可以看到 创建maven项目 

5.2、jenkins 配置工具信息

在这里配置 maven JDK的配置信息。git因为已经做了软连接,不用。

例如 配置maven

        这里需要注意的安装的maven 默认是官方的源镜像仓库,国内下载的话,各种被墙,所以这里需要修改maven settings.xml文件,我这里改成阿里的仓库。

```

<mirrors>

    <mirror>

      <id>alimaven</id>

      <name>aliyun maven</name>

      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>

      <mirrorOf>central</mirrorOf>       

    </mirror> 

 </mirrors>

```

至于settings.xml的位置,可以用find 查询下, 在/opt/maven/conf  下面.

5.3、创建一个maven工程

然后配置


pei

根据自己情况自己配置。

配置git 仓库信息:

这里说明下:已经配置了sshkey 结果还报错,这么解决 

然后再配置 git repo信息,就不报错了。这里222端口是宿主机 映射gitlab 容器的 22端口


配置maven 打包指令


然后 可以尝试跑一下,【立即构建】

这里看到 已经build成功了。

接下来,要做的事是把jar build成镜像,然后启动,

目前有两种解决办法:

        一个简单点的 直接用scp 指令将需要的jar直接传输到对应的服务器,

然后在目标服务器(app服务器)上做build images 和  启动操作。

        一个复杂点的方案就是使用私库,利用tag,构建将镜像在jenkins宿主机上build成image然后push到私库,

然后目标服务器(app服务器) 上pull images 然后启动。(私库没有删除镜像的操作,目前没找到)

不管那个方案,先编写jar build成images 的dockerfile,代码如下:


首先准备下Dockerfile文件 。

```

FROM openjdk:8-jdk-alpine

VOLUME /tmp

ADD ./target/gateway.jar gateway.jar

CMD java -Xms2G -Xmx2G -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m  -XX:+UseCompressedOops -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/dump/heap_trace.txt -XX:NewSize=512m -XX:MaxNewSize=512m -Djava.security.egd=file:/dev/./urandom -jar gateway.jar

EXPOSE 9988

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

```

这里解释下,

FROM openjdk:8-jdk-alpine 基于 openjdk:8-jdk-alpine 构建

VOLUME /tmp  将 /tmp 挂载的宿主机/tmp 目录,

ADD ./target/gateway.jar gateway.jar  添加gateway.jar (注意路径)

CMD java 这句 就是java -jar  xxx.jar 启动jar包了。

EXPOSE 9988 声明端口。
最后两句 就是定义时区和做了个软连接。

第一种解决方案:使用scp指令 直接在appServer上拷贝jar

scp 可以写个shell脚本, 也可以通过ssh加授信。

这里就说下加ssh授信怎么操作:

在appServer 生成rsa 非对称密钥对,

ssh-keygen -t rsa  

遇到提示直接回车就好。
然后生成的密钥在~/.ssh下 


然后在将id_rsa.pub这个公钥的内容copy到目标服务器(jenkins宿主机)的~/.ssh/ 目录下的 authorized_keys 里面去 (没有就创建一个authorized_keys 文件)。

然后可以测试下 ssh  ip ,直接进去表示成功了,

然后在jenkins 里面写shell指令。


如图:


```

docker stop gateway

docker rm gateway

docker rmi gateway

```


```

cd /soft/jenkinsdata/gateway

rm -rf *.jar

scp root@192.168.154.128:/soft/jenkins/jenkins_home/workspace/gateway/target/gateway.jar .

docker build -t gateway -f /soft/jenkinsdata/gateway/Dockerfile  .

docker run -it -d -p 9988:9988 -v /etc/localtime:/etc/localtime --name gateway  gateway

```

在build 之前先停止docker 容器,然后删除镜像。

然后再build成功之后。

重新scp jar 过来,build成镜像,然后启动成容器。

然后启动试一试:

Error response from daemon: No such container: gateway

Error: No such container:  gateway

Error: No such image: gateway


这里因为找不到容器,是因为 第一次还没启动过容器,但是这样写会导致报错,所以这里需要处理下。

当有这个容器的时候就关掉 然后删除容器及其image 如果没有,无事发生。这样处理就OK了。

用一个shell脚本来做这个操作:

```

#!/bin/sh

if [ $# == 0 ];then

echo "请输入需要关闭服务名称"

exit 0

else

  cid=$(docker ps -a | awk '$2~/'$1'/{print $1,$2}')

  arr=($cid)

  len=${#arr[@]}

  if [[ len -eq 0 ]];then

    echo "没有与$1相关的服务"

  elif [[ len -eq 2 ]];then

    echo "匹配到服务${arr[1]}"

    id=${arr[0]}

    echo "关闭containerId 为$id的服务"

    docker stop $id

    docker rm $id

    docker rmi ${arr[1]}

  else

    echo "匹配到多个与$1相关的服务"

    for i in "${!arr[@]}"

        do

        t=`expr $i % 2`

        if [ $t -eq 0 ];then

            let ii=i+1

            echo "${arr[$ii]}"

        fi

        done

  fi

fi

```

处理之后,修改下 jenkins shell配置,然后再次执行构建项目,经过一段时间等待,到appServer 看下  gateway已经启动了。

到这里就OK了,简版测试环境的自动化部署就大功告成。


最后总结:

Docker+Maven+Jenkins +Git 自动化部署解决方案,核心是利用jenkins的git和maven插件来完成项目的pull 和build操作,然后通过build的pre或者post的执行shell的机制来执行自己想要执行的任何shell脚本,这里就是docker的创建镜像和容器的指令。
需要注意的是shell 脚本执行错误导致整个构建失败的情况。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342