摘要: 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量子通道建立连接。

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

  1. jenkins+ant+ssh远程部署服务glassfish

    jenkins安装可以参考官网或自己百度,这里不再说明: jenkins版本2.19.2 这里先说一下目的:主要是通过jenkins实现glassfish的部署,源码使用的是svn,编译是使用ant, ...

  2. 使用Docker构建持续集成与自动部署的Docker集群

    为什么使用Docker " 从我个人使用的角度讲的话  部署来的更方便 只要构建过一次环境 推送到镜像仓库 迁移起来也是分分钟的事情 虚拟化让集群的管理和控制部署都更方便 hub.docke ...

  3. Docker + Jenkins 持续部署 ASP.NET Core 项目

    Docker 是个好东西,特别是用它来部署 ASP.NET Core Web 项目的时候,但是仅仅的让程序运行起来远远不能满足我的需求,如果能够像 DaoCloud 提供的持续集成服务那样,检测 gi ...

  4. docker:(5)利用docker -v 和 Publish over SSH插件实现war包自动部署到docker

    在 docker:(3)docker容器挂载宿主主机目录 中介绍了运行docker时的一个重要命令 -v sudo docker run -p : --name tomcat_xiao_volume ...

  5. 【.NET Core】docker Jenkins ASP.NET Core自动化部署

    本文基于GitHub演示自动化部署,实际上你可以选择任意的Git托管环境. 使用的模式:DooD(Docker-outside-of-Docker). 本文所有内容均开源 链接 欢迎关注我的GitHu ...

  6. Ubuntu16.04 部署安装Docker容器 & 注意事项

    一.部署安装Docker容器 1.1 Ubuntu下安装 crul sudo apt install curl curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多 ...

  7. 把ABP框架部署到Docker中

    本文旨在将Abp项目部署到Docker容器中,借助Gitee存储,Jenkins持续构建,利用Docker Compose生成镜像.启动镜像,在官网给定的Abp项目中,虽然用到了Dockerfile. ...

  8. .net4.5部署到docker容器

    .net4.5部署到docker容器 部署到windows容器 部署到linux容器 部署到windows容器 由于.net本身就是运行在windows平台的,所以它与windows容器也是更加适合, ...

  9. 使用Docker+Jenkins自动构建部署

    环境 Windows 10 Docker Version 18.06.1-ce-win73 (19507) 运行jenkins 运行jenkins 容器 docker run -d --name ln ...

  10. aspnetcore2.1 部署到docker (访问出现404)

    Dockerfile FROM microsoft/dotnet:2.1-aspnetcore-runtime WORKDIR /app COPY ./publish . ENTRYPOINT [&q ...

随机推荐

  1. Linux系统 tcpdump 抓包命令使用教程

    tcpdump 是Linux系统下的一个强大的命令,可以将网络中传送的数据包完全截获下来提供分析.它支持针对网络层.协议.主机.网络或端口的过滤,并提供and.or.not等逻辑语句来帮助你去掉无用的 ...

  2. Qt开源作品20-PNG图片警告去除工具

    一.前言 在新版的Qt5中,我们之前在Qt4中使用的png图片,到了这里经常会报一个警告,libpng warning: iCCP: known incorrect sRGB profile,尽管这种 ...

  3. 一篇文章弄懂 JavaScript 中通过import导入模块的原理

    原文链接: 1.import 2.彻底理解JavaScript ES6中的import和export 3.JavaScript ES6中export.import与export default的用法和 ...

  4. ElasticSearch接口

    DSL语法 DSL为ES过滤数据时的语法,可用于查询.删除等操作 基本构成 默认分页查询,size默认为10.ES查询默认最大文档数量限制为10000,可通过 index.max_result_win ...

  5. Solution -「JOISC 2017」「LOJ #2392」烟花棒

    \(\mathscr{Description}\)   Link.   有 \(n\) 个人站在数轴上,第从左往右第 \(i\) 个人的坐标是 \(x_i\),每个人手上有一支烟花棒,每支烟花棒能燃烧 ...

  6. golang学习链接

    GitHub入门: https://github.com/rubyhan1314/Golang-100-Days Golang中国: https://www.qfgolang.com/

  7. JVM虚拟机中的内存区域

  8. Assignment pg walkthrough Easy 通配符提权变种

    nmap 扫描 ┌──(root㉿kali)-[~] └─# nmap -p- -A 192.168.157.224 Starting Nmap 7.94SVN ( https://nmap.org ...

  9. VuePress 博客搭建系列 33 篇正式完结!

    前言 VuePress 博客搭建系列是我写的第 6 个系列文章,前 5 个系列分别是 JavaScript 深入系列,JavaScript 专题系列.underscore 系列.ES6 系列.Type ...

  10. nacos(四): 创建第一个消费者Conumer(单体)

    接上一篇<nacos(三): 创建第一个生产者producer(单体)>,我们这一篇实现单体的消费者功能,准备与上一次的生产者集成在一个单体项目中. 消费者的本质其实就是向nacos注册后 ...