一、简介

DevOps (Development和Operations的组合词)是一系列做法和工具,可以使 IT 和软件开发团队之间的流程实现自动化。其中,随着敏捷软件开发日趋流行,持续集成 (CI) 和持续交付 (CD) 已经成为该领域一个理想的解决方案。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。

我们借助KubeSphere来学习DevOpshttps://kubesphere.com.cn/docs/pluggable-components/devops/

在这里插入图片描述

  1. 拉取代码
  2. 项目编译
  3. 构建镜像
  4. 推送镜像仓库
  5. 部署k8s

二、DevOps流程

创建工程:
在这里插入图片描述

创建流水线:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
直接创建。
在这里插入图片描述

点击 编辑流水线:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1 拉取代码

在这里插入图片描述

点击运行,查看日志,第一步代码已经拉取成功:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.2 项目编译

使用mvn clean package -Dmaven.test.skip=true进行编译打包:
在这里插入图片描述
点击运行流水线:

在这里插入图片描述

编译打包成功:
在这里插入图片描述

注意:
在使用mvn clean pacgage Dmaven.test.skip=true 命令进行编译打包时,Maven会从中央仓库去下载依赖,这样速度会很慢,我们需要修改Maven的配置文件ks-devops-agent
在这里插入图片描述

加上阿里云的镜像仓库:

     <!-- 阿里云 -->
     <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>

在这里插入图片描述
在这里插入图片描述

并且已经下载过的依赖下次编译打包不会再重复下载了:
在这里插入图片描述

2.3 构建镜像

使用docker build -t helloworld:latest -f Dockerfile .命令创建镜像
在这里插入图片描述

查看运行日志:
在这里插入图片描述
如果有多个微服务可以点击添加并行阶段
在这里插入图片描述

2.4 推送镜像仓库

我们编辑Jenkinsfile文件:
environment定义环境变量,可以直接使用$来引用。
在这里插入图片描述
$BUILD_NUMBER 是版本号。
在这里插入图片描述

创建登录凭证:

在这里插入图片描述

推送镜像的Jenkinsfile文件:

    stage('推送镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-lsh' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin '
            sh 'docker tag helloworld:latest $REGISTRY/$DOCKERHUB_NAMESPACE/helloworld:SNAPSHOT-$BUILD_NUMBER '
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/helloworld:SNAPSHOT-$BUILD_NUMBER '
          }

        }

      }
    }

在这里插入图片描述

注意还需要修改保存环境变量:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.5 部署到k8s集群

给每个微服务准备一个deployment.yml文件:
在这里插入图片描述
部署到k8s集群:

在这里插入图片描述

在这里插入图片描述
此处的配置文件路径就是我们在项目中的文件的路径。点击 新建凭证
在这里插入图片描述

注意:
k8s部署镜像需要下载镜像,镜像是在我们的私有仓库中的,所以需要配置秘钥:
在这里插入图片描述
工程管理 - 凭证 - 创建

在这里插入图片描述

在配置中心创建秘钥:
在这里插入图片描述
在这里插入图片描述
注意:一定要创建出名称空间kubectl create ns helloworld

在这里插入图片描述
可以看到虽然流水线执行成功,但是我们还要确认k8s部署是否成功。
在这里插入图片描述
查看原因:

在这里插入图片描述
是因为编译时打包出错了,在pom文件上加上以下内容解决:

<build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

在这里插入图片描述
在这里插入图片描述
在容器内访问项目接口:
在这里插入图片描述

创建外网访问服务:
在这里插入图片描述

在这里插入图片描述

三、使用Webhook自动触发流水线

在创建流水线的时候指定代码仓库,就可以使用webhook来触发自动执行流水线部署。
当我们提交代码到仓库的时候,Gitee会回调webhook地址发送请求,从而触发流水线。
在这里插入图片描述
在这里插入图片描述

在码云仓库 管理 添加 webhook
在这里插入图片描述
在这里插入图片描述

四、注意

流水线执行成功后,还需要确认k8s部署是否成功。要看容器运行的日志报错信息来响应的解决,在第一次流水线调试成功之后,接下来的部署就会非常简单了。

踩坑指南:

  1. k8s拉取镜像时使用的秘钥,需要和项目在同一个命名空间下。
  2. 注意Jenkinsfile文件中的环境变量environment,如果没有设置是获取不到的。
    在这里插入图片描述
    到此 流水线部署就完成了。

附录

Jenkinsfile

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('base') {
          git(url: 'https://gitee.com/L1692312138/helloworld.git', credentialsId: 'gitee-lsh', branch: 'master', changelog: true, poll: false)
        }

        sh 'ls -l'

        sh 'ls -l deploy/'
      }
    }

    stage('项目编译') {
      agent none
      steps {
        container('maven') {
          sh 'mvn clean package  -Dmaven.test.skip=true'
        }

        sh 'ls -al'
      }
    }

    stage('default-2') {
      parallel {
        stage('构建镜像') {
          agent none
          steps {
            container('maven') {
              sh 'ls -l target/'
              sh 'docker build -t $APP_NAME:latest -f Dockerfile .'
            }

          }
        }

      }
    }

    stage('推送镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-lsh' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin '
            sh 'docker tag   $APP_NAME:latest $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER '
          }

        }

      }
    }

    stage('部署到k8s') {
      agent none
      steps {
        kubernetesDeploy(configs: 'deploy/**', enableConfigSubstitution: true, kubeconfigId: 'demo-kubeconfig', dockerCredentials: [])
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
    DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
    ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'helloworld'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: helloworld
  name: helloworld
  namespace: ruoyi   #一定要写名称空间
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      imagePullSecrets:
        - name: aliyun-docker-hub  #提前在项目下配置访问阿里云的账号密码
      containers:
        - image: $REGISTRY/$ALIYUNHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER
 #         readinessProbe:
 #           httpGet:
 #             path: /actuator/health
 #             port: 8080
 #           timeoutSeconds: 10
 #           failureThreshold: 30
 #           periodSeconds: 5
          imagePullPolicy: Always
          name: app
          ports:
            - containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: helloworld
  name: helloworld
  namespace: ruoyi
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: helloworld
  sessionAffinity: None
  type: ClusterIP
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐