k8s CI/CD板书
k8s CI/CD讲演稿导语(ppt1):各位同事大家好,很高兴大家能够对k8s环境下的CI/CD这个主题的相关知识感兴趣。本次主题分享的内容,是我们在以kubernetes环境部署应用的时候,如何快速集成,快速部署交付的过程,有原理也有实操。我这部分内容的讲解,是告诉大家可以如何做,至于究竟如何做,则需要根据我讲解的内容,结合项目特点,自行规划设计。什么是DevOps?(ppt2)DevOps(
k8s CI/CD讲演稿
导语(ppt1):
- 各位同事大家好,很高兴大家能够对k8s环境下的CI/CD这个主题的相关知识感兴趣。本次主题分享的内容,是我们在以kubernetes环境部署应用的时候,如何快速集成,快速部署交付的过程,有原理也有实操。我这部分内容的讲解,是告诉大家可以如何做,至于究竟如何做,则需要根据我讲解的内容,结合项目特点,自行规划设计。
什么是DevOps?(ppt2)
- DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(Dev)、运维人员(ops)和质量保障(QA)部门之间的沟通、协作与整合。
- 它的目的是构建一种文化和环境,使构建,测试,发布软件更加快捷,频繁和可靠。
- DevOps是个开放的体系,从实践中而来,并且还在不断的发展,具体到某个组织也并没有一致的套路,所以DevOps落地更多是因组织而异、因目标而异、因人而异
- 看下面这个图:
- 第一张图描述了,Dev开发人员和Ops运维人员的分工以及协作;
- 第二张图描述了,软件开发模式从瀑布开发模式到敏捷开发模式的演进
- 第三张图就比较有意思了,开发人员要应对需求不断变更实现,然而运维团队考虑的是系统的稳定、可用性和安全性。于是,当软件系统从墙的一端(Dev)传递到另一端(Ops)时,会发生各种各样不可预知的“异常”情况。
这些“异常”通常是由于交付了不正确的东西,包括:- 开发人员不清楚生产环境,而运维人员又搞不定既没有规范又没有文档的配置
- 开发过程中的不成熟版本进入了生产环境
- 当处于瀑布开发模式的时候,因为软件交付周期较长,通常运维人员有充足的时间对软件进行部署交付;但是当到了敏捷开发模式的情况下,便出现了很多的问题,看下面的幻灯片->
DevOps来自于敏捷开发(ppt3)
- 敏捷开发的核心理念是:
- 我们是无法充分了解用户的真实需求是怎样的,那么不如将一个大的目标不断拆解,把它变成一个个可交付的小目标,然后通过不断的迭代,以小步快跑的方式持续交付
- 与此同时,将测试工作从研发末端的一个独立环节注入整个开发活动中,对开发交付的内容进行持续验证,保证每次可交付的都是一个可用的功能集合,并且由于质量内建在研发环节中,交付功能的质量也是有保障的。
但是敏捷开发却忽略了一个重要问题,即频繁的软件迭代,频繁的交付,对于运维人员是一种非常大的挑战,即放大了我们前面提到的开发人员到运维人员的出现的异常情况,导致运维团队为了规避风险,不断延长预设上线时间窗口,不断的抬高上线门槛;
于是,在敏捷开发模式中,面对需求的快速迭代,为了按时交付软件产品和服务,开发和运维工作必须紧密合作,打破壁垒,开始了敏捷开发模式到DevOps开发模式的演进;并且DevOps是一个开放体系,也是一个不断在演进的模式,目前包含敏捷开放模式且不局限于敏捷这种模式!
DevOps原理和实践(ppt4)
DevOps主要原理方面,不是本次分享的重点,我就不赘述了
虽然我们前面说DevOps开发模式还在演进,但是我们今天讲解的CI/CD却是DevOps中,比较确定的部分,也是其必要组成部分:
下面来着重讲解下CI/CD的核心概念:
CI/CD概念讲解(ppt5)
CI/CD的概念:一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法,核心概念是持续集成、持续交付和持续部署;
- CI(即CONTINUOUS INTEGRATION,持续集成):开发人员的自动化流程,即任何应用代码的更新都会定期或触发式构建、测试并合并到一个存储库,如Gitlab中。可以按照需求,频繁一天多次地将代码集成到主干,实现快速迭代。其核心措施为,代码集成到主干之前,必须通过自动化测试,只要有一个测试用例失败,就不能集成。持续集成并不能消除Bug,而是让它们更容易发现与改正。
- CD:指开发人员将更改从存储发布到生产环境中,有两种意思:
- 持续交付(CONTINUOUS DELIVERY):频繁地将软件交付给用户供评审,如果无误即可进入生产阶段,其强调的事不管怎么更新,软件都是随时随地可以交付的。
- 持续部署(CONTINUOUS DEPLOYMENT):是指当交付的代码通过评审之后,自动部署到生产环境中。
- 持续部署是持续交付的最高阶段。
CI/CD的多样性(ppt6)
从上图可以看到,CI/CD的过程随项目实际情况会有些差异;并且,CI和CD也没有一个完全确定的先后关系,需要按照项目需求特点去规范,定义。
关于k8s CI/CD任务拆解(ppt7)
- 前面说明说过,DevOps是个开放的体系,DevOps落地更多是因组织而异、因目标而异、因人而异;只要涵盖DevOps最核心原则和模式的实践就是好的实践:
- 本文讲解CI/CD便是在k8s这个运维框架下的DevOps的一个很好的实践,能够让我们大幅度提高运维效率,也能有效地缩短个人和组织的学习曲线
- 当然,原则和实践是相对稳定的,而工具和命令的变化是非常快的,所以本文中的CI/CD实践的优势也只在于相对的时间,项目的需求空间 有效区间范围内;
- 按照任务拆解组件,本文将CI/CD分为如下几个部分:
- Jenkins:开源、提供友好操作界面的持续集成(CI)工具;自动化核心引擎;
- Gitlab:基于Git的代码管理工具且提供web服务;代码库及自动化触发器(webhook);
- 自定义触发器:Jenkins提供了标准的API,用户可以按照需求,搭建自己的触发规则服务;为我们自己开发适合我们自己项目的运维平台提供了接口;
- kubernetes:用于管理云平台中多个主机上的容器化的应用;自动化部署的操作系统
- Docker以及镜像管理harbor:一个开源的应用容器引擎;自动化部署的载体和仓库
下面看下他们之间的关系示意图
关于k8s CI/CD示意图(1)(ppt8)
- 开发人员:编写代码和dockerfile,k8s编排文件等,上传到gitlab存储;
- 运维人员:
- 创建不同的jenkins job,定义触发规则
- jenkins从gitlab中checkout代码,
- jenkins使用dockerfile构建docker镜像,
- jenkins保存镜像到harbor中,
- jenkins调用kubernetes的api,拉取harbor上面的docker镜像,创建pod,运行docker容器;
- 这就是整个在k8s环境下CI/CD的大致流程,后面,还要具体的分布进行讲解;
- 还有一点,我们能够注意到,只有第一步 需要人为触发,其他的,都是jenkins在做,所以,这个便是CI/CD实现自动化的基础。
接下来,看下面这个ppt
关于k8s CI/CD示意图(2)(ppt9)
这个流程图跟上一张ppt上面的示意图差不多,却能更具体的体现出来了jenkins的内部功能流程,具体包括:
- maven构建项目代码,
- 使用sonar进行静态代码分析,
- 运行单元测试进行单元功能的测试,
- build docker镜像
- 上传docker镜像
- 调用k8s API进行服务更新交付等
Jenkins使用讲解
总结起来,jenkins就是通过定义了一种编程语法和插件规则,以及丰富的对外API接口,用以实现复杂流程:
- Pipeline:一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化;
- Plugin机制:jenkins几乎所有的针对具体项目,如java,python等项目的部署,都是要依赖于相关的插件进行构建,启动运行的
- 开放API:提供CRUD,自定义触发规则,指定运行环境参数等
- 为了更快的理解上面所说的jenkins的功能,来看CI部分的演示
- 我们的CI的目标是生成并保存docker镜像,步骤是:
- 在gitlab中checkout下来源代码,以及镜像打包的dockerfile
- 使用maven命令对代码进行编译、打包成可以运行的springboot可运行jar包
- 使用dockerfile将jar包打成docker镜像,并将docker镜像推送到harbor中进行保存。
- 下面我们来看下,jenkins进行自动化部署的大致步骤:
- 登陆jenkins管理页面
http://10.110.149.185
ssh登陆:10.110.149.185 - 创建设置job
打开uuid.images configration页面 jenkins->demo->uuid.images
http://10.110.149.185/view/demo/job/uuid.image/configure - 插件设置
首先:Generic Webhook Trigger这个插件对外提供触发功能,通过token=uuid.image可以在外部调用API进行触发任务执行,另外该插件还提供了传入参数的功能,我们待会看下CD过程可以看到相关的参数设定,以及如何使用 - pipeline过程:
这个过程是最核心的部分,所有的功能实现都在这里面进行;
我们看到pipeline的定义,为了方便统一代码管理,我给放到了gitlab中,其实也可以在jenkins本地定义。下面看下pipeline的流程
- 登陆jenkins管理页面
pipeline{
agent any
tools {
maven 'maven-3.5.2'
jdk 'JDK8'
}
stages {
stage('=============================================代码检出已经打包docker镜像=============================================') {
steps{
script{
uuidUrl="git@gitlab.lenovo.com:saas/uuid-service.git";
deployUrl="git@gitlab.lenovo.com:caoyong1/knowledge_share.git";
credentialsId="caoyong1-gitlab-lenovo-com";
}
echo "清理当前目录中的代码"
sh("rm -rf *")
dir("deploy"){
echo "=============================================开始deploy部分检出代码============================================="
checkout([$class: 'GitSCM', branches: [[name: 'refs/heads/master']], userRemoteConfigs: [[credentialsId: "$credentialsId", url: "$deployUrl"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: []])
}
dir("uid"){
echo "=============================================开始uuid部分检出代码============================================="
checkout([$class: 'GitSCM', branches: [[name: 'refs/heads/master']], userRemoteConfigs: [[credentialsId: "$credentialsId", url: "$uuidUrl"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: []])
## 此处是读取pom文件中的version,用来指定镜像的版本号$vName
script{
pom = readMavenPom file: 'pom.xml'
vName=pom.version
}
echo "=============================================打包镜像uuid:$vName============================================="
sh("mvn clean compile package -P saas")
sh("docker build --no-cache -f ../deploy/demo/docker/uuid/uuid.dockerfile -t harbor.aipo.lenovo.com/apps/uuid:$vName .")
sh("docker push harbor.aipo.lenovo.com/apps/uuid:$vName")
}
}
}
}
}
顺便看下dockerfile:
FROM harbor.aipo.lenovo.com/base_env/alpine_java:8
WORKDIR /root/services
COPY target/*.jar ./app.jar
EXPOSE 30001
ENTRYPOINT ["java","-jar","app.jar","--server.port=30001"]
简单说明下dockerfile步骤…
如上就是整个持续集成的过程,因为我们CI/CD的要求之一是自动化,即人工参与的越少越好,那么如何触发整个job就是一个很重要的问题:我们可以选择1,在gitlab中设置webhook,2:在外部使用postman进行触发;3:也可以在jenkins本地触发
打开:https://gitlab.lenovo.com/saas/uuid-service/-/settings/integrations
如果使用gitlab进行触发,可以指定push事件、tag push等事件规则进行触发,目前因为jenkins和gitlab不在一个网段,所以,不能webhook成功;
下面我们演示下通过postman模拟在外部进行触发;
为了节省事件,大家直接看我之前触发的结果:http://10.110.149.185/view/demo/job/uuid.image/21/console
通过日志进行简单过程讲解…
该操作过程结果是,我们打包好的docker镜像能够在https://harbor.aipo.lenovo.com中看到(caoyong1
/Caoyong1@lenovo)
打开harbor进行镜像查看apps/uuid…
接下来我们继续看gitlab相关功能:
GitLab使用讲解(ppt11)
gitlab其实大家都很熟悉,大致讲下内容
- 其基本功能就是代码版本管理功能,
- 其次就是本身gitlab也具有cicd功能,叫jenkins弱
- 还有就是上面提到的可以设置webhook进行触发外部事件,
- 同时也有丰富的开放式API
接下来,给大家介绍下docker
docker使用讲解(ppt12)
首先我们给docker下一个非常简单的定义:
- docker容器的本质是宿主机上的一个进程
- docker通过namespace实现了资源隔离
- 通过cgroups实现了资源限制,就是cpu啊,内存等资源
几个重要概念: - 镜像:运行容器所需要的的文件系统的抽象定义;
- 容器:就是一个视图隔离,资源可限制,独立文件系统的进程集合。
那么其实docker解决的就是项目部署过程中,文件目录隔离,以及进程集合的创建。下面分别来讲解下这两部分:
docker文件系统层叠结构(ppt13)
ppt上面这张图描述的就是镜像和容器文件系统的层叠结构,如何理解呢?下面演示下,大家就很容易就懂了:
我们来看下一个dockerfile,所谓dockerfile,就是创建镜像的配置文件
FROM centos:7.6.1810
LABEL maintainer=caoyong1
WORKDIR /root
COPY caoyong.txt .
#指定时区以及安装各种插件
RUN yum -y install iputils && yum -y install net-tools.x86_64 && yum install -y redhat-lsb && yum -y install bridge-utils && yum -y install traceroute && yum -y install vim*
#指定字符集
COPY caoyong2.txt .
大致说下过程,
1.依赖于centos7.6基础镜像
2.拷贝宿主机文件caoyong.txt到镜像中
3.安装若干软件到镜像中
4.拷贝caoyong2.txt到镜像中
FROM centos:7.6.1810
LABEL maintainer=caoyong1
WORKDIR /root
COPY caoyong.txt .
#指定时区以及安装各种插件
RUN yum -y install iputils && yum -y install net-tools.x86_64 && yum install -y redhat-lsb && yum -y install bridge-utils && yum -y install traceroute && yum -y install vim*
COPY caoyong2.txt .
同样,为了节省时间,我在机器上面提前运行出来了结果;
先看下镜像的文件层级结构:
docker images
docker inspect 5d647d726379
先看Upper层,在看Lower层
其中
- 镜像层就是lowerdir,只读
- 容器层是upperdir,可写的
- 暴露在外的统一视图就是所谓的merged
看下LowerDir由上往下看,- 第一层caoyong2.txt,
- 第二层:yum安装的所有文件
find . -type f |more
- 第三层:caoyong.txt
- 最后一层:系统级的软件
看下UpperDir中可以看到我们COPY到该目录中的jar包
我们启动下容器: docker run -itd 5d647d726379 /bin/bash
同样看下容器的文件组成:docker inspect ef6f2aab9bec
分层结构跟镜像一样的结构,Lower,upper层等
有时间的话,可以对比一下,我这里可以告诉大家,对比结果就是容器层会合并镜像层的Upper和Lower,变成新的Lower层,并且会增加相应的可读写层Upper层
所以,可以看到docker的文件目录是一层一层叠加起来的
https://blog.csdn.net/11b202/article/details/21389067
容器启动之后,当读取文件的时候,按照从上往下的顺序进行读取,在某一层找到,就将副本读取到Upper层,如果修改,也是修改的Upper层中的副本,所以,镜像层的文件是只读的,容器层,即Upper层,的文件是可写的,在Upper层可以写入文件。
所以,我们平时写dockerfile的时候,尽量一次性拷贝所有的文件,一次性安装所有的文件,能够避免不必要的分层
其他的资源隔离,比如说网络隔离,pid隔离,ipc(就是进程间通讯)隔离、UTS(主机和域名)隔离等有兴趣的可以研究下,这里就不多说了。
通过实例看下进程如何隔离的
在宿主机上面,查看到进程 ps -ef|grep ef6f2aab9bec
执行docker exec -it ef6f2aab9bec /bin/bash,切换到容器的namespace下,ps -ef可以看到PID为1的进程id,
其实这两个进程是同一个进程,不过是在容器的namespace下,进程的被克隆,改变了一下名字和id而已;容器中的其他的进程,其实都是PID为1的这个进程的子进程而已,所以,如果PID这个进程退出了,其他的进程就自动退出了;在k8s的pod中,也是通过管理容器的PID为1的这个进程,来控制容器的启动退出的;
另一个值得注意的方面是,docker exec命令可以进入指定的容器内部执行命令。由它启动的进程属于容器的namespace和相应的cgroup。但是这些进程的父进程是Docker Daemon而非容器的PID1进程。
上面介绍了docker的本质,就是进程集合和文件系统的隔离,需要的所有功能,都要依赖宿主机的接口来提供,做到这些,我们就可以只需要配置一次部署环境,将应用以克隆的方式部署到任意的主机上了。
当然,我们光隔离是不行的,因为隔离带来了好处的同时,也带来了很多相关的问题,比如说网络不通,比如说存储,各种挂载管理起来也比较混乱,还有日志收集,服务检测等等,于是我们就需要一种,能够打通隔离和存储等资源治理混乱局面的工具,于是,kubernetes就是这样闪亮登场了。
k8s讲解-简介(ppt14)
kubernetes是谷歌开源的容器集群管理系统,非常牛掰,目前行业标准,完了。
k8s讲解-几个重要概念(ppt15)
- namespace:k8s集群内部的逻辑隔离机制(鉴权,资源额度等);
- pod:对一个或者一组容器的抽象(Pod只是一个逻辑概念),k8s最小的调度及资源单元;
- service:提供访问一个或多个pod市里的稳定访问地址
- Label Selector:k8s中实体之间松耦合关联关系的定义
- Container:容器是应用程序及其在运行时依赖的打包,运行于pod上
- Deployment:定义一组pod的副本数目,版本等;通过控制器,维持pod的数目(自动恢复失败的pod);通过控制器以指定的测量控制版本(滚动升级,重新生成,回滚等)
k8s讲解-总体架构(ppt16)
(参考:https://www.cnblogs.com/Tao9/p/12026232.html)
- 通常我们都是通过 kubectl 对 Kubernetes 下命令的,
- 通过命令行工具 kubectl 来与 Kubernetes APIServer 交互,通过 APIServer 去调用各个进程来完成对 Node 的部署和控制。
- APIServer 的核心功能是对核心对象(例如:Pod,Service,RC)的增删改查操作,同时也是集群内模块之间数据交换的枢纽。
- etcd 包含在 APIServer 中,用来存储资源信息
- Controller Manager 是 Kubernetes 资源的管理者,是运维自动化的核心,定义一套管理规则。它包括 8 个 Controller,分别对应着副本,节点,资源,命名空间,服务等等。
- Scheduler 通过调度算法/策略把 Pod 放到合适的 Node 中去,调度完以后就由 kubelet 来管理 Node 了
kubelet 用于处理 Master 下发到 Node 的任务(即 Scheduler 的调度任务),同时管理 Pod 及 Pod 中的容器。 - 在完成资源调度以后,kubelet 进程也会在 APIServer 上注册 Node 信息,定期向 Master 汇报 Node 信息,并通过 cAdvisor 监控容器和节点资源。
- 由于,微服务的部署都是分布式的,所以对应的 Pod 以及容器的部署也是。为了能够方便地找到这些 Pod 或者容器,引入了 Service(kube-proxy)进程,它来负责反向代理和负载均衡的实施。
k8s讲解-运行过程(ppt17)
因为时间关系,这里就不讲了,图中也能大致看下整个pod创建和维护的过程,有时间大家可以自己研究下
k8s讲解-应用演示CD过程(ppt18)
- CD的pipeline
pipeline{ agent any tools { maven 'maven-3.5.2' jdk 'JDK8' } stages { stage('=========================================将服务在k8s集群上运行============================================') { steps{ script{ uuidUrl="git@gitlab.lenovo.com:saas/uuid-service.git"; deployUrl="git@gitlab.lenovo.com:caoyong1/knowledge_share.git"; credentialsId="caoyong1-gitlab-lenovo-com"; ns = "ns-uuid-$envName" } dir("namespaces/$ns"){ echo "==================================创建namespace:$ns==================================" sh("cp ../../demo/k8s/uid/namespace.yaml .") sh("cp ../../demo/k8s/uid/cm-${envName}.yaml .") sh("sed -i -e 's/\${NAMESPACE}/${ns}/g' namespace.yaml") sh("kubectl apply -f namespace.yaml --validate=false") echo "===================================创建configMap:env-config==================================" sh("kubectl apply -f cm-${envName}.yaml --validate=false") } dir("pods/uuid"){ echo "===================================创建应用pod:uuid:${version}====================================" sh("cp ../../demo/k8s/uid/uuid.yaml .") sh("sed -i -e 's/\${NAMESPACE}/${ns}/g' \ -e 's/\${VERSION}/$version/g' \ -e 's/\${NODEPORT}/$nodePort/g' \ uuid.yaml") sh("kubectl apply -f uuid.yaml --validate=false") } } } } }
- CD的目标是三个:
- 将test环境下启动的服务,交付测试
- 将prod环境下启动的服务,上线
- 应用版本的升级,上线回退
- 来看下CD的步骤:
- 创建namespace,根据前端传入的参数:交付测试的ns-uuid-test,上线部署的ns-uuid-prod
apiVersion: v1 kind: Namespace metadata: name: ${NAMESPACE}
- 创建configMap,也是两个部署环境,分别是test测试环境,prod生产环境,configMap就是平时我们所说的配置文件,在test环境和prod环境下,不同的配置文件;目前配置文件中,我们只有一个键:demoValue,两个环境下的demoValue值分别是test和prod;
- prod环境
apiVersion: v1 kind: ConfigMap metadata: name: env-config namespace: ns-uuid-prod data: demo.value: prod #demoValue的值是prod
- test环境
apiVersion: v1 kind: ConfigMap metadata: name: env-config namespace: ns-uuid-test data: demo.value: test #demoValue的值是test
- prod环境
我们待会演示的时候,会在访问接口中看到demoValue中的值
3. 运行pod,启动uuidService容器
讲解下uuid的deployment编排文件:
apiVersion: apps/v1
kind: Deployment # Deployment只负责管理不同的版本的ReplicaSet,由ReplicaSet管理Pod副本数
# 每个ReplicaSet对应Deployment template的一个版本
# 一个ReplicaSet下的Pod都是相同的版本。
metadata:
name: uuid-deploy
namespace: ${NAMESPACE}
spec: #说明书开始,其实是ReplicaSet的说明书,隐藏了ReplicaSet这也是配置很不好理解的原因
replicas: 3 # pod副本数
selector:
matchLabels:
app: uuid-label #通过spec.selector字段来指定这个ReplicaSet管理哪些Pod。在上面的例子中,新建的ReplicaSet会管理所有拥有app:nginxLabel的Pod。
strategy:
type: Recreate
template: # template中所描述的是pod
metadata:
labels:
app: uuid-label # pod的标签
spec:
containers: # 容器描述
- name: uuid-server #容器的名称
image: harbor.aipo.lenovo.com/apps/uuid:${VERSION} # 容器的全名
imagePullPolicy: Always # 容器拉取策略
ports:
- name: http
containerPort: 30001 #容器暴露的端口
envFrom:
- configMapRef:
name: env-config #使用的configMap环境变量
---
apiVersion: v1
kind: Service #定义service
metadata:
name: uuidservice
namespace: ${NAMESPACE}
spec:
type: NodePort #service类型,NodePort是可以对外暴露服务
selector:
app: uuid-label #此处的选择器选择的是pod
ports:
- name: http
port: 80 #service暴露的端口
targetPort: 30001 #对应容器的端口
nodePort: ${NODEPORT} # service对外暴露的端口
#通过template.metadata.labels字段为即将新建的Pod附加Label。在上面的例子中,新建了一个名称为nginx的Pod,它拥有一个键值对为app:nginx的Label。
#通过spec.selector字段来指定这个RC管理哪些Pod。在上面的例子中,新建的RC会管理所有拥有app:nginxLabel的Pod。这样的spec.selector在Kubernetes中被称作Label Selector。
调用prod过程:使用postman:
curl --location --request POST 'http://10.110.149.185/generic-webhook-trigger/invoke?token=uuid.runner' \
--header 'Content-Type: application/json' \
--header 'X-Gitlab-Event: Tag Push Hook' \
--header 'X-Gitlab-Token: 93e7593af81a3862890f99dc53dee758' \
--header 'Content-Type: text/plain' \
--data-raw '{
"version": "v1.0.0.0",
"envName": "prod",
"nodePort":30051
}'
调用test过程:使用postman,调用触发jenkins:
4. 打开浏览器测试
test环境:http://10.110.149.172:30050/status
prod环境:http://10.110.149.172:30051/status
我们在上面的接口中,可以看到在不同的命名空间下,即在测试环境和生成环境中,demoValue的值是不同的,两个值分别来自于两个命名空间下的configMap;
接下来,我们来对版本回退和升级做介绍:
前文中我们提到,在uuid项目中,是根据pom中的version来定义镜像的版本的;我提前打包完成了两个镜像,在harbor上面我们也可以看到,分别是v1.0.0.0和v2.0.0.0
应用版本升级:
可以直接重新调用jenkins,在参数中指定镜像版本,重新对k8s上面的pod进行编排,效率有点低,有点浪费时间和资源
还有更好的方式,就是直接对镜像进行升级:
#镜像升级命令
#先查看pods,有三个副本
kubectl get pods -n ns-uuid-test
kubectl set image deployment/uuid-deploy uuid-server=harbor.aipo.lenovo.com/apps/uuid:v2.0.0.0 -n ns-uuid-test
#查看pods,有三个副本
kubectl get pods -n ns-uuid-test
#查看pod启动过程中的事件
kubectl describe pod/uuid-deploy-577cfb7467-cggr4 -n ns-uuid-test
#查看镜像版本
kubectl get pod/uuid-deploy-5fcdc755f6-6hb8w -o yaml -n ns-uuid-test
在通过接口访问,可以看到镜像的版本为v2.0.0.0;
回退版本过程:
#看下deployment的reversion
kubectl describe deployment/uuid-deploy -n ns-uuid-test
#查询版本列表
kubectl rollout history deployment/uuid-deploy -n ns-uuid-test
#保存的版本数量是可以指定的
#回滚到Deployment到某个版本,需要先查询版本列表
kubectl rollout undo deployment/uuid-deploy --to-revision=1 -n ns-uuid-test
#回退到上一个版本
kubectl rollout undo deployment/uuid-deploy -n ns-uuid-test
在通过接口访问,可以看到镜像的版本为v1.0.0.0;
配置文件其实也是可以使用
虽然说,在版本升级、回退过程中,可能还有很多事情要做,比如数据库中数据结构的变化,配置文件的变化等等,起码在应用层级上,k8s模式,为我们提供了无需手动的版本升级回退功能,带来了很大的方便。
结束语:
如上就是我今天分享的k8s环境下的CI/CD集成 方面的全部内容,非常感谢李飞,李冰洁,王磊对本次分享的大力支持,在他们提供的大量资料,我只是对材料进行了部分整理,并且提供了演示环境,谢谢大家!
更多推荐
所有评论(0)