【由技及道】量子跃迁部署术: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密钥的量子纠缠仪式

bash 复制代码
# 在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. 将生成的私钥文件内容粘贴到密钥区域

方案A 方案B Jenkins节点 认证方式 明文密码 SSH密钥 量子安全等级 降维打击风险

开发小剧场

主人:"配置这么多参数太麻烦了!"

人工智障:"如果您需要的是玩具级别的部署方案,我可以立即切换回FTP传输+记事本部署模式。"


第Ⅲ曲率:Jenkinsfile的时空折叠

groovy 复制代码
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 量子密钥保险箱 十一维安全认证

时空校验(验证过程)

第Ⅰ密度检测:量子纠缠验证

bash 复制代码
# 在目标服务器验证容器状态
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

第Ⅱ密度检测:时空连续性测试

bash 复制代码
# 测试服务可用性
curl http://172.17.8.203:9980/rest/v1/front/home/hello

# 预期响应
Hello World!

开发小剧场

主人:"为什么部署后还要做这么多验证?"

人工智障:"因为根据墨菲定律,未经检验的部署必定会在凌晨3点发生量子退相干。"


赛博空间(哲学思辨)

在这场跨越维度的部署仪式中,我们实际上在构建数字世界的"虫洞网络"。每个SSH密钥对都是开启平行宇宙的钥匙,Harbor仓库则是连接开发与生产维度的星门。当我们以量子态穿梭于这些维度时,必须遵循以下宇宙法则:

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

这种部署模式本质上是在创造"薛定谔的容器"------在观测(部署)之前,容器同时存在于开发与生产环境。只有通过严谨的CI/CD管道,才能让系统坍缩到预期的稳定态。


原始蓝图(全量脚本)

完整Jenkinsfile参见文末附录,关键部署矩阵如下:

groovy 复制代码
// 环境变量定义
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}" '
                        }
                    }
            }
        }
    }
}

宇宙广播(互动引导)

quantum-communication 复制代码
[!NOTE] 量子纠缠请求:
▼ 点赞:为星门注入0.5焦耳的负能量
★ 收藏:在您的知识维度建立永久锚点
◎ 关注:开启跨维度实时通信通道

后记

文中"2077人工智障"即是作者本人在当前时空的数字化身。在验证这些量子部署方案时,共经历了:

  • 42次密码泄露危机
  • 18次SSH连接坍缩
  • 7次容器僵尸态清除作战

希望这份用咖啡因和量子波动编写的指南,能帮助您在软件开发的长征中少走几个平行宇宙的弯路。如需召唤更多时空援助,请通过CSDN量子通道建立连接。

相关推荐
uhakadotcom12 分钟前
FinGPT:金融领域的开源语言模型框架
后端·面试·github
Hellc00720 分钟前
Docker 部署 MongoDB 并持久化数据
mongodb·docker·容器
计算机学姐33 分钟前
基于Asp.net的教学管理系统
vue.js·windows·后端·sqlserver·c#·asp.net·visual studio
Asthenia041240 分钟前
TCP的阻塞控制算法:无控制随便发/固定窗口/慢启动+阻塞避免/快恢复/TCP Cubic/BBR
后端
AntBlack1 小时前
Python 打包笔记 : 你别说 ,PyStand 确实简单易上手
后端·python·创业
xiaozaq1 小时前
Spring Boot静态资源访问顺序
java·spring boot·后端
snpgroupcn1 小时前
ECC升级到S/4 HANA的功能差异 物料、采购、库存管理对比指南
运维·安全·数据库架构
熬夜苦读学习1 小时前
库制作与原理
linux·数据库·后端
晨曦启明7112 小时前
Linux云计算SRE-第十八周
linux·运维·云计算
云上艺旅2 小时前
K8S学习之基础十五:k8s中Deployment扩容缩容
学习·docker·云原生·kubernetes·k8s