k8s CI/CD板书

k8s CI/CD讲演稿

导语(ppt1):

  • 各位同事大家好,很高兴大家能够对k8s环境下的CI/CD这个主题的相关知识感兴趣。本次主题分享的内容,是我们在以kubernetes环境部署应用的时候,如何快速集成,快速部署交付的过程,有原理也有实操。我这部分内容的讲解,是告诉大家可以如何做,至于究竟如何做,则需要根据我讲解的内容,结合项目特点,自行规划设计。

什么是DevOps?(ppt2)

  • DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(Dev)、运维人员(ops)和质量保障(QA)部门之间的沟通、协作与整合。
  • 它的目的是构建一种文化和环境,使构建,测试,发布软件更加快捷,频繁和可靠。
  • DevOps是个开放的体系,从实践中而来,并且还在不断的发展,具体到某个组织也并没有一致的套路,所以DevOps落地更多是因组织而异、因目标而异、因人而异
  • 看下面这个图:在这里插入图片描述
  • 第一张图描述了,Dev开发人员和Ops运维人员的分工以及协作;
  • 第二张图描述了,软件开发模式从瀑布开发模式到敏捷开发模式的演进
  • 第三张图就比较有意思了,开发人员要应对需求不断变更实现,然而运维团队考虑的是系统的稳定、可用性和安全性。于是,当软件系统从墙的一端(Dev)传递到另一端(Ops)时,会发生各种各样不可预知的“异常”情况。
    这些“异常”通常是由于交付了不正确的东西,包括:
    1. 开发人员不清楚生产环境,而运维人员又搞不定既没有规范又没有文档的配置
    2. 开发过程中的不成熟版本进入了生产环境
  • 当处于瀑布开发模式的时候,因为软件交付周期较长,通常运维人员有充足的时间对软件进行部署交付;但是当到了敏捷开发模式的情况下,便出现了很多的问题,看下面的幻灯片->

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分为如下几个部分:
  1. Jenkins:开源、提供友好操作界面的持续集成(CI)工具;自动化核心引擎;
  2. Gitlab:基于Git的代码管理工具且提供web服务;代码库及自动化触发器(webhook);
  3. 自定义触发器:Jenkins提供了标准的API,用户可以按照需求,搭建自己的触发规则服务;为我们自己开发适合我们自己项目的运维平台提供了接口;
  4. kubernetes:用于管理云平台中多个主机上的容器化的应用;自动化部署的操作系统
  5. 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镜像,步骤是:
  1. 在gitlab中checkout下来源代码,以及镜像打包的dockerfile
  2. 使用maven命令对代码进行编译、打包成可以运行的springboot可运行jar包
  3. 使用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的流程
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的目标是三个:
  1. 将test环境下启动的服务,交付测试
  2. 将prod环境下启动的服务,上线
  3. 应用版本的升级,上线回退
  • 来看下CD的步骤:
  1. 创建namespace,根据前端传入的参数:交付测试的ns-uuid-test,上线部署的ns-uuid-prod
    apiVersion: v1
    kind: Namespace
    metadata:
      name: ${NAMESPACE}
    
  2. 创建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
      

我们待会演示的时候,会在访问接口中看到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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值