使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

栏目: 编程工具 · 发布时间: 7年前

内容简介:接着上一篇《使用Helm优化Kubernetes下的研发体验:基础设施即代码》中笔者介绍了如何在项目中使用Helm,在项目源码中,我们通过Dockerfile定义了项目是如何构建的,使用Helm定义了项目是如何部署的。 团队中的任何人员(角色)在获取源码的同时就已经具备了一键构建,一键部署的能力。在这一篇中,我们将使用Jenkins在此基础上构建一条完整的持续交付流水线,并且让团队不同成员能够基于该流水线展开基本的协作。

接着上一篇《使用Helm优化Kubernetes下的研发体验:基础设施即代码》中笔者介绍了如何在项目中使用Helm,在项目源码中,我们通过Dockerfile定义了项目是如何构建的,使用Helm定义了项目是如何部署的。 团队中的任何人员(角色)在获取源码的同时就已经具备了一键构建,一键部署的能力。

整体目标

在这一篇中,我们将使用Jenkins在此基础上构建一条完整的持续交付流水线,并且让团队不同成员能够基于该流水线展开基本的协作。

  • 开发: 持续提交代码并能够通过持续集成(CI)过程快速获取反馈,在通过CI验证后,能够自动化部署到开发环境,以便后续的进一步功能测试(手动/自动自动化测试)等;
  • 测试: 在需要对项目功能进行验证时,可以一键部署测试环境,并且在此环境基础上可以完成功能验收(手动),以及全量的自动化验收测试等;
  • 运维:一键部署生产环境,同时发布创建版本,以便在发布异常时能够快速回归

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

资料来源: https://dzone.com/articles/easily-automate-your-cicd-pipeline-with-jenkins-he

示例项目的代码可以从 Github 下载,示例项目为 containerization-spring-with-helm 。接下来,我们将分阶段介绍如何通过 Jenkinsfile 定义整个过程。

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

项目构建阶段

当前阶段Jenkinsfile定义如下:

stage('Build And Test') {
    steps {

        dir('containerization-spring-with-helm') {
            sh 'docker build -t yunlzheng/spring-sample:$GIT_COMMIT .'
        }

    }
}

Build And Test 阶段,我们直接通过源码中的Dockerfile定义了整个持续集成阶段的任务,通过 dockerMulti-Stage Builds 特性,持续集成的所有任务全部通过Dockerfile进行定义,这样无论是在本地还是持续集成服务器中,我们都可以非常方便的进行运行CI任务。

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

发布镜像和Helm阶段

当前阶段Jenkinsfile定义如下:

stage('Publish Docker And Helm') {
  steps {

    withDockerRegistry([credentialsId: 'dockerhub', url: '']) {
      sh 'docker push yunlzheng/spring-sample:$GIT_COMMIT'
    }

    script {
      def filename = 'containerization-spring-with-helm/chart/values.yaml'
      def data = readYaml file: filename
      data.image.tag = env.GIT_COMMIT
      sh "rm $filename"
      writeYaml file: filename, data: data
    }

    script {
      def filename = 'containerization-spring-with-helm/chart/Chart.yaml'
      def data = readYaml file: filename
      data.version = env.GIT_COMMIT
      sh "rm $filename"
      writeYaml file: filename, data: data
    }

    dir('containerization-spring-with-helm') {
      sh 'helm push chart https://repomanage.rdc.aliyun.com/helm_repositories/26125-play-helm --username=$HELM_USERNAME --password=$HELM_PASSWORD  --version=$GIT_COMMIT'
    }

  }
}

Push镜像

通过 withDockerRegistry 的上下文中,Jenkins会确保docker client首先通过 credentials dockerhub 中定义的用户名和密码完成登录后,在运行 docker push 任务。并且我们确保使用当前代码版本的COMMIT_ID作为镜像的Tag,从而将Docker镜像版本与源码版本进行一一对应;

重写Chart镜像版本

通过 readYaml 读取chart的values.yaml内容到变量data后,通过 writeYaml 重写values.yaml中的镜像tag版本与当前构建镜像版本一致;

重写Chart版本

与镜像一样,我们希望Chart的版本与源码版本能够一一对应;

上传Chart

这里我们直接使用 阿里云效 提供的Helm仓库服务, 点击开通私有仓库服务 。通过Helm Push插件发布Chart到Helm仓库。

其中环境变量 $HELM_USERNAME$HELM_PASSWORD 是通过jenkins的Credentials加载到环境变量中:

environment {
      HELM_USERNAME = credentials('HELM_USERNAME')
      HELM_PASSWORD = credentials('HELM_PASSWORD')
}

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

部署到开发/测试环境阶段

当前阶段Jenkinsfile定义如下:

stage('Deploy To Dev') {
  steps {
    dir('containerization-spring-with-helm') {
      dir('chart') {
        sh 'helm upgrade spring-app-dev --install --namespace=dev --set ingress.host=dev.spring-example.local .'
      }
    }
  }
}

stage('Deploy To Stageing') {
  steps {
    input 'Do you approve staging?'
    dir('containerization-spring-with-helm') {
      dir('chart') {
        sh 'helm upgrade spring-app-staging --install --namespace=staging --set ingress.host=staging.spring-example.local .'
      }
    }
  }
}

在Jenkinsfile中我们分别定义了两个阶段 Deploy To DevDeploy To Stageing 。我们通过Kubernetes的命名空间划分单独的开发环境和测试环境。并且通过覆盖ingress.host确保能够通过ingress域名 dev.spring-example.localstaging.spring-example.local 访问到不同环境。 对于Staging环境而言,通过 input 确保该流程一定是通过人工确认的。

通过 helm upgrade 命令可以确保在特定命名空间下部署或者升级已有的Chart:

helm upgrade spring-app-staging --install --namespace=staging --set ingress.host=staging.spring-example.local .

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

部署到生产环境阶段

当前阶段Jenkinsfile定义如下:

stage('Deploy To Production') {
  steps {
    input 'Do you approve production?'

    script {                
        env.RELEASE = input message: 'Please input the release version',
        ok: 'Deploy',
        parameters: [
          [$class: 'TextParameterDefinition', defaultValue: '0.0.1', description: 'Cureent release version', name: 'release']
        ]
    }

    echo 'Deploy and release: $RELEASE'

    script {
      def filename = 'containerization-spring-with-helm/chart/Chart.yaml'
      def data = readYaml file: filename
      data.version = env.RELEASE
      sh "rm $filename"
      writeYaml file: filename, data: data
    }

    dir('containerization-spring-with-helm') {
      dir('chart') {
        sh 'helm lint'
        sh 'helm upgrade spring-app-prod --install --namespace=production --set ingress.host=production.spring-example.local .'
      }
      sh 'helm push chart https://repomanage.rdc.aliyun.com/helm_repositories/26125-play-helm --username=$HELM_USERNAME --password=$HELM_PASSWORD  --version=$RELEASE'
    }

  }
}

在最后一个 Deploy To Production 阶段中,与Dev和Stageing的部署不同在于当人工确认部署测试环境之后,我们需要用户手动输入当前发布的版本,以确保对当前发布的Chart版本能完成一个基线的定义:

使用Helm优化Kubernetes下的研发体验:实现持续交付流水线

这里,我们需要确保当前定义的版本是符合Sem规范的,因此这里使用了 helm lint 对Chart定义进行校验。

小结

通过代码提交版本(COMMIT_ID)关联了源码版本,镜像版本以及Chart版本。同时对于正式发布的软件版本而言,单独定义了正式发布的版本号。对于实践持续交付的研发团队而言,我们可以通过上述一条流水线基本实现软件交付的整个生命周期。而对于传统交付模式的团队,则可以通过将上述过程分拆到多条流水线(开发流水线,测试流水线,发布流水线)来适应自己的发布模式。

回到我们的总体目标而言,通过基础设施及代码的方式,我们定义了一个相对完备且自描述的应用。通过流水线即代码的方式,定义了应用的端到端交付过程。通过Docker定义项目的构建过程,通过Helm实现Kubernetes下应用的发布管理,通过Jenkinsfile定义了软件的整个交付过程,并且不同职能的团队成员,可以方便的在此基础上实现协作。最后借用《持续交付》的话“提前并频繁地做让你感到痛苦的事!“ ,希望大家都能够Happy Coding。

参考资料


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Data Mining

Web Data Mining

Bing Liu / Springer / 2006-12-28 / USD 59.95

Web mining aims to discover useful information and knowledge from the Web hyperlink structure, page contents, and usage data. Although Web mining uses many conventional data mining techniques, it is n......一起来看看 《Web Data Mining》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码