简述
简单的说就是利用jenkins工具来查询我们github上的代码有无发生变化,当github上仓库代码发生变化的时候,jenkins就会根据我们预先设置的步骤帮助我们进行自动构建,并推送到我们的服务器上,推送后调用我们的写好的脚本进行部署,并且可以用dockerfile等脚本来进行docker容器的创建启动。
这篇文章的最终效果是在ubuntu 16系统中,搭建jenkins服务,定时(或githook)的方式从github上拉取maven工程,构建jar包,推送到服务器上,使用docker构建image并启动部署项目。
docker
首先是docker的安装
$ sudo apt-get update
$ sudo apt-get install \
linux-image-extra-$(uname -r) \
linux-image-extra-virtual
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
$ sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
$ sudo systemctl enable docker
$ sudo systemctl start docker
docker的一些简单命令
构建一个容器
docker run --name container-name -d -p port1:port2 -it image-name:tagname
利用这个命令根据镜像创建容器 -d是端口的映射,-v是文件的映射。
而port1和port2是端口映射的部分,port1是宿主机的端口,port2是容器的端口,我们可以在宿主机上通过访问port1的方式访问port2。
容器删除
docker rm ...
列出所有存在的容器
用docker ps
可以列出容器
进入容器的终端
docker exec -it container-name bash
前提是容器中有终端才可以进入这个容器的终端。
宿主机的文件复制到容器
从主机复制到容器sudo docker cp host_path containerID:container_path
从容器复制到主机sudo docker cp containerID:container_path host_path
具体更复杂的使用就要去搜索了
(常用命令)
https://www.cnblogs.com/bethal/p/5945015.html
jenkins
在安装jenkins的时候,可以直接将jenkins安装到系统中,也可以将jenkins通过docker进行安装并启动。我是采用的第二种,如果通过docker来安装启动jenkins的话,后面部署的时候会遇到一些问题,因为我们在部署的时候要通过jenkins来运行脚本来部署我们的项目,而我们的项目又是通过docker创建容器来进行部署的,所以就相当与在一个容器中又调用了docker来创建另一个容器,这样只通过简单的拉取jenkins镜像启动容器是不行的。
我们需要赋予jenkins用户sudo权限以便能在容器内运行Docker命令。当然,也可以将jenkins用户加入到Docker组中来避免在所有Docker命令前使用‘sudo’,不过由于这个组gid的不同会造成不可移植的问题。所以采取的是第一种办法,在原来的jenkins镜像基础上我们做一点修改并重新构建镜像。
创建一个包容以下内容的Dockerfile:(当然在Dockerfile中还可以安装你所需要的东西,不过要去研究一下dockerfile的语法)
FROM jenkinsci/jenkins:lts
USER root
RUN apt-get update \
&& apt-get install -y sudo \
&& rm -rf /var/lib/apt/lists/*
RUN echo “jenkins ALL=NOPASSWD: ALL” >> /etc/sudoers
USER jenkins
构建并运行容器
docker build -t myjenk .
这个命令会执行当前目录下的Dockerfile
运行容器,将Docker socket和程序映射进来
sudo docker run -d -p 8080:8080 -p 50000:50000 --name jenkins -u root -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -v ~/jenkins:/var/jenkins_home myjenk
现在在Jenkins容器内应该可以运行Docker命令了。请注意,这里存在一个重大的安全问题:Jenkins用户对宿主具有root权限,比如Jenkins可以创建装载宿主任意目录的容器。因此,务必确保这个容器只对受信用户访问,并考虑使用VM来将Jekins与宿主其他部分隔离开。
jenkins的配置
通过上面的步骤,就可以在8080端口访问jenkins了,初始的密码在jenkins文件夹下面的secrets文件夹里,有个initialAdminPassword
在本机浏览器通过服务器的8080端口访问jenkins,然后输入密码,新建用户,安装默认插件,跟着他的步骤来问题不大。
需要我们自己手动安装的插件有:(也可以根据自己的需要安装插件,在系统管理的插件管理中安装)
Maven Integration plugin:有了它在新建Job时才能有Maven项目可以选择
Publish Over SSH:通过ssh推送文件,并可以执行shell命令
插件安装完成后最好重启一下jenkins
还需要指定jenkins的jdk和maven,进入系统管理->全局工具配置 ,jdk在jenkins中的/usr/lib/jvm/java-8-openjdk-amd64目录中,maven需要让他自动下载
由于之前安装了Publish Over SSH这个插件来完成后面的将构建结果推送到服务器功能
首先需要到系统管理->系统设置配置Publish over SSH内容。我这里使用的是使用账户密码方式登录(可以使用ssh文件登录)。配置如下:
Passphrase:登录密码
Name:服务器名称(自定)
Hostname:远程服务器地址
Username:登录用户
Remote Directory:访问的远程目录
新建一个Maven项目
下面开始新建一个Maven项目,在主页左侧点击新建,选择构建一个Maven项目,点击确定,主页列表会出现该项目。
然后进行项目的配置
从上到下的配置是(构建时也是按照从上到下进行执行的):
描述:就是项目详情,根据项目情况实际情况随意填写
源码管理:Repositories里面填写giturl,由于开源没有用户密码和ssh文件,下面的Credentials为空即可,如果是gitlab私有库或有权限限制则需要Add,Branches to build选择你需要构建的分支。
构建触发器:选择了两个常用的触发构建方式,触发远程构建让git使用hook的方式访问一个jenkins的url进行触发,轮训SCM是定时检查代码是否有变化,有变化则触发构建,值为5个*,分别表示分钟(0-59),小时(0-23),天(1-31),月份(1-12),周(0-7),其中H表示随机,H/5表示每5分钟检查一次。
Pre Steps:构建前的操作,可以增加执行shell,配置脚本echo “Pre Steps脚本启动成功”,此内容会在构建控制台中打印出来
Build:Root POM配置pom.xml(要构建的工程必须是maven,有pom文件),Goals and options配置clean package(也就是mvn的构建命令)
Post Steps:构建完成后的操作,可以增加执行shell,配置脚本echo "Post Steps脚本启动成功
W
O
R
K
S
P
A
C
E
"
,
{WORKSPACE}",
WORKSPACE",{WORKSPACE}为jenkins的环境变量。上方的3个单选项分别代表构建成功后执行、构建成功或不稳定执行、总是执行
构建后操作:使用Publish Over SSH这个插件,对应的选项是Send build artifacts over SSH
对Send build artifacts over SSH进行配置如下:
SSH server Name:需要SSH连接的Name(刚才配置好的)
Source files:要拷贝的文件地址(相对workspace)
Remove prefix:去掉Source files的前缀部分
Remote directory:要拷贝到host机器的哪个目录(这个目录是相对Remote Directory的目录)
Exec command:拷贝完成执行的命令
我这里需要传输两个文件,一个是构建出的jar包,另一个是Dockerfile。我的配置如下:
(这里的文件路径是相对于jenkins中项目的workspace而言的)
以上步骤就可以完成构建并推送的功能了,更重要的问题在于推送之后如何进行构建。注意到上面我们推送的文件中有一个Dockerfile,并且在推送完成后要执行一个脚本,就是通过.sh脚本来调用Dockerfile来构建我们后台服务器运行的镜像,并且进行一些删除原来旧的镜像和正在运行的同名容器的操作(因为我们在github上代码更新了,所以重新进行部署)
放上我的脚本和Dockerfile来献丑(好像在脚本中忘记删原来的镜像了,只删除了原来的容器)
.sh
docker --version
cd /root/swsad
docker build -t yxq:zgl .
cid=$(docker ps -a| grep "yxq-1.0" | awk '{print $1}')
if [ "$cid" != "" ]; then
docker rm -f $cid
fi
docker run -d --net=host -p 9999:9999 --privileged=true -v /root/swsad/images:/images --name yxq-1.0 yxq:zgl
dockerfile (就是和之前的构建jenkins镜像差不多,我们在这里构建了一个基于java环境的镜像,并且把我们的构建出来的jar包放进去,entrypoint是运行这个镜像的容器时执行的语句)
FROM java:8-alpine
LABEL maintainer="zgl"
ADD swsad-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
要根据自己的具体需要来对dockerfile和脚本进行修改
通过上面的步骤大体就已经完成了自动部署的效果了。如果有什么问题的话可以通过jenkins部署过程中的控制台来debug一下
点进去项目
workspace是拉取的代码以及构建出的东西,configure是进行刚刚的配置,然后下方是我们构建的纪录,点进去
在构建纪录的console output中就可以看到控制台的输出了
一些坑
最后纪录一下可能会遇到的问题:
镜像打包时Dockerfile中要COPY或者ADD的文件找不到
相对路径的问题
https://help.aliyun.com/knowledge_detail/85361.html
Linux 操作**.sh文件时 Permission denied
要加权限
https://blog.youkuaiyun.com/u014520797/article/details/80382792
windows下编辑的脚本等在Linux下运行可能会因为结束符而出现问题
(建议直接在linux下用vim等进行编写,或者本机直接用linux系统)
https://blog.youkuaiyun.com/kobejayandy/article/details/13291525
还有就是用到mysql,redis等其它东西的时候也可以通过docker来进行安装,只要开放对应的端口进行通信就行了。
涉及到一些容器间文件共享的内容
https://blog.youkuaiyun.com/magerguo/article/details/72514813
参考博客:
https://blog.youkuaiyun.com/zhou8622/article/details/52259709
https://blog.youkuaiyun.com/njzcx/article/details/80979157