GVKun编程网logo

案例 | 持续集成:Docker、Maven、Java(基于docker的持续集成系统)

12

本文将为您提供关于案例|持续集成:Docker、Maven、Java的详细介绍,我们还将为您解释基于docker的持续集成系统的相关知识,同时,我们还将为您提供关于8.4DockerCloud之持续集

本文将为您提供关于案例 | 持续集成:Docker、Maven、Java的详细介绍,我们还将为您解释基于docker的持续集成系统的相关知识,同时,我们还将为您提供关于8.4 Docker Cloud之持续集成和持续部署、Docker 从入门到放弃(四)Docker+Jenkins_自动化持续集成、Docker 入门(三):持续集成、持续部署、Docker 学习笔记 (二) Docker 实战之 Registry 以及持续集成的实用信息。

本文目录一览:

案例 | 持续集成:Docker、Maven、Java(基于docker的持续集成系统)

案例 | 持续集成:Docker、Maven、Java(基于docker的持续集成系统)

 陈光 分布式实验室

图片


在Alooma,我们非常非常非常喜爱Docker。真的, 我们想完全容器化我们的应用。 虽然容器化应用有非常多的好处,但在这里,我并不是要说服你用Docker。我们只是认为你和我们一样喜欢这东西。

接下来,让我们谈谈Alooma是如何在生产环境使用Docker来精简开发流程并快速push代码的。

image.png

Docker允许你把基础架构当作代码一样来对待。这个代码就是你的Dockerfile。

像其它代码一样,我们想要使用一个紧密的改变->提交->构建->测试的周期(一个完整的持续集成解决方案)。为了实现这个目标,我们需要构建一个流畅的DevOps流水线。

让我们把目标分解为更加详细的需求:

  • 在版本控制系统中管理Dockerfile

  • 在CI服务器上为每个commit构建Docker镜像

  • 上传构件并打标签(这个构件要能够简单的部署)

image.png

我们的DevOps流水线围绕GitHub、Jenkins和Maven构建。下面是它的工作流程:

  1. GitHub将repo的每一个push通知给Jenkins

  2. Jenkins触发一个Maven build

  3. Maven 构建所有的东西,包括Docker镜像

  4. 最后,Maven会把镜像推送到私有的Docker Registry。

这个工作流的好处是它允许我们能够很容易的为每个发布版本打标签(所有的commit都被构建并且在我们的Docker Registry中准备好了)。然后我们可以非常容易地通过pull和run这些Docker镜像进行部署。

事实上这个部署过程是非常简单的,我们通过发送一个命令给我们信任的Slack机器人:”Aloominion”(关于我们的机器人朋友的更多情况将在未来的文章中发表)开始这个过程。

你可能对这个工作流中的其他元素非常熟悉,因为它们都很常见。所以,让我们来深入了解如何使用Maven构建Docker镜像。

image.png

Alooma是一个Java公司。我们已经使用Maven作为我们构建流水线的中心工具,所以很自然的想到把构建Docker的过程也加入到我们的Maven构建过程中去。

当搜索和Docker交互的Maven插件时,出现了3个选项。我们选择使用Spotify的maven-docker-plugin —— 虽然rhus的和alexec的同名插件看起来也是一个不错的选择。

另一个我们的构建计划依赖的Maven插件是maven-git-commit-id-plugin。我们使用这个插件,所以我们的Docker镜像能使用git的commit ID来打标签 —— 这在部署过程中非常有帮助,我们可以了解运行的是哪个版本。

image.png

每一个docker镜像有它自己的Maven模块(所有上面提到的docker-maven 插件在一个模块一个Dockerfile时都能顺利地工作)

让我们从Spotify插件的一个简单配置开始:

image.png

我们看到这里我们把插件的build目标和Maven的package阶段绑定,我们也指导它去在我们模块的根目录下来寻找Dockerfile(使用DockerDirectory 元素来指定),我们还把镜像名称用它的构件Id来命名(用”alloma/”做前缀)。

我们注意到的第一件事情是这个镜像没有被push到任何地方,我们可以通过加入到配置中来解决这个问题。

但是现在这个镜像会被push到默认的Docker Hub Registry上。糟糕。

为了解决这个问题,我们定义了一个新的Maven属性并且把镜像名称imageName改为${docker.registry}alooma/${project.artifactId}。 你可能会想,“为什么需要为Docker Registry设置一个属性?”, 你是对的!但是有这个属性可以使我们在Regsitry URL改变的时候能够更方便的修改。

有一个更重要的事情我们还没有处理——我们想让每一个镜像用它的git commit ID来打标签。这可以通过改变imageName为${docker.registry}alooma/${project.artifactId}:${git.commit.id.abbrev}来实现。

${git.commit.id.abbrev}属性是通过我上面提到的maven-git-commit-id-plugin插件来实现的。

所以,现在我们的插件配置看起来像下面这样:

image.png

我们的下一个挑战是在我们的pom.xml中表达我们的Dockerfile的依赖。一些我们的Docker镜像在构建时使用了 FROM 其它的Docker 镜像作为基础镜像(也在同一个构建周期中构建)。例如,我们的webgate镜像(是我们的机遇Tomcat的WebApp)基于我们的base镜像(包含Java 8、更新到最新的 apt-get、等等)。

这些镜像在同一个构建过程中构建意味着我们不能简单的使用FROM docker-registry.alooma.io/alooma/base:some-tag因为我们需要这个标签编程当前构建的标签(即 git commit ID)。

为了在Dockerfile中获得这些属性,我们使用了Maven的resource filtering功能。这在一个资源文件中替换Maven 的属性。

image.png

在Dockerfile的内部我们有一个这样的FROM

FROM ${docker.registry}alooma/base:${git.commit.id.abbrevs}

一些更多的事情…….我们需要的是我们的配置来找到正确的Dockerfile(过滤过之后的),这可以在target/classes文件夹内找到,所以我们把dockerDirectory改为${project.build.directory}/classes。

这意味着现在我们的配置文件长这样:

image.png

此外,我们还要添加base构件作为webgate模块的一个Maven依赖来保证正确的Maven构建顺序。

但是我们还有另一个挑战:我们如何把我们编译和打包了的源文件添加到我们的Docker镜像中呢?我们的Dockerfile依赖于很多其它文件,它们通过ADDcopY命令插入。[你可以在这里(https://docs.docker.com/reference/builder/)读到更多的关于Dockerfile的指导。]

为了让这些文件可以被获取,我们需要使用插件配置的resources标签。

image.png

注意到我们排除了一些文件。

记住这个resources标签不应该和通常的Maven resources标签弄混,看看下面的例子,它来自于我们的pom.xml的一部分:

image.png

前一个添加在我们想添加一些静态资源到镜像时工作,但是如果我们想要添加一个在同一个构建中构建的构件时需要更多的调整。

例如,我们的webgate Docker镜像包含了我们的webgate.war,这是由另一个模块构建的。

为了添加这个war作为资源,我们首先必须把它作为我们的Maven依赖加进来,然后使用maven-dependency-plugin插件的copy目标来把它加到我们当前的构建目录中。

image.png

现在这允许我们简单的把这个文件加到Docker插件的resources中去。

image.png

我们需要做的最后一件事情是让我们的CI服务器(Jenkins)真的将镜像push到Docker Registry上。请记住本地构件默认是不会push镜像的。

为了push这些镜像,我们改变我们的

译注:这里的意思是,由于开发人员也要在本地构建然后测试之后才会提交,而测试的镜像不应该被提交到Registry,所以

这就完成了!让我们看一下最终的代码:

image.png

image.png

image.png


image.png

这个过程有两个能够提高你的构建和部署的性能的改进地方:

  • 让你的基础的机器镜像(在EC2的例子下是AMI)包含一些你的Docker镜像的基础版本。这样会使得docker pull只去pull那些改变了的层,即增量(相对于整个镜像来说要小得多)。

  • 在Docker Registry的前端放一个Redis缓存。这可以缓存标签和元数据,减少和真实存储(在我们的例子下是S3)的回环。

我们现在已经使用这个构建过程一段时间了,并且对它非常满意。然而仍然有提高的空间,如果你有任何关于让这个过程更加流畅的建议,我很乐意在评论中听到你的想法。

8.4 Docker Cloud之持续集成和持续部署

8.4 Docker Cloud之持续集成和持续部署

如果在docker cloud上绑定了AWS或者Azure之后,会有一个Launch Service选项

点击之后,在页面上勾选AUTODEPLOY,就可以在image有更新之后,就自动部署了

Docker 从入门到放弃(四)Docker+Jenkins_自动化持续集成

Docker 从入门到放弃(四)Docker+Jenkins_自动化持续集成

 

Windows 查看密码

$ cat /var/jenkins_home/secrets/initialAdminPassword
14e14c414f41481aa5955753d3f31f9f

自定义詹金斯
插件扩展了Jenkins的附加功能,以支持许多不同的需求。

开始安装

 安装完成后输入自己的用户名,密码等个人信息。然后Save and Finish一下,之后就可以启动Jenkins了

至此Jenkins 安装完成

 

参考

Docker+Jenkins_自动化持续集成

 

Docker 入门(三):持续集成、持续部署

Docker 入门(三):持续集成、持续部署

在软件开发过程中,如果我们每一次提交的代码都能够进行一次完整的编译、测试、打包、发布,就能及早发现问题、及早修复,在保证代码质量的同时让产品快速迭代。这就是持续集成(CI)、持续部署(CD)的好处。

目前 CI/CD 的方案有很多,本文将展示一个用 Docker + Jenkins 实现的完整过程。

本文的 CI/CD 流程

开发人员提交代码到自己的分支并 push 到远程仓库 ==> 触发远程仓库(GitHub/GitLab)的 Webhooks ==> Jenkins 接到通知自动执行之前准备好的一个流程(克隆代码,对代码进行编译、测试、打包,没有问题后会执行 docker 命令进行镜像构建)==> 最终发布到测试服务器中。

环境说明

  • 本文选用的测试环境是阿里云的服务器,所以全程也是在服务器上操作的,无需本地安装 docker,当然在本地操作也是可以的。
  • 本文选用的远程代码库是 GitHub 公有仓库,如果是私有仓库或 GitLab,步骤会略有不同。
  • 本文中所用的 Jenkins 也是用的 docker 版,并不是直接安装在宿主机上的。

开始一个 docker 应用

要演示整个过程,就得有一个应用,这里我们用一个 create-react-app 为例,无需 IDE,一个 terminal 即可搞定。

  • 首先创建 react-app 和 Dockerfile
4、5 行是增加了一个设置,是关掉 webpack 的 host 检查,如果不加此项,访问绑定域名的服务器就会被 webpack-dev-server 拦截。
$ npm install -g create-react-app
$ create-react-app my-app
$ cd my-app
$ touch .env
$ echo DANGEROUSLY_DISABLE_HOST_CHECK=true > .env
$ touch Dockerfile
  • 将以下内容写入 Dockerfile:
为了简单,我们这里直接采用 npm start 的方式启动它,就不 build 了,安装 cnpm 是为了提高依赖的下载速度
FROM node:8.11.1-slim

WORKDIR /home/app

COPY . ${WORKDIR}

RUN npm install -g cnpm --registry=https://registry.npm.taobao.org \
    && cnpm install

EXPOSE 3000

ENTRYPOINT [ "npm", "start" ]
  • 到这里就完全好了,单元测试什么的就暂且忽略。

为什么要使用 Jenkins

如果没有 Jenkins,就上面那个例子,我们想要将自己的代码集成并且部署到服务器,可能要经历以下步骤:

  • 1、将代码 push 到仓库
  • 2、ssh 登录服务器,克隆代码到宿主机(宿主机还要安装 git)
  • 3、执行以下命令完成镜像构建和部署
$ cd repository
$ docker build -t test .
$ docker run -d -p 80:3000 --name my-react test

可以看到上面那个过程需要人工操作,非常繁琐,这还没算上对代码进行测试,如果每次提交了代码都要来一个这样的过程,那是真的没法专心搞开发了。

如果用了 Jenkins,上面的整个过程都可以自动化完成。

初始化 Jenkins

Jenkins 的官网是 jenkins.io,它有很多种安装方式,例如下载 war 包到宿主机上,然后用 java -jar jenkins.war 命令启动。但是这种安装方式非常不利于管理和服务器的迁移,完全是在给 docker 托后腿。所以我选择用 docker 版的 jenkins。

使用 docker 版的 jenkins 是需要注意很多细节的

  • 首先我们要重写官方 jenkins 镜像
$ vi Dockerfile
FROM jenkins/jenkins:lts

USER root

RUN echo deb http://mirrors.aliyun.com/debian wheezy main contrib non-free \
    deb-src http://mirrors.aliyun.com/debian wheezy main contrib non-free \
    deb http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free \
    deb-src http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free \
    deb http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free \
    deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free \
    > /etc/apt/sources.list \
    && apt-get update \
    && apt-get install -y libltdl-dev
这里用了 jenkins 最新稳定版最为基础镜像,主要干了两件事:一、将账户改为 root,避免后面不必要的权限问题;二、安装 libltdl-dev ,它是为了解决用 jenkins 调用容器外部 docker 命令时发生以下错误的问题。(第 4~10 行是为了换阿里源提高速度)
docker: error while loading shared libraries: libltdl.so.7: cannot open shared object file: No such file or directory
  • 在启动刚刚重写好的 jenkins 镜像的时候还需要挂载三个宿主机的目录到容器内,第一个 jenkins_home 是为了对容器内 jenkins 的所有改动做数据持久化。最后两个目录是为了能让容器内的 jenkins 调用并操作容器外的 docker
$ vi docker-compose.yml
version: "3"
services:
 jenkins:
  build: .
  image: my_jenkins
  ports:
    - "8090:8080"
    - "50000:50000"
  container_name: my_jenkins
  volumes:
    - "/home/jenkins_home:/var/jenkins_home"
    - "/var/run/docker.sock:/var/run/docker.sock"
    - "/usr/bin/docker:/usr/bin/docker"
为了看起来清晰,我写了一个 docker-compose.yml 文件,将这个文件和之前的 Dockerfile 放在同一个目录中,可以用以下命令快速启动 jenkins,启动之后新构建的镜像和容器都名为 my_jenkins。
$ docker-compose up -d
  • 启动 jenkins 后浏览器访问 ip:8090 可看到初始化页面

这里要输入密码,它给出了密码在容器内的位置,我们要将路径改成宿主机上的,然后 cat 一下就能看到密码。
$ cat /home/jenkins_home/secrets/initialAdminPassword 
  • 将密码粘贴进去然后点继续,下一个页面选择插件,点默认推荐的就好了

  • 接着按提示创建一个账户

  • 之后就能够使用 jenkins 了

配置 Webhooks

要让 jenkins 操作本机上的 docker 的前提是它收到了我们 push 代码的通知,而这个通知就是由 GitHub 上的 Webhooks 来完成的,所以要将这两者关联起来。

  • 配置 Webhooks 之前首先要更改一下安全设置
打开全局安全配置,软后进行如下操作,否则 Webhooks 连接不成功,设置好了别忘了点保存。

  • 开始创建任务
点击首页的「开始创建一个新任务」,起个名字,选择流水线。

  • 生成身份令牌
点击「构建触发器」,选择「触发远程构建」,然后随便填写一段字符,然后把 URL 复制下来,记得把「JENKINS_URL」和「TOKEN_NAME」替换为相应的值,例如下图最终得到的 URL 就是 111.11.1.1:8090/job/test/build?token=123456,记下 URL 后点保存。

  • 去 GitHub 创建 Webhooks
打开我们要 push 代码的仓库,点击「Add webhook」

然后将刚才记下的回调 URL 填写到这里即可

此时,可以尝试一下 push 代码到仓库,正常情况下,jenkins 就会自动进行构建,虽然没有配置要构建什么,但是它也会进行这个任务,如果构建历史中自动出现了一个颜色是蓝色的任务则代表整个自动触发的过程是配置成功的。

编写自动任务脚本进行 CI/CD

  • 点击上面那个任务的「配置」,切换到流水线这里。本文不介绍流水线语法,就用 shell 命令来编写整个过程。但我们首先还是要点击「流水线语法」

  • 将示例步骤切换到「sh: Shell Script」,编写好 shell 脚本,熟悉 linux 命令的话,这个过程也应该很容易。写好之后点击「生成流水线脚本」,之后把生成好的流水线脚本复制下来

  • 将生成好的 流水线脚本复制到这里就好了,不过要把它复制到一个 node{} 里面才行。

以下是我写的生成好的流水线脚本,记得把定义的四个变量替换一下。
node {
    sh ''''''#!/bin/sh

    REPOSITORY_NAME="你的仓库名"
    REPOSITORY_URL="你的仓库地址"
    IMAGE_NAME="给你要构建的镜像起个名字"
    CONTAINER_NAME="给你要构建的容器起个名字"
       
    echo "清除仓库目录"
    rm ${REPOSITORY_NAME} -r
       
    echo "克隆远程仓库"
    git clone ${REPOSITORY_URL}

    echo "删除之前的镜像和容器"
    docker stop ${CONTAINER_NAME}
    docker rm ${CONTAINER_NAME}
    docker rmi ${IMAGE_NAME}
    
    echo "构建镜像"
    cd ${REPOSITORY_NAME}
    docker build -t ${IMAGE_NAME} .
    
    echo "发布应用"
    docker run -d -p 80:3000 --name ${CONTAINER_NAME} ${IMAGE_NAME}''''''

}
  • 最后可以提交一次代码或者点击「立即构建」,就会自动完成整个过程,在「控制台输出」那里可以看到构建过程。

此时,浏览器访问 ip 就能看到更新过的应用了,这就是一个 CI/CD 过程,整个过程省略的测试环节,可自行加上。

后记

用一个测试服务器来做 CI/CD,能够更及时的发现问题、解决问题,提高代码质量。

但是本文所展示的过程缺陷也很明显,在更新应用时,是会先停掉容器,再启动新容器的,不能做到无宕机更新。而且整个过程也没有服务监控什么的,不能很好地了解无服务的运行状态。

总之,到目前为止,我们已经能够很好地将 docker 用在日常的开发中了。

点击查看博客原文

Docker 学习笔记 (二) Docker 实战之 Registry 以及持续集成

Docker 学习笔记 (二) Docker 实战之 Registry 以及持续集成

学习资料

Git

https://git.oschina.net/dockerf/second fork 一下

视频

http://study.163.com/course/courseLearn.htm?courseId=1273002#/learn/video?lessonId=1515025&courseId=1273002


Docker Registry


什么是 Docker Registry?

Docker Registry 是存放 docker 镜像的仓库

什么是 Docker Hub?

Docker Hub 是 docker 官方的 Registryhttps://hub.docker.com/, 由于总所周知的网络原因,国内使用官方的 registry pull 镜像速度慢的像蜗牛・・・・

私有 Registry 搭建

[root@rancher-server]~# dao pull registry

# ----------------------------------------------------------------------------
# DaoCloud ToolBox for Docker
#
# DaoCloud, Inc. (c) 2016
#
# Fastest way to pull image from Docker Hub
# ----------------------------------------------------------------------------

Pulling repository library/registry 

7c4baf947271: Download complete                                                                                   
a3ed95caeb02: Download complete                                                                                   
f1d1dbdd4f97: Download complete                                                                                   
4e3899dc28fa: Download complete                                                                                   
e14b922ad4f5: Download complete                                                                                   
f2bbca3948d0: Download complete                                                                                   
1d4dc7bffbb8: Download complete                                                                                   
Pull library/registry:latest complete, you can find it with ''docker images''
#Registry服务默认会将上传的镜像保存在容器的/tmp/registry,我们将主机的/opt/registry目录挂载到该目录,即可实现将镜像保存到主机的/opt/registry目录了
[root@rancher-server]# docker run -d -p 5000:5000  --restart=always   -v /opt/registry:/tmp/registry  --name registry registry
7643b9b79730ce411bf80be5f7ebb776ec15823be5d40475e3c3ebcc0d6f2b5f
[root@rancher-server]/# docker logs -f 7643b9b79730ce411bf80be5f7ebb776ec15823be5d40475e3c3ebcc0d6f2b5f
[root@rancher-server]/# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                              NAMES
7643b9b79730        registry               "docker-registry"        8 minutes ago       Up 7 minutes        0.0.0.0:5000->5000/tcp             registry
5ca3bb6cfc42        rancher/agent:v1.0.1   "/run.sh run"            14 hours ago        Up 19 minutes                                          rancher-agent
0f38b7bab4fb        rancher/server         "/usr/bin/s6-svscan /"   14 hours ago        Up 19 minutes       3306/tcp, 0.0.0.0:8888->8080/tcp   rancher-server

上传镜像到 Registry

[root@rancher-server]/# vim /usr/lib/systemd/system/docker.service 
#添加--insecure-registry registry-host:5000
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/docker daemon --insecure-registry 192.168.2.22:5000 -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

#加载新的配置文件
[root@rancher-server]/# systemctl  daemon-reload  
#重启Docker服务
[root@rancher-server]/# systemctl  restart docker.service
#Tag镜像  registry_url/image_name:image_tag  这里我们tag一个jenkins镜像
[root@rancher-server]/# docker tag jenkins 192.168.2.22:5000/jenkins 
#Push镜像到私有Registry
[root@rancher-server]/# docker push 192.168.2.22:5000/jenkins
The push refers to a repository [192.168.2.22:5000/jenkins]
7105667cc19d: Image successfully pushed 
5f70bf18a086: Image successfully pushed 
8931f5a4c543: Image successfully pushed 
3d2200f39554: Image successfully pushed 
edc3eb62ecee: Image successfully pushed 
4cbfdafef1a6: Image successfully pushed 
7efd3ba34fe9: Image successfully pushed 
451fe6ec6290: Image successfully pushed 
910c11554e05: Image successfully pushed 
18a708dd9f86: Image successfully pushed 
c58360ce048c: Image successfully pushed 
0030e912789f: Image successfully pushed 
0ece0aa9121d: Image successfully pushed 
ef63204109e7: Image successfully pushed 
694ead1cbb4d: Image successfully pushed 
591569fa6c34: Image successfully pushed 
998608e2fcd4: Image successfully pushed 
c12ecfd4861d: Image successfully pushed 
Pushing tag for rev [62f5c69b8249] on {http://192.168.2.22:5000/v1/repositories/jenkins/tags/latest}

从私有 Registry pull 镜像到本地

#删除刚刚Push上去的镜像
[root@rancher-server]/# docker rmi 192.168.2.22:5000/jenkins
Untagged: 192.168.2.22:5000/jenkins:latest
再Pull下来
[root@rancher-server]/# docker pull 192.168.2.22:5000/jenkins
Using default tag: latest
Pulling repository 192.168.2.22:5000/jenkins
62f5c69b8249: Pulling dependent layers 
62f5c69b8249: Pulling image (latest) from 192.168.2.22:5000/jenkins 
c12ecfd4861d: Pulling metadata 
9bed728889e3: Pulling metadata 
284d895cc891: Pulling metadata 
255386472d2e: Pulling metadata 
636d6481a70c: Pulling metadata 
5bdfbeac8908: Pulling metadata 
e156e4746bc6: Pulling metadata 
79539a64183f: Pulling metadata 
43f767d950ba: Pulling metadata 
bb46233dab51: Pulling metadata 
acd71b58286e: Pulling metadata 
fae0335e5f13: Pulling metadata 
988b4f10914a: Pulling metadata 
dbde4f7c26b4: Pulling metadata 
a714af38eb97: Pulling metadata 
a1ffa5c5ac92: Pulling metadata 
43fd34bcdf1c: Pulling metadata 
bf942e9a6196: Pulling metadata 
ace3a12d121b: Pulling metadata 
62f5c69b8249: Already exists 
ba64f08c87cf: Already exists 
d521a4fa3dea: Already exists 
0382e085fcf1: Already exists 
909f5d01a2b5: Already exists 
9752b4caf6ed: Already exists 
4dde5ea7e731: Already exists 
5e37802efb0f: Already exists 
098d97977023: Already exists 
ffc5d1f38cc7: Already exists 
83ec3700b3b9: Already exists 
0e227729a063: Already exists 
acca8465e42e: Already exists 
a6e4e05a09e5: Already exists 
99d9866b6e00: Already exists 
1a6d35263e5b: Already exists 
2453e14f3604: Already exists 
657500b7f74a: Already exists 
dca53caaf190: Already exists 
431ede532da7: Already exists 
Status: Image is up to date for 192.168.2.22:5000/jenkins:latest
192.168.2.22:5000/jenkins: this image was pulled from a legacy registry.  Important: This registry version will not be supported in future versions of docker.
[root@rancher-server]/# docker images | grep  192.168.2.22:5000/jenkins
192.168.2.22:5000/jenkins               latest              2742172fed4c        11 days ago         708.9 MB

Push 到私有 Registry 报错

[root@rancher-agent]~# docker push 192.168.2.22:5000/rancher/agent
The push refers to a repository [192.168.2.22:5000/rancher/agent]
unable to ping registry endpoint https://192.168.2.22:5000/v0/
v2 ping attempt failed with errorGet https://192.168.2.22:5000/v2/: EOF
 v1 ping attempt failed with errorGet https://192.168.2.22:5000/v1/_ping: EOF

修改 docker 启动命令,重启 docker

[root@rancher-server]/# vim /usr/lib/systemd/system/docker.service 
#添加--insecure-registry registry-host:5000

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/docker daemon --insecure-registry 192.168.2.22:5000 -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

#加载新的配置文件
[root@rancher-server]/# systemctl  daemon-reload  
#重启Docker服务
[root@rancher-server]/# systemctl  restart docker.service

重启完成之后再次 Push

Docker 持续集成

使用 Docker 持续集成有什么好处?

  1. 很好的解决环境一致性问题

  2. 加快部署和持续集成

  3. Docker 资源消耗少

Docker-compose

Docker Compose 提供一个简单的基于 YAML 配置语言,用于描述和组装多容器的分布式应用。 使用 docker 定义和运行复杂的应用,使用 compose,可以在一个文件里,定义多容器的应用。只需要三步即可完成一个应用的创建。

#Install
[root@rancher-server]~curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose  
[root@rancher-server]~chmod +x /usr/local/bin/docker-compose 
#clone你之前fork的git仓库
[root@rancher-server]~# git clone https://git.oschina.net/vincent927/second.git
[root@rancher-server]~# cd second
[root@rancher-server]~/second# cat docker-compose.yml 
mysql:
   image: csphere/mysql:5.5
   ports: 
     - "3306:3306"
   volumes:
     - /var/lib/docker/vfs/dir/dataxc:/var/lib/mysql
   hostname: mydb.server.com

tomcat:
   image: csphere/tomcat:7.0.55
   ports:
      - "8080:8080"
   links:
      - mysql:db
   environment:
      - TOMCAT_USER=admin
      - TOMCAT_PASS=admin
   hostname: tomcat.server.com
#这里为了方面我们把image改一下
mysql:
   image: mysql
   ports: 
     - "3306:3306"
   volumes:
     - /var/lib/docker/vfs/dir/dataxc:/var/lib/mysql
   hostname: mydb.server.com

tomcat:
   image: tomcat
   ports:
      - "8080:8080"
   links:
      - mysql:db
   environment:
      - TOMCAT_USER=admin
      - TOMCAT_PASS=admin
   hostname: tomcat.server.com
#启动
[root@rancher-server]~/second# docker-compose up  -d
Recreating second_mysql_1...
Recreating second_tomcat_1...
#查看状态
[root@rancher-server]~/second# docker-compose ps    
     Name                   Command             State           Ports          
------------------------------------------------------------------------------
second_mysql_1    docker-entrypoint.sh mysqld   Up      0.0.0.0:3306->3306/tcp 
second_tomcat_1   catalina.sh run               Up      0.0.0.0:8080->8080/tcp 
#查看日志
[root@rancher-server]~/second# docker-compose logs
Attaching to second_tomcat_1, second_mysql_1
tomcat_1 | 17-Apr-2016 08:04:58.992 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.0.33
tomcat_1 | 17-Apr-2016 08:04:58.994 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Mar 18 2016 20:31:49 UTC
tomcat_1 | 17-Apr-2016 08:04:58.994 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.0.33.0
tomcat_1 | 17-Apr-2016 08:04:58.994 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
tomcat_1 | 17-Apr-2016 08:04:58.994 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            3.10.0-327.10.1.el7.x86_64
tomcat_1 | 17-Apr-2016 08:04:58.994 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
tomcat_1 | 17-Apr-2016 08:04:58.995 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/lib/jvm/java-7-openjdk-amd64/jre
tomcat_1 | 17-Apr-2016 08:04:58.995 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.7.0_95-b00
tomcat_1 | 17-Apr-2016 08:04:58.995 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
tomcat_1 | 17-Apr-2016 08:04:58.995 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
tomcat_1 | 17-Apr-2016 08:04:58.995 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.endorsed.dirs=/usr/local/tomcat/endorsed
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
tomcat_1 | 17-Apr-2016 08:04:58.996 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
tomcat_1 | 17-Apr-2016 08:05:01.179 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
tomcat_1 | 17-Apr-2016 08:05:01.352 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
tomcat_1 | 17-Apr-2016 08:05:01.355 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
tomcat_1 | 17-Apr-2016 08:05:01.357 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
tomcat_1 | 17-Apr-2016 08:05:01.358 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 8408 ms
tomcat_1 | 17-Apr-2016 08:05:01.386 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
tomcat_1 | 17-Apr-2016 08:05:01.386 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.0.33
tomcat_1 | 17-Apr-2016 08:05:01.419 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /usr/local/tomcat/webapps/ROOT
tomcat_1 | 17-Apr-2016 08:05:40.996 INFO [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [38,413] milliseconds.
tomcat_1 | 17-Apr-2016 08:05:42.017 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /usr/local/tomcat/webapps/ROOT has finished in 40,598 ms
tomcat_1 | 17-Apr-2016 08:05:42.018 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /usr/local/tomcat/webapps/docs
tomcat_1 | 17-Apr-2016 08:05:42.084 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /usr/local/tomcat/webapps/docs has finished in 66 ms
tomcat_1 | 17-Apr-2016 08:05:42.085 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /usr/local/tomcat/webapps/examples
tomcat_1 | 17-Apr-2016 08:05:44.082 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /usr/local/tomcat/webapps/examples has finished in 1,997 ms
tomcat_1 | 17-Apr-2016 08:05:44.082 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /usr/local/tomcat/webapps/host-manager
tomcat_1 | 17-Apr-2016 08:05:44.123 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /usr/local/tomcat/webapps/host-manager has finished in 41 ms
tomcat_1 | 17-Apr-2016 08:05:44.130 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /usr/local/tomcat/webapps/manager
tomcat_1 | 17-Apr-2016 08:05:44.201 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /usr/local/tomcat/webapps/manager has finished in 71 ms
tomcat_1 | 17-Apr-2016 08:05:44.223 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
tomcat_1 | 17-Apr-2016 08:05:44.246 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
tomcat_1 | 17-Apr-2016 08:05:44.251 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 42893 ms
#停止
[root@rancher-server]~/second# docker-compose stop
Stopping second_tomcat_1...
Stopping second_mysql_1...
#删除
[root@rancher-server]~/second# docker-compose rm
Going to remove second_tomcat_1, second_mysql_1
Are you sure? [yN] y
Removing second_mysql_1...
Removing second_tomcat_1...
[root@rancher-server]~/second# docker-compose ps
Name   Command   State   Ports 
------------------------------

Maven 配置

[root@rancher-server]~/maven-tar/
[root@rancher-server]~ cp apache-maven-3.3.3-bin.tar.gz /maven-tar/

Jenklins 安装配置

[root@rancher-server]/jenkins_home# docker run -d -p 8080:8080 --name jenkins -v /usr/bin/docker:/usr/bin/docker -v /./run/docker.sock:/var/run/docker.sock -v /maven-tar:/root -v  /var/jenkins_home jenkins

浏览器访问

http://your-host:8080/

安装 Git 插件

在可选插件里面搜索 git

勾选

git Client Plug-In

Git Parameter Plug-In

直接安装

系统管理 - 全局安全配置

Jenkins 注册新用户

 创建一个新的任务

演示代码地址

https://git.oschina.net/dockerf/build-nginx.git

增加一个构建步骤 - EXCUTE-SHELL

未完待续・・・

我们今天的关于案例 | 持续集成:Docker、Maven、Java基于docker的持续集成系统的分享就到这里,谢谢您的阅读,如果想了解更多关于8.4 Docker Cloud之持续集成和持续部署、Docker 从入门到放弃(四)Docker+Jenkins_自动化持续集成、Docker 入门(三):持续集成、持续部署、Docker 学习笔记 (二) Docker 实战之 Registry 以及持续集成的相关信息,可以在本站进行搜索。

本文标签: