Docker+Jenkins实现自动化部署小结
- 一、前言
- 二、准备
- 2.1 采用技术栈
- 2.2 工作空间目录结构
- 三、安装Docker
- 3.1 Docker本体安装
- 3.2 容器编排工具Docker-Compose安装
- 3.3 可视化容器管理Portainer安装
- 3.4 常用命令
- 四、编写配置Yaml文件
- 4.1 常用配置项说明
- 4.2 配置宿主机映射目录
- 4.3 配置自定义网络
- 4.4 参考配置yaml
- 五、安装和配置Jenkins
- 5.1 初始化及插件安装
- 5.1.1 Jenkins安装及初始化
- 5.1.2 其他所需安装插件
- 5.2 系统配置及全局工具配置
- 5.2.1 中文语言设置
- 5.2.2 Maven插件配置
- 5.2.3 NodeJs插件配置
- 5.2.4 Docker插件配置
- 5.2.5 远程SSH插件配置
- 5.2.6 JDK配置
- 5.3 配置远程宿主机Docker开放访问
- 5.4 配置Maven项目
- 5.4.1 创建项目
- 5.4.2 构建策略设置
- 5.4.3 源码管理设置
- 5.4.4 构建触发器设置
- 5.4.5 构建环境设置
- 5.4.6 构建设置
- 5.5 配置Vue项目
- 5.4.1 创建项目
- 5.4.2 构建策略
- 5.4.3 源码管理
- 5.4.4 构建触发器
- 5.4.5 构建环境
- 5.4.6 构建
- 六、配置GitLab持续集成
- 6.1 知识背景
- 6.2 GitLab配置
- 6.2.1 创建远程访问令牌
- 6.2.2 配置事件钩子
- 6.3 Jenkins配置
- 6.3.1 系统配置
- 6.3.2 项目配置
一、前言
在开发过程中项目的发布上线尤其是令人头疼的一个环节,代码更新、配置、编译、发布,每一个环节都需要人工参与的情况下,单个项目或许尚且能够接受,但如果多个项目的情况下,对于运维工作会是一场灾难。
另一方面,在部署项目时,系统的环境往往也是困扰着运维人员的一个因素,是Ubuntu还是CentOs,版本是8是7还是6,环境的因素很大程度上会影响部署的应用,更遑论每个应用间还会相互干扰。
因此引入了Docker+Jenkins,要实现的需求很简单,第一部署不再需要关心系统环境,每个应用独立运行;第二部署自动化,代码能够发布后不管。
再者,目前微服务盛行,而集群运维也越来越多的交给k8s,要上这两个首先容器化和部署自动化都是必须走的第一步。
二、准备
2.1 采用技术栈
- 应用容器引擎:Docker
- 容器编排工具:Docker-Compose
- 可视化容器管理工具:Portainer
- 持续集成工具:Jenkins
2.2 工作空间目录结构
├── jenkins_home (jenkins工作空间映射目录)
├── nginx (nginx容器映射目录)
│ ├── conf (nginx配置文件)
│ ├── html (前端项目部署目录)
│ └── logs (运行日志)
├── redis (redis容器映射目录)
│ ├── conf (redis配置文件)
│ └── logs (运行日志)
├── tomcat (tomcat容器映射目录)
│ ├── log (运行日志)
│ └── webapps (项目部署目录)
│ └── logs (运行日志)
└── docker-compose.yml (docker配置文件)
三、安装Docker
3.1 Docker本体安装
CentOs下的Docker安装只需执行以下命令:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
3.2 容器编排工具Docker-Compose安装
拉取稳定版Docker Compose进行安装(要安装其他版本可替换1.24.1):
curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
chmod +x /usr/local/bin/docker-compose
创建软链接:
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
3.3 可视化容器管理Portainer安装
通过docker拉取最新版本的portainer,映射在宿主机的9000端口,赋予其管理其他docker容器的权限,并设置随docker启动:
docker pull portainer/portainer
docker run -d -p 9000:9000 -v /root/portainer:/data -v /var/run/docker.sock:/var/run/docker.sock --restart=always --name dev-portainer portainer/portainer
3.4 常用命令
docker启动/重启:
systemctl start docker
systemctl restart docker
查看运行容器信息:
docker ps
查询容器
docker search 容器名
四、编写配置Yaml文件
4.1 常用配置项说明
services:
# 服务名
tomcat:
# 容器实例名,必须唯一
container_name: "tomcat"
# 镜像名,可以通过镜像名、镜像id、等方式定义
image: tomcat:8.5.38
# 映射端口,格式为:宿主机端口:容器端口
ports:
- "8001:8080"
# 映射目录,格式为:宿主机目录:容器目录
volumes:
- "/usr/local/workspace/tomcat/log:/usr/local/tomcat/logs"
- "/usr/local/workspace/tomcat/webapps:/usr/local/tomcat/webapps"
# 配置环境变量,仅在容器初始化时生效
environment:
# 配置容器初始化时需要执行的命令
command:
# 使用网络配置,用于定义容器间互相通讯用的内部地址/别名等
networks:
workspace:
ipv4_address: 172.19.0.80
注意文件缩进,使用空格缩进,不要使用tab。
4.2 配置宿主机映射目录
根据需要在宿主机上建立映射目录,如果拿不准容器下对应的目录路径,可以先不填,创建以后通过portainer登录容器控制端后查询,目前用到的几个目录如下:
volumes:
# tomcat日志
- "/usr/local/workspace/tomcat/log:/usr/local/tomcat/logs"
# tomcat项目部署目录
- "/usr/local/workspace/tomcat/webapps:/usr/local/tomcat/webapps"
volumes:
# redis配置文件
- "/usr/local/workspace/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf"
# redis日志
- "/usr/local/workspace/redis/log:/usr/local/etc/logs"
volumes:
# nginx配置文件
- "/usr/local/workspace/nginx/conf/nginx.conf:/etc/nginx/nginx.conf"
# 前端页面放置目录
- "/usr/local/workspace/nginx/html:/usr/share/nginx/html"
# nginx日志
- "/usr/local/workspace/nginx/logs:/var/log/nginx"
# 上传文件放置目录
- "/usr/local/workspace/tomcat/webapps/upload:/usr/share/nginx/html/upload_group/upload"
- "/usr/local/workspace/tomcat_stock/webapps/upload:/usr/share/nginx/html/upload_stock/upload"
volumes:
# jenkins项目工作空间
- "/usr/local/workspace/jenkins_home:/var/jenkins_home"
# 授权jenkins可以管理其他容器
- "/var/run/docker.sock:/var/run/docker.sock"
4.3 配置自定义网络
在默认情况下Docker在启动容器时会为容器自动配置内网ip,ip地址与容器启动的顺序有关。但实际业务中往往需要为应用配置固定IP,这个时候可以使用自定义配置网络
networks:
# 自定义网络名
workspace:
ipam:
driver: default
config:
# 子网掩码
- subnet: 172.19.0.0/16
4.4 参考配置yaml
# yml配置
version: "3"
# 自定义一个网络
networks:
workspace:
ipam:
driver: default
config:
- subnet: 172.19.0.0/16
services:
# 集团tomcat配置
tomcat:
container_name: "tomcat"
image: tomcat:8.5.38
ports:
- "8001:8080"
volumes:
- "/usr/local/workspace/tomcat/log:/usr/local/tomcat/logs"
- "/usr/local/workspace/tomcat/webapps:/usr/local/tomcat/webapps"
networks:
workspace:
ipv4_address: 172.19.0.80
# 股份tomcat配置
tomcat_stock:
container_name: "tomcat_stock"
image: tomcat:8.5.38
ports:
- "8002:8080"
volumes:
- "/usr/local/workspace/tomcat_stock/log:/usr/local/tomcat/logs"
- "/usr/local/workspace/tomcat_stock/webapps:/usr/local/tomcat/webapps"
networks:
workspace:
ipv4_address: 172.19.0.100
# mysql配置
mysql:
container_name: "mysql"
image: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "12345qwerT.."
MYSQL_ROOT_HOST: "%"
MYSQL_USER: "cus"
MYSQL_PASSWORD: "12345qwerT.."
MYSQL_DATABASE: "xin_group_fixed_asset_db"
networks:
workspace:
# redis配置
redis:
container_name: "redis"
image: redis
ports:
- "6379:6379"
volumes:
- "/usr/local/workspace/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf"
- "/usr/local/workspace/redis/log:/usr/local/etc/logs"
command:
"redis-server /usr/local/etc/redis/redis.conf"
networks:
workspace:
# nginx配置
nginx:
container_name: "nginx"
image: nginx
ports:
- "80:80"
- "100:100"
volumes:
- "/usr/local/workspace/nginx/conf/nginx.conf:/etc/nginx/nginx.conf"
- "/usr/local/workspace/nginx/html:/usr/share/nginx/html"
- "/usr/local/workspace/nginx/logs:/var/log/nginx"
- "/usr/local/workspace/tomcat/webapps/upload:/usr/share/nginx/html/upload_group/upload"
- "/usr/local/workspace/tomcat_stock/webapps/upload:/usr/share/nginx/html/upload_stock/upload"
networks:
workspace:
# jenkins配置
jenkins:
container_name: "jenkins"
image: jenkins/jenkins:lts
ports:
- "8000:8080"
- "50000:50000"
volumes:
- "/usr/local/workspace/jenkins_home:/var/jenkins_home"
- "/var/run/docker.sock:/var/run/docker.sock"
networks:
workspace:
注意配置文件名需命名为docker-compose.yaml,否则启动时需要指定配置文件名。编写好配置文件后跳转到配置文件所在目录,执行以下命令,docker-compose会自动拉取镜像进行配置安装:
docker-compose up -d
五、安装和配置Jenkins
5.1 初始化及插件安装
5.1.1 Jenkins安装及初始化
使用官方提供的最新镜像进行安装(jenkins/jenkins:lts),避免出错
初次访问需要登录Jenkins所在容器,执行查询命令获得初始密码
/var/jenkins_home/secrets/initialAdminPassword
选择安装推荐插件
因为网络的问题在安装过程中可能出现插件安装失败的情况,可以先将安装失败的插件名记录下来之后更换源后再重新下载,也可选择重试几次。插件安装完成后设置管理员信息,一路保存进入主界面
5.1.2 其他所需安装插件
首先为Jenkins设置源地址,加快插件下载速度,在Jenkins管理界面上,进入管理Jenkins>插件管理>Advanced页签,找到Update Site,设置为 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
在Jenkins管理界面上,进入管理Jenkins>插件管理,在可选插件标签页下查询可安装插件
需要安装的插件列表如下
- Maven插件
- NodeJs插件
- Docker插件
- Publish Over SSH插件
- GitLab & Git Parameter & Generic Webhook Trigger
- 中文语言包
安装完成后访问http://Jenkins地址/restart/,重启Jenkins,重启完成后在installed页签检查插件是否成功安装
5.2 系统配置及全局工具配置
5.2.1 中文语言设置
在系统设置中找到Locale一栏,输入zh_CN,并勾选下面的复选框
5.2.2 Maven插件配置
进入管理Jenkins>全局工具设置,找到Maven一栏(注意首先要安装Maven插件)
在Maven配置一栏中,可以选择使用默认配置(比较慢),也可以使用自定义配置,在宿主机的jenkins_home目录下放入maven配置,并在此处填写对应容器下的路径即可
在Maven一栏,点击Maven安装设置别名,勾选自动安装,选择从Apache安装,如此初次构建项目时Jenkins会自动在容器中安装Maven(如果自行安装了Maven则不需要勾选自动安装复选框)
5.2.3 NodeJs插件配置
进入管理Jenkins>全局工具设置,找到NodeJs一栏(注意首先要安装NodeJs插件),选择自动安装
5.2.4 Docker插件配置
*该项用于流水线构建,可以先不用设置
进入管理Jenkins>系统管理,在最下方找到Cloud(云)一栏,点击前往管理
在管理页面,点击add a new cloud按钮,在下拉框中选择docker,设置名称,并配置远程docker地址(远程宿主机需要先开放对应端口的访问,详见下一节),点击Test Connection检查配置情况
5.2.5 远程SSH插件配置
进入管理Jenkins>系统管理,找到Publish over SSH一栏,点击新增按钮,新增一条远程SSH配置,设置别名、链接Host、登录用户名、访问目录,点击高级,勾选Use password authentication, or use a different key复选框,输入登录密码
5.2.6 JDK配置
一般来说Jenkins安装应当自带JDK,可以登录容器查看是否安装java,如果没有同样可以自动安装
5.3 配置远程宿主机Docker开放访问
在宿主机下编辑docker配置信息
vim /usr/lib/systemd/system/docker.service
找到ExecStart一项,将其修改为
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
注意服务器开放2376端口,修改完成后重启网络并重启docker
systemctl daemon-reload
systemctl restart docker
5.4 配置Maven项目
5.4.1 创建项目
进入Jenkins主界面,点击左侧新建Item按钮,创建一个新工程,如果正确安装并配置了Maven插件,在工程创建向导页面会出现 构建一个Maven项目 的选项
当几个工程配置都差不多时,可以输入已有工程的名称,复制已有工程的配置
5.4.2 构建策略设置
可以设置工作空间中最多可保持的构建文件数量和保存天数,这里节省空间选则保持1个保留2天
5.4.3 源码管理设置
这里设置git地址和对应要拉取的分支,注意git版本要写对
5.4.4 构建触发器设置
这里选择api触发,此处设置token后,可以通过地址http://JENKINS_URL/job/工程名/build?token=TOKEN_NAME触发构建
5.4.5 构建环境设置
正确安装publish over ssh插件后,能够看到在构建前/后通过SSH向远程服务器发生文件或执行命令选项,这里在构建前执行停止tomcat容器,删除war包命令;构建后传送war包并启动tomcat容器:
使用Ant进行构建,注意jdk版本
5.4.6 构建设置
设置root目录下的pom文件,一般为pom.xml,设置要执行的maven命令
点击右下角 高级 按钮,可以在弹出的配置选项中为maven设置使用自定义的配置文件
保存完成配置后,可以立即构建查看效果
5.5 配置Vue项目
5.4.1 创建项目
选择free style project创建工程
5.4.2 构建策略
同Maven项目,也可以根据实际情况另行设置
5.4.3 源码管理
同Maven项目
5.4.4 构建触发器
同Maven项目
5.4.5 构建环境
构建前清空远程宿主机nginx映射目录下对应压缩包
构建后传输压缩文件,跳转到映射目录并解压压缩包
如果成功安装NodeJs插件并完成配置,此处会看到Provide Node & npm bin/ folder to PATH选项,勾选使用node进行编译
5.4.6 构建
执行两个命令,一个编译一个压缩
点击保存完成设置
六、配置GitLab持续集成
6.1 知识背景
Jenkins+GitLab实现CI/CD的基本原理简单来说就是当GitLab上发生了指定的事件(例如分支提交,或者标签提交),GitLab就向指定的集成服务地址发送一个包含push信息的post请求,集成服务端就根据这个信息来决定是否要进行构建。
首先来看一下GitLab发送过来的消息长什么样:
{
"object_kind":"push",
"event_name":"push",
"before":"aa78724f0ee82ba75a1aa8fac4f320e52c668875",
"after":"932a3f37dd4f767fb48d6e09bd27672994f2c8a1",
"ref":"refs/heads/dev_wph",
"checkout_sha":"932a3f37dd4f767fb48d6e09bd27672994f2c8a1",
"message":null,
"user_id":22,
"user_name":"xxx",
"user_username":"xxx",
"user_email":"",
"user_avatar":"https://www.gravatar.com/avatar/96e763b00b6b7e8a2fdd4856f4c3b71d?s=80&d=identicon",
"project_id":16,
"project":{项目信息},
"commits":[本次提交的详细内容],
"total_commits_count":3,
"push_options":{
},
"repository":{
"name":"项目名",
"url":"git@110.x.x.x:xinGroupFixedAsset/xinGroupFixedAssetApi.git",
"description":"描述",
"homepage":"http://110.x.x.x:8090/xinGroupFixedAsset/xinGroupFixedAssetApi",
"git_http_url":"http://110.x.x.x:8090/xinGroupFixedAsset/xinGroupFixedAssetApi.git",
"git_ssh_url":"git@110.x.x.x:xinGroupFixedAsset/xinGroupFixedAssetApi.git",
"visibility_level":0
}
}
这里要用到的关键数据有这几个:
- git_http_url:git地址
- object_kind:操作类型
- ref:本次提交影响的分支
- commitsId:本次提交的id
当接收到GitLab传来的消息后,我们需要使用JsonPath来获取到我们需要的关键数据,在JsonPath中,$代表根节点,例如我们要获取repository下的git_http_url,只需要这样写:
$.repository.git_http_url
6.2 GitLab配置
6.2.1 创建远程访问令牌
登录Gitlab,进入账号设置页面,点击左侧Access Tokens,进入令牌管理
输入名称,勾选api访问,要不要设置过期时间随意,点击下方绿色的生成令牌按钮
将生成的令牌保存下来,之后配置在Jenkins里,在Jenkins主动构建时就可以通过api获取和指定要构建的分支了
6.2.2 配置事件钩子
接下来为GitLab配置触发事件时需要推送的Jenkins地址,进入需要集成的项目,在左侧设置菜单下拉中找到Integrations(集成),在进入的页面中设置地址和需要触发的事件
地址填什么在接下来的Jenkins配置里细说,触发事件支持push触发/标签触发等,如果觉得push触发太频繁可以使用标签触发
6.3 Jenkins配置
6.3.1 系统配置
进入管理Jenkins>系统配置,找到Gitlab一栏,填写连接别名,访问地址(注意不是项目地址),设置访问令牌。这里的访问令牌就是6.2.1中我们创建的远程令牌,完毕后测试是否成功
6.3.2 项目配置
进入任意一个已经创建的job或者新建一个,在General页签下,GitLab Connection选择我们在系统配置中设置的Gitlab地址,勾选参数构建,在主动构建时允许我们选择分支
在源码管理页签下,指定分支里写 $ref,代表需要构建哪个分支从ref参数中取
最后在构建触发器页签下,勾选WebHook触发(Generic Webhook Trigger)
在Post content parameters一栏中添加需要从Gitlab推送消息中读取的数据,使用JsonPath语法读取
在Token一栏中配置访问令牌,在6.2.2中Gitlab配置的远程地址上需要带上这里设置的令牌
在Optional filter页签下设置过滤规则,使用正则表达式,可以用前面Post content parameters里设置的读取数据进行组合过滤,多个参数用 “_” 号隔开来,例如
$ref_$object_kind
这里只做了分支过滤