腾讯云上部署CICD(持续集成)+docker/k8s部署项目


1.部署流程

  • 1、研发push到github代码库(或gitlab)
  • 2、Jenkins 构建,pull git代码使用maven进行编译打包
  • 3、打包生成的代码,生成一个新版本的镜像,push到本地docker仓库harbor
  • 4、发布,测试机器pull新版本的镜像,并删除原来的容器,重新运行新版本镜像。

2.环境说明

服务及服务器说明腾迅云环境、代码仓库

1、 代码仓库

2、容器镜像仓库,部署harbor

  • ip:
    公网:124.222.48.123
  • 主机名:harbor

3、CI/CD服务器,部署jenkins

  • ip:
    公网:1.116.119.87
  • 主机名:jenkins
  • 安装软件:
    • jdk
    • jenkins
    • git
    • maven
    • docker

4、应用服务器(docker/k8s)

  • ip:
    公网:47.236.196.111
  • 主机名:docker
  • 安装软件:
    • jq
    • docker或者k8s集群

3 部署Harbor镜像仓库

3.1、下载安装

1.1 去官方地址下载harbor:

https://github.com/goharbor/harbor/releases
下载离线安装包:需要FQ
如果离线包下载好了,,可以通过打开一个终端执行:scp root@服务器公网ip地址:/root/harbor-offline-installer-v2.12.2.tgz 本地电脑的保存路径,将镜像备份到本地电脑备用

下一步,复制链接地址

下一步,去124.222.48.123服务器上安装harbor

如果特别慢的话,可以使用国内代理下载

wget https://ghproxy.com/https://github.com/goharbor/harbor/releases/download/v2.12.2/harbor-offline-installer-v2.12.2.tgz

harbor-offline-installer-v2.12.2.tgz镜像下载好或者上传好后,需要解压

tar xvf harbor-offline-installer-v2.12.2.tgz

安装

yum -y install lrzsz

安装compose

  • 第1种方式

      curl -L https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    

    或者

      curl -L https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    

    再执行以下命令,加上权限

      chmod +x /usr/local/bin/docker-compose
    

第2种方式,去github下载发布版:

  • 确保docker-compose-linux-x86_64上传到服务器上了

  • 移动文件并重命名:将文件移动到 /usr/local/bin/ 目录下,并重命名为 docker-compose。这是安装 Docker Compose 的标准位置和命名。

      sudo mv /root/docker-compose-linux-x86_64 /usr/local/bin/docker-compose
    
  • 给docker-compose文件目录添加权限

下一步,切换到harbor解压目录,修改配置文件:

cd harbor/
ls 

下一步,执行安装docker,如果已经安装过了可以忽略

yunm install docker -y

3.2 修改harbor.yml.tmpl文件

1.找到文件

2.执行 命令该文件名称

cp harbor.yml.tmpl harbor.yml

3.修改配置

vim harbor.yml

1)修改 hostname:ip地址或域名
2)http端口可以设置一个没有被占用的端口【harbor 端口使用9999】
3)去掉https的认证

修改完,保存退出。

4.启动harbor,切换到harbor目录,执行下面命令

./install.sh

下一步,出现以下界面说明harbor已经成功启动

4 访问harbor,登录

访问地址:http://ip:端口
初始化账号/密码:admin/Harbor12345

5 harbor的使用

5.1 创建项目

5.2 创建用户:chenshibao/密码

5.3 项目用户授权

授权完成,新创建的账户就有管理这个项目的权限了。

4 Jenkins环境搭建

4.1 安装docker

如果docker未安装,可执行以下步骤安装:

  1. 添加docker软件源

     dnf config-manager --add-repo=http://mirrors.tencent.com/docker-ce/linux/centos/docker-ce.repo
    
  2. 查看已添加的docker软件源

     dnf list docker-ce
    
  3. 安装docker

     dnf install -y docker-ce --nobest
    
  4. 运行docker

     systemctl start docker
    
  5. 查看docker信息

     docker info
    

如果是阿里云的centos服务器,可以执行以下操作安装docker:

	1.yum install -y yum-utils device-mapper-persistent-data lvm2 git
	2.yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
	3.wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
	4.yum install -y container-selinux
	5.ls
	6.rpm -ivh containerd.io-1.2.6-3.3.el7.x86_64.rpm
	7.yum install docker-ce -y
	8.systemctl start docker
	
	##以下是测试部分(可以不用操作)
	docker pull nginx
	docker tag nginx 124.222.48.124:9999/jenkins/nginx:v0
	docker login 124.222.48.124:9999
	rpm -ql docker-ce
	vim /etc/docker/key.json
	cd /etc/docker/
	ls

4.2 用nginx进行测试【这一步可以不做】

  1. 拉取nginx镜像

     docker pull nginx
    

如果拉取失败,如下图,可以去 /etc/docker/daemon.json,配置腾讯云docker镜像源加速镜像下载,

如果daemon.json文件不存在,可以创建;

touch daemon.json

daemon.json文件内容如下:

	{
	   "registry-mirrors": [
	   "https://mirror.ccs.tencentyun.com"
	  ]
	}

配置完后,需要重启docker,再拉取镜像

sudo systemctl restart docker
docker pull nginx

  1. 打包一个nginx的镜像

     docker tag nginx 124.222.48.124:9999/jenkins/nginx:v0
    
  2. 登录harbor,输入username和password
    docker login 124.222.48.124

Error response from daemon: Get "https://124.222.48.124/v2/": tls: failed to verify certificate: x509:

如果出现上面的错误,需要改一下daemon.json的配置,配置上124.222.48.124(harbor的ip)和端口,

{
		   "registry-mirrors": [
					  "https://mirror.ccs.tencentyun.com"

		   ],
		   "insecure-registries":["124.222.48.124:9999"]
}

原因是我们docker client使用的是https,而我们搭建的Harbor私库用的是http的,所以会有这样的报错,导致访问不了。

在Harbor所在的服务器上修改daemon.json文件

{
		   "registry-mirrors": [
					  "https://mirror.ccs.tencentyun.com"

		   ],
		   "insecure-registries":["124.222.48.124:9999"] #ip写Harbor所在的服务器ip,端口是harbor.yml文件中配置的port
}

重启docker

systemctl daemon-reload
systemctl restart docker

查看harbor是否已经启动,如果没有重新启动harbor

如果一切正常,那可以登录成功了;

  1. 将打包好的镜像上传到 harbor的镜像仓库

1.执行推送,镜像名称(nginx,版本:v0)

docker push 124.222.48.124:9999/jenkins/nginx:v0

以上出现,表示推送成功,可以登录harbor查看

  1. 业务服务器部署

    1)先安装docker,步骤可参考上面步骤

    2)安装jq(jq类似于sed/awk专门处理json格式的文件)

     yum install docker jq -y
    

    3)执行 visudo(阿里云centos需要这样,腾迅云不需要)

    visudo

4.3 Jenkins服务部署配置(如果Jenkins没有安装,需要先安装,可参考:jenkins安装配置流程

查看是否已安装jenkins

which jenkins

1.安装源,从Jenkins的官方网站下载稳定版的Jenkins YUM仓库配置文件,并将其保存到/etc/yum.repos.d/目录下,命名为jenkins.repo

wget-0 /etc/yum.repos.d/jenkins.repo https: //pkg. jenkins.io/redhat-stable/jenkins.repo 

2.导入key,使用rpm工具导入Jenkins的官方GPG密钥。

rpm --import https: //pkg.jenkins.io/redhat- stable/jenkins.io. key

3.安装,在服务器上自动安装Jenkins、Git和Maven这三个软件包

yum Install -y jenkins git maven

4.查看java是否已安装成功

java --version

5.启动jenkins

systemctl start jenkins

6.查jenkins进程信息

ps -ef|grep jenkins

========================================================================================

由于在Jenkins机器上docker是使用root用户运行的,而Jenkins是使用普通用户jenkins 运行的,所以要先配置下jenkins用户可以使用docker命令。
使用以下步骤:

1.使用visudo命令

visudo

2.在配置文件里添加用户,如下图所示

jenkins ALL=(root) NOPASSWD: /usr/bin/docker
Defaults: jenkins !requiretty

如果不配置的话,会报以下错误

3.安装插件

浏览器登录jenkins,http://1.116.119.87:7777,进行初始化配置
点击“系统管理”,点击“插件管理”,搜索插件“Maven Integration”和“SSH”,进行安装。

4.配置远程机器
登录jenkins,点击“Credentials”,点击 “Add domain”.

添加域

添加凭证

用户名和密码是登录这台服务器的 用户和密码

凭证生成完成。

下一步:

下一步:

配置docker应用服务器的ip地址,如果有多台服务器,可以再次新增

5.Jenkins构建Job

1.构建Maven风格的Job

下一步

下一步

下一步

下一步:

选择执行shell脚本,脚本内容如下

#Jenkins机器:编译完成后,build生成一个新版本的镜像,push到远程docker仓库variables

JENKINS_WAR_HOME='/root/jenkins/workspace/maven-docker-test/target'
DOCKERFILE_HOME='/root/jenkins/docker-file/maven-docker-test_war'
# harbor服务器上的配置项
HARBOR_IP='124.222.48.123'
REPOSITORIES='jenkins/maven-docker-test'
HARBOR_USER='chenshibao'
HARBOR_USER_PASSWD='Csb'
HARBOR_USER_EMAIL='714183244@qq.com'

#Copy the newest war to docker-file directory. 
\cp -f ${JENKINS_WAR_HOME}/easy-springmvc-maven.war ${DOCKERFILE_HOME}/maven-docker-test.war

#Delete image early version.
sudo docker login -u ${HARBOR_USER} -p ${HARBOR_USER_PASSWD} ${HARBOR_IP}:9999

IMAGE_ID='sudo docker images | grep ${REPOSITORIES} | awk '{print $3}''

if [-n "$(IMAGE_ID}" ];then
	sudo docker rmi ${IMAGE_ID}
fi

# Build image.
cd ${DOCKERFILE_HOME}
TAG='date +%Y%m%d-%H%M%S'
sudo docker build -t ${HARBOR_IP}:9999/${REPOSITORIES}:${TAG} . &>/dev/null
# Push to the harbor registry.

sudo docker push ${HARBOR_IP}:9999/${REPOSITORIES}:${TAG} &>/dev/null

以上shell脚本有问题时,可以使用以下这个shell脚本

#!/bin/bash

JENKINS_WAR_HOME='/root/jenkins/workspace/maven-docker-test/target'
DOCKERFILE_HOME='/root/jenkins/docker-file/maven-docker-test_war'

# Harbor 配置
HARBOR_IP='124.222.48.123'
HARBOR_PORT='9999'
REPOSITORIES='jenkins/maven-docker-test'
HARBOR_USER='chenshibao'
HARBOR_USER_PASSWD='Csb'
HARBOR_USER_EMAIL='714183244@qq.com'

# 复制最新的 war 包到 docker 目录
\cp -f ${JENKINS_WAR_HOME}/easy-springmvc-maven.war ${DOCKERFILE_HOME}/maven-docker-test.war

# Harbor 登录(更安全方式)
echo ${HARBOR_USER_PASSWD} | sudo docker login -u ${HARBOR_USER} --password-stdin ${HARBOR_IP}:${HARBOR_PORT}

# 删除旧镜像(确保只删除目标镜像)
IMAGE_IDS=$(sudo docker images ${HARBOR_IP}:${HARBOR_PORT}/${REPOSITORIES} --format "{{.ID}}")

if [ -n "$IMAGE_IDS" ]; then
	sudo docker rmi -f $IMAGE_IDS
fi

# 生成新的镜像 Tag
TAG=$(date +%Y%m%d-%H%M%S)

# 检查 Dockerfile 目录是否存在
if [ ! -d "$DOCKERFILE_HOME" ]; then
	echo "错误: 目录 $DOCKERFILE_HOME 不存在!"
	exit 1
fi
cd ${DOCKERFILE_HOME}

# 设置日志目录
LOG_DIR="/var/log/jenkins"
mkdir -p $LOG_DIR

# 构建新镜像
sudo docker build -t ${HARBOR_IP}:${HARBOR_PORT}/${REPOSITORIES}:${TAG} . > ${LOG_DIR}/docker_build.log 2>&1

# 推送镜像到 Harbor
sudo docker push ${HARBOR_IP}:${HARBOR_PORT}/${REPOSITORIES}:${TAG} > ${LOG_DIR}/docker_push.log 2>&1

===============================================================================================================================================

JENKINS_WAR_HOME=’/root/jenkins/workspace/maven-docker-test/target’目录在服务器不存在时创建,
DockerFile_Home=’/root/jenkins/docker-file/maven-docker-test_war’ ,这个目录如果在jenkins服务器上没有的话,可以先创建,maven-docker-test_war这个目录可以根据自己项目自定义(可以定义为:任务名称_war)
,然后再这个目录下创建DockerFile文件,输如一下内容:

cd /root/jenkins/docker-file/maven-docker-test_war 
vim Dockerfile 

Dockerfile文件内容:

# Version 1.0
# Base image
FROM tomcat:8.0.36-alpine

# Author information (使用 LABEL 代替 MAINTAINER)
LABEL maintainer="chenshibao <714183244@qq.com>"

# Add WAR file to Tomcat webapps directory
COPY maven-docker-test.war /usr/local/tomcat/webapps/

# Set working directory
WORKDIR /usr/local/tomcat/bin/

# Set environment variables
ENV PATH="/usr/local/tomcat/bin:$PATH"

# Define default command
CMD ["catalina.sh", "run"]

# Expose port (默认8080,如果你修改过server.xml就改成7777)
EXPOSE 8080

=====================================================================================================================

添加shell执行脚本:

拉取镜像,发布脚本如下

#!/bin/bash

# Harbor 配置
HARBOR_IP='124.222.48.123'
HARBOR_PORT='9999'
REPOSITORIES='jenkins/maven-docker-test'
HARBOR_USER='chenshibao'
HARBOR_USER_PASSWD='Csb'

# 登录 Harbor
docker login -u ${HARBOR_USER} -p ${HARBOR_USER_PASSWD} ${HARBOR_IP}:${HARBOR_PORT}

# 停止并删除旧容器
CONTAINER_ID=$(docker ps | grep "maven-docker-test" | awk '{print $1}')
if [ -n "$CONTAINER_ID" ]; then
  docker stop $CONTAINER_ID
  docker rm $CONTAINER_ID
else
  # 容器启动失败时,需要 `docker ps -a` 才能找到
  CONTAINER_ID=$(docker ps -a | grep "maven-docker-test" | awk '{print $1}')
  if [ -n "$CONTAINER_ID" ]; then
	docker rm $CONTAINER_ID
  fi
fi

# 删除旧镜像
IMAGE_ID=$(sudo docker images | grep "${REPOSITORIES}" | awk '{print $3}')
if [ -n "${IMAGE_ID}" ]; then
  docker rmi ${IMAGE_ID}
fi

# 获取最新镜像 TAG
TAG=$(curl -s http://${HARBOR_IP}:${HARBOR_PORT}/api/repositories/${REPOSITORIES}/tags | jq -r '.[-1]')
echo "Latest TAG: ${TAG}"

# 拉取最新镜像
echo "Pulling image: ${HARBOR_IP}:${HARBOR_PORT}/${REPOSITORIES}:${TAG}"
docker pull ${HARBOR_IP}:${HARBOR_PORT}/${REPOSITORIES}:${TAG} &>/dev/null

# 运行容器
docker run -d --name maven-docker-test -p 8080:8080 ${HARBOR_IP}:${HARBOR_PORT}/${REPOSITORIES}:${TAG}

====================================================================================================================================================

脚本如果没有问题,执行下面操作,立即构建,如果构建成功,可以去docker应用服务器上查看新生成的docker镜像

问题汇总及解决方式:

问题1.如果出现以下错误,说明maven没有正确安装好,Maven路径配置不对,

Started by user chenshibao
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/maven-docker-test
ERROR: A Maven installation needs to be available for this project to be built.Either your server has no Maven installations defined, or the requested Maven version does not exist.
Finished: FAILURE

可以通过查看 mvn -version版本,找到正确的安装地址,

1.确保 Maven 已在 Jenkins 中正确配置
虽然 mvn -version 在命令行可用,但 Jenkins 可能没有找到它,需要手动配置:

  • 步骤 1:进入 Jenkins 全局配置
    • 打开 Jenkins,进入 Manage Jenkins → Global Tool Configuration
    • 找到 Maven 配置部分:
    • 如果没有任何 Maven 版本,点击 Add Maven 添加一个。
    • 确保名称正确,例如 Maven 3.8.5。
    • 取消勾选 Install automatically(因为你的服务器已经安装了 Maven)。
    • 在 Maven home 里填入 /usr/share/maven(你的 mvn -version 显示的路径)。
  • 步骤 2:在 Jenkins 任务中选择 Maven
    • 进入你的 Job(maven-docker-test)
    • 点击 Configure,找到 Build Environment
    • 找到 “Build” -> “Invoke top-level Maven targets”
    • 确认 “Maven Version” 选择的是你在全局配置里添加的 Maven 3.8.5
    • 保存后重新构建

问题2.权限不足

出现以下问题:

cp: cannot stat '/root/jenkins/workspace/maven-docker-test/target/easy-springmvc-maven.war': Permission denied

原因:

  • Jenkins 运行时,默认使用 jenkins 用户,而你的 target 目录和 war 文件可能是 root 创建的,导致 jenkins 没有权限访问。

解决方案
修改文件权限(临时方案)

sudo chmod -R 777 /root/jenkins/workspace/maven-docker-test/target

问题3:Docker 登录失败

time="2025-03-18T15:07:30+08:00" level=info msg="Error logging in to endpoint, trying next endpoint" 
error="Get \"https://124.222.48.124:9999/v2/\": http: server gave HTTP response to HTTPS client"

原因:

  • 你的 Harbor 服务器 可能是 HTTP,但 Jenkins 试图用 HTTPS 访问。
  • 你需要 在 Docker 配置文件里加入 HTTP 例外。

解决方案:
1.修改 Docker 配置文件

	sudo mkdir -p /etc/docker
	sudo tee /etc/docker/daemon.json <<EOF
	{
	  "insecure-registries": ["124.222.48.123:9999"]
	}
	EOF

修改后,这是正确的jenkins服务器上/etc/docker/daemon.json的内容:

{
 "registry-mirrors": [
 	"https://mirror.ccs.tencentyun.com"
	],
  "insecure-registries":["124.222.48.124:9999"]
}

2.重启 Docker

sudo systemctl restart docker

3.jenkins服务器上,手动测试登录

sudo docker login -u chenshibao -p 'Csb' 124.222.48.123:9999

登录成功,说明docker配置已完成

问题 4:Docker Daemon 未运行

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

原因:

  • Docker 进程未启动
  • jenkins 用户没有访问 docker.sock 权限

解决方案
1.检查 Docker 运行状态

sudo systemctl status docker

2.如果 Docker 未运行:

sudo systemctl start docker
sudo systemctl enable docker

3.给 Jenkins 访问 Docker 权限

sudo usermod -aG docker jenkins
sudo systemctl restart jenkins

4.验证

sudo -u jenkins docker ps

5.如果返回 permission denied,可能需要重启服务器:

sudo reboot

如果返回以下的信息,说明设置可以了

问题5:Dockerfile 目录不存在

错误: 目录 /root/jenkins/docker-file/maven-docker-test_war 不存在!

解决方案

1.手动创建目录

sudo mkdir -p /root/jenkins/docker-file/maven-docker-test_war
sudo chown -R jenkins:jenkins /root/jenkins/docker-file/maven-docker-test_war

2.确认 Jenkins 配置的路径是否正确

打开 Jenkins 配置
检查 DOCKERFILE_HOME 路径是否正确

问题 6:Maven POM 文件找不到

ERROR: No such file /var/lib/jenkins/workspace/maven-docker-test/pom.xml

原因:

  • GitHub 仓库里可能没有 pom.xml 文件,或者路径不对。

解决方案
1.检查 GitHub 仓库

git ls-remote https://github.com/ChenShiBao/TestProject.git

如果没有 pom.xml,说明 TestProject 不是 Maven 项目,你需要修改构建方式。

2.在 Jenkins 里设置正确的 POM.xml 路径

进入 Jenkins → maven-docker-test → Configure
在 Build 选项中,确保 Root POM 设置为正确的路径,比如:

./TestProject/pom.xml

保存并重试