创建多集群流水线

由于云场上提供不同的托管 Kubernetes 服务,DevOps 流水线必须处理涉及多个 Kubernetes 集群的使用场景。

本教程将演示如何在 KubeSphere 创建一个多集群流水线。

准备工作

工作流程概述

本教程使用三个集群作为工作流中三个独立的环境。如下图所示:

use-case-for-multi-cluster

三个集群分别用于开发,测试和生产。当代码被提交至 Git 仓库,就会触发流水线并执行以下几个阶段 — 单元测试SonarQube 分析构建 & 推送部署到开发集群。开发者使用开发集群进行自我测试和验证。当开发者批准后,流水线就会进入到下一个阶段 部署到测试集群 进行更严格的验证。最后,流水线在获得必要的批准之后,将会进入下一个阶段 部署到生产集群,并向外提供服务。

动手实验

步骤 1:准备集群

下图展示每个集群对应的角色。

集群名称集群角色用途
host主集群测试
shire成员集群生产
rohan成员集群开发

备注

这些 Kubernetes 集群可以被托管至不同的云厂商,也可以使用不同的 Kubernetes 版本。针对 KubeSphere 3.3.0 推荐的 Kubernetes 版本:v1.19.x、v1.20.x、v1.21.x 、v1.22.x 和 v1.23.x(实验性支持)。

步骤 2:创建企业空间

  1. 使用 ws-manager 帐户登录主集群的 Web 控制台。在企业空间页面中,点击创建

  2. 基本信息页面中,将企业空间命名为 devops-multicluster,选择 ws-admin管理员,然后点击下一步

  3. 集群设置页面,选择所有集群(总共三个集群),然后点击创建

  4. 创建的企业空间会显示在列表。您需要登出控制台并以 ws-admin 身份重新登录,以邀请 project-adminproject-regular 至企业空间,然后分别授予他们 work-space-self-provisionerworkspace-viwer 角色。有关更多信息,请参见创建企业空间、项目、用户和角色

步骤 3:创建 DevOps 项目

  1. 您需要登出控制台,并以 project-admin 身份重新登录。转到 DevOps 项目页面并点击创建

  2. 在出现的对话框中,输入 mulicluster-demo 作为名称,在集群设置中选择 host,然后点击确定

    备注

    下拉列表中只有启用 DevOps 组件的集群可用。

  3. 创建的 DevOps 项目将显示在列表中。请确保邀请用户 project-regular 至这个项目,并赋予 operator 角色。有关更多信息,请参见创建企业空间、项目、用户和角色

步骤 4:在集群上创建项目

提前创建如下表所示的项目。请确保邀请 project-regular 用户到这些项目中,并赋予 operator 角色。有关更多信息,请参见创建企业空间、项目、用户和角色

集群名用途项目名
host测试kubesphere-sample-prod
shire生产kubesphere-sample-prod
rohan开发kubesphere-sample-dev

步骤 5:创建凭证

  1. 登出控制台,以 project-regular 身份重新登录。在 DevOps 项目页面,点击 DevOps 项目 multicluster-demo

  2. 凭证页面,您需要创建如下表所示的凭证。有关如何创建凭证的更多信息,请参见凭证管理使用 Jenkinsfile 创建流水线

凭证 ID类型应用场所
hostkubeconfig用于主集群测试
shirekubeconfig用于成员集群生产
rohankubeconfig用于成员集群开发
dockerhub-id用户名和密码Docker Hub
sonar-token访问令牌SonarQube

备注

在创建 kubeconfig 凭证 shirerohan 时,必须手动输入成员集群的 kubeconfig。确保主集群可以访问成员集群的 API Server 地址。

  1. 共创建五个凭证。

步骤 6:创建流水线

  1. 流水线页面点击创建。在显示的对话框中,输入 build-and-deploy-application 作为名称然后点击下一步

  2. 高级设置中选项卡中,点击创建即使用默认配置。

  3. 列表会展示被创建的流水线,点击流水线名称进入详情页面。

  4. 点击编辑 Jenkinsfile,复制和粘贴以下内容。请确保将 DOCKERHUB_NAMESPACE 的值替换为您自己的值,然后点击确定

    1. pipeline {
    2. agent {
    3. node {
    4. label 'maven'
    5. }
    6. }
    7. parameters {
    8. string(name:'BRANCH_NAME',defaultValue: 'master',description:'')
    9. }
    10. environment {
    11. DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    12. PROD_KUBECONFIG_CREDENTIAL_ID = 'shire'
    13. TEST_KUBECONFIG_CREDENTIAL_ID = 'host'
    14. DEV_KUBECONFIG_CREDENTIAL_ID = 'rohan'
    15. REGISTRY = 'docker.io'
    16. DOCKERHUB_NAMESPACE = 'your Docker Hub account ID'
    17. APP_NAME = 'devops-maven-sample'
    18. SONAR_CREDENTIAL_ID = 'sonar-token'
    19. TAG_NAME = "SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER"
    20. }
    21. stages {
    22. stage('checkout') {
    23. steps {
    24. container('maven') {
    25. git branch: 'master', url: 'https://github.com/kubesphere/devops-maven-sample.git'
    26. }
    27. }
    28. }
    29. stage('unit test') {
    30. steps {
    31. container('maven') {
    32. sh 'mvn clean test'
    33. }
    34. }
    35. }
    36. stage('sonarqube analysis') {
    37. steps {
    38. container('maven') {
    39. withCredentials([string(credentialsId: "$SONAR_CREDENTIAL_ID", variable: 'SONAR_TOKEN')]) {
    40. withSonarQubeEnv('sonar') {
    41. sh "mvn sonar:sonar -Dsonar.login=$SONAR_TOKEN"
    42. }
    43. }
    44. }
    45. }
    46. }
    47. stage('build & push') {
    48. steps {
    49. container('maven') {
    50. sh 'mvn -Dmaven.test.skip=true clean package'
    51. sh 'docker build -f Dockerfile-online -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'
    52. withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,credentialsId : "$DOCKER_CREDENTIAL_ID" ,)]) {
    53. sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
    54. sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
    55. }
    56. }
    57. }
    58. }
    59. stage('push latest') {
    60. steps {
    61. container('maven') {
    62. sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
    63. sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
    64. }
    65. }
    66. }
    67. stage('deploy to dev') {
    68. steps {
    69. container('maven') {
    70. withCredentials([
    71. kubeconfigFile(
    72. credentialsId: env.DEV_KUBECONFIG_CREDENTIAL_ID,
    73. variable: 'KUBECONFIG')
    74. ]) {
    75. sh 'envsubst < deploy/dev-all-in-one/devops-sample.yaml | kubectl apply -f -'
    76. }
    77. }
    78. }
    79. }
    80. stage('deploy to staging') {
    81. steps {
    82. container('maven') {
    83. input(id: 'deploy-to-staging', message: 'deploy to staging?')
    84. withCredentials([
    85. kubeconfigFile(
    86. credentialsId: env.TEST_KUBECONFIG_CREDENTIAL_ID,
    87. variable: 'KUBECONFIG')
    88. ]) {
    89. sh 'envsubst < deploy/prod-all-in-one/devops-sample.yaml | kubectl apply -f -'
    90. }
    91. }
    92. }
    93. }
    94. stage('deploy to production') {
    95. steps {
    96. container('maven') {
    97. input(id: 'deploy-to-production', message: 'deploy to production?')
    98. withCredentials([
    99. kubeconfigFile(
    100. credentialsId: env.PROD_KUBECONFIG_CREDENTIAL_ID,
    101. variable: 'KUBECONFIG')
    102. ]) {
    103. sh 'envsubst < deploy/prod-all-in-one/devops-sample.yaml | kubectl apply -f -'
    104. }
    105. }
    106. }
    107. }
    108. }
    109. }

    备注

    mvn 命令中的标志 -o 表示启用脱机模式。如果您在本地准备好了相关的 maven 依赖和缓存,可以保持脱机模式以节约时间。

  5. 流水线创建之后,可以在图形编辑面板上查看流水线的阶段和步骤。

步骤7:运行流水线并查看结果

  1. 点击运行按钮运行流水线。当流水线运行达到部署到暂存的阶段,将会暂停,因为资源已经被部署到集群进行开发。您需要手动点击继续两次,以将资源部署到测试集群 host 和生产集群 shire

  2. 一段时间过后,您可以看见流水线的状态展示为成功

  3. 在右上角点击查看日志,查看流水线运行日志。对于每个阶段,您可以点击显示日志以检查日志,同时日志可以被下载到本地进行进一步的分析。

  4. 当流水线运行成功时,点击代码检查,通过 SonarQube 检查结果。

  5. 转到项目页面,您可以通过从下拉列表中选择特定集群,来查看部署在各集群不同项目中的资源。