首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Kubesphere DevOps组件 创建CI/CD流水线

Kubesphere DevOps组件 创建CI/CD流水线

原创
作者头像
全栈研发知识库
修改2025-03-05 11:21:55
修改2025-03-05 11:21:55
6990
举报

使用Kubesphere-DevOps组件-创建访问可控的 CI/CD 流水线

DevOps 提供一系列持续集成 (CI) 和持续交付 (CD) 工具,可以使 IT 和软件开发团队之间的流程实现自动化。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。

DevOps 流水线工作流

DevOps CI/CD 流水线基于底层 Kubernetes Jenkins Agent 运行。这些 Jenkins Agent 可以动态扩缩,即根据任务状态进行动态供应或释放。Jenkins Controller 和 Agent 以 Pod 的形式运行在 KubeSphere 节点上。Controller 运行在其中一个节点上,其配置数据存储在一个持久卷声明中。Agent 运行在各个节点上,但可能不会一直处于运行状态,而是根据需求动态创建并自动删除。

当 Jenkins Controller 收到构建请求,会根据标签动态创建运行在 Pod 中的 Jenkins Agent 并注册到 Controller 上。当 Agent 运行完任务后,将会被释放,相关的 Pod 也会被删除。

动态供应 Jenkins Agent

资源分配合理:动态分配已创建的 Agent 至空闲节点,避免因单个节点资源利用率高而导致任务排队等待。

高可扩缩性:当集群因资源不足而导致任务长时间排队等待时,支持向集群新增节点。

高可用性:当 Jenkins Controller 故障时,DevOps 会自动创建一个新的 Jenkins Controller 容器,并将持久卷挂载至新创建的容器,保证数据不会丢失,从而实现集群高可用。

管理 DevOps 项目

使用 DevOps 创建和管理 DevOps 项目

使用 Jenkinsfile 创建流水线案例:

代码语言:shell
复制
pipeline {
  
  agent {
    node {
      label 'maven'
    }
  }
  
  stages {
    
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          // 使用指定的凭证拉取代码,指定分支
          // 注意凭证需要先创建
          git(url: 'https://gitee.com/heyangyi/grpcs.git', credentialsId: 'heyangyi-git-account' , branch: 'dev', changelog: true, poll: false)
          sh 'ls -al'
        }
      }
    }
    
    stage('构建镜像') {
      agent none
      steps {
        container('maven') {
          // 注意此处Dockerfile文件地址:GRPCS/GRPCS.NoticeService/Dockerfile GRPCS/
          sh 'docker build -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BRANCH_NAME-$BUILD_NUMBER -f GRPCS/GRPCS.NoticeService/Dockerfile GRPCS/'
          sh 'docker images'
        }
      }
    }
    
    stage('推送-构建编号-镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,credentialsId : "$DOCKER_CREDENTIAL_ID" ,)]) {
            sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
            sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BRANCH_NAME-$BUILD_NUMBER'
          }
        }
      }
    }
    
    stage('推送-latest-镜像') {
      steps {
        container('maven') {
          sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BRANCH_NAME-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
          sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
        }
      }
    }
    
    stage('部署到Test环境') {
      steps {
        container('maven') {
          //input(id: 'deploy-to-dev', message: 'deploy to dev?')
          withCredentials([kubeconfigContent(credentialsId : 'kubeconfig-credential-id' ,variable : 'KUBECONFIG_CONFIG' ,)]) {
            sh 'mkdir -p ~/.kube/'
            sh 'echo "$KUBECONFIG_CONFIG" > ~/.kube/config'
            // 注意:此处为源代码所在目录的deploy.yaml文件地址
            sh 'envsubst < GRPCS/GRPCS.NoticeService/deploy.yaml | kubectl apply -f -'
          }
        }
      }
    }
    
  }
  
  environment {
    // 阿里云镜像仓库账号密码凭证:用于推送镜像
    DOCKER_CREDENTIAL_ID = 'aliyun-docker-registry'
    // gitee账号密码凭证:用于拉取源代码
    GITHUB_CREDENTIAL_ID = 'heyangyi-git-account'
    // KUBECONFIG:连接和认证Kubernetes集群所需的各种参数和凭证信息
    KUBECONFIG_CREDENTIAL_ID = 'kubeconfig-credential-id'
    // 阿里云镜像仓库地址
    REGISTRY = 'registry.cn-hongkong.aliyuncs.com'
    // 阿里云镜像仓库命名空间
    DOCKERHUB_NAMESPACE = 'learn-work'
    // APP名称
    APP_NAME = 'grpcs'
    // APP在K8S命名空间:注意在KubeSphere是企业空间下的项目名称,需要先创建
    APP_NAMESPACE = 'demo-product'
    // 副本数
    REPLICAS = 1
    // 分支名称
    BRANCH_NAME = 'dev'
    // ASP.NET CORE 环境名称
    ASPNETCORE_ENVIRONMENT = 'ASPNETCORE_ENVIRONMENT'
    // ASP.NET CORE 环境名称值
    ASPNETCORE_ENVIRONMENT_VALUE = 'Development'
    // ASP.NET CORE 环境名称
    ASPNETCORE_URLS = 'ASPNETCORE_URLS'
    // ASP.NET CORE 环境名称值
    ASPNETCORE_URLS_VALUE = 'http://*:8080'
    // ASP.NET CORE 环境名称
    ASPNETCORE_TZ = 'TZ'
    // ASP.NET CORE 环境名称值
    ASPNETCORE_TZ_VALUES = 'Asia/Shanghai'
    // APP端口
    APP_PORT = '8080'
  }
  
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

上面使用的凭证:aliyun-docker-registry、heyangyi-git-account、kubeconfig-credential-id

deploy.yaml文件案例

代码语言:yaml
复制
apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
  name: ${APP_NAME}
  namespace: ${APP_NAMESPACE}
  labels:
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: ${APP_NAME}
  annotations:
    servicemesh.kubesphere.io/enabled: "true"
spec:
  selector:
    matchLabels:
      app.kubernetes.io/version: v1
      app.kubernetes.io/name: ${APP_NAME}
  addOwnerRef: true
  componentKinds:
    - group: ""
      kind: Service
    - group: apps
      kind: Deployment
    - group: apps
      kind: StatefulSet
    - group: extensions
      kind: Ingress
    - group: servicemesh.kubesphere.io
      kind: Strategy
    - group: servicemesh.kubesphere.io
      kind: ServicePolicy
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: ${APP_NAMESPACE}
  labels:
    version: v1
    app: ${APP_NAME}
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: ${APP_NAME}
  name: ${APP_NAME}-v1
  annotations:
    servicemesh.kubesphere.io/enabled: "true"
spec:
  replicas: ${REPLICAS}
  selector:
    matchLabels:
      version: v1
      app: ${APP_NAME}
      app.kubernetes.io/version: v1
      app.kubernetes.io/name: ${APP_NAME}
  template:
    metadata:
      labels:
        version: v1
        app: ${APP_NAME}
        app.kubernetes.io/version: v1
        app.kubernetes.io/name: ${APP_NAME}
      annotations:
        sidecar.istio.io/inject: "true"
    spec:
      containers:
        - name: container-${APP_NAME}
          imagePullPolicy: Always
          image: $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BRANCH_NAME-$BUILD_NUMBER
          ports:
            - name: grpc-${APP_NAME}
              protocol: TCP
              containerPort: ${APP_PORT}
          env:
            - name: ${ASPNETCORE_ENVIRONMENT}
              value: ${ASPNETCORE_ENVIRONMENT_VALUE}
            - name: ${ASPNETCORE_URLS}
              value: ${ASPNETCORE_URLS_VALUE}
            - name: ${ASPNETCORE_TZ}
              value: ${ASPNETCORE_TZ_VALUES}
      serviceAccount: default
      affinity: {}
      initContainers: []
      volumes: []
      imagePullSecrets:
        - name: ${DOCKER_CREDENTIAL_ID}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
---
apiVersion: v1
kind: Service
metadata:
  namespace: ${APP_NAMESPACE}
  labels:
    version: v1
    app: ${APP_NAME}
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: ${APP_NAME}
  annotations:
    kubesphere.io/serviceType: statelessservice
    servicemesh.kubesphere.io/enabled: "true"
  name: ${APP_NAME}
spec:
  sessionAffinity: None
  selector:
    app: ${APP_NAME}
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: ${APP_NAME}
  ports:
    - name: grpc-${APP_NAME}
      protocol: TCP
      port: 80
      targetPort: ${APP_PORT}
---

参考文档

Kubesphere 扩展组件使用 - CICD - DevOps

注意:安装DevOps扩展组件的过程中遇到一些问题,多数情况是镜像下载不下来,遇到下载不下来的情况下建议在安装过程中查看kubesphere-devops-system项目下容器组的镜像,发现下载不下来的镜像在本机拉取下来,然后导出到本机上传到k8s节点,再还原上去。

代码语言:shell
复制
#导出单个镜像
docker save -o [输出文件名].tar [镜像名称或ID]
代码语言:shell
复制
#加载单个镜像
docker load -i [输入文件名].tar

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用Kubesphere-DevOps组件-创建访问可控的 CI/CD 流水线
    • DevOps 流水线工作流
    • 动态供应 Jenkins Agent
    • 管理 DevOps 项目
    • 使用 DevOps 创建和管理 DevOps 项目
      • 使用 Jenkinsfile 创建流水线案例:
      • deploy.yaml文件案例
    • 参考文档
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档