? 知识点概览
为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。
本章节为【学成在线】项目的 day20
的内容。
- 原讲义中对该章节的
gitlab
与jenkins
安装步骤以及部署容器的内容和步骤描述得不够详细,在本文中做出了补充,详细的描述每个步骤。 - 本章节建议还是尝试看笔记来完成一次操作,然后再去看视频资料,这样能理解得更深刻。
目录
内容会比较多,可以根据目录进行按需查阅。
文章目录
- ? 知识点概览
- 目录
- 一、DevOps介绍
- 二、使用GitLab管理项目
- 0x01 安装Gitlab
- 0x02 创建项目
- 0x03 将项目推送至gitlab
- 三、部署微服务到Docker
- 0x00 Docker简介
- 0x01 安装docker
- 0x02 部署流程
- 0x03 打包
- 0x04 创建镜像
- 0x05 创建容器
- 0x06 启动容器
- 0x07 停止与删除
- 0x08 maven构建镜像
- 四、持续集成
- 0x01 持续集成介绍
- 需求分析
- 什么是持续集成?
- 本项目持续集成流程
- 0x02 搭建环境
- 安装Jenkins
- 1、使用Docker安装Jenkins
- 2、配置 SSH Remote Hosts
- 搭建Docker私有仓库
- 安装Gitlab
- 编写pom
- 0x03 创建持续集成任务
- 创建jenkins的构建任务
- 配置git仓库
- 配置自动构建流程
- **1、停止容器、删除容器、删除镜像**
- 2、配置maven步骤
- 3、配置docker步骤
- 执行任务
- 使用Gitlab通知Jenkins进行自动部署
- 1、安装gitlab hook插件
- 2、配置webhook
- 3、测试
- 0x04 思考一些问题
- 1、如何实现自动构建指定的服务工程?
- 需求分析
- 实现思路
- ? 认识作者
一、DevOps介绍
DevOps 是 Development
和 Operations
两个词的缩写,引用百度百科的定义:
DevOps
是一种方法或理念,它涵盖开发、测试、运维的整个过程。DevOps
是提高软件开发、测试、运维、运营等各部门的沟通与协作质量的方法和过程,DevOps
强调软件开发人员与软件测试、软件运维、质量保障(QA)部门之间有效的沟通与协作,强调通过自动化的方法去管理软件变更、软件集成,使软件从构建到测试、发布更加快捷、可靠,最终按时交付软件。
DevOps
兴起于2009年,近年来由于云计算、互联网的发展,促进了DevOps的基础设施及工具链的发展,涌现了一大批优秀的工具,这些工具包括开发、测试、运维的各各领域,例如:GitHub、Git/SVN、Docker、Jenkins、Hudson、Ant/Maven/Gradle、Selenium、QUnit、JMeter 等。下图是DevOps相关的工具集:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6TrNCM8J-1595704048578)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image3.png)]
二、使用GitLab管理项目
0x01 安装Gitlab
GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
GitLab 与 GitHub的功能相似,通常企业使用GitLab在局域网搭建自己的Git代码管理仓库
拉取gitlab、redis、postgresql,gitlab
依赖 redis
和 postgresql
。
sudo docker pull sameersbn/redis
sudo docker pull sameersbn/postgresql
sudo docker pull gitlab/gitlab-ce:latest
新建容器的目录
sudo mkdir /var/docker/postgresql/data -p
sudo mkdir /var/docker/redis/data -p
sudo mkdir /var/docker/gitlab/data -p
创建 postgresql、redis 容器:
# 创建postgresql容器
sudo docker run --name postgresql -d --privileged=true -e 'DB_NAME=gitlabhq_production' -e 'DB_USER=gitlab' -e 'DB_PASS=123123' -e 'DB_EXTENSION=pg_trgm' -v /var/docker/postgresql/data:/var/lib/postgresql sameersbn/postgresql# 创建redis容器
sudo docker run --name redis -d --privileged=true -v /var/docker/redis/data:/var/lib/redissameersbn/redis
创建gitlab容器:
sudo docker run --name gitlab -d --link postgresql:postgresql --link redis:redisio \
--hostname 10.1.1.161 -p 10022:22 -p 8910:80 -p 8911:443 -e 'GITLAB_PORT=8899' \
-e 'GITLAB_SSH_PORT=10022' \
-e 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' \
-e 'GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alpha-numeric-string' \
-e 'GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alpha-numeric-string' \
-e 'GITLAB_HOST=10.1.1.161' \
-e 'SMTP_AUTHENTICATION=login' \
-v /var/docker/gitlab/data:/home/git/data docker.io/gitlab/gitlab-ce
- 使用 \ 来标识shell命令的换行,在shell命令过长的情况下使用 \ 换行可以使内容更加清晰
- –link:可以用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量
浏览器访问:http://10.1.1.161:8910
初次访问需要等待一段时间。
查看 gitlab的启动日志
sudo docker logs -f gitlab
启动完成后,配置初始密码,默认用户名为 root
0x02 创建项目
登录 gitlab 后访问 http://10.1.1.161:8910/projects/new
填写项目的基本信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bqvoUHne-1595704048584)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image6.png)]
项目构建成功后,得到一个项目的链接 http://10.1.1.161:8910/root/xc-services-project
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hyk0NvRT-1595704048585)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image7.png)]
0x03 将项目推送至gitlab
打开 cmd,进入到项目的目录下
1、运行 git init
初始化项目的git配置
2、在项目根目录下创建 .gitignore
文件,将一些编译后生成的文件排除在外 不上传至git仓库,内容如下
.idea
*/target/*.*
*/target/**/*.*
*.class
*.iml
##ignore this file##
.classpath
.project
.settings
##filter databfile、sln file##
*.mdb
*.ldb
*.sln
##class file##
*.com
*.class
*.dll
*.exe
*.o
*.so
# compression file
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
*.via
*.tmp
*.err
# OS generated files #
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
3、执行 git add .
命令,暂存当前目录下的所有子目录以及文件到git记录
4、执行 git commit -m "第一次提交"
将暂存的记录正式提交到 git
记录内,-m 参数的内容为描述信息
5、执行以下命令,设置远程仓库的地址
git remote add origin "http://10.1.1.161:8910/root/xc-services-project.git"
6、执行 git push origin master
推送代码到远程仓库
推送成功,查看远程仓库
三、部署微服务到Docker
0x00 Docker简介
服务器虚拟化主要有两种技术:
1、Hypervisor也叫VMM(virtual machine monitor)即虚拟机监视器
Hypervisor
是一种将操作系统与硬件抽象分离的方法,实现在宿主机(host machine)上能同时运行多个客户机(guest machine),每个客户机就是一个虚拟机,这些虚拟机高效地分享宿主机的硬件资源。
如下图:
在服务器(宿主机)上安装操作系统,并安装hypervisor虚拟机管理软件,如VMware、VirtualBox等,由
hypervisor管理多个虚拟机,每个虚拟机上需要安装客户操作系统、依赖库、应用软件。
2、Containers容器化技术
容器技术中 docker
引擎取代了 hypervisor
,docker引擎是运行在住宿操作系统上的一个进程,该进程管理了多个docker容器,每个docker容器集成了应用软件、依赖库,容器之间相互隔离。
3、技术对比
资源占用:
虚拟机由于是独立的操作系统,占用资源比docker多。
启动速度:
虚拟机包括操作系统,启动虚拟机相当于启动一个操作系统,容器则不一样,容器中只包括操作系统的内核,启动
一个容器实例相当于启动一个进程,容器的启动速度比虚拟机快。
体积:
容器包括操作系统内核、软件及依赖库,虚拟机不仅包括软件和依赖库还将完整的操作系统打包进去,虚拟机的体
积比容器大的多。
4、Docker 容器架构
-
Docker daemon(Docker守护进程)
Docker守护进程是部署在操作系统上,负责支撑
Docker Container
的运行以及本地Image
的管理。 -
Docker client
用户不直接操作Docker daemon,用户通过
Docker client
访问Docker
,Docker client
提供
pull、run 等操作命令实现对docker的操作。 -
Docker Image
Docker 镜像就是一个只读的模板。 例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Tomcat或用户需要的其它应用程序。 镜像可以用来创建 Docker 容器。 Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
-
Docker Container
Docker 利用容器来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停
止、删除。每个容器都是相互隔离的、保证安全的平台。打个比方,镜像相当于类,容器相当于对象。 -
Docker Registry
Docker 仓库分为公开仓库(Public)和私有仓库(Private)两种形式 最大的公开仓库是
Docker Hub,存放了数量庞大的镜像供用户下载。 用户也可以在本地网络内创建一个私有仓库。 当用户创建自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
0x01 安装docker
Docker 可以运行在 MAC、Windows、Centos、DEBIAN、UBUNTU 等操作系统上,提供社区版和企业版,本教程基于Centos安装Docker。Centos6
对 docker 支持的不好,使用 docker
时建议升级到 centos7
。
1、在 Centos7 上安装Docker
直接通过yum安装即可:
yum install -y docker
启动docker:service docker start
查询docker版本: docker version
关于的 docker
的一些常用的命令和操作,参考 https://www.runoob.com/docker/docker-tutorial.html
0x02 部署流程
本项目微服务采用 SpringBoot
开发,将每个微服务工程打成Jar
包,最终在 Docker
容器中运行 jar
,部署流程如下:
1、SpringBoot 工程最终打成 Jar
包
2、创建Docker镜像
3、创建容器
4、启动容器
0x03 打包
1、使用 maven 的打包插件:
将下边的插件依赖拷贝到微服务工程中,本例子将学成在线的 Eureka
工程打包:
<build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
完整的 Eureka
工程 pom.xml
文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>xc-framework-parent</artifactId><groupId>com.xuecheng</groupId><version>1.0-SNAPSHOT</version><relativePath>../xc-framework-parent/pom.xml</relativePath></parent><modelVersion>4.0.0</modelVersion><artifactId>xc-govern-center</artifactId><dependencies><!-- 导入Eureka服务的依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
2、maven打包
在工程目录运行:mvn clear package
或通过IDEA执行 clear package
打包命令。
打包成功,如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2vRyWO0c-1595704048590)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image13.png)]
打包成功后在 target
目录下生成一个 jar包
0x04 创建镜像
将上一步打包好的 jar
包拷贝到我们要部署微服务的Linux服务器,准备创建镜像。
安装jdk环境
sudo apt-get install openjdk-8-jdk
测试 jar 包是否可以运行,执行:java -jar xc-govern-center-1.0-SNAPSHOT.jar
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8HIyv28S-1595704048591)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image14.png)]
访问服务器地址 http://10.1.1.162:50101/
注意我这里的虚拟机IP地址为 10.1.1.162 ,测试的时候要更换你虚拟机的地址
在 jar
包的目录下编写 Dockerfile
文件,执行 vim Dockerfile
FROM java:8
ENV ARTIFACTID xc-govern-center
ENV ARTIFACTVERSION 1.0-SNAPSHOT
ENV HOME_PATH /home
WORKDIR $HOME_PATH
ADD $ARTIFACTID-$ARTIFACTVERSION.jar $HOME_PATH/$ARTIFACTID.jar
ENTRYPOINT ["java", "-jar", "xc-govern-center.jar"]
dockerfile说明文档: https://www.runoob.com/docker/docker-dockerfile.html
在 Dockerfile 文件所在目录执行以下命令
docker build -t xc-govern-center:1.0-SNAPSHOT .
镜像创建成功,查询镜像
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HiSGkdKl-1595704048593)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image16.png)]
0x05 创建容器
基于前面我们生成的xc-govern-center:1.0-SNAPSHOT
镜像创建容器,容器名称为 xc-govern-center-test
docker create --name xc-govern-center-test -t -p 50101:50101 -e PORT=50101 \
-e EUREKA_SERVER=http://10.1.1.162:50101/eureka/,http://10.1.1.162:50102/eureka/ xc-govern-center:1.0-SNAPSHOT
docker create 语法 与 run 相同,create表示只创建不运行,而run是创建容器后并马上运行。
run命令说明文档 https://www.runoob.com/docker/docker-run-command.html
EUREKA_SERVER 为一个变量,用于服务启动时指定的 eureka
负载均衡到哪些 eureka
服务上,跟我们在 idea
的配置是一个道理,如下图
容器创建成功后会回显一个容器的id,可通过 docker ps -a
命令看到该容器的信息
0x06 启动容器
运行以下命令,启动容器
docker start xc-govern-center-test
容器启动完成可以通过 docker ps
查询正在运行中的容器。
测试访问
使用 docker logs -f xc-govern-center-test
可以查看容器的运行日志
这里报错是因为我们做了负载均衡,两个 eureka 需要相互注册,但这里我们只启动了一个 eureka 服务,但不影响正常使用。
0x07 停止与删除
要删除的一个镜像重新创建,需要通过如下步骤:
1、停止正在运行的容器
docker stop 容器名
例如:docker stop xc-govern-center-test
2、删除容器
docker rm 容器名
例如:docker rm xc-govern-center-test
3、删除镜像
docker rmi 镜像名或镜像Id
例如:docker rmi xc-govern-center:1.0-SNAPSHOT
0x08 maven构建镜像
上边构建的过程是通过手工一步一步完成,maven
提供 docker-maven-plugin
插件可完成从打包到构建镜像、构建容器等过程。
1、将服务工程的 pom.xml
复制一份,命名为 pom_docker.xml
并将 build
标签的内容替换下面的内容
<build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.0.0</version><!--docker镜像相关的配置信息--><configuration><!--镜像名,这里用工程名--><imageName>${project.artifactId}-${project.version}</imageName><!--Dockerfile文件所在目录--><dockerDirectory>${project.basedir}/src/main/resources</dockerDirectory><!--TAG,这里用工程版本号--><imageTags><imageTag>${project.version}</imageTag></imageTags><imageName>${project.artifactId}:${project.version}</imageName><!--构建镜像的配置信息--><resources><resource><targetPath>/</targetPath><directory>${project.build.directory}</directory><include>${project.artifactId}-${project.version}.jar</include></resource></resources></configuration></plugin></plugins>
</build>
2、将 Dockerfile 文件拷贝到 src/main/resources
下
3、将更新的内容提交到gitlab,并在服务器内拉取项目代码到本地
提交并推送新增的配置到远程仓库
在服务器内拉取项目代码到本地
4、删除之前创建的 xc-govern-center
镜像
# 停止容器
sudo docker stop xc-govern-center-test
# 删除容器
sudo docker rm xc-govern-center-test
# 删除镜像
sudo docker rmi xc-govern-center:1.0-SNAPSHOT
5、进入工程根目录( pom_docker.xml
所在目录)执行
安装 maven 环境
sudo apt install maven
添加 maven 仓库国内源以及配置 pluginGroup
,编辑 /usr/share/maven/conf/settings.xml
文件
在 mirrors
标签下添加如下内容
<mirror><id>aliyun-public</id><mirrorOf>*</mirrorOf><name>aliyun public</name><url>https://maven.aliyun.com/repository/public</url>
</mirror>
在 pluginGroups
标签下加入以下内容
<pluginGroup>com.spotify</pluginGroup>
如下图所示
给项目的目录设置权限,否则打包的时候会报错
sudo chown -R 1000:1000 ~/xc-services/
进入到 eureka 工程下,执行打包命令
mvn -f pom_docker.xml clean package -DskipTests docker:build
等待依赖下载完成后开始构建镜像,创建镜像成功,结果如下:
使用该镜像创建容器
docker create --name xc-govern-center-test -t -p 50101:50101 -e PORT=50101 \
-e EUREKA_SERVER=http://10.1.1.162:50101/eureka/,http://10.1.1.162:50102/eureka/ xc-govern-center:1.0-SNAPSHOT
容器创建成功
四、持续集成
0x01 持续集成介绍
需求分析
传统的软件开发流程如下:
1、项目经理分配模块给开发人员
2、每个模块的开发人员并行开发,并进行单元测试
3、开发完毕,将代码集成部署到测试服务器,测试人员进行测试。
4、测试人员发现bug,提交bug、开发人员修改bug
5、bug修改完毕再次集成、测试。
有哪些问题?
1、模块之间依赖关系复杂,在集成时发现大量bug
2、测试人员等待测试时间过长
3、软件交付无法保障
解决上述问题的思考:
1、能否把集成测试时间提前?
2、能否使用自动化工具代替人工集成部署的过程?
什么是持续集成?
持续集成(Continuous integration)简称 CI
,持续集成的思想是每天要多次将代码合并到主干,并进行集成、测试,这样就可以提早发现错误,进行修正。持久集成也属于 DevOps
持续集成的好处:
1、自动化集成部署,提高了集成效率。
2、更快的修复问题。
3、更快的进行交付。
4、提高了产品质量。
本项目持续集成流程
0x02 搭建环境
安装Jenkins
Jenkins是一个领先的开源自动化服务器,可用于自动化构建,测试,部署软件等相关任务。
官网地址:https://jenkins.io
1、使用Docker安装Jenkins
本教程在 docker
下安装 Jenkins
:
拉取镜像
docker pull jenkinsci/blueocean
创建容器挂载目录,并且赋予权限
mkdir /var/docker/jenkins -p
sudo chown -R 1000:1000 /var/docker/jenkins # 这里需要为jenkins的目录赋予1000权限
注意:在安装jenkins时候,挂在文件夹
/var/docker/jenkins
的归属用户id必须是1000,否则会抛出无操作权限异常。
创建容器:
docker run -itd --name jenkins -u root -p 8900:8080 --privileged=true \
-v /var/docker/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/jenkins:/home docker.io/jenkinsci/blueocean
docker run 创建容器并且运行
docker create 只创建而不运行
访问你虚拟机的 8900
端口,我这里的地址为 http://10.1.1.161:8900
初次运行 Jenkins
会经过一个安装过程,一般情况使用默认配置,下一步安装即可,其中一步需要输入密码,如下图
出现上边的画面需要输入 jenkins 的初始密码,查看容器的运行日志,从日志中找到初始里面
sudo docker logs -f jenkins
日志如下图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMwsuBTv-1595704048607)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image31.png)]
日志中没有找到初始密码?我们可以直接在该容器挂载到本地目录的文件下查看。
这里我们在创建容器时指定了 -v /var/docker/jenkins:/var/jenkins_home
,表示将 /var/docker/jenkins
目录映射到 jenkins
容器上的 /var/jenkins_home
目录上,所以我们可以直接在本地执行如下命令,查看 jenkins
的初始密码
cat /var/docker/jenkins/secrets/initialAdminPassword
初始密码如下
输入初始密码到 jenkins 页面后,继续完成后续的初始化步骤。
如果出现一直停留在在 ready
页面,如下图
修改 jenkins 的配置文件 hudson.model.UpdateCenter.xml
将 url 修改为国内的 jenkins
源
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
运行以下命令,并替换url标签内值为上述地址
vim /var/docker/jenkins/hudson.model.UpdateCenter.xml
输入密码后进入到插件安装页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gPNC5py8-1595704048611)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image35.png)]
如果愿意等的话,可以选择第一个安装所有默认推荐的插件,但是大概需要1小时左右才能安装完成。
为了节省时间我们可以选择第二个,取消默认选择的插件,然后继续下一步操作。
如果选择了安装推荐,则需要等待插件安装完成,如下图
插件安装完成后,设置管理员信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-od5JIoWy-1595704048612)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image37.png)]
本项目使用 Jenkins
需要配置Jdk1.8、Git、maven。
1)Maven 安装:
到官网下载最新版的maven http://maven.apache.org/download.cgi
解压 maven
压缩包到容器的挂载目录下
tar zxvf apache-maven-3.6.3-bin.tar.gz -C /var/docker/jenkins/lib/
在控制台 Global Tool Configuration
配置maven路径为容器内的目录 /var/jenkins_home/lib/apache-maven-3.6.3/
2)Jdk安装配置
如果jenkins镜像里面有该环境则不需要再安装
宿主机安装java
sudo apt-get install openjdk-8-jdk
拷贝本地 JDK
环境到 jenkins
容器的挂载目录的 lib 目录下
mkdir -p /var/docker/jenkins/lib/java-1.8.0-openjdk-amd64 && cp -r /usr/lib/jvm/java-1.8.0-openjdk-amd64/* /var/docker/jenkins/lib/java-1.8.0-openjdk-amd64
在 jenkins 设置 jdk的路径为 /var/jenkins_home/lib/java-1.8.0-openjdk-amd64
,该路径为容器里面的路径
3)Git安装方法同上
如果jenkins镜像里面有该环境则不需要再安装
宿主机安装git
apt-get install git
复制git到容器挂载的目录下
mkdir /var/docker/jenkins/lib/git && cp -r /usr/lib/git-core/* /var/docker/jenkins/lib/git
在 jenkins
控制台上配置容器中的 git 文件的路径 /var/jenkins_home/lib/git/git
2、配置 SSH Remote Hosts
SSH remote hosts 是 Jenkins
提供的一种远程访问 ssh
服务器的方法,通过如下步骤测试此功能:
1)安装插件SSH plugin
访问虚拟机的地址 http://10.1.1.161:8900/pluginManager/
从可选插件中选择SSH Plugin进行安装
安装成功可在已安装插件中查询:
2)配置凭证
访问虚拟机 http://10.1.1.161:8900/credentials/store/system/domain/_/newCredentials
配置部署服务的虚拟机的 SSH
登录账号和密码:
3)配置SSH sites
访问 http://10.1.1.161:8900/configure
找到 ssh sites 的配置,输入你要远程配置的服务器 IP
和 端口
等信息,并选择你刚才添加的凭证信息。
4)在任务构建中编写脚本
下拉到 “构建” 的选项,选择 Execute shell
的选项
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixJmgPK0-1595704048621)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image45.png)]
选择刚才添加的 ssh sites, 填写你要执行的shell命令,然后保存
点击保存后,点击左边的立即构建,测试是否能够执行 shell 命令到指定的服务器上。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anFVLA7g-1595704048623)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image47.png)]
远程命令执行成功,执行了 echo
命令写入内容到文件上,如下图
搭建Docker私有仓库
微服务的镜像会上传到 Docker
仓库保存,常用的公网 Docker
仓库有阿里云,网易云等,在企业局域网也可以搭建自己的 Docker
私有仓库,本教程使用 Docker 提供的私有仓库 registry
。
进入 Docker 私有仓库所在服务器执行:
1、安装 Docker
2、创建私有仓库容器
sudo docker run --name docker-registry -d -p 5000:5000 registry
执行结果如下:
上边显示 registry
镜像已经创建,并且 docker-registry
容器已经启动成功。
访问:http://10.1.1.161:5000/v2/_catalog
响应结果如下:
{"repositories":[]}
上边的响应结果说明在 docker
私有仓库中还没有镜像。
默认 docker-registry 只允许 https 提交镜像,如下配置使 docker-registry
支持 http
在宿主机 /etc/docker
下,创建 daemon.json
文件,写入:
{"insecure-registries":["10.1.1.161:5000"]
}
重启 docker:
systemctl restart docker.service
启动 docker-registry
sudo docker start docker-registry
安装Gitlab
由于前面的内容就已经需要用到 gitlab
,所以在本文开始的内容中已经介绍了整个 gitlab
安装部署流程
编写pom
本例子将 xc-govern-center
工程使用 Jenkins
进行构建。
在 xc-govern-center 工程根目录编写 pom_docker_registry.xml
此文件相比工程原有 pom_docker.xml
增加了docker-maven-plugin
插件,其作用是构建docker镜像并将镜像推送到 Docker
私有仓库,我的docker仓库地址是 10.1.1.161:5000
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>xc-framework-parent</artifactId><groupId>com.xuecheng</groupId><version>1.0-SNAPSHOT</version><relativePath>../xc-framework-parent/pom.xml</relativePath></parent><modelVersion>4.0.0</modelVersion><groupId>com.xuecheng</groupId><artifactId>xc-govern-center</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.0.0</version><!--docker镜像相关的配置信息--><configuration><!--镜像名,这里用工程名--><imageName>${project.artifactId}-${project.version}</imageName><!--Dockerfile文件所在目录--><dockerDirectory>${project.basedir}/src/main/resources</dockerDirectory><!--TAG,这里用工程版本号--><imageTags><imageTag>${project.version}</imageTag></imageTags><!--私有docker仓库地址--><registryUrl>10.1.1.161:5000</registryUrl><pushImage>true</pushImage><!--构建后的镜像名称--><imageName>10.1.1.161:5000/${project.artifactId}:${project.version}</imageName><!--构建镜像的配置信息--><resources><resource><targetPath>/</targetPath><directory>${project.build.directory}</directory><include>${project.artifactId}-${project.version}.jar</include></resource></resources></configuration></plugin></plugins></build>
</project>
稍后我们结合 jenkins
来进行自动构建。
0x03 创建持续集成任务
创建jenkins的构建任务
新建一个任务 xc-edu,选择 “构建一个自由风格的软件项目” ,点击确定
配置git仓库
1、配置git凭证
此凭证用于远程从 git
仓库克隆工程源代码
输入 git
仓库的账号和密码,这里如果使用码云,下边需要配置码云的账号和密码。
访问 http://10.1.1.161:8900/credentials/store/system/domain/_/newCredentials
2、在刚才我们新建的 xc-edu
任务下配置 git
仓库地址,此地址即 xc-edu
项目的地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJ1noTuS-1595704048629)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image52.png)]
配置自动构建流程
实现目标:
使用 jenkins
重复构建不要产生重复镜像
使用 jenkins
停止容器、删除容器、删除镜像之间进行判断
构建过程分为三步:
本例子以构建 xc-govern-center
工程为例,其它工程构建方式类似。
1、停止容器、删除容器、删除镜像
shell脚本如下:
#!/bin/bash
result=$(docker ps | grep "192.168.101.64:5000/xc-govern-center")
if [[ "$result" != "" ]]
then
echo "stop xc-govern-center"
sudo docker stop xc-govern-center
fi
result1=$(docker ps -a | grep "192.168.101.64:5000/xc-govern-center")
if [[ "$result1" != "" ]]
then
echo "rm xc-govern-center"
sudo docker rm xc-govern-center
fi
result2=$(docker images | grep "192.168.101.64:5000/xc-govern-center")
if [[ "$result2" != "" ]]
then
echo "192.168.101.64:5000/xc-govern-center:1.0-SNAPSHOT"
sudo docker rmi 192.168.101.64:5000/xc-govern-center:1.0-SNAPSHOT
fi
检查指定镜像是否有容器在运行,有则停止容器
检查指定镜像是否创建了容器,有则删除容器
检查是否存在指定镜像,存在则删除该镜像
添加一个构建步骤
选择我们的服务器地址,将脚本内容复制 command
中,作为第一步需要执行的内容
注意,如果在jenkins远程执行的 SSH凭证
非 root
用户,需要在远程服务器上执行以下命令,将当前用户加入到 docker
组内
sudo usermod -aG docker $USER
2、配置maven步骤
添加一个构建步骤,选择 调用顶层maven目标,如下图
配置第二步,执行如下maven指令
clean package -f xc-govern-center/pom_docker_registry.xml -DskipTests docker:build
如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrldNwjO-1595704048633)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image56.png)]
3、配置docker步骤
继续添加一个执行 shell
的构建步骤
配置第三步,从 docker
私有仓库拉取镜像并创建容器,启动容器
# 如果指定容器容器不存在则拉取后再进行创建,并且创建后自动执行
docker run --name xc-govern-center -p 50101:50101 -idt 10.1.1.161:5000/xc-govern-center:1.0-SNAPSHOT
docker logs xc-govern-center
注意使用log输出容器启动状态时不要加-f参数,否则会一直输出容器日志,导致任务一直处于构建中。c
如下图
添加完第三步后,点击保存
执行任务
1、进入任务页面,点击 “立即构建”
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BlRlDY6Q-1595704048637)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image59.png)]
2、开始构建,查看日志
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJNxUDwA-1595704048638)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image60.png)]
构建成功,如上图所示。
使用Gitlab通知Jenkins进行自动部署
1、安装gitlab hook插件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AN363c9Z-1595704048639)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image61.png)]
2、配置webhook
GitLab 中使用 webhook
向 jenkins
通知,当有代码 push 后将通知 jenkins
进行构建。
1、新建一个任务 “xc-edu”,在 Jenkins 中找到通知地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aF0JAyC3-1595704048640)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image62.png)]
2、进入Jenkins设置允许匿名访问jenkins,这样 GitLab
才能访问通知地址去通知 Jenkins
进行工作
进入到配置页面 http://10.1.1.161:8900/configure ,取消认证的勾选,认证默认是开启的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PrDEL1rz-1595704048642)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image63.png)]
3、使用管理员帐号 root 登录 Gitlab
,密码就是你 gitlab
搭建好之后第一次输入的密码,设置允许请求本地网络服务
4、设置钩子地址,即 jenkins
中的项目地址
访问项目的配置地址 http://10.1.1.161:8910/root/xc-services-project/-/settings/integrations
点击开启webhooks
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xo3ItdMl-1595704048645)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image65.png)]
将 jenkins
的触发地址设置到 gitlab
的 webhooks
地址中 ,点击最下面的添加即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LoJvNQCj-1595704048646)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image66.png)]
如果出现添加失败,并且显示如下错误
参考 https://blog.csdn.net/anqixiang/article/details/104968469 即可解决,并添加webhooks的白名单
由于webhooks的钩子是允许匿名访问的,建议还是设置白名单来提高安全性
配置完成后再回到之前的操作,添加webhooks的钩子地址即可,添加成功的效果如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TiPIm4nS-1595704048648)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image69.png)]
3、测试
尝试提交一个代码更新,观察jenkins是否能够收到通知并且执行构建任务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CQJOb90q-1595704048649)(https://qnoss.codeyee.com/20200704_5b6u5pyN5YqhW+WtpuaIkOWcqOe6v10gZGF5MjAtMe+8mkRldk9wcyDpobnnm67pg6jnvbLkuI7mjIHnu63pm4bmiJA=/image70.png)]
jenkins开始自动构建
构建成功,并自动启动容器
0x04 思考一些问题
1、如何实现自动构建指定的服务工程?
需求分析
例如我们在整个微服务项目当中有A、B、C三个服务,在代码更新时只更新了 服务A
相关的代码,而 jenkins
进行自动部署的时候,只需要部署 服务A
的代码即可。
实现思路
Comment (regex) for triggering a build
不可用,该选项只匹配merge request
的 commit- Gitlab 在同一个项目里面是否能够添加多个jenkins任务钩子?如何在gitlab上实现按需通知
? 认识作者
作者:? LCyee ,全干型代码?
自建博客:https://www.codeyee.com
记录学习以及项目开发过程中的笔记与心得,记录认知迭代的过程,分享想法与观点。
CSDN 博客:https://blog.csdn.net/codeyee
记录和分享一些开发过程中遇到的问题以及解决的思路。
欢迎加入微服务练习生的队伍,一起交流项目学习过程中的一些问题、分享学习心得等,不定期组织一起刷题、刷项目,共同见证成长。