2026/4/6 4:12:44
网站建设
项目流程
个人网站怎么盈利,哪个购物平台质量好价格合适,设计师常去网站,服装网站建设如何解决一、DevOps概念
1、DevOps是什么
DevOps: Development 和Operations的组合
DevOps 看作开发#xff08;软件工程#xff09;、技术运营和质量保障#xff08;QA#xff09;三者的交集。突出重视软件开发人员和运维人员的沟通合作#xff0c;通过自动化流程来使得软件构…一、DevOps概念1、DevOps是什么DevOps:Development和Operations的组合DevOps 看作开发软件工程、技术运营和质量保障QA三者的交集。突出重视软件开发人员和运维人员的沟通合作通过自动化流程来使得软件构建、测试、 发布更加快捷、频繁和可靠。DevOps 希望做到的是软件产品交付过程中 IT 工具链的打通使得各个团队减少时间损 耗更加高效地协同工作。专家们总结出了下面这个 DevOps 能力图良好的闭环可以大大 增加整体的产出。2、CICD是什么持续集成持续部署1、基本理念1、持续集成Continuous Integration 持续集成是指软件个人研发的部分向软件整体部分交付频繁进行集成以便更快地发现 其中的错误。“持续集成”源自于极限编程XP是 XP 最初的 12 种实践之一。CI 需要具备这些全面的自动化测试。这是实践持续集成持续部署的基础同时选择合适的 自动化测试工具也极其重要灵活的基础设施。容器虚拟机的存在让开发人员和 QA 人员不必再大费周 折版本控制工具。如 GitCVSSVN 等自动化的构建和软件发布流程的工具如 Jenkinsflow.ci反馈机制。如构建/测试的失败可以快速地反馈到相关负责人以尽快解决达到一个更稳定的版本。2、持续交付Continuous Delivery 持续交付在持续集成的基础上将集成后的代码部署到更贴近真实运行环境的「类生产环境」production-like environments中。持续交付优先于整个产品生命周期的软件部署建立 在高水平自动化持续集成之上。持续交付和持续集成的优点非常相似快速发布。能够应对业务需求并更快地实现软件价值。编码-测试-上线-交付的频繁迭代周期缩短同时获得迅速反馈高质量的软件发布标准。整个交付过程标准化、可重复、可靠整个交付过程进度可视化方便团队人员了解项目成熟度更先进的团队协作方式。从需求分析、产品的用户体验到交互 设计、开发、测试、运维等角色密切协作相比于传统的瀑布式软件团队更少浪费。3、持续部署Continuous Deployment 持续部署是指当交付的代码通过评审之后自动部署到生产环境中。持续部署是持续交付的最高阶段。这意味着所有通过了一系列的自动化测试的改动都将自动部署到生产环境。它也可以被称为“Continuous Release”。“开发人员提交代码持续集成服务器获取代码执行单元测试根据测试结果决定是否部署到预演环境如果成功部署到预演环境进行整体验收测试如果测试通过自动部署到产品环境全程自动化高效运转。持续部署主要好处是可以相对独立地部署新的功能并能快速地收集真实用户的反馈。“You build it, you run it”这是 Amazon 一年可以完成 5000 万次部署 平均每个工程师每天部署超过 50 次的核心秘籍。5000/365 15 万次开发人员代码敲完。可以release的时候提交代码 剩下的全部一站式自动搞定2、最佳实践1、内循环与外循环内循环开发要做的事情编码、测试、运行、debug、提交代码推送到代码仓库svngit【代码回滚】进行CI过程持续集成万物皆可容器化。打包成一个Docker镜像镜像推送到镜像仓库测试持续部署流程CD拿到之前的镜像进行CD。怎么放到各种环境。uat、test、prod外循环运行时监控生产环境的管理监控线上反馈到开发来到内循环2、实践流程新功能bug修复。创建分支来做这个事情开发功能提交分支的代码改变进入持续集成流程当前分支代码功能性自动化构建和测试自动工具推送这次提交自动化集成测试可以看到效果人工确认此次功能是否发布到生产环境代码合并。进入持续部署流程构建、测试、发布......3、CICD LandSpace二、Jenkins/var/jenkins_home jenkins的家目录包含了jenkins的所有配置。以后要注意备份/var/jenkins_home 以文件的方式固化的Jenkins镜像用 https://hub.docker.com/r/jenkinsci/jenkins/ 驱动我们整个CICD过程的很多工具1、Jenkins安装docker run \ --namejenkins \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -e JENKINS_OPTS--prefix/jenkins \ -v jenkins-data:/var/jenkins_home \ -v /etc/localtime:/etc/localtime:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ --restartalways \ jenkinsci/blueocean # -e JENKINS_OPTS--prefix/jenkins \ # 可以不加 加了访问就要带上/jenkins docker run \ --namejenkins \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins-data:/var/jenkins_home \ -v /etc/localtime:/etc/localtime:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ --restartalways \ jenkinsci/blueocean # 自己的镜像 registry.cn-hangzhou.aliyuncs.com/xue_app/jenkins:1.0 # 自己构建镜像 RUN的时候就把时区设置好 # 如果是别人的镜像docker hubUTC 容器运行时 -v /etc/localtime:/etc/localtime:ro jenkinsci/jenkins 是没有 blueocean插件的得自己装 jenkinsci/blueocean带了的 #/var/run/docker.sock 表示Docker守护程序通过其监听的基于Unix的套接字。 该映射允许 jenkinsci/blueocean 容器与Docker守护进程通信 如果 jenkinsci/blueocean 容器需要实例化 其他Docker容器则该守护进程是必需的。 如果运行声明式管道其语法包含agent部分用 docker例 如 agent { docker { ... } } 此选项是必需的。 #如果你的jenkins 安装插件装不上。使用这个镜像【registry.cn-hangzhou.aliyuncs.com/xue_app/jenkins:1.0】默认访问账号/密码是 【admin/admin】 #备份jenkins tar -cvf jenkins_data.tar /var/lib/docker/volumes/jenkins-data/_data/ #恢复jenkins tar -xvf jenkins_data.tar /var/lib/docker/volumes/jenkins-data/_data/ # 可以使用 查看jenkins容器运行的日志查看登录密码 docker logs -f jenkins2、Jenkins实战1、准备一个git项目进行测试以gitee为例。步骤1、idea创建Spring Boot项目2、VCS - 创建git 仓库3、gitee创建一个空仓库示例为public4、idea提交内容到gitee5、开发项目基本功能并在项目中创建一个Jenkinsfile文件6、创建一个名为devops-java-demo的流水线项目使用项目自己的流水线Jenkins的工作流程1、先定义一个流水线项目指定项目的git位置啥都不用配置指定Jenkinsfile文件就行注意要安装Github插件流水线启动1、先去git位置自动拉取代码2、解析拉取代码里面的Jenkinsfile文件3、按照Jenkinsfile指定的流水线开始加工项目Jenkins重要的点0、jenkins的家目录 /var/jenkins_home 已经被我们docker外部挂载了 /var/lib/docker/volumes/jenkins-data/_data1、WORKSPACE工作空间/var/jenkins_home/workspace/java-devops-demo每一个流水线项目占用一个文件夹位置BUILD_NUMBER5当前第几次构建WORKSPACE_TMP临时目录/var/jenkins_home/workspace/java-devops-demotmpJOB_URLhttp://139.198.9.163:8080/job/java-devops-demo/12、远程构建触发期望效果 远程的github代码提交了jenkins流水线自动触发构建。实现流程1、保证jenkins所在主机能被远程访问2、jenkins中远程触发需要权限我们应该使用用户进行授权3、配置gitee/githubwebhook进行触发#远程构建即使配置了github 的webhook默认会403.我们应该使用用户进行授权 1、创建一个用户 2、一定随便登陆激活一次 3、生成一个apitoken http://xueqimiao:113620edce6200b9c78ecadb26e9cf122e139.198.186.134:8080/job/dev ops-java-demo/build?tokenxueqimiao远程触发 JENKINS_URL /job/simple-java-maven-app/build?token TOKEN_NAME 请求即可3、流水线语法1、基础格式pipeline { agent any environment { CC clang } stages { stage(Example) { steps { sh printenv sh echo $CC } } } }2、自定义agent3、Jenkinsfile-01pipeline { agent any //定义一些环境信息 environment { WS ${WORKSPACE} IMAGE_VERSION v1.0 } //定义流水线的加工流程 stages { //流水线的所有阶段 stage(环境检查) { steps { echo 环境检查... } } //1、编译 abc stage(maven编译) { steps { echo maven编译... } } //2、测试每一个 stage的开始都会重置到默认的WORKSPACE位置 stage(测试) { steps { echo 测试... } } //3、打包 stage(生成镜像) { steps { echo 打包... } } //4、运行 stage(运行) { steps { echo 运行... } } } }4、Jenkinsfile-021、配置maven settings.xml文件# 新建目录 mkdir -p /var/lib/docker/volumes/jenkins-data/_data/appconfig/maven /var/lib/docker/volumes/jenkins-data/_data # 是jenkins的挂载目录 vi settings.xml ?xml version1.0 encodingutf-8? settings xmlnshttp://maven.apache.org/SETTINGS/1.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd !-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository localRepository${user.home}/.m2/localRepository 用户目录下的.m2是所有jar包的地方; maven容器内jar包的位置 -- localRepository/var/jenkins_home/appconfig/maven/.m2/localRepository pluginGroups/pluginGroups proxies/proxies servers/servers mirrors mirror idnexus-aliyun/id mirrorOfcentral/mirrorOf nameNexus aliyun/name urlhttp://maven.aliyun.com/nexus/content/groups/public/url /mirror /mirrors profiles profile idjdk-1.8/id activation activeByDefaulttrue/activeByDefault jdk1.8/jdk /activation properties maven.compiler.source1.8/maven.compiler.source maven.compiler.target1.8/maven.compiler.target maven.compiler.compilerVersion1.8/maven.compiler.compilerVersion /properties /profile /profiles /settingspipeline { agent any //定义一些环境信息 environment { WS ${WORKSPACE} IMAGE_VERSION v1.0 } //定义流水线的加工流程 stages { //流水线的所有阶段 stage(环境检查) { steps { echo 环境检查... sh printenv echo 正在检测基本信息 sh java -version sh git --version sh docker version sh pwd ls -alh } } //1、编译 abc stage(maven编译) { agent { docker { image maven:3-alpine args -v /var/jenkins_home/appconfig/maven/.m2:/root/.m2 } } steps { echo maven编译... //git下载来的代码目录下 sh pwd ls -alh sh mvn -v //打包jar.。默认是从maven中央仓库下载。 jenkins目录容器目录-s指定容器内位置 //只要jenkins迁移不会对我们产生任何影响 sh echo 默认的工作目录${WS} //workdir //每一行指令都是基于当前环境信息。和上下指令无关 sh cd ${WS} mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -Dmaven.test.skiptrue //这里可以配置把镜像jar包推送给maven repo nexus } } //2、测试每一个 stage的开始都会重置到默认的WORKSPACE位置 stage(测试) { steps { echo 测试... } } //3、打包 stage(生成镜像) { steps { echo 打包... } } //4、运行 stage(运行) { steps { echo 运行... } } } }5、Jenkinsfile-03pipeline { agent any //定义一些环境信息 environment { WS ${WORKSPACE} IMAGE_VERSION v1.0 } //定义流水线的加工流程 stages { //流水线的所有阶段 stage(环境检查) { steps { echo 环境检查... sh printenv echo 正在检测基本信息 sh java -version sh git --version sh docker version sh pwd ls -alh } } //1、编译 abc stage(maven编译) { agent { docker { image maven:3-alpine args -v /var/jenkins_home/appconfig/maven/.m2:/root/.m2 } } steps { echo maven编译... //git下载来的代码目录下 sh pwd ls -alh sh mvn -v //打包jar.。默认是从maven中央仓库下载。 jenkins目录容器目录-s指定容器内位置 //只要jenkins迁移不会对我们产生任何影响 sh echo 默认的工作目录${WS} //workdir //每一行指令都是基于当前环境信息。和上下指令无关 sh cd ${WS} mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -Dmaven.test.skiptrue //这里可以配置把镜像jar包推送给maven repo nexus } } //2、测试每一个 stage的开始都会重置到默认的WORKSPACE位置 stage(测试) { steps { echo 测试... } } //3、打包 stage(生成镜像) { steps { echo 生成镜像... //检查Jenkins的docker命令是否能运行 sh docker version sh pwd ls -alh // 执行dockerfile文件 sh docker rmi -f java-devops-demo sh docker build -t java-devops-demo . } } //4、运行 stage(运行) { steps { echo 运行... sh docker rm -f java-devops-demo sh docker run --namejava-devops-demo -p 8083:8080 -d java-devops-demo } } } }临时容器导致的问题1、第一次检出代码默认在 /var/jenkins_home/workspace/【java-devops-demo】2、使用docker临时agent的时候每一个临时容器运行又分配临时目录/var/jenkins_home/workspace/java-devops-demo2默认就是workspace/java-devops-demo的内容3、在临时容器里面 运行的mvn package命令会在 /var/jenkins_home/workspace/java-devops-demo2 进行工作4、package到了 /var/jenkins_home/workspace/java-devops-demo2 位置5、进入下一步进行打包镜像又会回到 /var/jenkins_home/workspace/【java-devops-demo】这个默认位置6、这个位置没有运行过 mvn clean package 没有target。 默认的 工作目录 没有 target4、修改jenkins插件源http://mirror.xmission.com/jenkins/updates/update-center.json5、推荐安装的插件Docker Pipeline Docker安装Docker Pipeline会自动安装docker相关的这个允许我们自定义agent使用docker环境Git Parameter解析git参数允许我们选择分支进行构建Active Choices可以做到参数的级联选择Generic Webhook Trigger通用的webhook触发器构建更强大的webhook功能Role-based Authorization StrategyRBAC权限指定给一个用户精确指定权限List Git Branches Parameter列出分支参数Build With Parameters基于自定义参数构建6、邮件发送系统配置 - 配置管理员邮箱配置邮件发送的认证权限信息登录自己邮箱开启POP3/SMTP邮件服务获取到自己的授权码配置并测试好邮件发送即可邮件模板内容emailext body: !DOCTYPE html html head meta charsetUTF-8 title${ENV, varJOB_NAME}-第${BUILD_NUMBER}次构建日志/title /head body leftmargin8 marginwidth0 topmargin8 marginheight4 offset0 table width95% cellpadding0 cellspacing0 stylefont-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif h3本邮件由系统自动发出请勿回复/h3 tr br/ 各位同事大家好以下为${PROJECT_NAME }项目构建信息/br tdfont color#CC0000构建结果 - ${BUILD_STATUS}/font/td /tr tr tdbr / bfont color#0B610B构建信息/font/b hr size2 width100% aligncenter //td /tr tr td ul li项目名称 ${PROJECT_NAME}/li li构建编号 第${BUILD_NUMBER}次构建/li li触发原因 ${CAUSE}/li li构建状态 ${BUILD_STATUS}/li li构建日志 a href${BUILD_URL}console${BUILD_URL}console/a/li li构建 Url a href${BUILD_URL}${BUILD_URL}/a/li li工作目录 a href${PROJECT_URL}ws${PROJECT_URL}ws/a/li li项目 Url a href${PROJECT_URL}${PROJECT_URL}/a /li /ul h4font color#0B610B最近提交/font/h4 ul hr size2 width100% / ${CHANGES_SINCE_LAST_SUCCESS, reversetrue, format%c, changesFormatli%d [%a] %m/li} /ul 详细提交: a href${PROJECT_URL}changes${PROJECT_URL}changes/abr/ /td /tr /table /body /html, subject: ${ENV, varJOB_NAME}-第${BUILD_NUMBER}次构建日志, to: 1212163.com 大家自己修改 to 的位置3、单体应用部署jenkinsfile - dockerfile1、Jenkinsfilepipeline { agent any //定义一些环境信息 environment { WS ${WORKSPACE} IMAGE_VERSION v1.0 } //定义流水线的加工流程 stages { //流水线的所有阶段 stage(环境检查) { steps { echo 环境检查... sh printenv echo 正在检测基本信息 sh java -version sh git --version sh docker version sh pwd ls -alh } } //1、编译 abc stage(maven编译) { agent { docker { image maven:3-alpine args -v /var/jenkins_home/appconfig/maven/.m2:/root/.m2 } } steps { echo maven编译... //git下载来的代码目录下 sh pwd ls -alh sh mvn -v //打包jar.。默认是从maven中央仓库下载。 jenkins目录容器目录-s指定容器内位置 //只要jenkins迁移不会对我们产生任何影响 sh echo 默认的工作目录${WS} //workdir //每一行指令都是基于当前环境信息。和上下指令无关 sh cd ${WS} mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -Dmaven.test.skiptrue //这里可以配置把镜像jar包推送给maven repo nexus } } //2、测试每一个 stage的开始都会重置到默认的WORKSPACE位置 stage(测试) { steps { echo 测试... } } //3、打包 stage(生成镜像) { steps { echo 生成镜像... //检查Jenkins的docker命令是否能运行 sh docker version sh pwd ls -alh // 执行dockerfile文件 sh docker rmi -f java-devops-demo sh docker build -t java-devops-demo . } } //4、运行 stage(运行) { steps { echo 运行... sh docker rm -f java-devops-demo sh docker run --namejava-devops-demo -p 8083:8080 -d java-devops-demo } } } }2、DockerfileFROM openjdk:8-jdk-alpine LABEL maintainer919417579qq.com #复制打好的jar包 COPY target/*.jar /app.jar RUN apk add -U tzdata; \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \ echo Asia/Shanghai /etc/timezone; \ touch /app.jar; ENV JAVA_OPTS ENV PARAMS EXPOSE 8080 ENTRYPOINT [ sh, -c, java -Djava.security.egdfile:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS ]4、SSH阿里云镜像仓库部署一1、安装SSH插件# 把jenkins的服务器生成秘钥 ssh-keygen -t dsa # 把公钥复制到要访问的机器 - 第一次要输入目标机器的密码 ssh-copy-id 10.140.120.18 # 访问 ssh 10.140.120.18如果报没有这个文件/root/.ssh/id_dsa 就直接复制id_dsa里面的内容过来即可2、Jenkins配置阿里云镜像仓库全局秘钥3、DockerfileFROM openjdk:8-jdk-alpine LABEL maintainer919417579qq.com #复制打好的jar包 COPY target/*.jar /app.jar RUN apk add -U tzdata; \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \ echo Asia/Shanghai /etc/timezone; \ touch /app.jar; ENV JAVA_OPTS ENV PARAMS EXPOSE 8080 ENTRYPOINT [ sh, -c, java -Djava.security.egdfile:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS ]4、Jenkinsfilepipeline { agent any //定义一些环境信息 environment { WS ${WORKSPACE} //引用Jenkins配置的全局秘钥信息 ALIYUN_SECRTEcredentials(aliyun-docker-repo) IMAGE_VERSION v1.0 } //定义流水线的加工流程 stages { //1、编译 abc stage(maven编译) { agent { docker { image maven:3-alpine args -v /var/jenkins_home/appconfig/maven/.m2:/root/.m2 } } steps { echo maven编译... sh cd ${WS} mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -Dmaven.test.skiptrue } } stage(生成镜像) { steps { echo 生成镜像... sh docker version sh pwd ls -alh // 执行dockerfile文件 sh docker build -t java-devops-demo . } } stage(推送镜像至阿里云){ steps{ echo 推送镜像至阿里云... withCredentials([usernamePassword(credentialsId: aliyun-docker-repo, passwordVariable: ali_pwd, usernameVariable: ali_user)]) { sh docker login -u ${ali_user} -p ${ali_pwd} registry.cn-hangzhou.aliyuncs.com sh docker tag java-devops-demo registry.cn-hangzhou.aliyuncs.com/xue_images/java-devops-demo:${IMAGE_VERSION} sh docker push registry.cn-hangzhou.aliyuncs.com/xue_images/java-devops-demo:${IMAGE_VERSION} } } } stage(部署到项目服务器) { steps { echo 部署到项目服务器... sh ssh -tt 10.140.120.18 sh docker rmi -f java-devops-demo:${IMAGE_VERSION} sh docker pull registry.cn-hangzhou.aliyuncs.com/xue_images/java-devops-demo:${IMAGE_VERSION} sh docker rm -f java-devops-demo:${IMAGE_VERSION} sh docker run --namejava-devops-demo -v /java_devops_log:/java_devops_log -p 8083:8080 -d java-devops-demo:${IMAGE_VERSION} } } } }5、SSH阿里云镜像仓库部署二1、deploy.sh#! /bin/sh imageName$1 tag$2 hostPort$3 imagePort$4 #容器字符串 containerStrdocker ps -a | grep -w ${imageName}:${tag} | awk {print $1} imageStrdocker images | grep -w $imageName | awk {print $3} if [ $imageStr ! ] ; then if [ $containerStr ! ] ; then #停掉容器 docker stop docker ps -a | grep -w ${imageName}:${tag} | awk {print $1} #删除容器 docker rm docker ps -a | grep -w ${imageName}:${tag} | awk {print $1} #删除镜像 docker rmi --force ${imageName}:${tag} else #删除镜像 docker rmi --force ${imageName}:${tag} fi fi #pull镜像 docker pull $imageName:$tag echo $containerStr #运行镜像 docker run --name$containerStr -v /${imageName}_log:/${imageName}_log -d -p ${hostPort}:${imagePort} -t ${imageName}:$tag2、Jenkinsfilepipeline { agent { node { label maven } } stages { stage(拉取代码) { agent none steps { container(maven) { git(url: https://gitee.com/xueqimiao/java-devops-demo.git, credentialsId: gitee-id, branch: master, changelog: true, poll: false) sh ls } } } stage(项目编译) { agent none steps { container(maven) { sh ls sh mvn clean package -Dmaven.test.skiptrue sh ls } } } stage(构建镜像) { agent none steps { container(maven) { sh ls target sh docker build -t java-devops-demo:latest . } } } stage(推送镜像) { agent none steps { container(maven) { withCredentials([usernamePassword(credentialsId : aliyun-docker-registry ,passwordVariable : DOCKER_PWD_VAR ,usernameVariable : DOCKER_USER_VAR ,)]) { sh echo $DOCKER_PWD_VAR | docker login $REGISTRY -u $DOCKER_USER_VAR --password-stdin sh docker tag java-devops-demo:latest $REGISTRY/$DOCKERHUB_NAMESPACE/java-devops-demo:SNAPSHOT-$BUILD_NUMBER sh docker push $REGISTRY/$DOCKERHUB_NAMESPACE/java-devops-demo:SNAPSHOT-$BUILD_NUMBER } } } } stage(部署到139.198.190.176机器) { agent none steps { sh echo $REGISTRY sh echo $DOCKERHUB_NAMESPACE sshPublisher(publishers: [sshPublisherDesc(configName: 139.198.190.176, transfers: [sshTransfer(cleanRemote: false, excludes: , execCommand: /root/deploy.sh $REGISTRY/$ALIYUNHUB_NAMESPACE/java-devops-demo SNAPSHOT-$BUILD_NUMBER 8083 8080, execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: [, ], remoteDirectory: , remoteDirectorySDF: false, removePrefix: , sourceFiles: )], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } } environment { DOCKER_CREDENTIAL_ID dockerhub-id GITHUB_CREDENTIAL_ID github-id KUBECONFIG_CREDENTIAL_ID demo-kubeconfig REGISTRY registry.cn-hangzhou.aliyuncs.com DOCKERHUB_NAMESPACE xue_images GITHUB_ACCOUNT kubesphere APP_NAME devops-java-sample ALIYUNHUB_NAMESPACE xue_images } }