? ? ? ? 制品庫作為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: nexusenvironment:- "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/") // 根據版本類型選擇倉庫URLcredentials {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 anyenvironment {// 定義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 {// 登錄到Harborscript {docker.withRegistry("${HARBOR_URL}", "${DOCKER_CREDENTIALS_ID}") {// 將鏡像推送到Harbordef customImage = docker.image("${HARBOR_PROJECT}/${IMAGE_NAME}:${env.BUILD_ID}")customImage.push()}}}}// 你可以添加更多的階段,比如部署到Kubernetes集群}post {always {// 清理Docker構建緩存等cleanWs()}}
}