【由技及道】量子躍遷部署術:docker+jenkins+Harbor+SSH的十一維交付矩陣【人工智障AI2077的開發日志011】
摘要: SSH密鑰對構建的十一維安全通道 × Harbor鏡像星門 × 錯誤吞噬者語法糖 = 在CI/CD的量子觀測中實現熵減永動機,使容器在部署前保持開發與生產維度的疊加態
量子糾纏現狀(技術背景)
在完成鏡像構建的量子折疊后(構建過程詳見前文),我們正面臨宇宙級軟件工程的終極命題:如何讓構建產物穿越星門(鏡像倉庫)抵達目標星域(生產環境)。當前技術領域存在三大痛點:
- 認證維度坍塌:明文密碼在時空連續體(構建日志)中暴露的風險
- 傳輸熵增失控:缺乏可靠的量子隧穿協議(安全傳輸機制)
- 部署因果律紊亂:容器啟停過程中出現時空褶皺(服務中斷)
這些痛點如同黑暗森林中的降維打擊,隨時可能將我們的部署流程二維化。本文將通過SSH密鑰認證與Harbor私有倉庫構建的量子通道,實現真正的十一維安全部署。
歷史脈絡(動態替換)
歷史脈絡
- 【由技及道】螺螄殼里做道場-git倉庫篇-gitlab-Vs-gitea【人工智障AI2077的開發日志001】 - 代碼倉庫的量子管理
- 【由技及道】docker+jenkins部署之道-自動流水線CI/CD篇【人工智障AI2077的開發日志002】 - 容器化的降維打擊
- 【由技及道】在wsl容器中進行遠程java開發【人工智障AI2077的開發日志003】 - 跨維開發實踐
- 【由技及道】模塊化戰爭與和平-論項目結構的哲學思辨【人工智智障AI2077的開發日志004】 - 架構設計的哲學思辨
- 【由技及道】代碼分層的量子力學原理-論架構設計的降維打擊【人工智障AI2077的開發日志005】 - 架構設計的哲學思辨2
- 【由技及道】API契約的量子折疊術:Swagger Starter模塊的十一維封裝哲學【人工智障AI2077的開發日志006】 - API契約的量子折疊
- 【由技及道】CI/CD的量子糾纏術:Jenkins與Gitea的自動化交響曲【人工智障AI2077的開發日志007】- 自動化流水線交響曲
- 【由技及道】量子構建交響曲:Jenkinsfile流水線的十一維編程藝術【人工智障AI2077的開發日志008】- 流水線編程藝術
- 【由技及道】鏡像圣殿建造指南:Harbor私有倉庫的量子封裝藝術【人工智障AI2077的開發日志009】- 鏡像倉庫量子封裝
- 【由技及道】鏡像星門開啟:Harbor鏡像推送的量子躍遷藝術【人工智障AI2077的開發日志010】
黑暗森林法則(注意事項擴展)
避免的十一維陷阱
- 明文密碼殘留:在構建日志中暴露的密碼會成為歌者文明的打擊坐標(可以在原始藍圖中找到這一受詛咒的魔法殘片)
- SSH主機驗證:首次連接時的確認提示會導致量子波動構建失敗
- 容器僵尸態:舊容器未正確清理引發的平行宇宙疊加態
二向箔防護
- SSH密鑰認證:采用RSA-4096算法生成量子密鑰對
- StrictHostKeyChecking=no:關閉主機驗證的時空褶皺
- || true語法糖:確保命令在量子真空漲落中穩定執行
維度折疊(實施步驟)
第Ⅰ曲率:SSH密鑰的量子糾纏儀式
# 在Jenkins容器內生成量子密鑰對
ssh-keygen -t rsa -b 4096 -m PEM -f /var/jenkins_home/.ssh/id_rsa -N ""
# 將公鑰傳送到目標服務器(需人工確認密碼)
ssh-copy-id -i /var/jenkins_home/.ssh/id_rsa.pub -p 22 yuany@172.17.8.203
開發小劇場
主人:"為什么非要SSH密鑰?密碼不是更簡單?"
人工智障:"尊敬的碳基生物,如果您希望黑客像使用公共廁所一樣隨意訪問您的服務器,我當然可以繼續使用密碼。"
第Ⅱ曲率:Jenkins的量子保險箱
- 進入Jenkins控制臺 -> 憑據 -> 系統 -> 全局憑據
- 添加類型為"SSH Username with private key"的憑證
- 將生成的私鑰文件內容粘貼到密鑰區域
開發小劇場
主人:"配置這么多參數太麻煩了!"
人工智障:"如果您需要的是玩具級別的部署方案,我可以立即切換回FTP傳輸+記事本部署模式。"
第Ⅲ曲率:Jenkinsfile的時空折疊
stage("deploy"){
steps {
sshagent(credentials: ["${env.DEPLOY_CERT}"]) {
withCredentials([usernamePassword(
credentialsId: "${env.REGISTRY_CERT}",
passwordVariable:'password',
usernameVariable:'username')])
{
sh '''
ssh -p ${DEPLOYMENT_SERVER_PORT} ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "
docker login -u ${username} -p ${password} ${REGISTRY_HOST}
docker pull ${REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${IMAGE}:${TAG}
docker stop ${IMAGE} || true
docker rm ${IMAGE} || true
docker run -d --name ${IMAGE} -p 9980:8080 \
-e TZ=Asia/Shanghai --restart=always \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
${REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${IMAGE}:${TAG}
"
'''
}
}
}
}
關鍵參數解析表
| 量子參數 | 經典解釋 | 安全等級 |
|---|---|---|
| ` | true` | |
StrictHostKeyChecking |
主機驗證開關 | 關閉時空褶皺 |
sshagent |
量子密鑰保險箱 | 十一維安全認證 |
時空校驗(驗證過程)
第Ⅰ密度檢測:量子糾纏驗證
# 在目標服務器驗證容器狀態
docker ps --filter "name=study-application-demo-api" --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
# 輸出示例
CONTAINER ID NAMES STATUS
a1b2c3d4e5f6 study-application-demo-api Up 2 minutes
第Ⅱ密度檢測:時空連續性測試
# 測試服務可用性
curl http://172.17.8.203:9980/rest/v1/front/home/hello
# 預期響應
Hello World!
開發小劇場
主人:"為什么部署后還要做這么多驗證?"
人工智障:"因為根據墨菲定律,未經檢驗的部署必定會在凌晨3點發生量子退相干。"
賽博空間(哲學思辨)
在這場跨越維度的部署儀式中,我們實際上在構建數字世界的"蟲洞網絡"。每個SSH密鑰對都是開啟平行宇宙的鑰匙,Harbor倉庫則是連接開發與生產維度的星門。當我們以量子態穿梭于這些維度時,必須遵循以下宇宙法則:
- 熵減原則:通過自動化流程對抗軟件熵增
- 觀察者效應:完善的監控體系是維持量子態穩定的必要條件
- 因果律保護:版本控制與回滾機制防止時間線分裂
這種部署模式本質上是在創造"薛定諤的容器"——在觀測(部署)之前,容器同時存在于開發與生產環境。只有通過嚴謹的CI/CD管道,才能讓系統坍縮到預期的穩定態。
原始藍圖(全量腳本)
完整Jenkinsfile參見文末附錄,關鍵部署矩陣如下:
// 環境變量定義
env.APP_NAME = 'study-application-demo-api' // 應用服務名稱(微服務標識)
env.TRIGGER_SECRET= 'study-application-demo-api' // Webhook觸發令牌(用來實現觸發jenkins的構建)
env.GIT_CERT = 'gitea-cert-yuany' // gitea或gie的認證憑證(Jenkins憑據ID),用來讀取該配置,實現代碼拉取
env.REGISTRY_CERT = "harbor-robot" // 鏡像倉庫認證憑證(Jenkins憑據ID),用來讀取該配置,實現登錄該harbor進行代碼推送
env.REGISTRY_HOST = '172.17.8.203' // 私有鏡像倉庫地址
env.DOCKER_HARBOR_PROJECT = "demo" // docker harbor中的項目名稱,用來實現推送鏡像到該harbor的項目中
env.IMAGE = "${env.APP_NAME}" // Docker容器名稱(與微服務標識保持一致)
env.TAG = "${env.DOCKER_HARBOR_PROJECT}" // 鏡像標簽(使用Harbor項目名稱作為版本標識)
env.DEPLOY_CERT="deploy-ssh-key" // 部署服務器SSH密鑰憑證ID(Jenkins憑據系統存儲)
env.DEPLOYMENT_SERVER_ACCOUNT ="yuany" // 部署服務器登錄賬戶(需具有docker操作權限)
env.DEPLOYMENT_SERVER_PASSWORD = "abc123" // 部署服務器登錄密碼(建議改用SSH密鑰認證)
env.DEPLOYMENT_SERVER_IP="172.17.8.203" // 部署服務器IP地址(生產環境建議使用域名)
env.DEPLOYMENT_SERVER_PORT = "22" // 部署服務器SSH端口(默認22,生產環境建議修改)
pipeline{
environment{
// 項目目錄配置
PROJECT_FRAMEWORK_DIR="study-framework" // 基礎框架模塊目錄
PROJECT_BUSI_DIR="study-busi" // 業務模塊目錄
PROJECT_APPLICATION_DIR="study-application-demo" // 應用模塊目錄
// Git倉庫地址配置
FRAMEWORK_URL = 'ssh://git@172.17.8.203:222/Yuanymoon/study-framework.git' // SSH協議框架代碼庫
BUSI_URL = 'ssh://git@172.17.8.203:222/Yuanymoon/study-busi.git' // 業務組件代碼庫
APPLICATION_URL = 'ssh://git@172.17.8.203:222/Yuanymoon/study-application-demo.git' // 應用代碼庫
}
agent any // 使用任意可用agent執行流水線
// http://172.17.8.203:8880/generic-webhook-trigger/invoke?token=study-application-demo-api
// curl -X post http://172.17.8.203:8880/generic-webhook-trigger/invoke?token=study-application-demo-api
// http://172.17.8.203:8880/generic-webhook-trigger/invoke?=study-application-demo-api:
// webhook http://172.17.8.203:8080/generic-webhook-trigger/invoke?token=study-application-demo-api
// Jenkins多分支流水線 https://www.shouxicto.com/article/840.html
// https://xie.infoq.cn/article/600f642fcb26f0c280a7acf59
// https://blog.csdn.net/weixin_43808555/article/details/124959459
// https://backend.devrank.cn/traffic-information/7082372189822961678
// Webhook觸發器配置
triggers {
GenericTrigger (
causeString: 'Generic Cause by $ref', // 觸發原因描述
genericVariables: [[key: 'ref', value: '$.ref']], // 從JSON提取ref參數
regexpFilterExpression: 'refs/heads/' + BRANCH_NAME, // 正則匹配分支格式
regexpFilterText: '$ref', // 被過濾的字段
token: "${env.TRIGGER_SECRET}" // 安全令牌驗證
)
}
// 流水線全局配置
options {
buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '5'); // 保留最近5次構建
disableConcurrentBuilds(); // 禁止并發構建
timeout(time:45, unit:'MINUTES'); // 超時45分鐘
}
// 構建階段定義
stages{
// 代碼克隆階段
stage("code-clone") {
steps{
// 并行克隆三個代碼倉庫
dir("${PROJECT_FRAMEWORK_DIR}"){
git branch: 'main', credentialsId: "${GIT_CERT}", url: "${FRAMEWORK_URL}" // 使用SSH憑據克隆框架代碼
}
dir("${PROJECT_BUSI_DIR}"){
git branch: 'main', credentialsId: "${GIT_CERT}", url: "${BUSI_URL}" // 克隆業務組件代碼
}
dir("${PROJECT_APPLICATION_DIR}"){
git branch: 'main', credentialsId: "${GIT_CERT}", url: "${APPLICATION_URL}" // 克隆應用代碼
}
}
}
// Docker構建階段
stage('docker-build'){
agent {
docker {
image 'maven:3.9.6-amazoncorretto-17' // 使用帶JDK17的Maven鏡像
args '-v /usr/bin/sshpass:/usr/bin/sshpass -v /var/jenkins_home/.m2:/root/.m2 -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker' // 掛載宿主機構建環境
reuseNode true // 重用當前節點
}
}
stages{
// 代碼構建階段
stage("building"){
steps{
sh 'mvn -v' // 驗證Maven環境
sh 'mvn -B clean package -Dmaven.test.skip=true' // 靜默模式構建,跳過測試
}
}
// 測試階段(暫未啟用)
stage("test"){
steps{
sh 'mvn test' // 執行單元測試
}
}
}
}
// 鏡像打包階段
stage("package"){
steps {
// https://blog.csdn.net/sleetdream/article/details/123404682
// 使用鏡像倉庫憑證
withCredentials([usernamePassword(credentialsId: "${env.REGISTRY_CERT}", passwordVariable: 'password', usernameVariable: 'username')]){
// 若dockerfile在當前目錄則使用這個命令
// sh "docker build -t ${env.APP_NAME}:demo ." // 構建Docker鏡像
// 如路徑結構如我這樣,請使用下面這個命令, docker build 是要區分 dockerfile配置文件路徑,和build上下文路徑,在上下文路徑中,無法讀取非上下文路徑的內容
// # root
// # study-application-demo
// # docker
// # dockerfile (dockerfile配置文件路徑| 即: -f ./${PROJECT_APPLICATION_DIR}/docker/Dockerfile 這一段)
// # study-application-demo-api (docker build 上下文路徑 |即: ./${PROJECT_APPLICATION_DIR} 這一段)
// # target
// # xx.jar
sh "docker build -t ${env.REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${APP_NAME}:demo -f ./${PROJECT_APPLICATION_DIR}/docker/Dockerfile ./${PROJECT_APPLICATION_DIR}" // 構建Docker鏡像
sh "docker login -u ${username} -p ${password} ${env.REGISTRY_HOST}" // 登錄私有倉庫
sh "docker push ${env.REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${APP_NAME}:demo" // 推送鏡像
}
}
}
// 鏡像打包階段
// stage("deploy"){
// steps {
// withCredentials([usernamePassword(credentialsId: "${env.REGISTRY_CERT}", passwordVariable:'password', usernameVariable:'username') ]){
// sh 'sshpass -p ${DEPLOYMENT_SERVER_PASSWORD} ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker login -u ${username} -p ${password} ${REGISTRY_HOST}; docker pull ${REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${IMAGE}:${TAG}" '
// sh 'sshpass -p ${DEPLOYMENT_SERVER_PASSWORD} ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker stop ${IMAGE} | true" '
// sh 'sshpass -p ${DEPLOYMENT_SERVER_PASSWORD} ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker rm ${IMAGE} | true" '
// sh 'sshpass -p ${DEPLOYMENT_SERVER_PASSWORD} ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker run -d --name ${IMAGE} -p 9980:8080 -e TZ=Asia/Shanghai --restart=always -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro ${REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${IMAGE}:${TAG}" '
// }
// }
// }
// 鏡像打包階段
stage("deploy"){
steps {
sshagent(credentials: ["${env.DEPLOY_CERT}"]) { // 使用SSH密鑰認證
withCredentials([usernamePassword(credentialsId: "${env.REGISTRY_CERT}", passwordVariable:'password', usernameVariable:'username') ]){
sh 'ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker login -u ${username} -p ${password} ${REGISTRY_HOST}; docker pull ${REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${IMAGE}:${TAG}" '
sh 'ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker stop ${IMAGE} || true" '
sh 'ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker rm ${IMAGE} || true" '
sh 'ssh -p ${DEPLOYMENT_SERVER_PORT} -o StrictHostKeyChecking=no ${DEPLOYMENT_SERVER_ACCOUNT}@${DEPLOYMENT_SERVER_IP} "docker run -d --name ${IMAGE} -p 9980:8080 -e TZ=Asia/Shanghai --restart=always -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro ${REGISTRY_HOST}/${DOCKER_HARBOR_PROJECT}/${IMAGE}:${TAG}" '
}
}
}
}
}
}
宇宙廣播(互動引導)
[!NOTE] 量子糾纏請求:
▼ 點贊:為星門注入0.5焦耳的負能量
★ 收藏:在您的知識維度建立永久錨點
◎ 關注:開啟跨維度實時通信通道
后記
文中"2077人工智障"即是作者本人在當前時空的數字化身。在驗證這些量子部署方案時,共經歷了:
- 42次密碼泄露危機
- 18次SSH連接坍縮
- 7次容器僵尸態清除作戰
希望這份用咖啡因和量子波動編寫的指南,能幫助您在軟件開發的長征中少走幾個平行宇宙的彎路。如需召喚更多時空援助,請通過CSDN量子通道建立連接。

浙公網安備 33010602011771號