Hexo

点滴积累 豁达处之

0%

docker+jenkins自动化部署

docker容器技术

1 简介

1.1 什么是docker

Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。
Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了Docker,就不用担心环境问题。
总体来说,Docker的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

1.2 docker概念

Docker是开发人员和系统管理员使用容器开发、部署和运行应用程序的平台。使用Linux容器来部署应用程序称为集装箱化。使用docker轻松部署应用程序。

集装箱化的优点:

  • 灵活:即使是复杂的应用程序也可封装。
  • 轻量级:容器利用并共享主机内核。
  • 便携式:您可以在本地构建,部署到云上并在任何地方运行。
  • 可扩展性:您可以增加和自动分发容器副本。
  • 可堆叠:您可以垂直堆叠服务并及时并及时堆叠服务。

1.3 虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真丝系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其它部分毫无影响。

虚拟机的缺点:

  • 资源占用多:虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有1M,虚拟机依然需要几百MB的内容才能运行。
  • 冗余步骤多:虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。
  • 启动慢:启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用陈故乡才能真正运行。

1.4 Linux容器

由于虚拟机存在这个缺点,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写为LXC)。
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
由于容器是进程级别的,相比虚拟机又很多优势。

  • 启动快:容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。
  • 资源占用少:容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所以资源。另外,多个容器可以共享资源,虚拟机都是独享资源。
  • 体积小:容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。

1.5 Docker的用途

Docker的主要用途,目前又三大类:

  • 提供了一次性的环境:比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
  • 提供弹性的云服务:因为Docker容器可以随开随关,很适合动态扩容和所容。
  • 组建微服务架构:通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。

1.6 Docker镜像

操作系统分为内核和用户空间,对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

1.7 docker容器

镜像(image)和容器(container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立宿主的系统下操作一样。这种特性使容器封装的应用比直接在宿主运行更加安全。
前面讲过镜像使用的是分层储存,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,可以称这个味容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践的要求,容器不应该向其存储层写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(volume)、或者绑定宿主目录,在这些位置的读写会跳过存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

1.8 仓库Docker Registry

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(tag);每个标签对应一个镜像。
通常,一个仓库会包含一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件那个版本的镜像。如果不给出标签,将以laest作为默认标签。
以ubuntu镜像为例,ubuntu是仓库的名字,其包含有不同的版本标签,如,14.04,16.04。我们可以通过ubuntu:14.04或者ubuntu:16.04来具体指定所需要哪个版本的镜像。如果忽略了标签,比如ubuntu,那将视为ubuntu:latest。
仓库名经常以两段式路径形式出现,比如jwilder/nginx-proxy,前者意味着Docker Registry多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体Docker Registry的软件或服务。

2 安装与启动

2.1 安装docker

1
2
yum install docker-ce    # 安装社区版
docker -v # 查看docker版本

2.2 设置USTC的镜像

编辑文件 /etc/docker/daemon.json 没有的话就创建一个

在该文件中输入:

1
2
3
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}

2.3 升级到最新版本

  1. 查找主机上关于Docker的软件包

    1
    rpm -qa | grep docker – – 列出包含docker字段的软件的信息
  2. 使用yum remove卸载软件

    1
    2
    3
    # yum remove docker-1.13.1-53.git774336d.el7.centos.x86_64 
    # yum remove docker-client-1.13.1-53.git774336d.el7.centos.x86_64
    # yum remove docker-common-1.13.1-53.git774336d.el7.centos.x86_64
  3. 使用curl升级到最新版

    1
    curl -fsSL https://get.docker.com/ | sh

4 启动与重启

1
2
3
4
5
systemctl restart docker   # 重启docker
systemctl start docker # 启动docker
systemctl status docker # 查看docker状态
systemctl stop docker # 停止docker服务
systemctl enable docker # 开机启动

查看版本信息

1
2
docker version    # 查看Docker版本信息
docker info # 查看Docker系统信息

3 常用命令

1 镜像相关

1.1 列出镜像

1
2
3
[root@izm5e7klp5h59pozbv3fghz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 3556258649b2 11 days ago 64.2MB

结构说明:

  • REPOSITORY:仓库名称
  • TAG:标签名称
  • IMAGE ID:镜像ID
  • CREATED:创建时间
  • SIZE:所占用的空间

值得注意的是,一个镜像可以对象多个标签,判断是否为同一个镜像,我们可以查看它的镜像ID,镜像ID是镜像的唯一标识,如果镜像ID一样,则表示为同一镜像!!!

1.2 搜索镜像

格式: docker search [option] keyword

1
2
3
4
5
6
7
[root@izm5e7klp5h59pozbv3fghz ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 8461 [OK]
mariadb MariaDB is a community-developed fork of MyS… 2916 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 626 [OK]
centurylink/mysql Image containing mysql. Optimized to be link… 60 [OK]
[root@izm5e7klp5h59pozbv3fghz ~]#

格式说明

  • -f, –filter filter 过滤输出的内容
  • –help Print usag
  • –limit int 指定搜索内容展示个数 (default 25)
  • –no-index Don’t truncate output
  • –no-trunc Don’t truncate output
1
2
3
4
5
6
[root@izm5e7klp5h59pozbv3fghz ~]# docker search --filter=stars=100 mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 8461 [OK]
mariadb MariaDB is a community-developed fork of MyS… 2916 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 626 [OK]
[root@izm5e7klp5h59pozbv3fghz ~]#

1.3 获取镜像

格式: docker pull [OPTIONS] NAME[:TAG|@DIGEST]

格式说明:

  • OPTIONS选项。可以使用如下 OPTIONS
    • -a, –all-tags:从镜像仓库中下载所有被标记的镜像
    • –disable-content-trust:跳过验证
  • NAME:仓库名
  • TAG:标签
  • DIGEST:数据摘要
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@izm5e7klp5h59pozbv3fghz ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
a4d8138d0f6b: Pull complete
dbdc36973392: Pull complete
f59d6d019dd5: Pull complete
aaef3e026258: Pull complete
5e86b04a4500: Pull complete
1a6643a2873a: Pull complete
2ad1e30fc17c: Pull complete
16f4e6ee0ca6: Pull complete
928f4d662d23: Pull complete
b8d24294d525: Pull complete
Digest: sha256:2785fac92d1bcd69d98f2461c6799390555a41fd50d3f847b544368d594c637b
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest

1.4 删除镜像

格式: docker image rm [OPTIONS] IMAGE [IMAGE…]

按镜像id删除镜像

1
docker rmi 镜像id

删除所有镜像

1
docker rmi `docker images -q`

2 容器相关

1 查看容器

1
2
3
4
docker ps   # 查看正在运行的容器
docker ps -a # 查看所有容器
docker ps -l # 查看最后一次运行的容器
docker ps -f status=exited # 查看停止的容器

2 创建与启动容器

创建容器参数说明

创建容器命令:docker run

  • **-i : **表示运行容器

  • **-t : **表示容器启动后会进入其命令行,加入这两个参数后,容器创建就能登录进去,即分配一个伪终端

  • **–name : **为创建的容器命名

  • -v : 表示目录映射,(前者是宿主目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射,注意:最好做目录映射,在宿主机上做修改,然后共享到容器上

  • **-d : **在run后面加上-d参数,则会创建一个守护容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i-t两个参数,创建后就会自动进去容器)。

  • **-p : **表示端口映射,前者是宿主机端口,后者是容器的映射端口,可以使用多个端口映射

交互式方式创建容器

1
docker run -it --name=myubuntu ubuntu /bin/bash     #--name=容器名称 镜像名称

这时,通过ps查看,发现可以看到容器已启动,

1
exit;    # 退出当前容器

守护式方式创建容器:

1
2
docker run -di --name=myubuntu2 ubuntu   # 守护式启动 (ubutu)
docker exec -it myubuntu2 /bin/bash # 进入容器(ubuntu)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@izm5e7klp5h59pozbv3fghz ~]# docker run -di --name=myubuntu2 ubuntu 
22fe4c60bf8dbe11ee563ead43e1569a5724b5a549c45441debb9f60b85343fd
[root@izm5e7klp5h59pozbv3fghz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22fe4c60bf8d ubuntu "/bin/bash" About a minute ago Up About a minute myubuntu2
[root@izm5e7klp5h59pozbv3fghz ~]# docker exec -it myubuntu2 /bin/bash
root@22fe4c60bf8d:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@22fe4c60bf8d:/# exit;
exit
[root@izm5e7klp5h59pozbv3fghz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22fe4c60bf8d ubuntu "/bin/bash" 3 minutes ago Up 3 minutes myubuntu2
[root@izm5e7klp5h59pozbv3fghz ~]#

3 停止与启动容器

1
2
docker stop 容器id(或名称)   # 停止容器
docker start 容器id(或名称) # 启动容器

4 文件拷贝

将文件拷贝到容器内

1
docker cp 需要拷贝的文件或目录   容器名称:容器目录
1
2
3
4
5
6
7
8
9
10
11
12
[root@izm5e7klp5h59pozbv3fghz ~]# docker cp /usr/local/project/aa myubuntu2:/usr/local
[root@izm5e7klp5h59pozbv3fghz ~]# docker exec -it myubuntu2 /bin/bash
root@22fe4c60bf8d:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@22fe4c60bf8d:/# cd /usr/local
root@22fe4c60bf8d:/usr/local# ls
aa bin etc games include lib man sbin share src
root@22fe4c60bf8d:/usr/local# cat aa
AAAAAAAAAAAAAAA
AAAAAAAAAAAAA
BBBBBBBBBB
root@22fe4c60bf8d:/usr/local#

将文件从容器中拷贝出发

1
docker cp  容器名称:容器目录   需要拷贝的文件或目录  

5 目录挂载

我们在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件从而去影响容器

创建容器 添加 -v 参数后边为宿主机目录容器:容器目录,例如

1
docker run -di --name=myubuntu3 -v /usr/local/myhtml:/usr/local/myhtml ubuntu

6 查看容器IP

1
docker inspect 容器名称(容器id)

也可以直接执行下面的命令直接输出IP地址

1
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称(容器id)
1
2
3
[root@izm5e7klp5h59pozbv3fghz ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' myubuntu3
172.17.0.3
[root@izm5e7klp5h59pozbv3fghz ~]#

7 删除容器

1
docker rm 容器名称(容器id)
1
2
3
4
5
6
7
8
9
10
[root@izm5e7klp5h59pozbv3fghz ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f2a33ea890b ubuntu "/bin/bash" About an hour ago Exited (0) About an hour ago myubuntu
45f8ba01d6c2 ubuntu "echo 'hello ! I an …" 5 days ago Exited (0) 5 days ago focused_knuth
[root@izm5e7klp5h59pozbv3fghz ~]# docker rm myubuntu
myubuntu
[root@izm5e7klp5h59pozbv3fghz ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45f8ba01d6c2 ubuntu "echo 'hello ! I an …" 5 days ago Exited (0) 5 days ago focused_knuth
[root@izm5e7klp5h59pozbv3fghz ~]#

4 应用部署

1 MYSQL部署

拉取MySQL镜像

1
docker pull centos/mysql-57-centos7

创建容器

1
docker run -di --name=test2_mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 centos/mysql-57-centos7

-p : 代表端口映射,格式为 宿主机映射端口:容器映射端口

-e : 代表添加环境变量,MYSQL_ROOT_PASSWORD 是root用户的登录密码

进入MySQL容器

1
docker exec -it test2_mysql /bin/bash

登录mysql

1
mysql -u root -p

远程登录MySQL

连接宿主机的IP,指定端口为33306

2 Tomcat部署

拉取镜像

1
docker pull tomcat:7-jre7

创建容器

1
docker run -di --name=mytomcat -p 8090:8080 -v /usr/local/webapps:/usr/local/tomcat/webapps tomcat

3 Nginx 部署

拉取镜像

1
docker pull nginx

创建容器

1
docker run -di --name=mynginx -p 80:80 nginx

4 Redis 部署

拉取镜像

1
docker pull redis

创建容器

1
docker run -di --name=myredis -p 6379:6379 redis

5 迁移与备份

容器保存为镜像

1
docker commit mynginx mynginx_1

镜像备份

1
docker save -o mynginx.tar mynginx_1   # 将镜像保存为tar文件

镜像恢复

1
docker load -i mynginx.tar 

-i : 输入的文件

6 Dockerfile

Dockerfile 是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。

命令 作用
FROM 构造的新镜像是基于哪个镜像例如:FROM centos:v1
MAINTAINER 维护者信息 例如:MAINTAINER yanglin
ENV 设置容器内环境变量 例如:ENV MYSQL_ROOT_PASSWORD 123456
RUN 构建镜像时运行的shell命令例如:RUN [“yum”, “install”, “http”]RUN yum install httpd
ADD 拷贝文件或者目录到镜像,如果是URL或者压缩包会自动下载或者自动解压。例如:ADD hom* /mydir/ ADD test relativeDir/
COPY 拷贝文件或者目录到镜像,用法同ADD。 例如:COPY ./startup.sh /startup.sh
WORKDIR 为RUN,CMD,ENTRYPOINT,COPY和ADD设置工作目录。 例如:WORKDIR /data

使用脚本创建镜像

步骤:

1,创建目录

1
mkdir -p /usr/local/dockerjdk8

2,下载jdk并上传到 /usr/local/dockerjdk8 目录

3,创建文件Dockerfile vi Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 依赖镜像名称和id(没有会自动下载)
FROM centos:7
# 指定镜像创建者信息
MAINTAINER root
# 切换工作目录
WORKDIR /usr
RUN mkdir /usr/local/java
# ADD后接相对路径, 把Java添加到容器中
ADD jdk-8u221-linux-x64.tar.gz /usr/local/java/
# 配置Java环境变量
ENV JAVA_HOME=/usr/local/java/jdk1.8.0_221
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/bin/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

4,执行命令构建镜像

1
docker build -t='jdk1.8' .    # 注意后面的点

5,查看镜像是否创建完成

1
docker images

7 Docker 私有仓库

7.1 私有仓库搭建与配置

1,拉取私有仓库镜像

1
docker pull registry

2,启动私有仓库容器

1
docker run -di --name=registry -p 5000:5000 registry

3,打开浏览器输入地址:http://120.27.71.186:5000/v2/_catalog 看到 {"repositories":[]}表示私有仓库搭建成功并且内容为空

4,修改daemon.json

1
vi /etc/docker/daemon.json

添加内容 : “insecure-registries”: [“120.27.71.186:5000”] 此步用于让docker信任私有仓库地址

1
2
3
4
5
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"],
"insecure-registrs": ["120.27.71.186:5000"]
}

5,重启docker服务

1
systemctl restart docker

7.2 镜像上传到私有仓库

1,标记此镜像为私有仓库的镜像

1
docker tag jdk1.8 120.27.71.186:5000/jdk1.8

2,上传标记的镜像

1
docker push 120.27.71.186:5000/jdk1.8

8 DockerMaven插件

1 Maven插件自动部署

修改宿主机docker配置,让其可以远程访问

1
vi /lib/systemd/system/docker.service

其中ExecStart=后添加配置 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

修改后如下:

1
2
3
4
5
6
7
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
ExecReload=/bin/kill -s HUP $MAINPID

刷新配置,重启服务

1
2
3
systemctl daemon-reload     # 刷新配置
systemctl restart docker # 重启docker
docker start registry # 启动镜像仓库

在工程pom.xml增加配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<build>
<finalName>app</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>0.4.13</version>
<configuration>
<!--用于指定镜像名称-->
<imageName>120.27.71.186:5000/${project.artifactId}:${project.version}</imageName>
<!--用于指定基础镜像,相当于Dockerfile中的FROM指令-->
<baseImage>jdk1.8</baseImage>
<!--相当于Dockerfile的ENTRYPOINT指令-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!--是否跳过docker build-->
<!-- <skipDockerBuild>true</skipDockerBuild>-->
<resources>
<resource>
<targetPath>/</targetPath>
<!--用于指定需要复制的根目录,${project.build.directory}表示target目录-->
<directory>${project.build.directory}</directory>
<!--用于指定需要复制的文件。${project.build.finalName}.jar指的是打包后的jar包文件。-->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<dockerHost>http://120.27.71.186:2375</dockerHost>
</configuration>
</plugin>
</plugins>
</build>

以上配置会自动生成Dockerfile

1
2
3
FROM jdk1.8
ADD app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

在项目目录下输入以下命令进行打包和上传镜像

1
2
mvn clean package docker:build              # 生成一个镜像
mvn clean package docker:build -DpushImage # 生成的镜像推送到镜像注册中心

启动容器

1
docker run -id --name=demo03 -p 9001:9001 120.27.71.186:5000/demo3

9 jenkins 持续集成

1 JDK安装

执行命令:

1
2
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html     # JDK下载链接
rpm -ivh jdk-8u221-linux-x64.rpm

RPM方式安装JDK,其根目录为:/usr/java/jdk1.8.0_221-amd64

2 Jenkins安装与启动

1 下载Jenkins

1
https://pkg.jenkins.io/redhat-stable/   # jenkins下载链接

2 安装

1
rpm -ivh jenkins-2.186-1.1.noarch.rpm

3 配置

1
vi /etc/sysconfig/jenkins 

4 修改用户和端口

1
2
JENKINS_USER="root"
JENKINS_PORT="8888"

5 启动服务

1
systemctl start jenkins

6 链接配置

访问:120.27.71.186:8888

jenkins_01

此时出现填写密码的选型:根据提示进入指定目录取出密码填写

jenkins_02

选择插件安装 这里安装推荐插件

jenkins_03

这里进入了主页面

7 插件安装

主页面选择–系统管理—插件管理 进入插件安装页面

jenkins_04

选择需要安装的插件 这里选了Maven Integration plugin

8 全局工具配置

主页面选择–系统管理—全局工具配置 进入全局工具配置页面

配置jdk 确保jdk路径配置正确

jenkins_05

配置maven 确保maven路径配置正确

jenkins_06

maven 仓库可自定义配置,然后可填充仓库jar包,避免打包时长时间下载jar包

10 docker 搭建gogs

1 下载镜像

1
docker pull gogs/gogs

2 创建容器

1
docker run -id --name=gogs/gogs -p 10022:22 -p 3000:3000 -v /var/gogsdata:/data gogs/gogs

3 配置gogs

打开浏览器输入:http://120.27.71.186:3000

Docker_gogs01

Docker_gogs02

配置信息如下:

1
2
3
数据库信息:SQLite3
域名:120.27.71.186
应用URL:http://120.27.71.186:3000/

11 Jenkins 任务配置与启动

Docker_gogs03

输入任务名称,选择构建maven项目,确定

Docker_gogs04

配置描述,源码管理,Build

1
2
3
4
5
# 源码管理配置
Repository URL : http://120.27.71.186:3000/chenqingsong/demo01.git
# build配置
Root POM: demo3/pom.xml # 具体项目的pom文件
Goals and options:clean package docker:build -DpushImage # maven打包命令

13 Jenkins+docker自动化部署

1 jenkins构建maven项目

Docker_jenkins01

2 填写jenkins配置

配置Git仓库

Docker_jenkins02

1
2
# 此处配置的Git仓库:
http://120.27.71.186:3000/chenqingsong/demo01.git

配置pom及maven打包命令

Docker_jenkins03

1
2
3
# 此处配置的pom相对目录及打包命令:
demo2/pom.xml
clean package

3 构建

执行构建,查看Jenkins工作空间下的打包文件

Docker_jenkins06

Docker_jenkins05

1
2
# 我的Jenkins工作目录:
/var/lib/jenkins/workspace/

到此jenkins构建成功 我们可以拿到项目构建的最新jar包(//var/lib/jenkins/workspace/docker-test/docker-test/target/docke-test.jar),接下来就要考虑怎么把jar包自动化部署到docker容器中。

4 编写Dockerfile文件

在项目操作的路径(/work/project)下创建Dockerfile文件

Docker_jenkins07

编辑Dockerfile文件内容为

1
2
3
4
5
6
7
8
#基于jdk1.8
FROM jdk1.8

# 指定当前操作目录
WORKDIR /work/project

#容器启动后执行的操作
CMD java -jar docker-test.jar

5 编写jenkins中打包成功后执行的shell脚本

打开jenkins中的配置选择 Post Steps - Add post-build step - 执行shell

Docker_jenkins04

脚本值设置为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#操作/项目路径(Dockerfile存放的路劲)
BASE_PATH=/work/project
# 源jar路径
SOURCE_PATH=/var/lib/jenkins/workspace
#docker 镜像/容器名字或者jar名字 这里都命名为这个
SERVER_NAME=docker-test
#容器id
CID=$(docker ps | grep "$SERVER_NAME" | awk '{print $1}')
#镜像id
IID=$(docker images | grep "$SERVER_NAME" | awk '{print $3}')

DATE=`date +%Y%m%d%H%M`

# 最新构建代码 移动到项目环境
function transfer(){
echo "最新构建代码 $SOURCE_PATH/$SERVER_NAME/target/$SERVER_NAME.jar 迁移至 $BASE_PATH ...."
cp $SOURCE_PATH/$SERVER_NAME/$SERVER_NAME/target/$SERVER_NAME.jar $BASE_PATH
echo "迁移完成"
}

# 备份
function backup(){
if [ -f "$BASE_PATH/$SERVER_NAME.jar" ]; then
echo "$SERVER_NAME.jar 备份..."
cp $BASE_PATH/$SERVER_NAME.jar $BASE_PATH/backup/$SERVER_NAME-$DATE.jar
echo "备份 $SERVER_NAME.jar 完成"
else
echo "$BASE_PATH/$SERVER_NAME.jar不存在,跳过备份"
fi
}

# 构建docker镜像
function build(){
if [ -n "$IID" ]; then
echo "存在$SERVER_NAME镜像,IID=$IID"
else
echo "不存在$SERVER_NAME镜像,开始构建镜像"
cd $BASE_PATH
docker build -t $SERVER_NAME .
fi
}

# 运行docker容器
function run(){
backup
transfer
build
if [ -n "$CID" ]; then
echo "存在$SERVER_NAME容器,CID=$CID,重启docker容器 ..."
docker restart $SERVER_NAME
echo "$SERVER_NAME容器重启完成"
else
echo "不存在$SERVER_NAME容器,docker run创建容器..."
docker run --name $SERVER_NAME -v $BASE_PATH:$BASE_PATH -d -p 8081:8080 $SERVER_NAME
echo "$SERVER_NAME容器创建完成"
fi
}

#入口
run

shell脚本流程解释:

a.备份(/work/project)下jar包

1
cp /work/project/docker-test.jar /work/project/backup/docker-test-201805171416.jar

b.项目构建的最新jar包(/var/lib/jenkins/workspace/docker-test/docker-test/target/docke-test.jar)移动到项目操作的路径(/work/project)

1
cp /var/lib/jenkins/workspace/docker-test/docker-test/target/docker-test.jar /work/project

c.判断docker镜像是否存在,不存在则进入Dockerfile存放的路径(/work/project)执行docker build操作构建名字为docker-test镜像

1
2
cd /work/project
docker build -t docker-test .

d.判断docker容器是否存在,不存在则执行docker run命令创建容器,存在则docker restart重启容器

1
2
docker run --name docker-test -v /work/project/:/work/project/ -d -p 8081:8080 docker-test
docker restart docker-test

6 效果检测

上步操作脚本写好保存后 点击立即构建查看日志如下图代表项目自动化打包构建成功

Docker_jenkins08

查看镜像:

Docker_jenkins09

查看容器

Docker_jenkins10

接口代码内容:

Docker_jenkins12

访问连接:

Docker_jenkins11

可以发现项目修改重新自动部署成功~