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

docker 自动化搭建laravel docker 自动化部署_tomcat

docker 自动化搭建laravel docker 自动化部署_docker_02


选择安装推荐插件

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_03


因为网络的问题在安装过程中可能出现插件安装失败的情况,可以先将安装失败的插件名记录下来之后更换源后再重新下载,也可选择重试几次。插件安装完成后设置管理员信息,一路保存进入主界面

docker 自动化搭建laravel docker 自动化部署_nginx_04

5.1.2 其他所需安装插件

首先为Jenkins设置源地址,加快插件下载速度,在Jenkins管理界面上,进入管理Jenkins>插件管理>Advanced页签,找到Update Site,设置为 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

docker 自动化搭建laravel docker 自动化部署_tomcat_05

在Jenkins管理界面上,进入管理Jenkins>插件管理,在可选插件标签页下查询可安装插件

docker 自动化搭建laravel docker 自动化部署_nginx_06


docker 自动化搭建laravel docker 自动化部署_docker_07

需要安装的插件列表如下

  • Maven插件
  • docker 自动化搭建laravel docker 自动化部署_docker_08

  • NodeJs插件
  • docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_09

  • Docker插件
  • docker 自动化搭建laravel docker 自动化部署_tomcat_10

  • Publish Over SSH插件
  • docker 自动化搭建laravel docker 自动化部署_nginx_11

  • GitLab & Git Parameter & Generic Webhook Trigger
  • docker 自动化搭建laravel docker 自动化部署_nginx_12


  • docker 自动化搭建laravel docker 自动化部署_nginx_13


  • docker 自动化搭建laravel docker 自动化部署_docker_14

  • 中文语言包
  • docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_15


  • docker 自动化搭建laravel docker 自动化部署_tomcat_16

安装完成后访问http://Jenkins地址/restart/,重启Jenkins,重启完成后在installed页签检查插件是否成功安装

5.2 系统配置及全局工具配置

5.2.1 中文语言设置

在系统设置中找到Locale一栏,输入zh_CN,并勾选下面的复选框

docker 自动化搭建laravel docker 自动化部署_tomcat_17


docker 自动化搭建laravel docker 自动化部署_tomcat_18

5.2.2 Maven插件配置

进入管理Jenkins>全局工具设置,找到Maven一栏(注意首先要安装Maven插件)

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_19


在Maven配置一栏中,可以选择使用默认配置(比较慢),也可以使用自定义配置,在宿主机的jenkins_home目录下放入maven配置,并在此处填写对应容器下的路径即可

docker 自动化搭建laravel docker 自动化部署_docker_20


在Maven一栏,点击Maven安装设置别名,勾选自动安装,选择从Apache安装,如此初次构建项目时Jenkins会自动在容器中安装Maven(如果自行安装了Maven则不需要勾选自动安装复选框)

docker 自动化搭建laravel docker 自动化部署_nginx_21

5.2.3 NodeJs插件配置

进入管理Jenkins>全局工具设置,找到NodeJs一栏(注意首先要安装NodeJs插件),选择自动安装

docker 自动化搭建laravel docker 自动化部署_docker_22

5.2.4 Docker插件配置

*该项用于流水线构建,可以先不用设置

进入管理Jenkins>系统管理,在最下方找到Cloud(云)一栏,点击前往管理

docker 自动化搭建laravel docker 自动化部署_tomcat_23


在管理页面,点击add a new cloud按钮,在下拉框中选择docker,设置名称,并配置远程docker地址(远程宿主机需要先开放对应端口的访问,详见下一节),点击Test Connection检查配置情况

docker 自动化搭建laravel docker 自动化部署_nginx_24

5.2.5 远程SSH插件配置

进入管理Jenkins>系统管理,找到Publish over SSH一栏,点击新增按钮,新增一条远程SSH配置,设置别名、链接Host、登录用户名、访问目录,点击高级,勾选Use password authentication, or use a different key复选框,输入登录密码

docker 自动化搭建laravel docker 自动化部署_nginx_25

5.2.6 JDK配置

一般来说Jenkins安装应当自带JDK,可以登录容器查看是否安装java,如果没有同样可以自动安装

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_26

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项目 的选项

docker 自动化搭建laravel docker 自动化部署_nginx_27


docker 自动化搭建laravel docker 自动化部署_docker_28


当几个工程配置都差不多时,可以输入已有工程的名称,复制已有工程的配置

5.4.2 构建策略设置

可以设置工作空间中最多可保持的构建文件数量和保存天数,这里节省空间选则保持1个保留2天

docker 自动化搭建laravel docker 自动化部署_nginx_29

5.4.3 源码管理设置

这里设置git地址和对应要拉取的分支,注意git版本要写对

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_30

5.4.4 构建触发器设置

这里选择api触发,此处设置token后,可以通过地址http://JENKINS_URL/job/工程名/build?token=TOKEN_NAME触发构建

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_31

5.4.5 构建环境设置

正确安装publish over ssh插件后,能够看到在构建前/后通过SSH向远程服务器发生文件或执行命令选项,这里在构建前执行停止tomcat容器,删除war包命令;构建后传送war包并启动tomcat容器:

docker 自动化搭建laravel docker 自动化部署_docker_32


docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_33


使用Ant进行构建,注意jdk版本

docker 自动化搭建laravel docker 自动化部署_tomcat_34

5.4.6 构建设置

设置root目录下的pom文件,一般为pom.xml,设置要执行的maven命令

docker 自动化搭建laravel docker 自动化部署_nginx_35


点击右下角 高级 按钮,可以在弹出的配置选项中为maven设置使用自定义的配置文件

docker 自动化搭建laravel docker 自动化部署_docker_36

保存完成配置后,可以立即构建查看效果

5.5 配置Vue项目

5.4.1 创建项目

选择free style project创建工程

docker 自动化搭建laravel docker 自动化部署_tomcat_37

5.4.2 构建策略

同Maven项目,也可以根据实际情况另行设置

5.4.3 源码管理

同Maven项目

5.4.4 构建触发器

同Maven项目

5.4.5 构建环境

构建前清空远程宿主机nginx映射目录下对应压缩包

docker 自动化搭建laravel docker 自动化部署_tomcat_38


构建后传输压缩文件,跳转到映射目录并解压压缩包

docker 自动化搭建laravel docker 自动化部署_docker_39


如果成功安装NodeJs插件并完成配置,此处会看到Provide Node & npm bin/ folder to PATH选项,勾选使用node进行编译

docker 自动化搭建laravel docker 自动化部署_nginx_40

5.4.6 构建

执行两个命令,一个编译一个压缩

docker 自动化搭建laravel docker 自动化部署_tomcat_41


点击保存完成设置

六、配置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,进入令牌管理

docker 自动化搭建laravel docker 自动化部署_docker_42


输入名称,勾选api访问,要不要设置过期时间随意,点击下方绿色的生成令牌按钮

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_43


将生成的令牌保存下来,之后配置在Jenkins里,在Jenkins主动构建时就可以通过api获取和指定要构建的分支了

6.2.2 配置事件钩子

接下来为GitLab配置触发事件时需要推送的Jenkins地址,进入需要集成的项目,在左侧设置菜单下拉中找到Integrations(集成),在进入的页面中设置地址和需要触发的事件

docker 自动化搭建laravel docker 自动化部署_nginx_44


地址填什么在接下来的Jenkins配置里细说,触发事件支持push触发/标签触发等,如果觉得push触发太频繁可以使用标签触发

6.3 Jenkins配置

6.3.1 系统配置

进入管理Jenkins>系统配置,找到Gitlab一栏,填写连接别名,访问地址(注意不是项目地址),设置访问令牌。这里的访问令牌就是6.2.1中我们创建的远程令牌,完毕后测试是否成功

docker 自动化搭建laravel docker 自动化部署_nginx_45

6.3.2 项目配置

进入任意一个已经创建的job或者新建一个,在General页签下,GitLab Connection选择我们在系统配置中设置的Gitlab地址,勾选参数构建,在主动构建时允许我们选择分支

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_46


在源码管理页签下,指定分支里写 $ref,代表需要构建哪个分支从ref参数中取

docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_47


最后在构建触发器页签下,勾选WebHook触发(Generic Webhook Trigger)

docker 自动化搭建laravel docker 自动化部署_nginx_48


在Post content parameters一栏中添加需要从Gitlab推送消息中读取的数据,使用JsonPath语法读取

docker 自动化搭建laravel docker 自动化部署_tomcat_49


docker 自动化搭建laravel docker 自动化部署_docker_50


docker 自动化搭建laravel docker 自动化部署_tomcat_51


docker 自动化搭建laravel docker 自动化部署_docker 自动化搭建laravel_52


在Token一栏中配置访问令牌,在6.2.2中Gitlab配置的远程地址上需要带上这里设置的令牌

docker 自动化搭建laravel docker 自动化部署_docker_53


在Optional filter页签下设置过滤规则,使用正则表达式,可以用前面Post content parameters里设置的读取数据进行组合过滤,多个参数用 “_” 号隔开来,例如

$ref_$object_kind

这里只做了分支过滤

docker 自动化搭建laravel docker 自动化部署_tomcat_54