制品库作为DevOps价值流中的一个关键环节,其重要性日益凸显。制品库,作为存储和管理软件开发过程中产生的各种制品(如代码包、镜像、配置文件等)的仓库,是连接开发、测试、部署等多个环节的桥梁。它不仅能够实现制品的统一存储和高效分发,还能够通过版本控制和依赖管理等功能,确保软件构建的稳定性和可追溯性。因此,深入探索和实践制品库的使用,对于提升DevOps价值流的整体效率和质量具有至关重要的作用。本文将围绕制品库在DevOps价值流中的实战应用,深入探讨其设计原则、关键功能、最佳实践以及未来发展趋势。通过具体的案例分析和实战经验分享,帮助读者更好地理解制品库的核心价值,掌握其在软件开发过程中的应用技巧,从而推动DevOps价值流的持续优化和创新。
一、制品与制品库概述
1 制品定义
制品是软件开发过程中的重要产出物,是源代码经过编译、打包后生成的二进制文件,这些文件可以在服务器上运行或作为编译依赖。制品种类繁多,包括但不限于Java的JAR、WAR、EAR文件,C/C++的二进制可执行文件,Python的.py文件,以及NuGet、Ruby gems、NPM等软件包格式。在容器化环境下,Docker镜像和Helm charts也是关键的制品类型。
2 制品库分类
根据使用场景和存储内容的不同,制品库可细分为:
-
通用制品仓库:存储ZIP、tar.gz等压缩文件以及.exe、.sh等可执行文件,适用于各种软件开发和部署场景。
-
镜像仓库:专门用于存储Docker镜像和Helm charts等容器化制品,支持Kubernetes等容器编排平台的部署需求。
-
依赖仓库:管理Maven、NPM、PyPI等开发语言的依赖包,通过私服代理和本地缓存加速依赖包的下载速度,确保开发环境的稳定性和一致性。
二、制品库在DevOps实践中的核心价值
1 DevOps与DevSecOps中的安全风险
在DevOps和DevSecOps实践中,制品库扮演着举足轻重的角色。然而,不当的制品库管理会带来一系列安全风险:
-
第三方依赖包管理混乱:缺乏安全漏洞扫描和安全准入设置,可能导致漏洞被引入生产环境,造成生产事故。
-
制品管理混乱:缺乏统一的制品管理平台,导致冗余制品无法及时清理,造成资源管理混乱。
-
溯源管理缺失:缺乏对制品全生命周期的过程管控,导致无法历史溯源,增加了问题排查的难度。
-
服务中断风险:制品库缺乏高可用设计时,存在因故障引起服务中断的风险,影响研发和运维工作。
-
运维成本高昂:缺乏集群部署和制品同步分发功能,导致重复建设问题严重,维护成本高。
2 制品库在DevOps实践中的必要性
在典型的软件开发流程中,制品库在多个环节中都发挥着关键作用:
-
开发构建阶段:提供依赖组件的集中管理和安全扫描功能,确保开发过程中使用的组件安全无虞。同时,通过私服代理功能加速依赖包的下载速度,提高开发效率。
-
构建管理阶段:对构建的制品进行集中存储和版本管理,确保开发团队能够随时获取到最新或指定版本的制品。通过访问控制和权限管理功能,确保只有授权用户才能访问和修改制品。
-
测试部署阶段:提供可靠的传输介质和版本管理功能,确保测试环境和生产环境中使用的制品一致且可靠。通过高可用设计和异地节点同步分发功能,确保制品库的稳定性和可用性,避免因制品库故障导致的服务中断问题。
3 制品库优化策略
为了充分发挥制品库在DevOps实践中的价值,企业需要进行深度优化:
-
集成CI/CD流程:将制品库与持续集成/持续交付流程紧密结合,实现自动化构建、测试和部署,提高开发效率和交付速度。
-
精细化权限管理:根据团队成员的角色和职责设置不同的权限级别,确保最小权限原则的实施。同时建立清晰的团队协作机制,促进团队成员之间的沟通和协作。
-
采用高效存储和传输技术:利用分布式存储、压缩算法等技术手段提高制品库的存储效率和传输速度,降低运维成本。
-
加强监控与审计:建立制品库的监控与审计机制,定期检查运行状态和数据完整性。及时发现和处理异常情况,同时记录和审计操作日志,确保制品的安全性和可追溯性。
三 Nexus与Harbor的联合使用
1 为什么选择Nexus与Harbor联合使用
在容器化环境下,公司内部使用的镜像不可能直接放在Docker Hub上,因此需要一个私有的Docker镜像仓库。目前Docker registry的实现方案很多,包括官方的registry、Harbor以及Nexus等。然而,它们各自存在优缺点,因此选择将Nexus与Harbor联合使用以达到最佳效果。
-
Harbor的优势:Harbor提供了自建文件夹进行分组的功能,非常适合作为私有的镜像仓库。同时,Harbor还支持用户权限管理、审计日志等功能,能够确保镜像的安全性和可追溯性。
-
Nexus的补充:虽然Harbor在镜像管理方面表现出色,但它无法直接帮助用户下载镜像。而Nexus则很好地弥补了这一缺陷。通过Nexus,用户可以方便地拉取公网镜像,并将其缓存到本地,以供后续使用。此外,Nexus还支持多种制品类型的存储和管理,能够满足企业多样化的需求。
2 联合使用场景
-
镜像拉取与缓存:在Kubernetes环境下,企业可能需要从公网拉取镜像。此时,可以通过Nexus代理Harbor或其他公网镜像仓库,实现镜像的拉取与缓存。这样,既能够确保镜像的安全性,又能够提高拉取速度。
-
制品管理与分发:除了镜像外,企业还需要管理其他类型的制品,如源代码、编译后的二进制文件等。此时,可以利用Nexus的通用制品仓库功能,对这些制品进行集中存储和管理。同时,通过Nexus的访问控制和权限管理功能,可以确保只有授权用户才能访问和修改制品。
四 Nexus应用实践
Nexus Repository 3是Nexus公司的仓库管理平台,它是使用最为广泛的开源仓库管理平台,可以管理整个软件供应链中的组件、二进制文件和构建制品。Nexus Repository 3分为社区版和企业版,社区版可以免费且全面地管理二进制文件和制品,企业版具有更多的安全特性。Nexus Repository 3支持的二进制文件仓库类型如下图
1 Nexus Repository 3安装
1.1. 获取镜像
首先,从Docker Hub上拉取指定版本的Nexus Repository 3镜像。这里以3.75.1版本为例:
docker pull sonatype/nexus3:3.75.1
1.2. 创建持久化文件目录并设置权限
为Nexus Repository 3创建一个用于存储数据的持久化目录,并设置适当的权限。这里将目录创建在/home/docker/nexus
下:
mkdir -p /home/docker/nexus
# 注意:通常不建议使用chmod 777,因为这会给所有用户完全访问权限。
# 更安全的做法是设置合适的用户和组权限。但在这里,为了简化步骤,我们暂时使用777。
# 在生产环境中,请务必考虑安全性。
chmod 777 -R /home/docker/nexus/
- 创建一个专门的用户(如
nexus_user
)来运行Nexus容器,并为该用户设置适当的目录权限。
1.3. 编辑 docker-compose 文件
创建一个docker-compose.yml
文件,并配置Nexus服务:
version: "3.1"
services:
nexus:
image: sonatype/nexus3:3.75.1 # 指定镜像版本
container_name: nexus
environment:
- "INSTALL4J_ADD_VM_PARAMS=-Xms1g -Xmx1g -XX:MaxDirectMemorySize=1g" # 设置JVM参数
ports:
- "9707:8081" # 将容器的8081端口映射到宿主机的9707端口
volumes:
- /home/docker/nexus:/nexus-data # 将宿主机的/home/docker/nexus目录挂载到容器的/nexus-data目录
restart: always # 确保容器在崩溃后自动重启
注意:
-
在
volumes
部分,请确保路径正确无误。上面的示例中使用了绝对路径/home/docker/nexus
。 -
在
environment
部分,可以根据需要调整JVM参数。
1.4. 启动服务
使用docker-compose
命令启动Nexus服务:
docker-compose up -d
1.5. 查看登录密码
Nexus首次启动时会生成一个默认的admin用户密码,并保存在/nexus-data/admin.password
文件中。可以使用以下命令查看密码:
docker exec -it nexus cat /nexus-data/admin.password
注意:
-
出于安全考虑,建议在首次登录后更改默认密码。
-
在生产环境中,请确保不要将密码暴露给未经授权的用户。
1.6. 页面登录并设置密码
打开浏览器,访问http://<your_server_ip>:9707
(将<your_server_ip>
替换为你的服务器IP地址或域名),使用用户名admin
和上述步骤中查看到的密码登录Nexus管理界面。
登录后,系统会提示你更改密码。请按照提示操作,确保账户安全。
2 搭建Maven私服仓库
通常情况下,开发人员在进行代码开发时会使用一些包管理工具,如Maven、Gradle,这些都是常见项目的编译构建工具。我们可以将这些工具理解为命令行工具。使用私服,就是在企业内部建立中央存储仓库。例如,在公司内部通过Nexus Repository 3创建一个代理仓库,将公网仓库中的Maven包代理到内网仓库中。这样就可以直接访问内网的私服下载、构建依赖包。内网的速度要比公网快,这会直接加快管道的构建速度。代理仓库不会把公网仓库中的所有包下载到本地,而是按需缓存。例如,此时需要使用aa这个包,如果代理仓库中没有,则请求外部服务器下载这个包并进行缓存,当第二次访问时,即可直接访问代理仓库。
2.1 创建代理仓库
导航进入Nexus Repository 3的管理页面,单击Create repository按钮创建仓库
2.2 填写仓库信息
选择maven2(proxy),进入新增仓库页面
2.3 设置默认的maven-public仓库
3 更新仓库依赖
3.1 maven
Maven客户端要想使用私服,需要编辑配置文件。编辑settings.xml文件并添加mirror配置,配置如下。
<mirrors>
<mirror>
<id>nexus-public</id>
<mirrorOf>central</mirrorOf>
<name>central repository</name>
<url>http://ip:port/repository/maven-public/</url>
</mirror>
</mirrors>
3.2 gradle
对于Gradle,您需要在项目的build.gradle
文件或全局的gradle.properties
文件中配置仓库地址。
<mirrors>
<mirror>
<id>nexus-public</id>
<mirrorOf>central</mirrorOf>
<name>central repository</name>
<url>http://ip:port/repository/maven-public/</url>
</mirror>
</mirrors>
如果您希望将用户名和密码等敏感信息保存在其他地方,可以在gradle.properties
文件中定义它们,并在build.gradle
文件中引用:
# gradle.properties
NEXUS_USERNAME=your-nexus-username
NEXUS_PASSWORD=your-nexus-password
// build.gradle
repositories {
maven {
url "http://your-nexus-ip:your-nexus-port/repository/maven-public/"
credentials {
username = project.findProperty("NEXUS_USERNAME") ?: ""
password = project.findProperty("NEXUS_PASSWORD") ?: ""
}
}
}
3.3 npm
对于npm,您需要在项目的.npmrc
文件或全局的npm配置文件中添加私服仓库地址
registry=http://your-nexus-ip:your-nexus-port/repository/npm-group/
_auth=<base64-encoded-username:password>
email=your-email@example.com
always-auth=true
请注意,_auth
字段的值是username:password
经过Base64编码后的字符串。您可以使用在线工具或命令行工具(如echo -n 'username:password' | base64
)来生成这个编码字符串。
另外,always-auth=true
表示对于所有请求都需要进行身份验证,这对于使用私有仓库时非常重要。
4 制品上传方式
4.1 Web页面上传
Nexus Repository 3提供了通过Web页面上传制品的途径。单击左侧菜单的Upload,然后选择要上传的目标仓库,如图所示:
4.2 maven命令上传
1 设置setting.xml文件
<settings>
<!-- 其他配置 -->
<servers>
<server>
<id>nexus-releases</id> <!-- 与pom.xml中的repository ID相匹配 -->
<username>your-nexus-username</username> <!-- 替换为你的Nexus用户名 -->
<password>{your-encrypted-password}</password> <!-- 使用mvn --encrypt-password加密后的密码,或明文密码(不推荐) -->
</server>
<server>
<id>nexus-snapshots</id> <!-- 与pom.xml中的snapshotRepository ID相匹配(如果有快照版本) -->
<username>your-nexus-username</username> <!-- 替换为你的Nexus用户名(通常与releases相同) -->
<password>{your-encrypted-password}</password> <!-- 使用mvn --encrypt-password加密后的密码,或明文密码(不推荐) -->
</server>
<!-- 其他服务器配置 -->
</servers>
<!-- 其他配置 -->
</settings>
-
在
pom.xml
中,<distributionManagement>
部分配置了用于部署的仓库ID和URL。这些ID应该与settings.xml
中配置的服务器ID相匹配。 -
在
settings.xml
中,<servers>
部分配置了用于认证服务器的用户名和密码。如果密码是加密的,你需要先使用mvn --encrypt-password
命令生成加密密码,并将其放在<password>
标签内。 -
确保将
your-nexus-server
、your-nexus-username
和{your-encrypted-password}
替换为你的实际Nexus服务器地址、用户名和加密后的密码。
2 修改pom文件
<project>
<!-- ... 其他POM配置 ... -->
<!-- 版本信息 -->
<version>1.0.0</version>
<packaging>jar</packaging> <!-- 或者其他打包方式,如war -->
<!-- ... 其他POM配置 ... -->
<!-- 分发管理配置,指定部署到的仓库 -->
<distributionManagement>
<!-- 发布版本(非快照)的仓库 -->
<repository>
<id>nexus-releases</id> <!-- 与settings.xml中配置的服务器ID一致 -->
<url>http://your-nexus-server:8081/repository/maven-releases/</url> <!-- Nexus发布仓库的URL -->
</repository>
<!-- 快照版本的仓库(如果有快照发布需求) -->
<snapshotRepository>
<id>nexus-snapshots</id> <!-- 与settings.xml中配置的服务器ID一致(用于快照) -->
<url>http://your-nexus-server:8081/repository/maven-snapshots/</url> <!-- Nexus快照仓库的URL -->
</snapshotRepository>
</distributionManagement>
<!-- ... 其他POM配置,如依赖、插件等 ... -->
</project>
在这个pom.xml
的相关部分中,distributionManagement
元素包含了两个子元素:repository
和snapshotRepository
。这些元素指定了Maven在部署发布版本和快照版本时应该使用的仓库。
-
repository
元素用于配置发布版本的仓库。id
属性应该与settings.xml
文件中配置的服务器ID相匹配,而url
属性则指定了Nexus发布仓库的URL。 -
snapshotRepository
元素(可选)用于配置快照版本的仓库。它的配置方式与repository
类似,但用于快照版本的部署。
请确保将your-nexus-server
替换为你的实际Nexus服务器地址,并且该服务器地址在你的Maven settings.xml
文件中已经通过服务器认证配置进行了验证。
3 使用Maven命令部署
mvn clean deploy
这个命令将执行以下操作:
-
clean
:清理以前构建生成的文件。 -
deploy
:根据pom.xml
中的配置,将制品部署到配置的Nexus仓库中。
执行完命令后,登录到Nexus Repository的Web界面,导航到相应的仓库(maven-releases
或maven-snapshots
),并查找你刚刚上传的制品。
4.3 gradle命令上传
1 配置 build.gradle
文件
plugins {
id 'maven-publish'
}
group = 'com.yourcompany.yourproject' // 替换为你的项目组ID
version = '1.0.0' // 替换为你的项目版本
repositories {
mavenCentral() // 或者其他你需要的仓库
}
repositories {
maven {
name = "maven-snapshots"
url = version.endsWith('SNAPSHOT') ?
uri("http://ip:port/repository/maven-snapshots/") :
uri("http://ip:port/repository/maven-releases/") // 根据版本类型选择仓库URL
credentials {
username = findProperty("nexusUsername") ?: System.getenv("NEXUS_USERNAME") ?: ""
password = findProperty("nexusPassword") ?: System.getenv("NEXUS_PASSWORD") ?: ""
}
}
}
2 配置 gradle.properties
文件
在你的项目根目录下或用户主目录下的 .gradle
文件夹中,创建或编辑 gradle.properties
文件,并添加以下内容以存储Nexus的用户名和密码。
nexusUsername=your-nexus-username
nexusPassword=your-nexus-password-or-encrypted-value
3 使用 Gradle 命令部署
./gradlew clean build publish
4.3 npm命令上传
1 配置 .npmrc
文件
在你的项目根目录下,创建或编辑 .npmrc
文件,并添加以下内容以配置Nexus npm仓库的认证信息和仓库URL。
registry=http://your-nexus-server:8081/repository/npm-group/
_auth=<base64-encoded-username:password> // 使用base64编码的用户名和密码组合(不推荐明文存储密码)
email=your-email@example.com
always-auth=true
2 准备 package.json
文件
确保 package.json
文件已经正确配置了你的项目信息,包括 name
、version
、description
、main
(入口文件)、scripts
(脚本命令)、dependencies
(依赖项)等。
3 使用 npm 命令发布
npm pack // 可选,用于测试打包是否成功
npm publish // 发布到配置的Nexus npm仓库
5 Jenkins插件上传制品
5.1 安装Nexus Artifact Uploader插件
进入Jenkins插件管理,搜索并安装Nexus Artifact Uploader插件
5.2 使用片段生成器生成流水线代码
stage('上传制品') {
steps {
nexusArtifactUploader(
credentialsId: 'nexus',
groupId: 'com.mlz.team',
nexusUrl: 'ip:port',
nexusVersion: 'nexus3',
protocol: 'http',
repository: 'maven-snapshots',
version: '0.0.1-SNAPSHOT', // 确保版本号正确
artifacts: [
[artifactId: 'demo-pipeline', classifier: '', file: 'build/libs/demo-pipeline-0.0.1-SNAPSHOT.jar', type: 'jar']
]
)
}
}
五 Harbor应用实践
随着云原生技术的快速发展,容器技术因轻量级虚拟化特性,成为企业数字化转型的关键。Docker的普及推动了容器技术的广泛应用,容器镜像简化了软件打包与分发。然而,镜像数量增加后,容器镜像的管理在云原生应用从开发到测试、部署、管理的全生命周期中变得至关重要。这正是Harbor所专注的核心问题。作为一款专为满足企业安全合规需求的云原生制品仓库,Harbor不仅包含了Docker Distribution的核心功能,还融入了权限控制、镜像签名和安全漏洞扫描等特性,为中国云原生用户提供了更安全可靠的解决方案。
1 Harbor 2.0架构
Harbor 2.0的架构自上而下分为代理层、功能层和数据层,每一层都承担着特定的职责,共同构建了这一强大的云原生制品仓库。
1.1 代理层
代理层是Harbor的门户,实质为一个Nginx反向代理。它负责接收来自不同客户端(如浏览器、用户脚本、Docker及其他Artifact命令行工具)的请求,并根据请求类型和URI将这些请求转发至相应的后端服务进行处理。这一层确保了Harbor的所有功能都能通过单一的主机名进行访问。
1.2 功能层
功能层由一组HTTP服务构成,这些服务提供了Harbor的核心功能。这些服务包括核心功能组件(Core、Portal、JobService、Docker Distribution、RegistryCtl)以及可选组件(如Notary、ChartMuseum和镜像扫描器)。
-
核心功能组件:
-
Portal:基于Angular开发的前端应用,由内置的Nginx服务器提供静态资源服务。当用户通过浏览器访问Harbor的用户界面时,代理层的Nginx会将请求转发至Portal容器,以便获取运行前端界面所需的Javascript文件、图标等静态资源。
-
Core:Harbor的核心组件,封装了大部分业务逻辑。它基于Beego框架提供中间件和RESTful API处理器,处理来自界面和其他客户端的API请求。Core组件还负责连接内部数据库或外部身份认证服务进行用户认证,以及处理Artifact的推送和拉取请求,进行权限检查、配额扣除等操作,并将请求转发至Docker Distribution组件。
-
Docker Distribution:由Docker公司维护的镜像仓库,实现了镜像的推送、拉取等功能。Harbor通过它实现了Artifact的读写和存取。
-
RegistryCtl:Docker Distribution的控制组件,与其共享配置,并提供RESTful API以触发垃圾回收等动作。
-
JobService:异步任务组件,负责处理Harbor中的耗时功能,如Artifact复制、扫描、垃圾回收等。它通过RESTful API接收任务请求,将任务放入Redis队列中,并根据时间表调度执行。任务执行结果通过回调方式通知调用方。
-
1.3 数据层
数据层主要负责业务数据和Artifact内容的保存与持久化,使核心组件能够无状态地处理业务逻辑和用户请求。
-
数据存储组件:
-
数据库(PostgreSQL):存储Harbor的应用数据,如项目信息、用户与项目的关系、管理策略和配置信息等。Artifact的元数据也保存在此。Harbor目前仅支持PostgreSQL作为后台数据库。
-
缓存服务(Redis):存储生命周期较短的数据,如多个实例共享的状态信息。JobService的持久化数据也保存在Redis中。不同的索引号对应不同的组件,实现数据的隔离和共享。
-
Artifact存储:存储Artifact本身的内容。默认情况下,Harbor将Artifact写入本地文件系统,但用户也可以配置第三方存储服务(如S3、GCS、OSS等)作为后端存储。
-
1.4 可选组件
可选组件是Harbor在核心功能基础上,通过与第三方开源软件集成提供的额外功能服务,如镜像签名、漏洞扫描等。这些组件在安装时可根据用户需求选择是否安装,并与Harbor的核心组件共用数据库、Redis等服务,以实现更好的集成和协作。
-
Notary:提供镜像签名功能,确保镜像的完整性和来源可信。它包括server和signer两个容器,分别负责签名和验证操作。
-
ChartMuseum:提供Helm Chart的存储和管理功能。
-
镜像扫描器:如Clair或Trivy等,提供镜像漏洞扫描功能,帮助用户发现并及时修复安全漏洞。
2 核心功能
Harbor作为云原生制品仓库服务,其核心功能是存储和管理Artifact。用户可通过命令行工具推送和拉取容器镜像及其他Artifact,同时Harbor提供图形管理界面,便于用户查阅和删除这些Artifact。自Harbor 2.0版本起,除容器镜像外,还支持OCI规范的Helm Chart、CNAB、OPA Bundle等。Harbor为管理员提供了丰富的管理功能。
2.1. 资源隔离与多租户体系
-
项目概念:Harbor通过项目实现资源的逻辑隔离,每个项目都是一个独立的命名空间,用于存储和管理Artifact(镜像、Helm Chart等)。
-
RBAC访问控制:支持基于角色的访问控制(RBAC),预定义了多种角色(如访客、开发者、维护者、项目管理员和系统管理员),权限逐级递增,确保用户只能访问其被授权的资源。
-
配额管理:为项目和命名空间设置存储配额,防止资源滥用,确保资源的合理分配和使用。
-
多种用户系统支持:支持内嵌的数据库用户系统、AD/LDAP系统以及通过OIDC机制对接的其它用户系统,方便集成到现有的IT环境中。
-
机器人账号:提供项目级别的机器人账号,方便CI/CD集成使用,支持系统级别的机器人账号,提供更多类型的权限和灵活性。
2.2. 镜像分发机制
-
基于策略的镜像复制:支持将源仓库中的特定镜像集合在指定条件下复制到目标镜像仓库中,支持多种过滤器和触发模式(手动、基于时间、定时触发),以及推送和拉取两种模式。
-
多层分发体系:构建主从或中心-边缘的多层分发体系,实现镜像内容的高效和稳定分发。
-
项目级别缓存:在拉取镜像时,如果项目中不存在,则由适配器将请求代理到上游仓库来响应请求,并将镜像缓存到项目中,提高分发效率。
-
P2P加速:与P2P提供者实现集成,利用P2P能力实现镜像的加速,减少对上游仓库的请求。
-
预热策略:创建预热策略,将所选镜像提前从Harbor仓库传输到特定P2P引擎的缓存中,进一步提高分发效率。
2.3. 安全机制
-
镜像签名:与Notary集成,支持镜像签名,确保镜像的完整性和可信度。用户可以在Docker客户端设置环境变量来开启签名流程,项目管理员可配置策略,强制仅允许签名镜像被拉取。
-
漏洞扫描:支持对镜像制品进行漏洞扫描,通过插件式的方式对接多种扫描引擎(如Clair、Trivy、Aqua CSP等),提供包含CVE列表的详细报告。管理员可设置白名单,跳过特定CVE。
-
不可变tag:实现不可变tag的安全机制,用户通过设置不可变tag的规则,使得满足这个规则的tag都进入不可变更的状态,防止镜像被恶意篡改。
2.4. 资源清理与垃圾回收
-
Tag保留机制:基于用户设置的规则计算出需要保留的镜像tag,并清除不在保留列表里的tag,确保仓库整洁。每次清理或保留的tag列表会在日志里保留,不可变镜像tag不会被清理。
-
垃圾回收(GC):支持在线垃圾回收,用户可通过管理界面触发或设置定时循环触发。每次GC执行的具体信息会被记录在日志里。在2.1版本之后,实现了非阻塞式GC模式,GC过程中依然支持推送新镜像到Harbor。
2.5. 高级管理功能
-
Artifact复制策略:支持Artifact在不同Harbor实例间的复制,提高可用性和灾难恢复能力。
-
存储配额管理:为项目和命名空间设置存储配额,确保资源的合理分配和使用。
-
保留策略:管理Artifact的保留和删除规则,确保仓库整洁,避免无用数据的积累。
-
日志与监控:提供详细的日志记录和监控功能,帮助管理员及时发现和解决潜在问题。
3 安装Harbor
Harbor提供了多种安装方式,其中包括在线安装、离线安装、源码安装及基于Helm Chart的安装。
◎ 在线安装:通过在线安装包安装Harbor,在安装过程中需要从Docker Hub获取预置的Harbor官方组件镜像。
◎ 离线安装:通过离线安装包安装 Harbor,从离线安装包中装载所需要的Harbor组件镜像。
◎ 源码安装:通过编译源码到本地安装Harbor。
◎ 基于Helm Chart的安装:通过Helm安装Harbor Helm Chart到Kubernetes集群。本章基于Ubuntu 18.04的基础环境来说明Harbor的每种安装方式。
下面是针对Harbor安装的详细步骤和优化后的内容,以Ubuntu 18.04为基础环境,重点介绍离线安装方式。
3.1 下载Harbor离线安装包
首先,从官方GitHub发布页面下载指定版本的Harbor离线安装包。例如,要下载2.3.4版本的离线安装包,可以访问以下链接并下载相应的.tgz
文件:
https://github.com/goharbor/harbor/releases/download/v2.3.4/harbor-offline-installer-v2.3.4.tgz
3.2 将安装包拖拽到Linux服务器并解压
将下载好的安装包通过SFTP、SCP或其他文件传输方式上传到Linux服务器。然后,在终端中执行以下命令将安装包解压到/usr/local/
目录:
tar -zxvf harbor-offline-installer-v2.3.4.tgz -C /usr/local/
3.3 修改Harbor配置文件
在解压后的目录中,你会找到harbor.yml.tmpl
文件,这是Harbor的配置模板文件。为了进行自定义配置,你需要复制这个文件并重命名为harbor.yml
:
cp /usr/local/harbor/harbor.yml.tmpl /usr/local/harbor/harbor.yml
接下来,使用你喜欢的文本编辑器(如vi
、nano
或vim
)打开harbor.yml
文件进行编辑。你需要根据实际需求修改配置,包括但不限于:
-
hostname
:Harbor服务器的域名或IP地址。 -
http
或https
配置:根据你的需求选择HTTP或HTTPS协议,并配置相应的证书(如果使用HTTPS)。 -
harbor_admin_password
:设置Harbor管理员的初始密码。 -
database
:配置数据库连接信息(默认情况下,Harbor使用PostgreSQL数据库)。 -
log
:配置日志存储位置。 -
其他相关配置,如存储后端、通知等。
3.4 启动Harbor
完成配置文件的修改后,保存并关闭编辑器。然后,在Harbor安装目录下执行以下命令来启动Harbor服务:
cd /usr/local/harbor
./install.sh
安装完成后会在当前目录自动生成docker-compose.yml文件
查看
docker-compose ps
再次安装,就可以执行以下命令
docker-compose up -d
停止
docker-compose down
3.5 登录Harbor
Harbor服务启动后,你可以通过浏览器访问Harbor的Web界面。在浏览器中输入Harbor服务器的域名或IP地址,然后输入管理员用户名(默认为admin
)和你设置的密码进行登录。
4 Harbor应用
Harbor作为镜像仓库,主要的交互方式就是将镜像上传到Harbor上,以及从Harbor上下载指定镜像
在传输镜像前,可以先使用Harbor提供的权限管理,将项目设置为私有项目,并对不同用户设置不同角色,从而更方便管理镜像。
4.1 添加用户构建项目
创建用户
构建项目(设置为私有)
给项目追加用户
4.2 发布镜像到Harbor
修改镜像名称
在推送镜像到Harbor之前,您需要按照Harbor的要求修改镜像的名称格式。格式通常为:<Harbor地址>/<项目名>/<镜像名>:<版本>
。
例如,如果Harbor地址是harbor.example.com
,项目名是myproject
,镜像名是myapp
,版本是1.0
,则镜像名称应该修改为:
harbor.example.com/myproject/myapp:1.0
可以使用docker tag
命令来重命名镜像:
docker tag 原始镜像名:原始版本 harbor.example.com/myproject/myapp:1.0
修改daemon.json
,支持Docker仓库,并重启Docker
确保Docker守护进程配置文件(通常是/etc/docker/daemon.json
)中包含了正确的insecure-registries设置,以允许Docker访问私有仓库(如果Harbor没有使用HTTPS)。例如:
{
"insecure-registries": ["harbor.example.com"]
}
修改配置文件后,重启Docker服务以应用更改:
sudo systemctl restart docker
注意:在生产环境中,建议使用HTTPS来保护您的Harbor仓库。
设置登录仓库信息
使用docker login
命令登录到Harbor仓库。您需要提供Harbor的用户名、密码和地址:
docker login -u 用户名 -p 密码 harbor.example.com
登录成功后,Docker CLI会返回一个Login Succeeded
消息。
绕过登录可以直接推送
mkdir -p ~/.docker
nano ~/.docker/config.json
{
"auths": {
"ip:port": {
"auth": ""
}
},
"credsStore": "",
"credHelpers": {}
}
echo -n 'admin:harbor123456' | base64
将输出的结果替换到 config.json 文件中的 auth 字段。
推送镜像到Harbor
最后,使用docker push
命令将标记好的镜像推送到Harbor仓库:
docker tag myapp:1.0 harbor.example.com/myapp/myapp:1.0
docker push harbor.example.com/myapp/myapp:1.0
4.3 从Harbor拉取镜像ls
docker pull harbor.example.com/myapp/myapp:1.0
5 jenkins 集成harbor
1. 安装Docker Pipeline插件
首先,你需要在Jenkins中安装Docker Pipeline插件。这个插件提供了对Docker构建和部署的支持。
-
登录到你的Jenkins实例。
-
导航到"Manage Jenkins" > "Manage Plugins"。
-
在"Available"标签页中搜索"Docker Pipeline"。
-
选中它并点击"Install without restart"或"Download now and install after restart"。
2. 为Harbor添加凭证
为了在Jenkins中访问Harbor,你需要添加Harbor的凭证(用户名和密码)。
-
导航到"Credentials" > "System" > "Global credentials (unrestricted)"。
-
点击"Add Credentials"。
-
选择适当的域(通常是"Global credentials (unrestricted)")。
-
选择"Secret text"或"Username with password"作为凭证类型。
-
输入Harbor的用户名和密码,或者Harbor的Docker registry登录命令的输出(包含用户名、密码和email,但email对于登录通常是可选的)。
-
点击"OK"保存凭证。
3. 创建Pipeline项目
接下来,你需要在Jenkins中创建一个新的Pipeline项目。
-
导航到"New Item"。
-
输入项目名称,选择"Pipeline",然后点击"OK"。
-
在项目配置页面中,选择"Pipeline"标签。
-
在"Definition"部分,选择"Pipeline script from SCM"或"Pipeline script"来定义你的Pipeline脚本。
4. 编写Pipeline脚本
Pipeline脚本定义了构建和部署Docker镜像到Harbor的整个过程。以下是一个简单的示例脚本,它假设你已经有一个Dockerfile在你的项目根目录中,并且你想要将镜像推送到Harbor的一个特定项目中。
pipeline {
agent any
environment {
// 定义Harbor的URL、项目名和镜像名
HARBOR_URL = 'https://your-harbor-domain.com'
HARBOR_PROJECT = 'your-harbor-project'
IMAGE_NAME = 'your-image-name'
DOCKER_CREDENTIALS_ID = 'your-harbor-credentials-id' // 这是你在Jenkins中创建的凭证ID
}
stages {
stage('Build') {
steps {
// 使用Docker构建镜像
script {
def customImage = docker.build("${HARBOR_PROJECT}/${IMAGE_NAME}:${env.BUILD_ID}")
// 这里可以添加额外的构建步骤,比如单元测试
}
}
}
stage('Push') {
steps {
// 登录到Harbor
script {
docker.withRegistry("${HARBOR_URL}", "${DOCKER_CREDENTIALS_ID}") {
// 将镜像推送到Harbor
def customImage = docker.image("${HARBOR_PROJECT}/${IMAGE_NAME}:${env.BUILD_ID}")
customImage.push()
}
}
}
}
// 你可以添加更多的阶段,比如部署到Kubernetes集群
}
post {
always {
// 清理Docker构建缓存等
cleanWs()
}
}
}