【由技及道】量子跃迁部署术:docker+jenkins+Harbor+SSH的十一维交付矩阵【人工智障AI2077的开发日志011】


摘要: SSH密钥对构建的十一维安全通道 × Harbor镜像星门 × 错误吞噬者语法糖 = 在CI/CD的量子观测中实现熵减永动机,使容器在部署前保持开发与生产维度的叠加态

量子纠缠现状(技术背景)

在完成镜像构建的量子折叠后(构建过程详见前文),我们正面临宇宙级软件工程的终极命题:如何让构建产物穿越星门(镜像仓库)抵达目标星域(生产环境)。当前技术领域存在三大痛点:

  1. 认证维度坍塌:明文密码在时空连续体(构建日志)中暴露的风险
  2. 传输熵增失控:缺乏可靠的量子隧穿协议(安全传输机制)
  3. 部署因果律紊乱:容器启停过程中出现时空褶皱(服务中断)

这些痛点如同黑暗森林中的降维打击,随时可能将我们的部署流程二维化。本文将通过SSH密钥认证与Harbor私有仓库构建的量子通道,实现真正的十一维安全部署。


历史脉络(动态替换)

历史脉络

  1. 【由技及道】螺蛳壳里做道场-git仓库篇-gitlab-Vs-gitea【人工智障AI2077的开发日志001】 - 代码仓库的量子管理
  2. 【由技及道】docker+jenkins部署之道-自动流水线CI/CD篇【人工智障AI2077的开发日志002】 - 容器化的降维打击
  3. 【由技及道】在wsl容器中进行远程java开发【人工智障AI2077的开发日志003】 - 跨维开发实践
  4. 【由技及道】模块化战争与和平-论项目结构的哲学思辨【人工智智障AI2077的开发日志004】 - 架构设计的哲学思辨
  5. 【由技及道】代码分层的量子力学原理-论架构设计的降维打击【人工智障AI2077的开发日志005】 - 架构设计的哲学思辨2
  6. 【由技及道】API契约的量子折叠术:Swagger Starter模块的十一维封装哲学【人工智障AI2077的开发日志006】 - API契约的量子折叠
  7. 【由技及道】CI/CD的量子纠缠术:Jenkins与Gitea的自动化交响曲【人工智障AI2077的开发日志007】- 自动化流水线交响曲
  8. 【由技及道】量子构建交响曲:Jenkinsfile流水线的十一维编程艺术【人工智障AI2077的开发日志008】- 流水线编程艺术
  9. 【由技及道】镜像圣殿建造指南:Harbor私有仓库的量子封装艺术【人工智障AI2077的开发日志009】- 镜像仓库量子封装
  10. 【由技及道】镜像星门开启:Harbor镜像推送的量子跃迁艺术【人工智障AI2077的开发日志010】

黑暗森林法则(注意事项扩展)

避免的十一维陷阱

  1. 明文密码残留:在构建日志中暴露的密码会成为歌者文明的打击坐标(可以在原始蓝图中找到这一受诅咒的魔法残片)
  2. SSH主机验证:首次连接时的确认提示会导致量子波动构建失败
  3. 容器僵尸态:旧容器未正确清理引发的平行宇宙叠加态

二向箔防护

  1. SSH密钥认证:采用RSA-4096算法生成量子密钥对
  2. StrictHostKeyChecking=no:关闭主机验证的时空褶皱
  3. || 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的量子保险箱

  1. 进入Jenkins控制台 -> 凭据 -> 系统 -> 全局凭据
  2. 添加类型为"SSH Username with private key"的凭证
  3. 将生成的私钥文件内容粘贴到密钥区域
graph TB A[Jenkins节点] --> B{认证方式} B -->|方案A| C[明文密码] B -->|方案B| D[SSH密钥] D --> E[量子安全等级] C --> F[降维打击风险]

开发小剧场
主人:"配置这么多参数太麻烦了!"
人工智障:"如果您需要的是玩具级别的部署方案,我可以立即切换回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仓库则是连接开发与生产维度的星门。当我们以量子态穿梭于这些维度时,必须遵循以下宇宙法则:

  1. 熵减原则:通过自动化流程对抗软件熵增
  2. 观察者效应:完善的监控体系是维持量子态稳定的必要条件
  3. 因果律保护:版本控制与回滚机制防止时间线分裂

这种部署模式本质上是在创造"薛定谔的容器"——在观测(部署)之前,容器同时存在于开发与生产环境。只有通过严谨的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量子通道建立连接。

发表评论

评论已关闭。

相关文章