1.环境规划
本教程使用4台虚拟机作为服务器,系统均为centos7.x版本。
角色 | IP |
---|---|
Docker Swarm Manager | 192.168.2.129 |
Docker Swarm Worker | 192.168.2.130 |
Docker Swarm Worker | 192.168.2.131 |
Docker/Jenkins/Harbor/Gitlab | 192.168.2.132 |
2.Docker/Docker-Compose安装(所有服务器)
2.1 卸载旧版Dokcer
sudo yum remove docker docker-common container-selinux docker-selinux docker-engine
复制代码
2.2 安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
复制代码
2.3 添加阿里云yum源
本教程中使用阿里云docker yum源,亦可使用网易163,清华等yum源。
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
复制代码
2.4 更新并安装Docker CE
sudo yum makecache fast
sudo yum -y install docker-ce
复制代码
2.5 启动Docker
sudo service docker start
复制代码
2.6 添加阿里云镜像加速器
阿里云镜像加速地址可在此获取[cr.console.aliyun.com/cn-hangzhou…] 。xxxx.mirror.aliyncs.com换成对应加速器地址即可。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
#重新加载配置并重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
复制代码
2.7 安装Docker-Compose
docker-compose最新版本见官网文档[docs.docker.com/compose/ins…], 版本中使用版本为1.25.5
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
复制代码
验证是否安装成功
3.Docker Swarm集群安装
在129,130,131三台服务,其中129位manager节点,130、131为worker节点。
3.1 修改Docker启动参数
vim /lib/systemd/system/docker.service
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://bvmsud8x.mirror.aliyuncs.com"],
"hosts": ["192.168.2.129:2375","unix:///var/run/docker.sock"]
}
systemctl daemon-reload
systemctl restart docker
复制代码
3.2 安装docker swarm
3.2.1 开启相应端口(与关闭防火墙二者选其一)
# TCP端口2377集群管理端口
# TCP与 UDP端口7946节点之间通讯端口
# TCP与 UDP端口4789 overlay 网络通讯端口
firewall-cmd --zone=public --add-port=2377/tcp --permanent
firewall-cmd --zone=public --add-port=7946/tcp --permanent
firewall-cmd --zone=public --add-port=7946/udp --permanent
firewall-cmd --zone=public --add-port=4789/tcp --permanent
firewall-cmd --zone=public --add-port=4789/udp --permanent
firewall-cmd --reload
复制代码
3.2.2 manager节点
在manager节点执行即可
#192.168.2.129为当前执行机器ip 如果多网卡必填
docker swarm init --advertise-addr 192.168.2.129
复制代码
执行结果如下:
3.2.3 worker节点
在worker节点执行
manager节点执行完命令后,可以从打印出的信息看到如下命令即可添加worker节点
docker swarm join --token SWMTKN-1-0a3ulzft9wrjbf8to4akangmajva2qptkrilmrofh8c35k3roh-ebei8ptaulxr88vnls5iq4qlc 192.168.2.129:2377
复制代码
3.2.4 验证是否成功
docker node ls #查看节点信息
复制代码
4.Docker私有仓库Harbor安装
harbor下载地址[github.com/goharbor/ha…]
本文中使用2.0.0离线版本。
4.1 下载安装包,解压
wget https://github.com/goharbor/harbor/releases/download/v2.0.0/harbor-offline-installer-v2.0.0.tgz
tar -zvxf hharbor-offline-installer-v2.0.0.tgz
复制代码
4.2 安装harbor
修改harbor.yml文件
hostname: 192.168.2.132 #安装机器ip地址
#https:
# # https port for harbor, default is 443
# port: 443
# # The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
复制代码
启动
#加载harbor配置
./prepare
#安装harbor
./install.sh
docker-compose up -d 启动
docker-compose stop 停止
docker-compose restart 重新启动
复制代码
4.3 验证安装
默认用户名密码 admin Harbor12345
4.4 docker配置私服地址
修改daemon.json,增加Docker私服ip配置。
vim /etc/docker/daemon.json
"insecure-registries":["192.168.2.132"]
复制代码
5.基于Docker的Jenkins安装
5.1 自定义Jenkins Docker镜像
5.1.1 定义Dockerfile,并制作镜像
可按需在镜像中增加所需环境。
FROM jenkins/jenkins:lts
MAINTAINER Trazen <trazen@126.com>
USER root
RUN echo '' > /etc/apt/sources.list.d/jessie-backports.list \
&& echo "deb http://mirrors.aliyun.com/debian jessie main contrib non-free" > /etc/apt/sources.list \
&& echo "deb http://mirrors.aliyun.com/debian jessie-updates main contrib non-free" >> /etc/apt/sources.list \
&& echo "deb http://mirrors.aliyun.com/debian-security jessie/updates main contrib non-free" >> /etc/apt/sources.list
#更新源并安装缺少的包
RUN apt-get update && apt-get install -y libltdl7
ARG dockerGid=999
RUN echo "docker:x:${dockerGid}:jenkins" >> /etc/group USER jenkins
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
复制代码
#构建docker镜像
docker build -t trazen/jenkins:lts .
复制代码
5.1.2 定义docker-compose.yml
本教程中jenkins构建所需jdk,maven等环境直接挂载宿主机现有环境目录。亦可在容器中安装相应功能使用。
version: '3'
services:
jenkins:
image: 'trazen/jenkins:lts'
container_name: jenkins
restart: always
ports:
- '8080:8080'
- '50000:50000'
volumes:
- '/home/jenkins/data:/var/jenkins_home' #宿主机jenkins数据目录挂载
- '/usr/local/bin/docker-compose:/usr/local/bin/docker-compose' #宿主机docker-compose挂载
- '/usr/bin/docker:/usr/bin/docker' #解决docker in docker
- '/var/run/docker.sock:/var/run/docker.sock'
- '/etc/localtime:/etc/localtime:ro'
- '/opt/jdk1.8.0_161:/var/local/jdk1.8.0_161' #宿主机jdk挂载
- '/opt/jdk1.8.0_161/bin/java:/usr/bin/jdk1.8.0_161/java'
- '/usr/bin/mv:/usr/bin/mv'
- '/opt/apache-maven-3.6.3:/var/local/apache-maven-3.6.3' #宿主机maven挂载
- '/opt/apache-maven-3.6.3/conf/settings.xml:/var/jenkins_home/.m2/settings.xml'
- '/opt/repository:/var/local/repository'
复制代码
5.1.3 定义启动脚本start_jenkins.sh
#!/bin/bash
#创建数据目录
mkdir -p /home/jenkins/data
chown -R 1000:1000 /home/jenkins/data
#启动jenkins
docker-compose up -d
复制代码
5.1.4 Jenkins插件安装
5.2 制作jenkins slave镜像
5.2.1 定义jenkins slave Dockfile文件
次镜像主要为构建java语言maven项目环境,可自定义在Dockerfile中安装其他编译环境
FROM openjdk:8-jdk
LABEL MAINTAINER="Trazen <trazen@126.com>"
#####################################################
# arguments
ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
ARG JENKINS_AGENT_HOME=/home/${user}
ARG JNLP_SLAVE_VERSION=3.28
#####################################################
# environments
ENV DEBIAN_FRONTEND noninteractive
ENV JENKINS_AGENT_HOME ${JENKINS_AGENT_HOME}
ENV JNLP_SLAVE_VERSION ${JNLP_SLAVE_VERSION}
ENV DOCKER_VERSION 18.09.0
ENV DOCKER_CHANNEL stable
ENV DOCKER_ARCH x86_64
ENV DIND_COMMIT 52379fa76dee07ca038624d639d9e14f4fb719ff
#####################################################
# create jenkins user
RUN groupadd -g ${gid} ${group} \
&& useradd -d "${JENKINS_AGENT_HOME}" -u "${uid}" -g "${gid}" -m -s /bin/bash "${user}"
RUN mkdir ${JENKINS_AGENT_HOME}/.jenkins
#####################################################
# 更新阿里云的stretch版本包源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
echo "deb http://mirrors.163.com/debian/ buster main non-free contrib" > /etc/apt/sources.list && \
echo "deb http://mirrors.163.com/debian/ buster-updates main non-free contrib" >> /etc/apt/sources.list && \
echo "deb http://mirrors.163.com/debian/ buster-backports main non-free contrib" >> /etc/apt/sources.list && \
echo "deb-src http://mirrors.163.com/debian/ buster main non-free contrib" >> /etc/apt/sources.list && \
echo "deb-src http://mirrors.163.com/debian/ buster-updates main non-free contrib" >> /etc/apt/sources.list && \
echo "deb-src http://mirrors.163.com/debian/ buster-backports main non-free contrib" >> /etc/apt/sources.list && \
echo "deb http://mirrors.163.com/debian-security/ buster/updates main non-free contrib" >> /etc/apt/sources.list && \
echo "deb-src http://mirrors.163.com/debian-security/ buster/updates main non-free contrib" >> /etc/apt/sources.list
#####################################################
# install required packages
# - build-essential: provide make and gcc which will be used in "npm install"
# - sshpass: allow ssh to other servers
# - bzip2: used by installing firefox
# - gnome-keyring: required by keytar
# - libsecret-1-dev: required by npm install rebuild keytar
# - dbus-x11: includes dbus-launch
# - libdbus-glib-1-2: used by firefox
# - libx11-dev libxkbfile-dev: required by theia
# - xvfb: required by cypress
# - iptables: required by docker
RUN apt-get update && apt-get install --no-install-recommends -y \
openssh-server \
vim curl wget rsync pax build-essential sshpass zip jq locales \
iptables
#####################################################
# configure locale
RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen \
&& /usr/sbin/locale-gen
#####################################################
# install jnlp slave jar
RUN curl --create-dirs -fsSLo /usr/share/jenkins/slave.jar https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/${JNLP_SLAVE_VERSION}/remoting-${JNLP_SLAVE_VERSION}.jar \
&& chmod 755 /usr/share/jenkins \
&& chmod 644 /usr/share/jenkins/slave.jar
#####################################################
# install docker
RUN set -eux; \
groupadd docker; \
useradd -g docker docker; \
usermod -aG docker ${user}; \
if ! wget -O docker.tgz "http://192.168.29.188:8888/linux/static/${DOCKER_CHANNEL}/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz"; then \
echo >&2 "error: failed to download 'docker-${DOCKER_VERSION}' from '${DOCKER_CHANNEL}' for '${DOCKER_ARCH}'"; \
exit 1; \
fi; \
\
tar --extract \
--file docker.tgz \
--strip-components 1 \
--directory /usr/local/bin/ \
; \
rm docker.tgz; \
\
dockerd --version; \
docker --version; \
wget -O /usr/local/bin/dind "https://raw.githubusercontent.com/docker/docker/${DIND_COMMIT}/hack/dind"; \
chmod +x /usr/local/bin/dind
#####################################################
# Clean apt cache
RUN rm -rf /var/lib/apt/lists/*
#####################################################
# the new "openjdk:8-jdk" base image put Java in "/usr/local/openjdk-8" folder
# we need a symlink
RUN mkdir -p /usr/java \
&& ln -s /usr/local/openjdk-8 /usr/java/openjdk-8 \
&& ln -s /usr/local/openjdk-8 /usr/java/default
###########
# Maven3.6.3
###########
ENV MAVEN_VERSION=3.6.3
RUN curl -fsSL http://192.168.29.188:8888/apache-maven-3.6.3-bin.tar.gz | tar xzf - -C /usr/share \
&& mv /usr/share/apache-maven-$MAVEN_VERSION /usr/share/maven \
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
ENV MAVEN_HOME=/usr/share/maven
###########
# Docker Compose
###########
RUN curl -L http://192.168.29.188:8888/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose && \
chmod +x /usr/local/bin/docker-compose && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#####################################################
# define volume
VOLUME "${JENKINS_AGENT_HOME}" "/tmp" "/run" "/var/run"
WORKDIR "${JENKINS_AGENT_HOME}"
# switch back to root user
USER root
#####################################################
# expose and entrypoint
EXPOSE 22
COPY setup-entrypoint /usr/local/bin/setup-entrypoint
RUN chmod +x /usr/local/bin/setup-entrypoint
ENTRYPOINT ["/usr/local/bin/setup-entrypoint"]
复制代码
5.2.2 定义容器脚本setup-entrypoint
#!/bin/bash
set -ex
################################################################################
# Use for testing (not as Jenkins agent):
# docker run <image/id> <command>
# Use as SSH agent:
# docker run <image/id> [<public key>]
# Or provide in environment variables :
# * JENKINS_SLAVE_SSH_PUBKEY : SSH public key
#
# Use as regular JNLP agent:
# docker run <image/id> [options] -url http://jenkins [SECRET] [AGENT_NAME]
# Optional environment variables :
# * JENKINS_TUNNEL : HOST:PORT for a tunnel to route TCP traffic to jenkins host, when jenkins can't be directly accessed over network
# * JENKINS_URL : alternate jenkins URL
# * JENKINS_SECRET : agent secret, if not set as an argument
# * JENKINS_AGENT_NAME : agent name, if not set as an argument
# * JENKINS_AGENT_WORKDIR : agent work directory, if not set by optional parameter -workDir
#
# Use as JNLP agent run in Docker Swarm:
# docker run <image/id>
# Required environment variables :
# * DOCKER_SWARM_PLUGIN_JENKINS_AGENT_SECRET : jenkins secret if run as swarm agent
# * DOCKER_SWARM_PLUGIN_JENKINS_AGENT_JAR_URL : jenkins url if run as swarm agent
# * DOCKER_SWARM_PLUGIN_JENKINS_AGENT_JNLP_URL : jenkins jnlp url if run as swarm agent
write_key() {
mkdir -p "${JENKINS_AGENT_HOME}/.ssh"
echo "$1" > "${JENKINS_AGENT_HOME}/.ssh/authorized_keys"
chown -Rf jenkins:jenkins "${JENKINS_AGENT_HOME}/.ssh"
chmod 0700 -R "${JENKINS_AGENT_HOME}/.ssh"
}
echo "============ Environment Variables Start ===================================="
env
echo "============ Environment Variables End ======================================"
################################################################################
# start docker-in-docker
exec "$(which dind)" dockerd \
--host=unix:///var/run/docker.sock \
--host=tcp://0.0.0.0:2375 &
################################################################################
# determine which mode to run, default is jnlp
START_MODE=JNLP
if [ -n "$DOCKER_SWARM_PLUGIN_JENKINS_AGENT_JNLP_URL" ]; then
START_MODE=SWARM
elif [ -n "$JENKINS_SLAVE_SSH_PUBKEY" ]; then
START_MODE=SSH
elif [ $# -gt 0 ]; then
echo "============ Command Line Start ===================================="
echo $@
echo "============ Command Line End ======================================"
if [[ $1 == ssh-* ]]; then
# only one parameter and it starts with "ssh-", so it's a SSH public key
START_MODE=SSH
elif [[ $1 == "/usr/sbin/sshd" ]]; then
# docker plugin may start container with this command:
# /usr/sbin/sshd -D -p 22 -o AuthorizedKeysCommand=/root/authorized_key -o AuthorizedKeysCommandUser=root
START_MODE=SSH
elif [[ $1 == "sh" ]]; then
# if `docker run` only has one arguments, we assume user is running alternate
# command like `bash` to inspect the image
START_MODE=COMMAND
fi
fi
echo ">>>>>> Docker container will be started in $START_MODE mode. <<<<<<"
################################################################################
# start mode: command
# user run own command like bash
if [ "$START_MODE" = "COMMAND" ]; then
exec "$@"
################################################################################
# start mode: jnlp
elif [ "$START_MODE" = "JNLP" ]; then
# if -tunnel is not provided, try env vars
case "$@" in
*"-tunnel "*) ;;
*)
if [ ! -z "$JENKINS_TUNNEL" ]; then
TUNNEL="-tunnel $JENKINS_TUNNEL"
fi ;;
esac
# if -workDir is not provided, try env vars
if [ ! -z "$JENKINS_AGENT_WORKDIR" ]; then
case "$@" in
*"-workDir"*) echo "Warning: Work directory is defined twice in command-line arguments and the environment variable" ;;
*)
WORKDIR="-workDir $JENKINS_AGENT_WORKDIR" ;;
esac
fi
if [ -n "$JENKINS_URL" ]; then
URL="-url $JENKINS_URL"
fi
if [ -n "$JENKINS_NAME" ]; then
JENKINS_AGENT_NAME="$JENKINS_NAME"
fi
if [ -z "$JNLP_PROTOCOL_OPTS" ]; then
echo "Warning: JnlpProtocol3 is disabled by default, use JNLP_PROTOCOL_OPTS to alter the behavior"
JNLP_PROTOCOL_OPTS="-Dorg.jenkinsci.remoting.engine.JnlpProtocol3.disabled=true"
fi
# if java home is defined, use it
JAVA_BIN="java"
if [ "$JAVA_HOME" ]; then
JAVA_BIN="$JAVA_HOME/bin/java"
fi
# if both required options are defined, do not pass the parameters
OPT_JENKINS_SECRET=""
if [ -n "$JENKINS_SECRET" ]; then
case "$@" in
*"${JENKINS_SECRET}"*) echo "Warning: SECRET is defined twice in command-line arguments and the environment variable" ;;
*)
OPT_JENKINS_SECRET="${JENKINS_SECRET}" ;;
esac
fi
OPT_JENKINS_AGENT_NAME=""
if [ -n "$JENKINS_AGENT_NAME" ]; then
case "$@" in
*"${JENKINS_AGENT_NAME}"*) echo "Warning: AGENT_NAME is defined twice in command-line arguments and the environment variable" ;;
*)
OPT_JENKINS_AGENT_NAME="${JENKINS_AGENT_NAME}" ;;
esac
fi
#TODO: Handle the case when the command-line and Environment variable contain different values.
#It is fine it blows up for now since it should lead to an error anyway.
exec $JAVA_BIN $JAVA_OPTS $JNLP_PROTOCOL_OPTS -cp /usr/share/jenkins/slave.jar hudson.remoting.jnlp.Main -headless $TUNNEL $URL $WORKDIR $OPT_JENKINS_SECRET $OPT_JENKINS_AGENT_NAME "$@"
################################################################################
# start mode: jnlp in swarm
elif [ "$START_MODE" = "SWARM" ]; then
# this container is started with Jenkins Docker Swarm Plugin, need to start slave
curl --connect-timeout 20 --max-time 60 -o slave.jar $DOCKER_SWARM_PLUGIN_JENKINS_AGENT_JAR_URL && \
exec java -jar slave.jar -jnlpUrl $DOCKER_SWARM_PLUGIN_JENKINS_AGENT_JNLP_URL \
-secret $DOCKER_SWARM_PLUGIN_JENKINS_AGENT_SECRET \
-noReconnect -workDir $JENKINS_AGENT_HOME
################################################################################
# start mode: ssh
elif [ "$START_MODE" = "SSH" ]; then
# this container is started with ssh?
if [[ $JENKINS_SLAVE_SSH_PUBKEY == ssh-* ]]; then
write_key "${JENKINS_SLAVE_SSH_PUBKEY}"
fi
if [[ $# -gt 0 ]]; then
if [[ $1 == ssh-* ]]; then
write_key "$1"
shift 1
else
exec "$@"
fi
fi
# ensure variables passed to docker container are also exposed to ssh sessions
env | grep _ >> /etc/environment
# start SSHd
ssh-keygen -A
exec /usr/sbin/sshd -D -e "${@}"
fi
复制代码
#构建docker镜像
docker build -t trazen/jenkins_slave_java .
复制代码
5.3 Jenkins与Docker Swarm的集成
Jenkins与Docker Swarm的集成依赖依赖于Jenkins Docker Swarm Plugin插件。
下图为本文中架构图,Jenkins Master单独安装在一台Docker环境中,亦可安装在Docker Swarm【需要注意的是Jenkins Master需要固定安装到所有Swarm Manager节点】,Docker Swarm中为Jenkins动态Slave节点。相比较于传统的Jenkins Master Slave架构,在节省服务器资源的同时也更加充分利用闲置资源。
5.3.1 集成配置
5.4.2 基于流水线的动态Jenkins Slave测试
新建一个流水线任务,pileline脚本如下:
pipeline {
agent {
label 'jnlp-slave-java'
}
stages {
stage('Hello') {
steps {
echo 'Hello World'
sh 'mvn -v'
sh 'docker images'
sleep 20
}
}
}
}
复制代码
6.基于流水线发布SpringBoot项目到Docker Swarm集群
6.1 SpringBoot演示项目
DemoController.java
@RestController
public class DemoController {
@GetMapping("/demo")
public Object test(){
return "springboot demo!";
}
}
复制代码
Dockerfile
FROM openjdk:8-jre
MAINTAINER Trazen<trazen@126.com>
#设置时区
ENV TZ=Asia/Shanghai
RUN cp /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone
COPY target/*.jar /app.jar
EXPOSE 18080
#jvm参数
ENV JAVA_OPTS="-Xms256m -Xmx2g"
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
复制代码
docker-compose.yml
version: "3.8"
services:
springboot-demo:
image: "${DOCKER_IMAGE_URL}"
ports:
- "18080:18080"
volumes:
- /opt/logs:/opt/logs
environment:
- TZ=Asia/Shanghai
deploy:
mode: replicated
#mode为replicated时,指定容器副本的数量
replicas: 1
#该服务分配了一个虚拟 IP(VIP)
endpoint_mode: vip
restart_policy:
#失败重启
condition: on-failure
#资源限制
resources:
limits:
#设置该容器最多只能使用 20% 的 CPU
cpus: "0.2"
#设置该容器最多只能使用 2M 的内存空间
memory: "2G"
networks:
- hxcloud_network
networks:
hxcloud_network:
external: true
name: hxcloud_network
复制代码
6.2 创建流水线任务
如下步骤新建流水线任务
流水线脚本:
def remote = [:]
remote.name = "root"
remote.host = "192.168.2.129"
remote.allowAnyHosts = true
pipeline {
agent any
environment {
//git地址
REPOSITORY="http://192.168.2.132:8090/trazen/springboot-demo.git"
//harbor仓库地址
HARBOR_URL="192.168.2.132:8081"
//镜像namespace
DOCKER_NAMESPACE="dev"
//镜像名称
DOCKER_NAME="springboot-demo"
//打包环境
PROFILE="dev"
//swarm管理节点shell存放目录
SWARM_SHELL_FOLDER="/home/shell"
}
options {
//一时间最多只允许一个pipeline运行
disableConcurrentBuilds()
//保留最新的7个build log和1个artifact
buildDiscarder(logRotator(numToKeepStr: '7',artifactNumToKeepStr: '1',daysToKeepStr: '5'))
}
parameters {
gitParameter name: 'BRANCH_TAG',
type: 'PT_BRANCH_TAG',
branchFilter: 'origin/(release.*)',
defaultValue: 'master',
selectedValue: 'DEFAULT',
sortMode: 'ASCENDING_SMART',
description: 'Select your branch or tag.'
}
stages {
stage('获取代码') {
steps {
echo "start fetch code from ${REPOSITORY}"
checkout([$class: 'GitSCM',
branches: [[name: "${params.BRANCH_TAG}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [],
gitTool: 'Default',
submoduleCfg: [],
userRemoteConfigs: [[url: "${REPOSITORY}",credentialsId: 'gitlab-trazen',]]
])
}
}
stage('Maven构建') {
steps {
withMaven(maven : 'maven3.6.3'){
script {
sh 'mvn clean install -e -U -Dmaven.test.skip=true -P${PROFILE}'
def pom = readMavenPom file:'pom.xml'
print pom.version
env.version = pom.version
}
}
}
}
stage('构建&发布Docker镜像') {
steps {
script {
echo "start build docker image ${HARBOR_URL}"
docker.withRegistry('http://${HARBOR_URL}', 'harbor-tuyong'){
def imageUrl = "${DOCKER_NAMESPACE}/${DOCKER_NAME}:${env.version}"
def customImage = docker.build(imageUrl);
customImage.push()
}
}
}
}
stage ('发布到Docker Swarm') {
steps {
echo "run in Docker Swarm"
withCredentials([sshUserPrivateKey(credentialsId: 'ssh-129',keyFileVariable: 'identity',passphraseVariable: '',usernameVariable: 'userName')]){
script {
remote.user = userName
remote.identityFile = identity
try{
sshCommand remote: remote, command: "sudo mkdir ${SWARM_SHELL_FOLDER}/${DOCKER_NAME}-${PROFILE}"
sshPut remote: remote, from: "docker-compose.yml", into: "${SWARM_SHELL_FOLDER}/${DOCKER_NAME}-${PROFILE}"
def IMAGE_URL = "${HARBOR_URL}/${DOCKER_NAMESPACE}/${DOCKER_NAME}:${env.version}"
def COMPOSE_FOLDER = "/${DOCKER_NAME}-${PROFILE}"
echo "开始部署应用--服务名称:${DOCKER_NAME} 镜像地址:${IMAGE_URL}"
sshCommand remote: remote, command: "${SWARM_SHELL_FOLDER}/deploy-swarm.sh ${DOCKER_NAME} ${IMAGE_URL} ${COMPOSE_FOLDER}"
}
catch (exc) {
echo '发布到Docker Swarm失败!'
throw exc
}
finally{
sshCommand remote: remote, command: "sudo rm -rf ${SWARM_SHELL_FOLDER}/${DOCKER_NAME}-${PROFILE}"
}
}
}
}
}
}
post {
failure {
echo '构建失败'
script{
log_url=env.JENKINS_URL+"blue/organizations/jenkins/"+env.JOB_NAME+"/detail/"+env.JOB_NAME+"/"+env.BUILD_NUMBER+"/pipeline#"
}
echo "${log_url}"
dingtalk (
robot: '43f773e2-a2bc-4fdd-80b0-e8c58f552d62',
type: 'LINK',
title: '构建失败❌',
text: [
"项目信息:${currentBuild.fullDisplayName} ",
"构建结果:${currentBuild.result}",
"构建时间:${currentBuild.durationString}",
"构建镜像:${DOCKER_NAMESPACE}/${DOCKER_NAME}:${env.version}"
],
messageUrl: "${log_url}",
picUrl: 'http://www.iconsdb.com/icons/preview/soylent-red/x-mark-3-xxl.png'
)
}
success {
echo '构建成功'
script{
log_url=env.JENKINS_URL+"blue/organizations/jenkins/"+env.JOB_NAME+"/detail/"+env.JOB_NAME+"/"+env.BUILD_NUMBER+"/pipeline#"
}
dingtalk (
robot: '43f773e2-a2bc-4fdd-80b0-e8c58f552d62',
type: 'LINK',
title: '构建成功✅',
text: [
"项目信息:${currentBuild.fullDisplayName}",
"构建结果:${currentBuild.result}",
"构建时间:${currentBuild.durationString}",
"构建镜像:${DOCKER_NAMESPACE}/${DOCKER_NAME}:${env.version}"
],
messageUrl: "${log_url}",
picUrl: 'http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png'
)
}
}
}
复制代码
6.3 发布脚本以及环境初始化
6.3.1 Docker Swarm主节点定义发布脚本
deploy-swarm.sh
#!/usr/bin/env bash
cd $(dirname $0)
set -e
export APP_NAME=$1
export DOCKER_IMAGE_URL=$2
export COMPOSE_FILE_FOLDER=$3
docker stack deploy -c .$COMPOSE_FILE_FOLDER/docker-compose.yml $APP_NAME
复制代码
6.3.2 Docker Swarm自定义网络
创建专用网络用于发布的项目。
docker network create --driver=overlay --subnet=172.20.0.0/16 --attachable hxcloud_network
复制代码