Docker+Gitlab+Jenkins+Registry源码层级持续发布应用

一、发布流程及环境

1.1.发布流程

运维人员利用jenkins和gitlab来持续发布应用可以给开发测试人员提供较为迅速的反馈,在我的上一篇文章Jenkins+Gitlab+Maven自动构建部署代码 中是利用jenkins中设置的maven工具来对java源代码进行自动打包,然后将生成的war包SSH传送到目标服务器启动应用,但是不同的代码编译环境不一样,这就要求针对不同的代码来安装不同的插件,这非常依赖于jenkins对这些编译工具的兼容性,正好jenkins提供了Docker插件功能,而利用Dockerfile可以很好的将所有的依赖以及源代码装载到镜像里,这就解决了需要jenkins对每一种语言的编译环境的兼性考量

04abcn

本文的中对代码的具体发布流程如下:

  • 推送代码到仓库gitlab
  • webhook触发jenkins拉取最新代码到工作空间
  • jenkins利用docker构建应用镜像
  • jenkins推送镜像到registry
  • 利用基于swarm框架开发的容器发布平台datahub拉取应用镜像发布应用容器

1.2.环境说明

平台 公网地址 内网地址 平台访问地址 平台账号及密码 平台系统
Gitlab 47.100.101.235 172.19.159.9 http://47.100.101.235:9090/ root/88888888 Centos7.5
Jenkins 139.224.232.7 172.19.159.8 http://139.224.232.7:8080/ admin/88888888 Centos7.5
Datahub 47.100.107.199 172.19.159.7 http://47.100.107.199< admin/admin Centos7.5
Registry 47.101.166.64 172.19.159.10 https://registry.linuxwt.com/v2/_catalog wangteng/123456 Centos7.5
Web registry 47.101.166.64 172.19.159.10 http://47.101.166.64:8080/ Centos7.5

上表是本人完成部署测试成功后实际的配置,四台服务器均为处于同一大区的阿里云ECS,测试端是个人电脑,所以个人访问gitlab、jenkins、registry、web registry都是通过外网来访问,但这几个服务之间通信是通过内网地址,这样既可以规避风险,也能让数据传输更迅速

服务间使用内网通信有两处:

  • jenkins通过webhook与gitlab间的通信
  • jenkins推送镜像到registry

服务间使用外网通信有一处:

  • web registry链接registry

二、服务部署

2.1.Gitlab部署

采用docker-compose来编排部署
cat docker-compose.yml

gitlab:
  image: 'gitlab/gitlab-ce:latest'
  restart: always
  container_name: gitlab
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'http://47.100.101.235:9090'
      gitlab_rails['gitlab_shell_ssh_port'] = 2224
  ports:
    - '9090:9090'
    - '2224:22'
  volumes:
    - '/srv/gitlab/config:/etc/gitlab'
    - '/srv/gitlab/logs:/var/log/gitlab'
    - '/srv/gitlab/data:/var/opt/gitlab'

上面的external_url如果访问服务的客户端与gitlab服务处于同一网段可以使用内网地址,这里使用公网地址,docker-compose up -d启动服务需要等待五分钟左右
访问地址 http://47.100.101.235:9090 就可以看到gitlab页面

注册完后有两个配置需要完成

  • 配置邮件完成账号注册
  • 配置超级管理员账号

前者参考文章Jenkins+Gitlab+Maven自动构建部署代码里的gitlab部分,这里不作详述

配置管理员账号
04jek1

2.2.Jenkins部署

宿主机部署,参考编写tomcat自启动脚本引发的shell模式思考
中的jenkins部署部分,部署完成后访问 http://139.224.232.7:8080/ 需要安装组件以及配置初始密码及权限

配置jenkins权限添加管理员账户
04jek2

添加其他用户
配置完管理员账户后退出jenkins,在登录页面创建一个新用户wangteng,该用户只有登陆权限,需要通过管理员对其配置相应的权限

04jet5

jenkins系统配置
参考Jenkins+Gitlab+Maven自动构建部署代码中的jenkins部署部分,主要是配置jenkins_url、smtp以及ssh服务

2.3.配置webhook触发

push代码后,gitlab通过webhook来通知jenkins拉取最新的代码,这部分同样也可以参考上面的文章,这里有一处需要注意,gitlab的webhook配置处必须要是客户端能够访问,所以这里需要使用公网地址,如果我们是处于服务的同一网段,则可以使用内网地址,如下两图所示
gitlab
04gitt1
jenkins
04git2
两张图的地址最好保持一致,这里是为了具体说明为什么本文中gitlab上必须使用公网地址来配置webhook而故意作了区分,假如我们客户端是jenkins和gitlab服务同一网段中,这里就可以均使用内网地址

2.4.配置实例

截取部分重要的地方,其余的可以参考前面提到的文章
04git5

04git6

04git7

2.5.Registry部署

参考公网服务器搭建Docker私有镜像仓库Registry,该文使用了https访问registry以及registry的ssl认证,所以不能直接使用内网地址来查看仓库详情,但是在目标服务器上设置docker daemon服务的insecure-registries参数后可以通过内网地址来推送和拉取镜像,而不需要通过域名地址来进行推送和拉取,这比通过域名地址来获取镜像要快很多,而文中的registry web服务使用的是域名来连接registry,这是因为无法直接使用http的方式去访问registry
再次强调,加了insecure-registries参数可以拉取推送镜像,但是并不能以http的方式访问registry这个服务,在目标服务器(与registry处于同一网段)上直观的区别如下:
curl 172.19.159.10:5000/v2/_catalog --username wangteng:123456返回null
docker push 172.19.159.10:5000/loader:1.2 正常推送

2.6.Web registry部署

参考上文中的文章

2.7.Datahub部署

Datahub作为容器的发布平台,页面配置相关参数后发布容器到远程服务器,以下是项目结构和相关配置文件
整个项目的代码结构
04ngh

先看一下主服务的配置
cat docker-compose.yml

version: '3'
services:
  dockerloader:
    image: dockerloader:1.3
    restart: always
    container_name: dockerloader
    ports:
      - 9020:9029
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    env_file: .env
    environment:
      - NETWORK_ID=${NETWORK_ID}
      - DEBUG=${DEBUG}
    networks:
      - vmbridge

  mysql:
    image: mysql:5.7.24
    restart: always
    container_name: mysql
    command: [
      '--default-authentication-plugin=mysql_native_password',
      '--character-set-server=utf8mb4',
      '--collation-server=utf8mb4_unicode_ci'
    ]
    env_file: .env
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
    ports:
      - "9106:3306"
    volumes:
      - $PWD/volume/mysql/data:/var/lib/mysql
    networks:
      - vmbridge

  influxdb:
    image: influxdb:1.5.4
    container_name: influxdb
    hostname: influxdb
    volumes:
      - $PWD/volume/influxdb/data:/var/lib/influxdb
    env_file: .env
    environment:
      INFLUXDB_DB: ${INFLUXDB_DB}
      INFLUXDB_ADMIN_ENABLED: ${INFLUXDB_ADMIN_ENABLED}
      INFLUXDB_HTTP_AUTH_ENABLED: ${INFLUXDB_HTTP_AUTH_ENABLED}
      INFLUXDB_ADMIN_USER: ${INFLUXDB_ADMIN_USER}
      INFLUXDB_ADMIN_PASSWORD: ${INFLUXDB_ADMIN_PASSWORD}
    ports:
      - "8086:8086"
    networks:
      - vmbridge

  datahub:
    image: datahub:1.2
    restart: always
    container_name: datahub
    ports:
      - 9030:9039
    depends_on:
      - mysql
      - influxdb
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    env_file: .env
    environment:
      DEBUG: ${DEBUG}
      MYSQL_URL: ${MYSQL_URL}
      INFLUX_URL: ${INFLUX_URL}
      INFLUX_DATABASE: ${INFLUXDB_DB}
      EXECUTOR_ADDRESS: ${EXECUTOR_ADDRESS}
      DATA_SOURCE_ADDRESS: ${DATA_SOURCE_ADDRESS}
      DOCKER_LOADER_PORT: ${DOCKER_LOADER_PORT}
      DOCKER_MONITOR_PORT: ${DOCKER_MONITOR_PORT}
      DOCKER_HOST_VOLUMES: ${DOCKER_HOST_VOLUMES}
    networks:
      - vmbridge

  telegraf:
    image: telegraf:latest
    container_name: telegraf
    restart: always
    depends_on:
      - influxdb
    networks:
      - vmbridge
    volumes:
      - $PWD/conf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
      - /var/run/docker.sock:/var/run/docker.sock

networks:
 vmbridge:
  external: true

cat .env

#mysql
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=demo
MYSQL_URL=root:123456@tcp(mysql:3306)/demo?charset=utf8mb4&parseTime=True


#influxdb
INFLUXDB_DB=monitor
INFLUXDB_ADMIN_ENABLED=true
INFLUXDB_HTTP_AUTH_ENABLED=true
INFLUXDB_ADMIN_USER=root
INFLUXDB_ADMIN_PASSWORD=root


#datahub
MYSQL_URL=root:123456@tcp(mysql:3306)/demo?charset=utf8mb4&parseTime=True
INFLUX_URL=influx://root:root@influxdb:8086
EXECUTOR_ADDRESS=47.100.101.235
DATA_SOURCE_ADDRESS=47.100.101.235
DOCKER_LOADER_PORT=9020
DOCKER_MONITOR_PORT=9010
DOCKER_HOST_VOLUMES=/var/lib/container-data/

#NETWORK_ID=07b4d16c8b6ded187b64a0f0f9b06e50f5dac95ac5b8189d243e7992f8ead568
NETWORK_ID=65629ae783f42d3673cf847e264d4f0608706ed23342babb6767ae63275474a9
DEBUG=false

通过该配置启动datahub服务、dockerloader服务、mysql服务、influxdb服务、telegraf服务,同时宿主机部署一个nginx服务,如果要在远程服务器上部署服务,需要修改主服务配置文件下同目录的.env文件,同时在远程服务器上部署dockerloader服务与telegraf服务

datahub服务会连接mysql与influxdb,telegraf采集系统数据及数据库数据到influxdb,nginx放置前端代码,mysql存放datahub平台的配置数据

下面展示datahub平台的界面
04datahub_1
04datahub_2
04datahub_3
04datahub_4
04dataub_5

ps:因为datahub是自有项目,源代码这里就不放了,主要是做一个记录方便后期查阅,方便部署