一. 准备工作

1. 配置java运行环境

2. 下载Jenkins

3. 本地部署Jenkins

nohup java -jar jenkins.war &

默认的启动端口是8080

4. 安装SSH插件

初始化时候, 按要求把推荐的插件全部按要求安装即可

到菜单栏的manage Jenkins下, 选择

jenkins在docker中安装部署 node jenkins部署docker微服务_Jenkins


进行管理插件.为了能远程部署,需要在安装Publish Over SSH插件

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_02

二. 项目结构说明

jenkins在docker中安装部署 node jenkins部署docker微服务_Jenkins_03

这是项目的服务模块,其中就包含了好几个微服务模块,这里以阿里云OSS微服务模块为例进行部署说明.

每个服务模块中都要包含Dockerfile文件, 这是后面通过docker启动项目时, 定位jar包的配置文件. 其中内容每个模块大同小异,按需修改即可. 内容如下

FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY ./target/service_edu-0.0.1-SNAPSHOT.jar service_edu.jar
ENTRYPOINT ["java","-jar","/service_edu.jar", "&"]

./target/service_edu-0.0.1-SNAPSHOT.jar是maven打包之后jar包的相对路径位置, service_edu.jar是我们自定义的简化名称. 之后的模块也只需修改这两个参数就可以了!

三. Jenkins的配置

在菜单栏Manage Jenkins中, 有两项配置, 可以进入Jenkins的配置页面

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_04


jenkins在docker中安装部署 node jenkins部署docker微服务_Jenkins_05

1. 配置java环境

Global Tool Configuration中,进行java根目录路径的配置

jenkins在docker中安装部署 node jenkins部署docker微服务_Jenkins_06

2. 配置maven环境

先到Global Tool Configuration中,进行Maven根目录路径的配置

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_07

再到Configure System中进行Maven仓库的配置, 设置Maven仓库的所在路径

jenkins在docker中安装部署 node jenkins部署docker微服务_配置文件_08

3. 配置远程Git服务器

先到Global Tool Configuration中,进行git命令所在路径的配置, 一般同图片配置即可.

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_09

4. 配置远程服务器

Configure System中,找到Publish over SSH配置选项, 添加服务器

jenkins在docker中安装部署 node jenkins部署docker微服务_配置文件_10


注意,服务器如果需要密码验证的需要勾选Use password authentication, or use a different key选项,输入密码即可.

Name是远程服务器配置的名称, 后面调用此配置需要使用这个Name

Username就是登入服务器的用户名.

Remote Directory就是远程连接以后的根目录, 需要提前在远程服务器创建这个目录,或者选择一个已经存在的目录作为远程连接根目录.

Timeout设置连接超时时间.

如果需要分布式部署可以点击新增添加多台远程服务器, 如上所述的配置即可!

四. Jenkins远程部署微服务

1. 新建一个任务

在菜单栏点击新建item,选择

jenkins在docker中安装部署 node jenkins部署docker微服务_配置文件_11

2. 配置任务

配置项一共有如下几个,

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_12

(1) 选择源码管理

我们的源码通过git的方式获取, 因此先配置远程git仓库的地址, 如果项目是私有项目还需要输入用户名密码或者ssh秘钥进行用户权限认证处理.

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_13


Repository URL填入仓库地址, 接着选择指定分支(默认是master)即可.

我这里使用的是一个公共存储的项目,因此不需要认证处理.

(2) 构建

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_14


在execute shell中填入如下代码

#!/bin/bash
mvn clean install -pl ./service/service_oss -am

表示单独构建service_oss模块, 之后部署其他微服务模块只需修改./service/service_oss参数即可.

(3) 配置构建环境

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_15

1. 勾选Send files or execute commands over SSH after the build runs选项,表示在项目构建之后通过ssh的方式向远程服务器发送文件或执行shell脚本.

这里需要传输2个文件:

  1. Dockerfile
    Source files: 源文件的路径, **/service_oss/Dockerfile, **表示通配符,可以解释为任何路径下service_oss文件夹中的Dockerfile文件. 这里根目录就是我们的项目根目录,所以**/service_oss/Dockerfile也可以表示为service/service_oss/Dockerfile.
    Remove prefix: 去除源文件路径的前缀,这里要注意的就是去除的前缀路径必须要存在且和源文件文件的路径相匹配. 还要注意, 去除路径前缀的参数中不能使用路径通配符!!!
    Remote directory: 上传文件到远程服务器的目标目录,这个目录会自动创建.
  2. 可执行jar文件
    每个参数的意思同理,但有一点需要特别注意!!!
    由于在Dockerfile文件中,我们有如下代码:
...
COPY ./target/service_edu-0.0.1-SNAPSHOT.jar service_edu.jar
...

也就说我们的jar包是存在于target文件夹中, 而Dockerfile文件和target文件夹处于同级目录!
因此, 再对jar包去除路径前缀的时候要很小心, 不要把/target路径去除掉.

2. 编写docker自动执行脚本
#!/bin/bash
#maven打包
echo 'package ok!'
echo 'build start!'
cd  /www/service_oss
service_name="service_oss"
service_prot=8002
#查看镜像id
IID=$(docker images | grep "$service_name" | awk '{print $3}')
echo "IID $IID"
if [ -n "$IID" ]
then
    echo "exist $SERVER_NAME image,IID=$IID"
    #删除镜像
    docker rmi -f $service_name
    echo "delete $SERVER_NAME image"
    #构建
    docker build -t $service_name .
    echo "build $SERVER_NAME image"
else
    echo "no exist $SERVER_NAME image,build docker"
    #构建
    docker build -t $service_name .
    echo "build $SERVER_NAME image"
fi
#查看容器id
CID=$(docker ps | grep "$SERVER_NAME" | awk '{print $1}')
echo "CID $CID"
if [ -n "$CID" ]
then
    echo "exist $SERVER_NAME container,CID=$CID"
    #停止
    docker stop $service_name
    #删除容器
    docker rm $service_name
else
    echo "no exist $SERVER_NAME container"
fi
#启动
docker run -d --name $service_name --net=host -p $service_prot:$service_prot $service_name
#查看启动日志
#docker logs -f  $service_name

特别注意需要修改的参数, 之后每个微服务的部署只需要修改这些参数即可:

  1. cd /www/service_oss 表示切换到/www/service_oss,这个目录中存在Dockerfile文件, 使用docker来运行镜像需要存在这个文件.
  2. service_name=“service_oss” 表示服务名称, 由于在Dockerfile文件中自定义jar包名称,所以后面运行jar包也需要使用这个名称.
  3. service_prot=8002 表示服务的运行端口号,注意要和.properties文件中定义的端口号一致.

3. 构建

jenkins在docker中安装部署 node jenkins部署docker微服务_配置文件_16


第一次构建需要等待一段时间, 注意查看控制台输出.

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_17


如果出现构建失败, 要记得删除之前的构建,因为构建之后占的空间还是非常大的, 经常需要多次尝试构建才能成功,所以养成习惯每次删除失败的构建.

4. 构建其余的微服务项目

同上面的方式一样,但不需要重头填写配置,只需要克隆之前的配置即可,然后修改几个关键参数

jenkins在docker中安装部署 node jenkins部署docker微服务_配置文件_18


在这里选择复制的配置,然后直接克隆一个.

需要修改的配置:

  1. mvn构建脚本中的参数
  2. 上传文件的路径, 大部分只需要切换模块名称
  3. docker脚本中的要切换目录和2个变量参数
cd  /www/service_oss
service_name="service_oss"
service_prot=8002

五. 一些问题的解决方法

我在部署的时候又遇到一些问题,这里总结出来.

1. 构建成功,但服务没能跑起来

当微服务构建完成, docker也没有报出错误(注意不是警告). 通过命令

docker ps

查看docker镜像的运行情况, 然而发现没有预期的镜像在运行.

出现这种情况,八成是可执行jar文件执行失败,出现了异常导致服务未能启动.可以通过命令

docker logs [CID]

jenkins在docker中安装部署 node jenkins部署docker微服务_docker_19


这里的97ecdf883304就是CID, 来查看服务启动日志, 定位错误的原因.

我这里遇到的错误是因为我的配置文件统一交由Nacos注册中心管理, 但本地的bootstrap.properties配置文件中的Nacos注册中心地址是127.0.0.1:8848, 但部署的时候Nacos已经提前部署到了另一台服务器上. 因此, 这时访问本地8848端口肯定是失败的, 更无法进一步获取配置文件信息. 所以只要去修改bootstrap.properties配置文件中Nacos地址即可. 同时,我们是进行发布需要切换运行环境

spring.profiles.active=prod

我使用Nacos进行配置文件管理, 所以同时还需要修改配置文件的命名空间

spring.cloud.nacos.config.namespace=f2982ad2-86ac-4b1f-9875-5de7b1f581c0

jenkins在docker中安装部署 node jenkins部署docker微服务_配置文件_20

切换为如上图中的编号即可. 之后往这个生产环境中添加配置文件就可以了, 直接克隆导入! 最后修改相应的网络地址还有端口信息!

接下来还要特别注意, 我们使用Jenkins构建微服务, 源码是通过Git来获取的. 因此, 我们也需要把修改后的代码push到远程git仓库才行.

同理, 在进行远程部署的时候,一定要注意一些网络地址的配置. 这里我十分推荐把配置文件交由Nacos管理, 这可以方便我们集群式部署和避免我们在多模块间切换修改配置文件头疼的问题.

2. 去除前缀和源文件路径不匹配

我们在填写源文件路径的时候一定要保证让源文件路径不会出现二义性, 否则, Jenkins只会匹配到第一个匹配上的路径, 我们在填写去除前缀的路径是相对路径,没有通配符, 因此不容出现二义性,这时候就容易出现二者不匹配, 导致构建阶段出现错误.

3. 各种的文件找不到, 路径不匹配

出现这种情况一个是不细心, 另一个就是不了解Jenkins的路径规则. 我们只需知道Jenkins在填写构建参数的时候只需要提供一个相对路径, 相对于项目的根路径! 所以项目的根路径就可以直接写为/. 对于远程服务器, 根目录就是ssh连接中设置的目录.