💯 作者: 俗世游子【谢先生】。 8年开发3年架构。专注于Java、云原生、大数据等领域技术。

💥 成就: 从CRUD入行,负责过亿级流量架构的设计和落地,解决了千万级数据治理问题。

📖 同名社区:​​51CTO​​​、 ​​github​​​、掘金​、​​gitee​​​。

📂 清单: ​​​goku-framework​​​、​【更新中】享阅读II

DevOps系列

​深入浅出DevOps:DevOps核心思想​

​深入浅出DevOps:版本控制Git&Gitlab​

​深入浅出DevOps:持续集成工具Jenkins​

​深入浅出DevOps:简易Docker入门​

​深入浅出DevOps:Jenkins实战之CI​

​深入浅出DevOps:SonarQube提升代码质量​

​深入浅出DevOps:SonarQube提升代码质量【下】​

​深入浅出DevOps:Jenkins构建器​

​深入浅出DevOps:私有镜像仓库Harbor​

有个小插曲

最近隔壁项目组发生了一件事情,让我觉得DevOps在整个项目迭代环境下变得尤为重要。事情是这样的:

本人所在公司开发的数据治理平台,为了将各个单独的系统进行统一整合,开始了一系列的改造。改造内容包括:

  • 用户中心
  • 资源管理
  • 调度平台

XXX【具体项目组不透露,已XXX代替】项目组所开发的系统由于项目负责人对工时评估不足而被迫开始了“996”的日子。

随着提测日期不断逼近,本着严谨交付的态度开始了冒烟测试,保证冒烟测试通过率达到95%之后才能上线到正式的测试环境,开始正式测试。然而搞笑的一点是:

  • 每次调整Bug之后部署因为环境的问题就需要扯很长时间

经过排查发现环境问题占了很大一部分原因。而由于历史原因,整个项目在部署的时候还使用了传统的部署方式:也就是上传jar包,通过java -jar的方式来启动。

本组也是有Jenkins的,还是没有普及开来

最近的八卦内容都已经是如下对话了:
“你们昨晚什么时候走的啊?”
“9点多快10点”


整合Harbor

系统环境是个大问题,有简单的法子不香么?

从上节使用Harbor的过程中我们已经明白,如果想要将镜像推送到仓库中需要使用到docker命令,但是由于我们采用Docker部署的Jenkins服务,且在Jenkins容器内部无法使用docker命令。

我们当然不会去修改Jenkins镜像,那么我们只有一个办法:

  • 使用宿主机本身安装的Docker来操作

配置docker.sock的权限

那么我们之前安装Jenkins的方式就需要做一个调整,让Jenkins容器内部挂载本地Docker指令,接下来注意我的操作

深入浅出DevOps:Jenkins基于Harbor部署_Harbor

首先我们要先对​​docker.sock​​进行下手

/var/run/docker.sock是docker daemon监听的套接字socket(ip+port),容器中的进程可以通过它与docker daemon通信。
而如果容器内有docker文件,那么在容器内执行docker ps、docker port这些命令,和在宿主机上执行的效果是一样的,因为它们的请求发往的是同一个docker daemon;

那么,我们了解到它的重要性之后,我们需要将它挂载到容器内部,先来调整一下权限

chown root:root /var/run/docker.sock
chmod o+rw /var/run/docker.sock

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins整合Harbor_02

除此之外,还需要使用到​​/usr/bin/docker​​,这属于docker的客户端程序,并且为了不在容器内部额外配置docker,那么我们还需要将​​/etc/docker/daemon.json​​也挂载到容器内部

也就是说在Jenkins内部使用Docker程序,最少需要挂载三个成员

  • /var/run/docker.sock
  • /usr/bin/docker
  • /etc/docker/daemon.json

重新定义Jenkins容器

完成之后就需要处理Jenkins,将其挂载定义到​​volumes​​下

version: "3"
services:
jenkins:
image: jenkins/jenkins:2.332.1-lts
container_name: jenkins
user: root
restart: always
privileged: true
ports:
- 8080:8080
- 50000:50000
volumes:
- /opt/jenkins/:/var/jenkins_home/
- /usr/bin/docker:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
- /etc/docker/daemon.json:/etc/docker/daemon.json

理论上可以通过设置 ​​user:root​​ 来保证Jenkins容器内部能够永久使用宿主机docker

建议:在宿主机重新添加一个用户,并且将当前归到docker分组中

按道理这样就已经完成了,但是这里会有一个坑,我们先买个关子,先来重新创建Jenkins容器

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins_03

能够看到是已经启动成功的,但是细心的同学会发现,在容器内执行docker命令的时候会出现划线的错误,但是我们在宿主机上执行docker命令并没有这样的问题,很是奇怪对不对。

QA、【libltdl.so.7:No such file or directory】

这主要是因为宿主机上存在​​libltdl.so.7​​,但是在Jenkins容器内部并没有,所以这里我们还是将其挂载到容器中

如果大家百度的话会发现网上有很多帖子会教大家通过Dockerfile的方式重写Jenkins镜像,当然也是一种方式。大家喜欢就好

大家在挂载这个文件的时候需要注意:

  • 确定宿主机器中libltdl.so.7的位置

由于宿主机系统不同,个别系统当前文件会在​​/usr/lib/x86_64-linux-gnu/libltdl.so.7​​下,那么在容器挂载文件的时候就直接挂载这个目录就可以

- /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7

本人用的是CentOS7 x86_64的系统,libltdl.so.7这个文件在/usr/lib64下,但是在挂载的时候也必须挂载到容器内部的/usr/lib/x86_64-linux-gnu/libltdl.so.7下,不然还是找不到,防止执行出现问题

- /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7

所以这个问题需要大家根据自己的系统情况按需作出调整

接下来我们来看看改动之后的效果

深入浅出DevOps:Jenkins基于Harbor部署_Harbor_04

出现如下效果就说明整合已经成功,接下来我们就来改进Jenkins任务

改造Jenkins任务

之前我们构建任务的流程是这样的:

  • 调用顶层Maven目标,通过maven进行项目构建
  • 通过SonarQube进行代码质量检测
  • 在构建后操作中,通过SSH的插件将编译好的依赖包推送到指定的服务器上
  • 随后执行docker命令进行脚本的构建

这里的改造主要在最后两步上,我们一一来看

构建:执行shell命令

既然需要执行shell命令,那么我们通过添加构建步骤,选择执行shell即可,随后将我们的脚本放到输入框中

cd module01
docker build -t ${JOB_NAME}:v0.0.${BUILD_NUMBER} .
docker tag ${JOB_NAME}:v0.0.${BUILD_NUMBER} 192.168.10.201/presentation/${JOB_NAME}:v0.0.${BUILD_NUMBER}

docker login -u admin -p Harbor12345 192.168.10.201
docker push 192.168.10.201/presentation/${JOB_NAME}:v0.0.${BUILD_NUMBER}

深入浅出DevOps:Jenkins基于Harbor部署_Harbor_05

以上命令都是我们所熟悉的指令,但是这里我们 需要注意第一行​​cd module01​​,我来解释一下为什么要加这一行

先来看一下本人当前任务的工作空间

深入浅出DevOps:Jenkins基于Harbor部署_Harbor_06

默认情况下Jenkins所在目录和Gitlab仓库上项目的位置是一致的,如果当前项目为单体项目,在执行脚本的时候去掉第一行的​​cd​​命令。

如果大家的项目和本人演示的一样属于多模块项目的话,那么我们在执行shell脚本的时候需要根据模块项目进入到对应的目录下

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins整合Harbor_07

只有目录下才有我们所需要的文件。这是大家需要注意的一个方面

我们改造一步看一下效果,点击Build进行项目构建,只要在控制台日志中能够发现如下的日志,说明整个改造是成功的

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins整合Harbor_08

接下来我们进入到Harbor中查看是否在仓库中已经存在当前镜像

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins_09

第一步改造完美收工


构建后步骤:在201机器上运行镜像

上面只改造了百分之五十,接下来我们看另外的百分之五十。

推送到仓库之后,肯定是要其他服务器将镜像拉取下来,通过该镜像创建容器运行服务的。都到了这一步了不可能再去人工执行的。

手动是不可能的,这辈子都不可能手动的

那接下来我们还是需要用到Publish Over SSH插件,不需要推送任何文件,只需要在远程服务器上执行命令就好

还记的​​Exec command​​内输入的内容是啥吧,将其改成下面执行的命令

docker pull 192.168.10.201/presentation/${JOB_NAME}:v0.0.${BUILD_NUMBER}
docker container stop ${JOB_NAME} && docker container rm ${JOB_NAME}
docker run -d -p ${port}:8080 --name ${JOB_NAME} 192.168.10.201/presentation/${JOB_NAME}:v0.0.${BUILD_NUMBER}

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins_10

是不是非常神奇,当然了如果想要更加方便的一次性实现拉取镜像和启动的命令,还是推荐采用脚本文件的方式。

各位大神们就自己去发挥吧

我们来看一下最终的执行效果

深入浅出DevOps:Jenkins基于Harbor部署_Jenkins整合Harbor_11

剩下的百分之五十完美完成

最后

整个过程非常简单,只需要两部即可完成整个改造过程。

建议大家手动来尝试下,毕竟我看了!= 我会了,大家觉得呢!!!