开发将源码上传到github仓库,通过 Jenkins 持续集成引擎结合 git 工具,将源码拉取到 Jenkins 服务器,通过工具maven在本地将源码编译打包成war包,在ssh到Docker宿主机,通过执行脚本生成制作自定义的Dockerfile,最终执行生成images,并启动container,即启动了包含war包的tomcat,即可实现对外提供web服务。
主机名 | IP地址 | 作用 |
---|---|---|
Docker-server | 172.20.6.20 | Docker宿主机 |
Jenkins-server | 172.20.6.22 | Jenkins服务器 |
Jenkins 的安装及配置 Jenkins 服务器的相关工具(maven、git、ssh)配置,详细步骤可参考 Jenkins笔记(1)的相关工具的安装及配置。
Docker的基础命令可参考容器Docker详解,需要在Docker宿主机pull下tomcat的基础环境以及jenkins服务器通过docker用户登录Docker宿主机,讲war包发布到制定目录,执行特定脚本来生成Dockerfile,最终根据Dockerfile生成images,并启动基于包含war包的container,从而实现对外提供WEB服务。
创建ssh发布用户及目录
useradd docker
echo "docker:docker" |chpasswd #为docker用户设置密码
mkdir -pv /data/dockerfiles/scripts
上传脚本
将脚本上传到 /data/dockerfiles/scripts,命名为devops,此名称可自定义,但是之后在配置jenkins执行ssh命令时候的脚本名称需要一致。由于脚本内部的分发路径是写的绝对路径,所以需要讲目录为固定,也可以根据实际修改。此脚本author:junsansi,可以参考其进行修改。
cat >/data/dockerfiles/scripts/devops.sh<<EOF
#!/bin/bash
# this script function is :
# deploy new docker container
#
# USER YYYY-MM-DD - ACTION
# junsansi 2016-01-25 - CREATED
parasnum=5
# function
help_msg()
{
cat << help
+ Error Cause:
+ you enter $# parameters
+ the total paramenter number must be $parasnum
+ 1st :DOCKER_NAME
+ 2nd :PROJECT_NAME
+ 3rd :PROJECT_VERSION
+ 4th :SOURCE_PORT
+ 5th :DESTINATION_PORT
help
}
# Check parameter number
if [ $# -ne ${parasnum} ]
then
help_msg
exit
fi
# Initialize the parameter.
DOCKER_NAME=$1
PROJECT_NAME=$2
PROJ_VERSION=$3
SPORT=$4
DPORT=$5
PROJ_VERSION=${PROJ_VERSION/"origin/"/""}
DOCKER_FILE="/data/dockerfiles/${DOCKER_NAME}/Dockerfile"
DOCKER_FILE_DIR=/data/dockerfiles/${DOCKER_NAME}
if [ ! -d ${DOCKER_FILE_DIR} ]; then
mkdir -p ${DOCKER_FILE_DIR}
fi
# check docker images
DOCKER_IMAGE=`/usr/bin/docker images | grep ${DOCKER_NAME} | awk -F ' ' '{print $3}'`
if [ -n "${DOCKER_IMAGE}" ]; then
# check docker container
for dc in `/usr/bin/docker ps -a | grep ${DOCKER_NAME} | awk -F " " '{print $1}'`
do
echo "Stop container: ${dc}"
/usr/bin/docker stop ${dc}
# delete while docker container was exists
echo "##Delete exists Container_Id: "${dc}
/usr/bin/docker rm ${dc}
done
# delete while docker image was exists
echo "#Delete exists Image: "${DOCKER_IMAGE}
/usr/bin/docker rmi ${DOCKER_IMAGE}
fi
# Init dockerfile
echo "**Init dockerfile start: "${DOCKER_FILE}
echo "FROM tomcat" > ${DOCKER_FILE}
echo 'MAINTAINER junsansi "junsansi@sina.com"' >> ${DOCKER_FILE}
echo "ADD *.war /usr/local/tomcat/webapps/${PROJECT_NAME}.war" >> ${DOCKER_FILE}
echo "EXPOSE 8080" >> ${DOCKER_FILE}
echo "CMD /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out" >> ${DOCKER_FILE}
cat ${DOCKER_FILE}
echo "**Init dockerfile end."
# Build dockerfile
cd ${DOCKER_FILE_DIR}
rm *.war -rf
mv /data/dockerfiles/war/${DOCKER_NAME}/*.war ./
echo ""
echo "##Build dockerfile for "${DOCKER_NAME}
/usr/bin/docker build -t ${DOCKER_NAME}:${PROJ_VERSION} .
# Run docker container
echo ""
echo "##Running docker container: "${DOCKER_NAME}
/usr/bin/docker run --name ${DOCKER_NAME}_d1 -d -p ${SPORT}:${DPORT} ${DOCKER_NAME}:${PROJ_VERSION}
EOF
chmod +x /data/dockerfiles/scripts/devops.sh
chown docker.docker /data/dockerfiles -R
Docker宿主机获取tomcat镜像
docker pull docker.io/tomcat 使用docker images查看tomcat镜像
此时Docker宿主机就已经配置完毕。
登录Jenkins的WEB界面
系统管理—-系统设置—-Publish over SSH—-增加SSH Server
添加SSH Server可以使用密钥形式添加,也可以直接使用用户名密码, 此处使用用户名密码,选择Use password authentication, or use a different key,即docker用户的密码,进行登录发布,之前已经讲/data/dockerfiles
目录的属主属组更改为docker,确认Jenkins服务器使用docker用户可以正常在此目录下进行后续操作。
为保证Jenkins服务器的磁盘有充足的空间,在选中丢弃旧的构建->保持构建的最大个数为10个
在真实开发环境中,成员直接相互协助,GIT是多分支的,考虑到分支管理,需在此选中参数化构建->选择Git Parameter->定义名称为release_branch,因此选择参数类型为Branch:如果自己发现devops脚本可以看到里面是调用了此参数进行选择构建的分支。
同时创建考虑到创建Docker的名称,此时需要给后续创建的docker images以项目的名称命名。
源码管理选择git,填入仓库url:git@github.com:redhatxl/zrlog.git
此时发现会出现报错信息,因为此仓库为我的私有仓库,需要配置Credentials,点开add, Add Credentials的 Kind选择SSH Username with private key,Username选择之前在github上传的公钥用户的用户名,此次为root,Private Key为jenkins服务器登录github的本地私钥,查看私钥cat /root/.ssh/id_rsa 复制粘贴到Key区域,完成添加。此时可以发现报错已经消失。
在Branches to build模块需要填写之前我们参数话的变量,在此引用$release_branch
在build的Goals and options添加maven构建参考及命令:clean install -D maven.test.skip=true
增加构建后步骤—-选择Send build artifacts over SSH SSH-Server name选择Docker宿主机
Transfers中填写Source files:target/*.war
Remove prefix:target/ Remote directory:/war/$project_name,即在远端/data/dockerfiles下的war目录(/data/dockerfiles/war/docker01-tomcat-zrlog) Exec command:/data/dockerfiles/scripts/devop.sh $project_name zrlog $release_branch 8888 8080
即 Jenkins 服务器ssh到docker宿主机之后执行的脚本命令,执行/data/dockerfiles/scripts/devop.sh脚本,此脚本需要传入5个参考,
两个端口,前一个端口及宿主机的监听端口,后一个端口及映射到docker容器内部的端口,在此处使用的为tomcat,默认的为8080端口。
注意:再次可以添加多个server,即实现集群,可以讲web服务器为无状态,将日志文件挂载到本地物理磁盘以实现日志监控即数据持久化存储。
添加增加构建后操作,选择Editable Email Notification,利用插件邮件来发送通知。
可以根据需求自定义邮件主题与内容,此处添加信息接受人,由于全局配置了always,在高级设置内,填写接受人邮箱。
创建完毕后点击应用并保存。
选择Build with Parameters,然后在右边release_branch内选择需要执行的github上的分支,此处为master,同理选择 project_name,为docker images的name可以选择自己添加自定义的名字,点击开始构建。
查看Console Output
查看邮件通知
登录 Docker 宿主机查看 images 与 container
网页测试
至此利用Jenkins简单的实现了讲github上的源码拉去到Jenkins服务器本地,利用maven编译生成war包并分发到 Docker宿主机,执行脚本生成 Dockerfile,并启动容器,最终邮件通知。
在配置Jenkins的ssh后的命令我们可以添加多个server从而实现分布式,同时我们也可以对在一台主机上通过区分端口号来生成多个images并启动多个不通端口的container。
在General的参数化构建过程中增加第三个参数proxy_port
可以设置为docker宿主机的本地监听端口从而实现多端口多实例
在ssh命令中调用
在构建开始时可以定义不同的images对应不通的端口
查看启动后的容器
注意:如果有特殊需求,例如发布php代码或其他可以自行对脚本进行修改,可以根据需求定义多个参数灵活使用。
来源:https://blog.51cto.com/kaliarch/2051998 转自:DevOps时代