当前位置: 首页 > news >正文

使用 Docker、Jenkins、Harbor 和 GitLab 构建 CI/CD 流水线

随着 DevOps 文化的普及,CI/CD(持续集成与持续交付)已经成为现代软件开发中的一部分。通过自动化代码的构建、测试和部署过程,CI/CD 不仅提高了软件质量,还大幅提高了开发效率。在本文中,我们将介绍如何利用 Docker、Jenkins、Harbor 和 GitLab 实现一个完整的 CI/CD 流水线。

1. 环境准备

在开始之前,确保以下软件已安装并运行:

  • Docker:用于容器化应用。
  • Jenkins:用于自动化构建和部署。
  • Harbor:用于管理 Docker 镜像。
  • GitLab:用于版本控制与源代码管理。

可以参考官方文档安装这些工具:

  • Docker 安装指南
  • Jenkins 安装指南
  • Harbor 安装指南
  • GitLab 安装指南

2. 搭建 GitLab 代码仓库

首先,在 GitLab 上创建一个代码仓库。如果你已经有一个仓库,可以直接使用。

  1. 登录 GitLab,创建一个新的项目。
  2. 将你的代码推送到 GitLab 仓库:
 
git init
git remote add origin https://gitlab.com/your-username/your-repo.git
git add .
git commit -m "Initial commit"
git push -u origin master

使用docker Registry代替了harbor

CI/CD

  • Git 代码版本管理系统 只能命令行去管理git
  • Gitlab 基于git做了图形管理页面,企业使用gitlab做私有的代码管理仓库
  • Github 公共代码管理仓库

设计流程

  • 使用 Gitlab 作为代码仓库
  • 使用 Harbor 作为镜像仓库
  • 使用Jenkins发布系统部署
  • Docker管理Jenkins+Harbor+Gitlab

工作流程

  1. 迁入代码push到Gitlab
  2. Gitlab触发webhook的push触发事件并主动通知Jenkins构建
  3. Jenkins在Gitlab获取源码并通过配置好的规则与shell脚本进行构建
    • 如果是工具库,则dotnet push到私有Nuget
    • 如果是Web应用,则通过dockerfile构建docker镜像并push到Docker Registry,然后由docker swarm create多节点

安装Docker

请参考安装Docker

设置端口

vim /usr/lib/systemd/system/docker.service

添加以下内容

ExecStart=/usr/bin/dockerd -H fd:// -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --containerd=/run/containerd/containerd.sock
systemctl daemon-reload
service docker restart

安装 Docker Registry

安装Registry

安装Registry,作私有仓库

docker run -d -p 6000:5000  --restart=always --name registry registry

以下命令执行有问题

docker run -d -p 6000:5000  --restart=always --name registry registry --volume /root/registry:/var/lib/registry

配置修改

编辑所有需要docker registry使用的节点的daemon.json文件,确保能正常访问

vim /etc/docker/daemon.json
{"insecure-registries":["192.168.234.133:6000","192.168.234.133:7080"]
}
systemctl daemon-reload;
service docker restart;

如果需要推送镜像到私库确保标签(tag)前缀带有私库地址

docker push 192.168.234.133:6000/testdockerswarm

使用和停止其他容器相同的docker container stop命令来停止你的registry

docker container stop registry

使用docker container rm 命令来移除此container

docker container stop registry && docker container rm -v registry

docker swarm初始化(可选)

把相关涉及到docker swarm的节点端口开启

firewall-cmd --permanent --zone=public --add-port=2377/tcp
firewall-cmd --permanent --zone=public --add-port=4789/udp
firewall-cmd --permanent --zone=public --add-port=7946/udp
firewall-cmd --reload

选取Server作为Manager节点,执行下面的指令后会出现docker swarm join的指令文本,复制保存下来

docker swarm init --advertise-addr 192.168.234.133

Server A和Server C为Worker节点,执行刚刚保存下来指令

docker swarm join --token SWMTKN-1-0nggzpa2t3ye69rq0jhr4eid2criq40ij483s89rd7btl2lq0e-1gslrqufyv0s02lg5sw5dr9es 192.168.234.133:2377
docker node ls

安装Jenkins

请参考Docker部署Jenkins

安装Harbor

请参考Docker部署harbor

安装GitLab

请参考Docker部署GitLab

需要到jenkins配置以下信息

安装Git

yum -y install git
which git

然后找到Jenkins下的系统管理-全局工具配置-Git,将上面复制的git的路径放在Path to Git executable中

安装Nuget

Nuget安装

基于docker的Nuget安装

docker run -d \-p 9082:80 -p 9443:443 --restart=always\--env NUGET_API_KEY=chengong \-v /root/nuget/database:/var/www/db \-v /root/nuget/packages:/var/www/packagefiles \--name nuget-server \sunside/simple-nuget-server

修改host

nslookup nuget.org 8.8.8.8
[root@k8s-node3 ~]# nslookup nuget.org 8.8.8.8 
Server:		8.8.8.8
Address:	8.8.8.8#53Non-authoritative answer:
Name:	nuget.org
Address: 52.237.135.91
nslookup api.nuget.org 8.8.8.8

vim /etc/hosts
52.237.135.91 nuget.org

配置端口

firewall-cmd --permanent --add-port=9082/tcp
firewall-cmd --permanent --add-port=9443/tcp
firewall-cmd --reload

相关指令

上传包指令,注意包名有中文会导致上传出现bad request

dotnet nuget push --source http://192.168.234.133:9082/ -k chengong TestPackage.1.0.0.nupkg

删除包指令

dotnet nuget delete --source http://192.168.234.133:9082/ -k chengong  TestPackage 1.0.0

如果在Windowsx系统可以通过工具上传

https://github.com/NuGetPackageExplorer/NuGetPackageExplorer

添加私有包源

在Server添加私有Nuget包源,因为在.Net Core应用 Build和Publish的时候会触发Restore指令(还原包),默认只有微软的nuget源,如果缺少了私有Nuget源会还原包失败

dotnet nuget add source http://192.168.234.133:8082 -n LocalNugetServer

NuGet微软中国

为解决国内访问NuGet服务器速度不稳定的问题 ,这里推荐使用NuGet微软官方中国国内镜像

地址:https://nuget.cdn.azure.cn/v3/index.json

linux添加NuGet源的方式

dotnet nuget add source https://nuget.cdn.azure.cn/v3/index.json -n nuget.org.cn

Visual Studio添加NuGet源的方式,菜单: 工具 -> NuGet包管理器 -> 程序包管理器设置

列出已有包源

dotnet nuget list source

可以通过 dotnet restore -s http://192.168.234.133:8082 指令指定还原包源,但是为了避免如果服务地址变动后shell脚本会大面积的修改,还是建议通过dotnet nuget add soure指令。

查找配置文件

find / -name NuGet.Config*

编辑配置

  • linux
  • /root/.config/NuGet
  • /root/.nuget/NuGet/NuGet.Config
  • /var/lib/docker/overlay2/d494d4262b85da17df3c92a072f0050ace37a2a2bf243f53531f30cdd8a4b946/diff/root/.nuget/NuGet/NuGet.Config
vim ~/.nuget/NuGet/NuGet.Config

/root/.nuget/NuGet/NuGet.Config配置文件内容调整为

<?xml version="1.0" encoding="utf-8"?>
<configuration><packageSources><add key="huaweicloud.com" value="https://repo.huaweicloud.com/repository/nuget/v3/index.json" /><add key="azure.cn" value="https://nuget.cdn.azure.cn/v3/index.json" /><add key="nuget.org" value="https://api.nuget.org/v3/index.json" /></packageSources><disabledPackageSources> <add key="azure.cn" value="true" /> <add key="nuget.org" value="true" /> </disabledPackageSources>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration><packageSources><add key="azure.cn" value="https://nuget.cdn.azure.cn/v3/index.json" /><add key="huaweicloud.com" value="https://repo.huaweicloud.com/repository/nuget/v3/index.json" /><add key="disabledSources1" value="https://api.nuget.org/v3-index/repository-signatures/5.0.0/index.json" /><add key="nuget.org" value="https://api.nuget.org/v3/index.json" /></packageSources><disabledPackageSources> <add key="disabledSources1" value="true" /> <add key="nuget.org" value="true" /> </disabledPackageSources>
</configuration>

将/var/lib/docker/overlay2/d494d4262b85da17df3c92a072f0050ace37a2a2bf243f53531f30cdd8a4b946/diff/root/.nuget/NuGet/NuGet.Config配置文件内容调整为

vim /var/lib/docker/overlay2/d494d4262b85da17df3c92a072f0050ace37a2a2bf243f53531f30cdd8a4b946/diff/root/.nuget/NuGet/NuGet.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration><packageSources><add key="azure.cn" value="https://nuget.cdn.azure.cn/v3/index.json" /><add key="huaweicloud.com" value="https://repo.huaweicloud.com/repository/nuget/v3/index.json" /><add key="disabledSources1" value="https://api.nuget.org/v3-index/repository-signatures/5.0.0/index.json" /><add key="nuget.org" value="https://api.nuget.org/v3/index.json" /></packageSources><disabledPackageSources> <add key="disabledSources1" value="true" /> <add key="nuget.org" value="true" /> </disabledPackageSources>
</configuration>
  • win 10
C:\Users\Administrator\AppData\Roaming\NuGet

将配置文件内容调整为

<?xml version="1.0" encoding="utf-8"?>
<configuration><packageSources><add key="nuget.org" value="https://nuget.cdn.azure.cn/v3/index.json" protocolVersion="3" /><add key="Package source" value="D:\Nuget\Package" /><add key="Microsoft Visual Studio Offline Packages" value="D:\Nuget\NuGetPackages" /></packageSources><disabledPackageSources><add key="Microsoft and .NET" value="true" /></disabledPackageSources><packageRestore><add key="enabled" value="True" /><add key="automatic" value="True" /></packageRestore><bindingRedirects><add key="skip" value="False" /></bindingRedirects><packageManagement><add key="format" value="0" /><add key="disabled" value="False" /></packageManagement>
</configuration>

如果不配置NuGet.Config,在使用docker file时,会出现以下错误信息

Started by GitLab push by longfuchu
Running as SYSTEM
Building in workspace /var/jenkins_home/workspace/webapp1
The recommended git tool is: NONE
using credential 2
> git rev-parse --resolve-git-dir /var/jenkins_home/workspace/webapp1/.git # timeout=10
Fetching changes from the remote Git repository
> git config remote.webapp1.url http://192.168.234.133:7080/net/webapp1.git # timeout=10
Fetching upstream changes from http://192.168.234.133:7080/net/webapp1.git
> git --version # timeout=10
> git --version # 'git version 2.30.2'
using GIT_ASKPASS to set credentials gitlab
> git fetch --tags --force --progress -- http://192.168.234.133:7080/net/webapp1.git +refs/heads/*:refs/remotes/webapp1/* # timeout=10
skipping resolution of commit remotes/webapp1/main, since it originates from another repository
Seen branch in repository webapp1/main
Seen 1 remote branch
> git show-ref --tags -d # timeout=10
Checking out Revision bc0e43d7c2a3146667d6b22dd7d357bd265141a0 (webapp1/main)
> git config core.sparsecheckout # timeout=10
> git checkout -f bc0e43d7c2a3146667d6b22dd7d357bd265141a0 # timeout=10
Commit message: "36"
> git rev-list --no-walk c92fa9ee9420a7f094bc53e588354997a7506832 # timeout=10
Docker Build
Docker Build: building image at path /var/jenkins_home/workspace/webapp1
Step 1/16 : FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base---> 56bc39541821Step 2/16 : WORKDIR /app---> Running in 7d827b313abaRemoving intermediate container 7d827b313aba---> fadfb17d8c08Step 3/16 : EXPOSE 80---> Running in f0583aace3adRemoving intermediate container f0583aace3ad---> e608a0c27da9Step 4/16 : FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build---> b847a4eb3c52Step 5/16 : WORKDIR /src---> Running in 7d7f4fcb044aRemoving intermediate container 7d7f4fcb044a---> 07d3ca41aefcStep 6/16 : COPY ["WebApp1.csproj", "."]---> f46fd47e9c67Step 7/16 : RUN dotnet restore "./WebApp1.csproj"---> Running in d52acffd8a82Determining projects to restore.../src/WebApp1.csproj : error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json./src/WebApp1.csproj : error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json.Failed to restore /src/WebApp1.csproj (in 11.34 sec).ERROR: Build step failed with exception
com.github.dockerjava.api.exception.DockerClientException: Could not build image: The command '/bin/sh -c dotnet restore "./WebApp1.csproj"' returned a non-zero code: 1
at com.github.dockerjava.core.command.BuildImageResultCallback.getImageId(BuildImageResultCallback.java:80)
at com.github.dockerjava.core.command.BuildImageResultCallback.awaitImageId(BuildImageResultCallback.java:52)
at com.nirima.jenkins.plugins.docker.builder.DockerBuilderPublisher$Run.buildImage(DockerBuilderPublisher.java:404)
at com.nirima.jenkins.plugins.docker.builder.DockerBuilderPublisher$Run.run(DockerBuilderPublisher.java:344)
at com.nirima.jenkins.plugins.docker.builder.DockerBuilderPublisher.perform(DockerBuilderPublisher.java:486)
at jenkins.tasks.SimpleBuildStep.perform(SimpleBuildStep.java:123)
at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:80)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:816)
at hudson.model.Build$BuildExecution.build(Build.java:199)
at hudson.model.Build$BuildExecution.doRun(Build.java:164)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:524)
at hudson.model.Run.execute(Run.java:1899)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)
at hudson.model.ResourceController.execute(ResourceController.java:107)
at hudson.model.Executor.run(Executor.java:449)
Build step 'Build / Publish Docker Image' marked build as failure
Finished: FAILURE

清空缓存

dotnet nuget locals http-cache --clear;
dotnet nuget locals global-packages --clear;
dotnet nuget locals temp --clear;
dotnet nuget locals plugins-cache --clear;
dotnet nuget locals all --clear;

安装.Net SDK

因为在Server安装了Jenkins,因此会基于Server的环境进行.Net的应用进行打包、发布。

NET 也可通过packages.microsoft.com获得。

  • CentOS
  • Debian
  • Fedora
  • openSUSE
  • SLES
  • Ubuntu

检查环境

dotnet --list-sdks
dotnet --list-runtimes

在线安装

rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
sudo yum install dotnet-sdk-3.1
sudo yum install dotnet-sdk-5.0
sudo yum install dotnet-sdk-6.0

离线安装

1.下载Microsoft 包签名密钥,上传服务器后添加到受信任密钥列表,并添加 Microsoft 包存储库

下载地址:Microsoft 包签名密钥

执行安装:

sudo rpm -Uvh /tmp/packages-microsoft-prod.rpm

2.微软SDK下载页下载SDK二进制包

下载地址:.NET 下载(Linux、macOS 和 Windows) (microsoft.com)

3.上传服务器并进行安装(本文假定上传至根目录tmp文件夹)

cd /tmp
mkdir -p $HOME/dotnet && tar zxf dotnet-sdk-6.0.301-linux-x64.tar.gz -C $HOME/dotnet && tar zxvf dotnet-sdk-3.1.420-linux-x64.tar.gz -C $HOME/dotnet
export DOTNET_ROOT=$HOME/dotnet
export PATH=$PATH:$HOME/dotnet
source /etc/profile

注意,如果手动安装 .NET Core 或发布自包含的应用,则需要确保已安装以下库:

  • krb5-libs
  • libicu
  • openssl-libs
  • zlib

如果目标运行时环境的 OpenSSL 版本为1.1 或更高版本,则需要安装 compat-openssl10。

对于使用 System.Drawing.Common 程序集的 .NET Core 应用,还需要以下依赖项:

  • libgdiplus(版本 6.0.1 或更高版本)

配置环境变量

dotnet --info

sudo vim /etc/profile
export PATH=$PATH:/usr/share/dotnet/
export DOTNET_ROOT=/usr/share/dotnet/

注:/data/dotnet是我的存储路径,这里改成你自己的路径

端口映射

# 查看防火墙状态
systemctl status firewalld# 启动防火墙
systemctl start firewalld# docker swarm的节点端口开启
firewall-cmd --zone=public --add-port=2376/tcp --permanent
firewall-cmd --zone=public --add-port=2377/tcp --permanent
firewall-cmd --zone=public --add-port=4789/udp --permanent
firewall-cmd --zone=public --add-port=7946/udp --permanent# 开启6000端口
firewall-cmd --zone=public --add-port=6000/tcp --permanent # 开启8022端口
firewall-cmd --zone=public --add-port=8022/tcp --permanent # 开启8443端口
firewall-cmd --zone=public --add-port=8443/tcp --permanent # 开启8060端口
firewall-cmd --zone=public --add-port=8060/tcp --permanent # 开启8081端口
firewall-cmd --zone=public --add-port=8081/tcp --permanent # 开启8082端口
firewall-cmd --zone=public --add-port=8082/tcp --permanent # 开启8090端口
firewall-cmd --zone=public --add-port=8090/tcp --permanent # 开启48080端口
firewall-cmd --zone=public --add-port=48080/tcp --permanent # 重启防火墙才能生效
systemctl restart firewalld# 或者重新启动防火墙
firewall-cmd --reload# 查看已经开放的端口
firewall-cmd --list-ports# 关闭防火墙命令:
systemctl stop firewalld
# 查看防火墙状态
sudo ufw status# 安装防火墙
sudo sudo apt-get install ufw# 启动防火墙
sudo ufw enable# 开启6000端口
sudo ufw allow 6000# 开启8022端口
sudo ufw allow 8022# 开启8443端口
sudo ufw allow 8443# 开启48080端口
sudo ufw allow 48080# 开启完成,需要重启防火墙生效
sudo ufw reload# 查看端口信息
sudo ufw status# 关闭防火墙命令:
sudo ufw disable

Jenkins配置

API Token

插件管理

管理Jenkins->系统配置-->插件管理-->

分别搜索Git Parameter/Git/Pipeline/docker/Config File Provider/Gitlab Hook /Gitlab/Push Over SSH,选中点击安装。

  • Git:拉取代码
  • Git Parameter:Git参数化构建
  • Pipeline:流水线
  • GitLab:
  • Config File Provider:存储配置文件
  • Extended Choice Parameter:扩展选择框参数,支持多选
  • Docker-build-stepVersion
  • CloudBees Docker Build and Publish plugin: docker插件

如果无法顺利安装则到Jenkins Plugins下载插件手动上传。

修改时区

docker exec -it 81 /bin/bash

执行下面命令

tzselect4
9
1
1cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime##查看时间
date -R

gitlab插件配置

需要到jenkins配置以下信息

Connection name为gitlab的登录账号

docker插件配置

该配置提供给任务构建配置的“Build / Publish Docker Image”配置选择。

  • 需要安装插件CloudBees Docker Build and Publish、docker-build-stepVersion
  • 需要开启2376端口
  • 需要修改docker.service
vim /usr/lib/systemd/system/docker.service

添加以下内容

ExecStart=/usr/bin/dockerd -H fd:// -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --containerd=/run/containerd/containerd.sock
systemctl daemon-reload
service docker restart

系统管理-->节点管理-->集群配置

生成 SSH Key

生成key
cd /var/lib/jenkins
ssh-keygen -t rsa

输入文件名为jenkins_rsa,输入密码(为空)

会在目录/root/.ssh生成id_rsa私钥、id_rsa.pub公钥,将公钥的内容写入到同目录下的authorized_keys文件(jenkins连接多台服务器,将公钥写入到相应服务器的authorized_keys文件即可)

公钥文件

将公钥写入authorized_keys文件

cd /root/.ssh/
cat /var/lib/jenkins/jenkins_rsa.pub >> authorized_keys
chmod 600 authorized_keys

验证SSH Key

ssh -p 8081 root@192.168.234.133

配置私钥凭证

在jenkins的linux虚拟机上执行如下命令查看私钥

cd /var/lib/jenkins
mv jenkins_rsa /root/.ssh/
cat /root/.ssh/jenkins_rsa

登录jenkins配置凭据,系统管理-->

类型选择:SSH Username with private key
Username: 一般是linux虚拟机上配置的用户

将私钥 复制到key处,然后点击确定即可。

在jenkins系统配置中,配置SSH remote hosts,如果提示不能连接,请检查服务器sshd文件配置

配置SSH remote hosts

系统管理-->系统管理--下拉菜单选择"SSH remote hosts",

按以下截图配置,Credentials选择刚刚配置的jenkins ssh

如果提示不能连接,请检查服务器sshd文件配置。

配置Publish over SSH

在把SSH配置好后,点击系统管理-->系统管理--下拉菜单选择Publish over SSH;

在【SSH Servers】模块把服务器地址、账号密码填进去保存,因为后续会使用到。

点击新增Service按钮,输入Jenkins所在服务器的IP,及账号,远程目录

接着点击Test configuration测试下连接是否成功,如下:

如果测试配置不是Success,则按以下操作继续

在Passphrase / Password维护输入Jenkins所在服务器的UserName(root)用户名对应的密码,如下:

新建任务

到首页面板点击【新建任务】-选择【构建一个自由风格的软件项目】(FreeStyle Project)。

自由风格的项目更多是使用shell脚本结合相应平台的指令实现自动化,因此建议大家对shell脚本有个初步的认识与学习,虽然Jenkins也提供了对应平台语言的一些插件,但是只要您熟悉了shell就会发现它的灵活性与便捷性。

接下来我们只要关注3个模块,源码管理、构建触发器、构建

任务构建配置

新建完任务后,需要对该任务进行构建配置。

General

参数化构建过程配置,分别添加两个字符串参数ImageName,Version

源码构建

源码构建,填写您要自动发布的项目的源码地址,并输入账号密码。

Repository URL输入gitlab的项目访问地址,Credentials选择一个或新增一个gitlab的有效账号

无法连接仓库:Command "git ls-remote -h -- http://192.168.234.133:48080/net/WebApp1.git HEAD" returned status code 128:
stdout:
stderr: remote: HTTP Basic: Access denied
fatal: Authentication failed for 'http://192.168.234.133:48080/net/WebApp1.git/'

构建触发器

构建触发器,这里勾选Build when a chenge ……,把URL 复制记录下来,等下在Gitlab需要使用到。这里就是与Gitlab webhook做了联动,可以理解成Jenkins开放了一个接口,让Gitlab被push代码后会主动告诉Jenkins做一次自动化构建。

构建

这里其实就是执行shell脚本完成发布。这里得注意下我是用ssh,因为我的Jenkins是使用了docker安装的,如果我使用了【构建】模块里的【执行shell】就会在Jenkins环境里进行编译、打包,同时也需要安装相应的环境 例如dotnet sdk等。值得注意的是,我的环境与Jenkins挂载的都是在了Server这个宿主环境,因此通过Jenkins的SSH Publishers连到Jenkins的宿主服务器(Server),执行相应的shell脚本从Jenkins挂载的目录进行构建镜像。当然有同学想在Jenkins环境先打包然后通过SSH的Transfers模块进行文件传也是可以的。

Send files or execute commands over SSH

构建步骤选择“Send files or execute commands over SSH

# 工作空间目录
mkdir -p /root/jenkins/jenkins_home/workspace/webapp1
# 执行脚本目录
mkdir -p /root/jenkins/jenkins_home/workspace/build/webapp1

创建build.sh

#!/bin/bashecho '清除原webapp1容器执行开始'
docker stop webapp1   
docker rmi webapp1
echo '清除原webapp1容器执行结束'echo '脚本开始执行'base_path=/root/jenkins/jenkins_home/workspace/webapp1project_name=webapp1
project_path=$base_path/webapp1
publish_path=$project_path/bin/Release/netcoreapp6.0/publishcd $project_path
rm -rf $project_path/bindotnet publish -c Release && (cd $publish_path &&docker stop $project_namedocker rm $project_namedocker image rm $project_namedocker build -t $project_name . &&docker run -d -p 5000:80 -e ASPNETCORE_ENVIRONMENT="Development" --name $project_name $project_name &&echo '发布成功:'$project_path'' ||echo '发布失败:'$project_path''
) || echo '发布失败:'$project_path''echo '脚本执行结束'

将build.sh保存到/root/jenkins/jenkins_home/workspace/build/WebApp1目录下。

Remote directory输入/,Exec command输入以下内容

sh /root/jenkins/jenkins_home/workspace/build/webapp1/build.sh
Build / Publish Docker Image

Directory for Dockerfile:./

Cloud:选择自己在jenkins配置的docker

Image:$ImageName:$Version

构建脚本(没用到那)

Nuget脚本

这个是工具库发布到私有Nuget的脚本

#脚本开始执行
echo '脚本开始执行'base_path=/root/jenkins/jenkins_home/workspace/TestNuget
nuget_url=http://192.168.234.133:8081/
nuget_api_key=chengongproject_path=$base_path/TestNuget
package_path=$project_path/bin/Debug
cd $project_pathrm -rf $package_path/*.nupkgdotnet pack $project_path &&dotnet nuget push --source $nuget_url -k $nuget_api_key $package_path/*.nupkg >/dev/nullif [ $? -eq 0 ]; thenecho '发布成功:'$project_path''
elseecho '发布失败:'$project_path''
fiecho '脚本执行结束'

Web应用

下面这个是Web应用发布到单台服务器的脚本

#!/bin/bashecho '清除原webapp1容器执行开始'
docker stop webapp1   
docker rmi webapp1
echo '清除原webapp1容器执行结束'echo '脚本开始执行'base_path=/root/jenkins/jenkins_home/workspace/webapp1project_name=webapp1
project_path=$base_path/webapp1
publish_path=$project_path/bin/Release/netcoreapp6.0/publishcd $project_path
rm -rf $project_path/bindotnet publish -c Release && (cd $publish_path &&docker stop $project_namedocker rm $project_namedocker image rm $project_namedocker build -t $project_name . &&docker run -d -p 5000:80 -e ASPNETCORE_ENVIRONMENT="Development" --name $project_name $project_name &&echo '发布成功:'$project_path'' ||echo '发布失败:'$project_path''
) || echo '发布失败:'$project_path''echo '脚本执行结束'

下面这个是通过Docker Swarm把Web应用发布到多台服务器

#!/bin/bash
echo '脚本开始执行'base_path=/root/jenkins/jenkins_home/workspace/webapp1project_name=webapp1
project_path=$base_path/webapp1
publish_path=$project_path/bin/Release/netcoreapp6.0/publish
private_registry_url=192.168.234.133:6000
version=`date "+%Y%m%d%H%M%S"`cd $project_path
rm -rf $project_path/bindotnet publish -c Release && ( (cd $publish_pathdocker service rm testdockerswarmdocker images | grep $private_registry_url/$project_name | awk '{print $3}' | xargs docker rmidocker build -t $private_registry_url/$project_name:$version ./docker push $private_registry_url/$project_name:$version) &&docker service create -d -p 5000:80 --replicas 2 -e ASPNETCORE_ENVIRONMENT="Development"  --constraint=" node.role==worker"  --name $project_name $private_registry_url/$project_name:$version &&echo '发布成功:'$project_path'' ||echo '发布失败:'$project_path''
) || echo '发布失败:'$project_path''echo '脚本执行结束'

上面脚本有一处地址得注意下我指定了--constraint=" node.role==worker" 也就是woker节点才会部署应用,因为我定义了ServerA和C是Web服务器。当然各位可以按照自己的需要处理。

Dockerfile

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
#EXPOSE 443FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WebApp1.csproj", "."]
COPY ["nuget.config", "."]
RUN dotnet restore "./WebApp1.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "WebApp1.csproj" -c Release -o /app/buildFROM build AS publish
RUN dotnet publish "WebApp1.csproj" -c Release -o /app/publishENV TZ=Asia/ShanghaiFROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApp1.dll"]

nuget.config

<?xml version="1.0" encoding="utf-8"?>
<configuration><packageSources><add key="huaweicloud.com" value="https://repo.huaweicloud.com/repository/nuget/v3/index.json" /><add key="azure.cn" value="https://nuget.cdn.azure.cn/v3/index.json" /></packageSources><disabledPackageSources><add key="huaweicloud.com" value="true" /></disabledPackageSources>
</configuration>

gitlab配置

默认情况下gitlab不允许在本地调用,因此我们需要设置本地调用

创建项目

创建一个私有的WebApp1项目

参数配置

出站请求

设置-->网络-->出站请求

勾选----Allow requests to the local network from web hooks and services

并编辑触发webhook的本地服务器地址

以上设置解决webhook内部请求失败的问题

Webhooks

进入一个Project,点击【Setting】-【Webhooks】,把刚刚在Jenkins的复制下来的Url填写进去,勾选相应的触发事件后保存。

jenkins的配置url

分别输入jenkins 的url=http://192.168.234.133:8081/project/WebApp1及api token=110fbb87488254464129c23fe4c73d0d42

设置成功后使用test选择触发事件进行测试

如果测试报http 403:

  • 安装插件:gitlab/gitlab hook/Build Authorization Token Root Plugin
  • 系统管理-->configure global security -->去掉勾选 防止跨站点请求伪造(可能)
  • 系统管理-->系统设置-->去掉 Enable authentication for '/project' end-point
  • 打开jenkins,选择系统管理-系统配置,找到Gitlab选项,取消gitlab认证

 配置 Jenkins 与 GitLab 集成

  1. 在 Jenkins 中安装 GitLab Plugin,以便 Jenkins 可以与 GitLab 进行交互。

  2. 在 GitLab 中创建一个访问 Token,进入 GitLab 个人设置 > Access Tokens,生成一个新的 Token。

  3. 在 Jenkins 中配置 GitLab 连接:

    • 进入 Jenkins > Manage Jenkins > Configure System,找到 GitLab Plugin 部分。
    • 添加一个新的 GitLab 服务器,输入 GitLab 地址和 Token。
  4. 配置 Jenkins 使用 GitLab 的 Webhook 自动触发构建。

    配置 Jenkins 构建流程

  5. 在 Jenkins 中创建一个新的 Pipeline 作业。
  6. 在 Pipeline Script 部分,配置流水线脚本,内容如下:
    pipeline {agent anyenvironment {REGISTRY = "harbor.example.com/your-project"IMAGE_NAME = "your-image-name"GITLAB_CI_TOKEN = credentials('gitlab-ci-token')  // 用于从 GitLab 拉取代码}stages {stage('Checkout') {steps {git 'https://gitlab.com/your-username/your-repo.git'}}stage('Build Docker Image') {steps {script {docker.build("${REGISTRY}/${IMAGE_NAME}:${BUILD_ID}")}}}stage('Push Docker Image') {steps {script {docker.withRegistry('https://harbor.example.com', 'harbor-credentials') {docker.image("${REGISTRY}/${IMAGE_NAME}:${BUILD_ID}").push()}}}}stage('Deploy to Production') {steps {// 此处填写部署命令,取决于你的生产环境配置sh 'docker-compose up -d'}}}
    }
    

配置 GitLab CI/CD 集成

  1. 在 GitLab 项目中创建一个 .gitlab-ci.yml 文件,配置 GitLab CI/CD 管道:
    stages:- build- deployvariables:REGISTRY: "harbor.example.com/your-project"IMAGE_NAME: "your-image-name"build:stage: buildscript:- docker build -t $REGISTRY/$IMAGE_NAME:$CI_COMMIT_REF_NAME .- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD harbor.example.com- docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_REF_NAMEdeploy:stage: deployscript:- docker-compose up -d
    

推送代码

在另外一台机器上安装git,将项目的源码包上传

以上就是本篇的内容了,完成了部署后,可以在Jenkins点击【立刻构建】和在Gitlab迁入一次代码查看运行效果。

流水线工作流

  1. 每次代码推送到 GitLab 时,GitLab 会触发 CI/CD 流程。
  2. Jenkins 会拉取最新代码,构建 Docker 镜像,并推送到 Harbor。
  3. 一旦镜像推送成功,Jenkins 会自动部署到生产环境。

总结

通过结合 Docker、Jenkins、Harbor 和 GitLab,可以实现一个高效、自动化的 CI/CD 流水线。这种流水线不仅简化了应用的构建和部署过程,还提高了代码的质量和开发效率。随着团队规模的扩大和需求的增加,你还可以根据项目需求扩展和调整流水线配置。

http://www.xdnf.cn/news/1367299.html

相关文章:

  • Linux文件系统深入解析:从原理到实践
  • 通义灵码插件——AI 重构表单开发!半小时搭建可视化拖拽系统,效率碾压传统模式
  • 面试:Spring
  • MySQL 面试题系列(三)
  • week5-[循环结构]听歌
  • cuda编程笔记(16)--使用 cuDNN 实现卷积、激活、池化等反向操作
  • 淘宝/天猫商品详情API数据解析【附代码】
  • AP8105 PFM升压芯片数据手册
  • 支持向量机(SVM)学习笔记
  • 如何安装 VS2019 和 .NET Core SDK 2.2.301(winx64)?完整操作步骤(附安装包下载)
  • Ubuntu22.04安装OBS
  • 【软考论文】论自动化测试方法及其应用
  • 办公无纸化的关键:cpolar让Paperless-ngx远程扫描更便捷
  • 【Elasticsearch】k-NN 搜索深度解析:参数优化与分数过滤实践
  • 【SystemUI】锁屏来通知默认亮屏Wake模式
  • 32.Ansible平台搭建
  • 1424. 对角线遍历 II
  • 2024年Engineering SCI2区,面向工程管理的无人机巡检路径与调度,深度解析+性能实测
  • 计算机毕业设计 java 药店药品信息管理系统 基于 Java 的药店药品管理平台Java 开发的药品信息系统
  • 设计模式:原型模式(Prototype Pattern)
  • 如何通过虚函数实现多态?
  • 实现自己的AI视频监控系统-第二章-AI分析模块2
  • 【git使用场景】本地仓库与远程仓库存在独立历史
  • ​Visual Studio + UE5 进行游戏开发的常见故障问题解决
  • 系统开发 Day4
  • 音视频学习(五十六):单RTP包模式和FU-A分片模式
  • Linux驱动开发笔记(七)——并发与竞争(上)——原子操作
  • 深度学习-----《PyTorch深度学习核心应用解析:从环境搭建到模型优化的完整实践指南》
  • 链表OJ习题(2)
  • 操作系统中,进程与线程的定义与区别