热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【DevOps实战系列】第八章:详解Jenkins集成Docker私服Nexus3

个人亲自录制全套DevOps系列实战教程:手把手教你玩转DevOps全栈技术Jenkins集成Docker镜像仓库docker私服已经搭建完毕,下边我们



个人亲自录制全套DevOps系列实战教程 :手把手教你玩转DevOps全栈技术


在这里插入图片描述


Jenkins集成Docker镜像仓库



docker私服已经搭建完毕,下边我们期望jenkins做的事是:


  • ①通过git拉取代码
  • ②通过maven构建生成jar包
  • ③构建含有jar包的镜像
  • ④推送到docker仓库
  • ⑤通知宿主从仓库拉取镜像并启动容器

有什么好处?避免将jar包拷贝到宿主机,而是直接将jar包打入镜像上传到私服。

为什么不是jenkins直接拉取并启动容器?从角色上看jenkins并不是docker服务,生产中多数是部署docker集群,所以拉取镜像并部署容器更应该由docker自身操作。

非要用jenkins拉取和部署可以吗?当然可以,但jenkins容器中一直只映射单个docker宿主机的docker.sock,如果是docker集群就不好解决了,比较麻烦。


Jenkins容器编排文件修改

注意:之前我们讲的都是jenkins构建完jar包后,传输到宿主机,由宿主机通过docker命令完成构建和启动容器,

此处我们期望jenkins能完成这些事,有几种方法:


  • 在jenkins中安装docker服务或安装docker cli并连接到宿主
  • 直接将宿主机的docker内核映射给jenkins容器,让jenkins能操作宿主机的docker【推荐】

# 很简单只需要将jenkins的docker-compose.yml修改一下即可
version: '3'
services:
jenkins:
build:
context: .
dockerfile: Dockerfile
image: 'lij/jenkins:2.346.3-2-lts-centos7'
restart: always
container_name: 'jenkins'
hostname: 'jenkins'
environment:
- JAVA_OPTS="-Dhudson.model.DownloadService.noSignatureCheck=true"
ports:
- '9078:8080'
- '50000:50000'
networks:
- 'exist-net-bloom'
volumes:
- '/docker/jenkins/home:/var/jenkins_home'
- '/docker/jenkins/mvnrepo:/mvnrepo'
- '/etc/timezone:/etc/timezone:ro'
- '/etc/localtime:/etc/localtime:ro'
# 新增加内容
- '/var/run/docker.sock:/var/run/docker.sock'
- '/usr/bin/docker:/usr/bin/docker'
- '/etc/docker/daemon.json:/etc/docker/daemon.json'
networks:
exist-net-bloom:
external:
name: devops

解释:/var/run/docker.sock 是docker服务器后台进程执行docker客户端命令的服务,

不论是docker cli还是对外开放的api最终都是与/var/run/docker.sock进行交互,所以把他映射到jenkins内部,jenkins就可以内部操作宿主机了。

另外还需映射docker命令(即客户端命令)和已经配置好的配置文件。

问题:更新配置后执行docker info报权限问题
在这里插入图片描述
分析:这应该是执行docker.sock的权限问题,我们进入宿主机查看docker.sock的权限
在这里插入图片描述



解决:这里有几种方式


  • 以root用户登录jenkins,我实际我们用的是jenkins用户,这样容器导致用户权限过大,不推荐


# 修改方法只需在docker-compose.yml中增加以root登录即可
user: root


  • 将宿主机的docker.sock文件的权限改为可以让jenkins的账号ID=1000的用户使用即可【推荐】
  • 这里我们粗暴些,直接777权限


# 第一种:授权777权限
chmod 777 /var/run/docker.sock
# 第二种:授权other组可读写
chmod o+rw /var/run/docker.sock



修改jenkins的job配置

当maven构建后,直接在jenkins工作目录构建镜像并推送镜像到私服

[此处我们以Nexus作为私服演示,对于大型项目harbor优势较大,成本相对也较高,比如内置数据库PostgreSQL,

而我们一般会使用公共数据库,所以至少要有一个PostgreSQL实例,等等,而Nexus就就相对简单些,也能和Maven仓库复用,成本较低]

注意:jenkins中运行shell脚本的目录是jenkins_home/workspace/jobName目录

# 注意:因为我们要构建镜像而不需要直接启动容器,所以只需要Dockerfile文件,而暂时不需要使用docker-compose.yml
# 1.构建镜像的命令,我们使用docker build,通过-t指定镜像标签,最后指定Dockerfile的目录,我们使用当前目录即可
docker build -t 10.10.1.199:9082/busybox:v-${branch} .
# 注意:jenkins中运行shell脚本当前目录是[workspace/jobName]目录
set -e \
&& mv target/*.jar docker/ \ # 拷贝jar包到docker目录
&& cd docker \
&& docker build -t demo:v-$branch . \ # 构建镜像,使用分支名作为版本号
&& docker tag demo:v-$branch 10.10.1.199:9082/demo:v-$branch \ #给镜像打标签,准备推送私服
&& docker login -u admin -p jie123456 10.10.1.199:9082 \ #登录私服hosted仓库
&& docker push 10.10.1.199:9082/demo:v-$branch \#推送镜像
#避免构建同一个镜像产生悬空镜像,假设已经执行了当前jenkins job,那么再次执行时,本地一定是拉取了镜像,所以直接构建会产生悬空镜像
&& docker image prune -f

在这里插入图片描述
问题:点击构建会报错,如下:
在这里插入图片描述
原因:就是镜像名称定义的不规范,因为我们使用的git分支名,而分支默认都是orgin/开头,而放到镜像中斜杠就不合适了,所以我们在git参数构建时,将[orgin/]过滤掉,配置如下:使用正则orgin/(.*)即可
在这里插入图片描述
再次构建,就没问题了。


宿主机拉取镜像并部署容器

解决目标:既然是jenkins通知宿主机,那么就可能是多个jenkins的job都有这种通知操作,

所以我们不能写死拉取镜像的信息,而是通过jenkins的通知将这些参数传递过来,比如拉取镜像的地址、镜像标识等,并且要处理镜像重复等问题。

思路:怎么让jenkins给宿主传参数呢?说的比较抽象,其实我们之前已经做过了,就是ssh。

jenkins的job做完构建镜像并推送后,就可以执行ssh连接宿主,然后执行脚本,而jenkins的job中可以设置变量,在执行宿主机脚本是可以直接引用过来,而这次脚本比较多,我们就不再jenkins中罗列了,而是直接写入到shell脚本,让jenkins直接调用。

脚本内容:在宿主机目录创建shell脚本, vi /share/jenkins/demo/script/publish.sh

注意:脚本权限问题,我是root创建,并且jenkins中ssh也是使用的root所以没问题,大家根据自己情况去酌情处理。

# 定义变量
repositoryUrl=$1
jobName=$2
imageVersion=$3
remoteImageName=$repositoryUrl/$jobName:$imageVersion #远程私服仓库的完整镜像名称
echo "remoteImageName is "$remoteImageName
### 检查是否存在同名镜像运行的容器,如果存在则需要先删除,然后再删除镜像,然后再拉取新镜像,最后以新镜像启动容器
#获取已启动的容器ID
containerId=$(docker ps -a | grep -w "$remoteImageName" | awk '{print $1}')
if [ "$containerId" ! = "" ]; then
docker stop $containerId && docker rm $containerId
fi
#如果镜像存在同样先删除
imageId=$(docker images | grep -w "$repositoryUrl/$jobName" | grep -w "$imageVersion" | awk '{print $3}')
if [ "$imageId" ! = "" ]; then
docker rmi -f $imageId
fi
#从私服拉取镜像:如果不允许匿名,则需要先登录,因为我已经设置允许匿名,所以可以不登录直接拉取
docker login -u admin -p 123456 $repositoryUrl
docker pull $remoteImageName
#启动容器:我们之前启动都是拿docker-compose.yml,但此时因为在宿主机,并没有这么一个docker-compose.yml文件,
#所以我们可以直接使用docker run运行容器
docker run -d \
-p 9099:8080 \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
--network devops \
--privileged=true \
--name $jobName $remoteImageName

解释:其实我们jenkins容器已经拿到宿主机的docker执行权了,那这个文件不传到宿主机执行,在本地容器执行也是可以的,但由于角色不同,该脚本由docker服务器执行更合适,并且如果是docker集群那么容器执行会很麻烦。

优化:简单起见,或者说为了隔离、可扩展,我们把这个脚本文件放到springboot中,让jenkins帮我们远程拷贝到宿主机的固定目录,然后执行

在这里插入图片描述
参数配置: 我们脚本里引用了那么几个参数,哪里来的?

jenkins我们知道可以参数化构建,比如我们用的git参数,当然他也可以指定普通参数,如下,我们在job中增加这些参数:

[当然也可以直接写到脚本执行的后边,我这里就只配一个示意一下,其他参数直接传递]
在这里插入图片描述
在这里插入图片描述







推荐阅读
  • 记一次jenkins 构建go项目经历
    记一次jenkins构建go项目经历,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Mybatis拦截器实现数据权限的示例代码
    在我们日常开发过程中,通常会涉及到数据权限问题,本文主要介绍了Mybatis拦截器实现数据权限的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的 ... [详细]
  • docker+k8s+git+jenkins
    docker+k8s+git+jenkins,Go语言社区,Golang程序员人脉社 ... [详细]
  • Jenkins教程:使用Jenkins进行持续集成
    【注】本文译自:https:www.edureka.coblogjenkins-tutorial本文将重点介绍Jenkins架构和Jenkins构建管道,并向您展示如何在Jenki ... [详细]
  • Jenkins是什么?Jenkins是一个开源软件项目百,是基于Java开发的一种持续集成(CI)工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成 ... [详细]
  • ps:本文转载于:https:www.ibm.comdeveloperworkscnjavaj-lo-git-mangeindex.htmlGit是目前最流行的源代码管理工具。大量 ... [详细]
  • 开发笔记:DevOps Gitlab环境部署
    本文由编程笔记#小编为大家整理,主要介绍了DevOpsGitlab环境部署相关的知识,希望对你有一定的参考价值。DevOps介绍 ... [详细]
  • 如果您使用的是ConnectorJ的8.x版,您可能会注意到生成器尝试为MySql信息模式(sys,information_schema,performance_schema等)中的表生成代码。 ... [详细]
  • python项目python完整项目
    广告关闭腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元ÿ ... [详细]
  • 技能速成|一文带你学会MybatisPlus
    一.MP简介我们知道,Mybatis属于一个半自动的ORM框架。之所以说Mybatis是一个半自动的ORM框架,原因是它还需要我们自己在注解或是映射文 ... [详细]
  • Azure devops更新json文件Powershell脚本
    我创建了powershell脚本来使用变量更新json文件。Json文件位于Azuredevops存储库中,json文件名为v ... [详细]
author-avatar
O依楼观雪O
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有