Nexus 是支持 Nuget、Docker、Npm 等多種包的倉庫管理器,可用做私有包的存儲分發,緩存官方包。本篇將手把手教學使用 Nexus 搭建自己的 NuGe t& Docker 私有倉庫。 ...
前言
Nexus 是支持 Nuget、Docker、Npm 等多種包的倉庫管理器,可用做私有包的存儲分發,緩存官方包。本篇將手把手教學使用 Nexus 搭建自己的 NuGe t& Docker 私有倉庫。
特點
-
私有化倉庫管理
-
支持許可權管理
-
緩存依賴包
-
支持插件機制和 REST API
-
成熟穩定強大
-
支持的倉庫/包管理
使用情況
- 成熟文檔,使用四平八穩,部署完基本就不需要操心太多
- 功能強大,啟動起來記憶體大概 1.4G+,目前團隊使用4G記憶體的伺服器部署,差不多是夠用的
- 支持 docker 倉庫,嘗試一番終於搞定,後續會在 DevOps 系列中使用
- 文檔比較完善,遇到問題可以多理解理解文檔
安裝部署
使用 docker compose 安裝
-
創建數據掛載目錄並賦予許可權:以 UID 200 的形式運行
mkdir ./data && chown -R 200 ./data
-
指定版本:
sonatype/nexus3:3.61.0
-
預設埠:
8081
-
指定訪問首碼:/
-
指定網路:devopsnetwork (
docker network create devopsnetwork
) -
部署伺服器 IP:
192.168.123.214
-
創建 compose.yml
version: '3.1' services: nexus: image: sonatype/nexus3:3.61.0 container_name: nexus_3_61 restart: always environment: # Nexus 上下文路徑 NEXUS_CONTEXT: / # 指定jvm參數 INSTALL4J_ADD_VM_PARAMS: -Xms1g -Xmx1g -XX:MaxDirectMemorySize=3g volumes: # 需要先給許可權 chown -R 200 ./data - ./data:/nexus-data ports: - "8081:8081" networks: - devopsnetwork networks: devopsnetwork: external: true
-
運行:
docker compose up -d
-
運行需要時間,耐心等待 2-3 分鐘,訪問:
http://192.168.123.214:8081/
-
可以看到提示預設 admin 的密碼在 ./data/admin.password ,獲取後點擊右上角 Sign In 進行登錄
-
登錄成功會進行引導修改密碼 devops666 和禁用匿名訪問
使用 nginx 配置功能變數名稱訪問
- 使用 ./02.build-ssl.sh nexus.devops.test.com 生成證書,重載配置即可
server {
listen 80;
listen 443 ssl;
server_name nexus.devops.test.com;
# allow large uploads of files
client_max_body_size 1G;
ssl_certificate /certs/nexus.devops.test.com/server.crt;
ssl_certificate_key /certs/nexus.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://nexus_3_61:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
落地實踐
使用 Nexus 管理 Nuget 包
預設項說明
- nuget-group:組合存儲庫,可以將多個遠程或本地存儲庫組合成一個虛擬存儲庫,預設包含 nuget-hosted,nuget.org-proxy。拉取包的地址一般配置此倉庫地址
- nuget-hosted:托管存儲庫,本地發佈的包可以存儲到此存儲庫。推送包的地址需要配置此倉庫地址
- nuget.org-proxy:代理存儲庫,緩存 nuget.org 的包並從本地伺服器上提供它們
賬號的規劃及創建
一個企業可能存在著多個團隊或項目組,每個團隊的包可以分開或者約定好不同的名稱首碼
包的讀寫許可權需要分離,即上傳者和使用者分開,上傳者包含讀寫許可權,使用者只需要有訪問許可權
創建角色
許可權說明:文檔
拉取角色:pull-man ,設置許可權:nx-repository-view-*-*-browse
nx-repository-view-*-*-read
推送角色:push-man ,設置許可權:nx-component-upload
nx-repository-view-*-
-
創建賬號
拉取賬號:puller , 設置密碼 devops666,設置角色:pull-man
推送賬號:pusher,設置密碼 devops666,設置角色:push-man,nuget 使用的 APIKey 所以暫時沒有用到,後面管理 docker 的時候使用
生成 NuGet API 密鑰
推送 NuGet 包時需要使用,點擊管理員頭像->NuGet API 密鑰->生成密鑰
啟用 NuGet API 密鑰領域
上一步獲取了密鑰,還無法直接使用,還需要在設置中 Security>Realms 中啟用 NuGet API-Key Realm。
類似啟用的驗證方式,領域說明見文檔
設置部署策略
預設 nuget 包托管是啟用了, 而為了防止包被惡意篡改,可以將 nuget-hosted 倉庫修改為禁用重新部署,多人協同開發時可防止包被被其他人覆蓋,相關文檔說明 。在設置了禁用重新部署時,推送重覆包的時候將會返回 400 錯誤
使用 Nexus 的 NuGet 包源
因為前面配置關閉了匿名訪問以及配置了相應的賬號,所以為了方便的從 Nexus 服務中拉取 Nuget 包,可以通過配置文件 nuget.config (文檔)來指定 nuget 源為 Nexus 服務 nexus.devops.test.com
-
指定配置節的名稱和源(預設使用 NuGet V3,V2 不需要加 index.json)
-
指定使用包源的賬號密碼
-
將其放到和解決方案同級目錄即可生效
-
nuget.config 文件
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="nexus.devops.test.com" value="https://nexus.devops.test.com/repository/nuget-group/index.json" /> </packageSources> <packageSourceCredentials> <nexus.devops.test.com> <add key="Username" value="puller" /> <add key="ClearTextPassword" value="devops666" /> </nexus.devops.test.com> </packageSourceCredentials> </configuration>
推送 NuGet 包到 Nexus
從本地推送一個 NuGet 包到 Nexus 服務進行托管,需要兩步,打包,推送。為了更好的使用,可以結合腳本來快速打包,以之前的一個計算欄位封裝為例將其打包成 NuGet 包推送到 Nexus 中
-
目錄結構如下
-
首先新建配置一個 .nuspec 模板,根據需要修改庫的相關信息,nuspec 配置文檔
<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>Devops.Common.EvalSDK</id> <version>0.0.15</version> <authors>yimo</authors> <description>計算欄位</description> <projectUrl>https://github.com/yimogit/MeDevOps</projectUrl> <tags>Devops.Common.EvalSDK</tags> <repository type="git" url="https://github.com/yimogit/MeDevOps.git" branch="main"/> </metadata> <files> <file src="..\Devops.Common.EvalSDK\bin\Release***.dll" target="lib" /> <file src="..\Devops.Common.EvalSDK\bin\Release***.pdb" target="lib" /> </files> </package>
-
打包庫的參考,多個版本使用 TargetFrameworks
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>netstandard2.1;netcoreapp3.1;net5.0;net7.0;</TargetFrameworks> </PropertyGroup> <PropertyGroup> <DocumentationFile>bin$(Configuration)$(TargetFramework)\Devops.Common.EvalSDK.xml</DocumentationFile> </PropertyGroup> </Project>
-
新建打包腳本,修改密鑰和地址,後續每次執行前修改版本號,執行即可
#!/bin/bash pwd current_dir=`pwd` #nuget api密鑰 nuget_key="aa7890bf-8dfb-33e3-bed9-c1571e5b9b96" #托管倉庫地址 nuget_source="https://nexus.devops.test.com/repository/nuget-hosted/" #包的版本 package_version="0.0.2" #包名 nupkg_pakcage_name="Devops.Common.EvalSDK.${package_version}.nupkg" #項目庫路徑 csproj_path="../Devops.Common.EvalSDK/Devops.Common.EvalSDK.csproj" #包配置 nuspec_path="Devops.Common.EvalSDK.nuspec" #nuspec path , relative csproj path nuspec_path_relative_csproj="../pack/Devops.Common.EvalSDK.nuspec" #git pull #刪除舊版本 rm -f nupkg_pakcage_name cd ${current_dir} #替換版本號 sed -i 's|<version>.*</version>|<version>'${package_version}'</version>|g' ${nuspec_path} echo pack ${nupkg_pakcage_name} #打包nupkg文件到當前pack目錄 包名.x.x.x.nupkg dotnet pack ${csproj_path} -p:NuspecFile=${nuspec_path_relative_csproj} -c Release --output ../pack -v m #判斷是否打包成功 echo if [ ! -f "${nupkg_pakcage_name}" ]; then echo "pack ${nupkg_pakcage_name} is error" exit -1 fi #推送包 echo push ${nupkg_pakcage_name} dotnet nuget push ${nupkg_pakcage_name} -k ${nuget_key} -s ${nuget_source}
-
執行成功,在使用 Nexus 源的包管理器中就能搜索使用了
使用 Nexus 管理 Docker 鏡像
當前版本支持 docker 鏡像的管理,使用發現通過 docker-group 推送鏡像是需要企業版的,不過還是可以根據拉取和推送的功能變數名稱/埠分開來達到推送的效果。
可以先看下麵這個流程圖,再看後續如何配置就很清晰了
創建角色
許可權說明:文檔 這裡給了所有倉庫的拉取以及推送許可權,和前面一樣,可以只創建對應的 docker 許可權
拉取角色:pull-man ,設置許可權:nx-repository-view-*-*-browse
nx-repository-view-*-*-read
推送角色:push-man ,設置許可權:nx-component-upload
nx-repository-view-*-
-
創建賬號
拉取賬號:puller , 設置密碼 devops666,設置角色:pull-man
推送賬號:pusher,設置密碼 devops666,設置角色:push-man
創建 Docker 倉庫
和前面 nuget 的三個倉庫一樣,docker 的倉庫也新建三個
- docker-group:組合存儲庫,可以將多個遠程或本地存儲庫組合成一個虛擬存儲庫,預設包含 docker-hosted,docker-proxy。拉取包的地址配置此倉庫地址(企業版才支持推送,開源版可以推送到 hosted 庫)
- docker-hosted:托管存儲庫,本地發佈的包可以存儲到此存儲庫。推送包的地址需要配置此倉庫地址
- docker-proxy:代理存儲庫,緩存 官方 docker 包並從本地伺服器上提供它們
- 創建 docker-hosted 托管庫,禁用重新部署,勾上允許部署 latest,存儲位置可以自行選擇。
- 除此之外,還需要準備一個推送鏡像的功能變數名稱:
push.nexus.devops.test.com
(開源版不支持使用 group 推送鏡像)
- 創建 docker-proxy 代理庫,配置代理地址:
https://registry-1.docker.io
並使用 Use Docker Hub 的索引
- 創建 docker-group 分組庫:選擇成員倉庫:docker-hosted,docker-proxy 到右邊,保存即可
推送和拉取功能變數名稱的 nginx 代理配置
根據文檔與實際使用,https 是必須的,所以依托於之前 nginx 的證書申請 以及 dns 服務的使用,我們可以在區域網中配置功能變數名稱來訪問 nexus3 提供的 docker 鏡像倉庫服務
預設拉取使用 nexus.devops.test.com
,推送則使用:push.nexus.devops.test.com
以下為 nginx 的配置,根據官方文檔所修改,主要替換其中功能變數名稱與證書,因為是區域網的自定義功能變數名稱,需要在客戶端安裝證書才不會有不安全的提示,同理 linux 下使用,也需要安裝對應 pem 證書
server {
listen 80;
listen 443 ssl;
server_name nexus.devops.test.com;
# allow large uploads of files
client_max_body_size 10G;
ssl_certificate /certs/nexus.devops.test.com/server.crt;
ssl_certificate_key /certs/nexus.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /v2 {
proxy_pass http://nexus_3_61:8081/repository/docker-group/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location /v1 {
proxy_pass http://nexus_3_61:8081/repository/docker-group/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location / {
proxy_pass http://nexus_3_61:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto "https";
}
}
server {
listen 80;
listen 443 ssl;
server_name push.nexus.devops.test.com;
# allow large uploads of files
client_max_body_size 10G;
ssl_certificate /certs/push.nexus.devops.test.com/server.crt;
ssl_certificate_key /certs/push.nexus.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /v2 {
proxy_pass http://nexus_3_61:8081/repository/docker-hosted/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location /v1 {
proxy_pass http://nexus_3_61:8081/repository/docker-hosted/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location / {
proxy_pass http://nexus_3_61:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto "https";
}
}
重載配置生效後訪問確認 https 是否生效,以及可以查看 restapi 介面是否可以訪問
至此,私有的 docker 倉庫已經搭建好了,本文基於區域網的自定義功能變數名稱,如果是伺服器,正常解析功能變數名稱到伺服器,申請 ssl 證書等踩的坑都會少一點。接下來就是如何使用 nexus.devops.test.com
,push.nexus.devops.test.com
來拉取&推送 docker 鏡像了
CentOS8 中使用 Nexus 的 Docker 倉庫
因為本文功能變數名稱是區域網中的 dns 解析,所以需要在 linux 中設置 dns,確保功能變數名稱能夠訪問到 nexus 訪問,伺服器則不需要考慮,跳過直接使用即可
- 使用機器 IP:192.168.123.219
CentOS8 設置 DNS
編輯 dns 配置文件:vi /etc/resolv.conf
nameserver 192.168.123.214
nameserver 114.114.114.114
寫入後重啟網路生效:systemctl restart NetworkManager
ping nexus.devops.test.com
ip 是 192.168.123.214 就對了
安裝自簽證書
- 上傳或寫入證書 myCA.pem 到需要使用的主機 192.168.123.219
- 複製證書到證書安裝目錄
cp ./myCA.pem /etc/pki/ca-trust/source/anchors/
- 更新證書信任庫:
update-ca-trust -f
- 重啟 openssl 服務(查找 openssl
ps aux | grep openssl
的 pid: xxx xxx pid 號 pts/0 R+,kill 掉 pid,會自動重新啟動kill pid號
) 或直接重啟伺服器生效(reboot
)
因為是自簽證書,如果未安裝證書就使用 docker login nexus.devops.test.com
會提示:tls: failed to verify certificate: x509: certificate signed by unknown authority
Docker 鏡像源認證
docker login nexus.devops.test.com -u puller -p devops666
docker login push.nexus.devops.test.com -u pusher -p devops666
登錄成功後可以查看配置的源:cat /root/.docker/config.json
拉取鏡像
- 從 nexus.devops.test.com (docker-group)拉取一個 nginx 鏡像:
docker pull nexus.devops.test.com/nginx
- 拉取完成後,在 docker-proxy 代理庫中也可以查看到對應的鏡像信息了
推送鏡像
- 確保 push.nexus.devops.test.com 鏡像源已認證:
docker login push.nexus.devops.test.com -u pusher -p devops666
- 將上面拉取的鏡像打包成新的鏡像:
docker tag nexus.devops.test.com/nginx
push.nexus.devops.test.com/nginx_custom
- 將新的鏡像推送到 push.nexus.devops.test.com(docker-hosted) :
docker push push.nexus.devops.test.com/nginx_custom
踩坑記錄
-
數據目錄不設置許可權啟動失敗
數據目錄許可權:此目錄需要可由 Nexus 寫入 進程,以 UID 200 的形式運行
chown -R 200 ./data
-
NuGet V2 和 NuGet V3 配置對比
-
NuGet 的 API 密鑰生成,但是沒有啟用領域配置,無法推送包到 Nexus
- 如果直接使用密鑰推送,提示 401,檢查 apikey 是否正確,以及設置 NuGet API 密鑰領域
- 啟用 NuGet API-Key Realm
- 如果直接使用密鑰推送,提示 401,檢查 apikey 是否正確,以及設置 NuGet API 密鑰領域
-
禁用重新部署時,但是推送了相同的包時,會返回 400
-
Linux 上安裝證書,看到很多資料都是執行
update-ca-trust
就結束了,按著步驟來設置了但無效。最後才想到可能是因為沒生效,重啟完發現真是,想了下應該是 openssl 需要重啟,試了下果然,才得以解決進行下一步。如果不適用區域網功能變數名稱問題會少很多~ -
Docker 倉庫新建的時候那個協議設置理解了半天,找到的文章都是設置埠,配置功能變數名稱的方式也是一點點理解文檔,然後試出來的。
-
解決了之前 Windows 生成自簽證書時不能自動輸入信息的問題,需要像下麵這樣寫,參考
winpty openssl req -new -key $DOMAIN/server.key -out $DOMAIN/server.csr -subj "//C=CN\ST=Beijing\L=Beijing\O=TestOrganization\OU=TestOU\CN=TestRootCA\[email protected]"
相關文檔
後語
本篇嘔心瀝血,絕對是值得收藏的,同時也希望看官們能順手再點個贊~
書山有路勤為徑,學海無涯苦作舟。
沉迷學習,無法自拔。jpg
作者:易墨
Github:yimogit
純靜態工具站點:metools
說明:歡迎拍磚,不足之處還望園友們指出;
迷茫大概是因為想的太多做的太少。