k8s CI/CD板书

104 篇文章 135 订阅

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集成 方面的全部内容,非常感谢李飞,李冰洁,王磊对本次分享的大力支持,在他们提供的大量资料,我只是对材料进行了部分整理,并且提供了演示环境,谢谢大家!

转载至https://blog.csdn.net/cyxinda/article/details/106013583

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes (k8s) 是一种流行的容器编排平台,可以大大简化应用程序的部署和管理。CI/CD(持续集成/持续交付)管道是软件开发过程中的关键环节,可以将代码从开发到部署的流程自动化和加速。在 k8s 上部署 CI/CD 管道的步骤如下: 1. 创建代码仓库。您可以使用 Git 或其他版本控制工具。确保您的代码仓库可以与 CI/CD 工具集成。 2. 配置 CI 工具。这可以是 Jenkins、GitLab CICircleCI 等等。您需要将 CI 工具配置为从代码仓库拉取代码,并将其构建为容器镜像。确保您的 CI 工具可以与 Kubernetes 集群通信。 3. 配置 Docker Registry。您需要一个 Docker Registry 来存储构建的容器镜像,以便它们可以在 Kubernetes 集群中使用。您可以使用 Docker Hub、Google Container Registry、AWS ECR 等等。 4. 创建 Kubernetes 资源定义文件。这些文件告诉 Kubernetes 如何部署和管理您的应用程序。确保您的资源定义文件包含必要的配置和环境变量,以及指向您的 Docker Registry 的正确信息。 5. 部署应用程序。使用 kubectl 工具将 Kubernetes 资源定义文件应用于 Kubernetes 集群。 6. 配置 CD 工具。这可以是 Helm、Spinnaker、Argo CD 等等。您需要将 CD 工具配置为从 Docker Registry 拉取构建的容器镜像,并将其部署到 Kubernetes 集群。确保您的 CD 工具可以与 Kubernetes 集群通信。 7. 自动化部署。使用 CD 工具将新版本的应用程序自动部署到 Kubernetes 集群中。 总的来说,上述步骤是一个基本的 CI/CD 管道部署过程。当然,具体实现方式会因不同的应用程序和工具而异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值