5.云原生之DevOps和CICD

发布时间:2024年01月04日


怎么理解DevOps?

DevOps是Development (开发)和Operations (运维)的组合,是一种方法论,是一组过程、方法与系统的统称,用于促进应用开发、应用运维和质量保障(QA)部门之间的沟通、协作与整合,一起打破传统开发和运营之间的壁垒和鸿沟;

DevOps是一种重视软件开发人员(Dev)和IT运维技术人员(Ops)之间沟通合作的文化、运动或惯例,通过自动化软件交付和架构变更的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠;具体来说,就是在软件交付和部署过程中提高沟通与协作的效率,旨在更快、更可靠的的发布更高质量的产品;

也就是说 DevOps 是一组过程和方法的统称,并不指代某一特定的软件工具或软件工具组合;各种工具软件或软件组合可以实现DevOps的概念方法,其本质是一整套的方法论,而不是指某种或某些工具集合,与软件开发中设计到的OOP, AOP, IOC (或DI)等类似,是一种理论或过程或方法的抽象或代称。

总结:DevOps是打破开发、运维、QA之间屏障的方法论,实现基于CICD,CICD落地实现基于gitlab和jenkins
学习参考:为什么大厂都在做DevOps,和CICD有什么关系?

所需环境介绍

工具简介
JenkinsJenkins 是一个开源的持续集成和持续交付工具,可用于自动化构建、测试和部署软件。Jenkins 提供了丰富的插件生态系统,可以与各种工具和技术进行集成。Jenkins 的主要优点是易于安装和使用,支持广泛的编程语言和操作系统。
SonarQubeSonarQube 是一个开源的代码质量管理平台,可用于检测代码缺陷、漏洞和代码规范违规等问题。SonarQube 提供了丰富的代码分析和报告功能,可以帮助开发团队提高代码质量和可维护性。SonarQube 的主要优点是易于安装和使用,支持多种编程语言和集成工具。
GitLabGitLab 是一个基于 Git 的开源代码托管和协作平台,提供了代码管理、问题跟踪、持续集成和部署等功能。GitLab 还包括一个内置的 CI/CD 工具,可以自动化构建、测试和部署软件。GitLab 的主要优点是集成度高、易于使用、支持自托管和云托管等多种部署方式。
NexusNexus 是一个开源的 Maven 仓库管理器,用于存储和分发软件包和依赖项。Nexus 支持多种软件包管理格式,包括 Maven、npm、Docker 等。Nexus 还提供了一些高级功能,如安全漏洞扫描、仓库清理、仓库镜像等。Nexus 的主要优点是易于安装和使用、支持多种软件包管理格式、提供了丰富的管理功能。
HarborHarbor 是一个开源的 Docker 镜像仓库管理器,用于存储和分发 Docker 镜像。Harbor 提供了一些高级功能,如安全漏洞扫描、镜像复制、访问控制等。Harbor 还支持多种身份验证和授权机制,可以与 Kubernetes 等容器编排平台进行集成。Harbor 的主要优点是易于安装和使用、提供了丰富的管理功能、支持多种身份验证和授权机制。

创建devops java项目

image.png

不同企业中项目目录结构存在差异,该差异影响Jenkinsfile流水线文件中的内容,该项目采取比较通用的多模块项目,项目只存在二级模块。

DockerFile文件

# 只包含了Java运行时环境和一些基本的工具,没有Java编译器和其他开发工具
FROM java:openjdk-8-jre-alpine

#作者
MAINTAINER zw <1293780497@qq.com>
#系统编码
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
#声明一个挂载点,容器内此路径会对应宿主机的某个文件夹
# VOLUME /tmp
#应用构建成功后的jar文件被复制到镜像内,名字也改成了app.jar
ADD target/*.jar app.jar
#启动容器时的进程并制定启动超参数
ENTRYPOINT ["java","-jar","/app.jar","--spring.profiles.active=dev", "--server.port=8080"]
#暴露8080端口
EXPOSE 8080

openjdk:8u201-jdk-alpine3.9 和 java:openjdk-8-jre-alpine、openjdk:8-jdk 是两个不同的 OpenJDK 8 镜像,它们之间存在以下区别:

  1. 镜像内容:
    • openjdk:8u201-jdk-alpine3.9 使用的是 Alpine Linux 3.9 版本作为基础镜像,而 openjdk:8-jdk 使用的是 Debian 或 Ubuntu 等常见的 Linux 发行版作为基础镜像。
    • openjdk:8u201-jdk-alpine3.9 是一个包含完整的 JDK(Java Development Kit)的镜像。它包含了编译、调试和运行 Java 应用程序所需的工具和库。
    • java:openjdk-8-jre-alpine 是一个只包含 JRE(Java Runtime Environment)的镜像。它适用于仅需要运行 Java 应用程序的场景,不包含编译和调试工具,只提供 Java 运行时环境。
  2. 镜像大小:
    • openjdk:8u201-jdk-alpine3.9 是一个基于 Alpine Linux 的轻量级镜像,因此它的镜像大小通常比 java:openjdk-8-jre-alpine 要大一些。这是因为完整的 JDK 镜像需要包含更多的工具和库。
    • java:openjdk-8-jre-alpine 是一个只包含 JRE 的轻量级镜像,因此它的镜像大小通常比 openjdk:8u201-jdk-alpine3.9 要小一些。
  3. 功能用途:
    • openjdk:8u201-jdk-alpine3.9 适用于开发和构建 Java 应用程序的场景。它提供了完整的 JDK 功能,包括编译、调试和运行 Java 代码所需的工具和库。
    • java:openjdk-8-jre-alpine 适用于仅需要运行 Java 应用程序的场景。它只提供 Java 运行时环境,不包含编译和调试工具。

Jenkinsfile

pipeline {
    agent {
        node {
            label 'maven'
        }

    }
    stages {
        stage('拉取代码') {
            agent none
            steps {
                container('maven') {
                    git(url: 'http://gitlab.base.svc.cluster.local/root/devops-sample.git', credentialsId: 'gitlab-id', branch: 'master', changelog: true, poll: false)
                    sh 'ls -al'
                }
            }
        }

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

            }
        }

        stage('并行构建镜像') {
            parallel {
                stage('构建devops-service镜像') {
                    agent none
                    steps {
                        container('maven') {
                            sh 'ls devops-service/target'
                            sh 'docker build -t devops-service:latest -f devops-service/Dockerfile  ./devops-service/'
                        }

                    }
                }
                stage('构建devops-web镜像') {
                    agent none
                    steps {
                        container('maven') {
                            sh 'ls devops-web/target'
                            sh 'docker build -t devops-web:latest -f devops-web/Dockerfile  ./devops-web/'
                        }

                    }
                }

            }
        }


       stage('并行推送镜像') {
            parallel {
                stage('推送devops-service镜像') {
                    agent none
                    steps {
                        container('maven') {
                            sh 'docker login -u harbor仓库账号 -p harbor仓库密码 harbor仓库地址'
                            sh 'docker tag devops-service:latest harbor仓库地址/library/devops-service:SNAPSHOT-$BUILD_NUMBER'
                            sh 'docker push harbor仓库地址/library/devops-service:SNAPSHOT-$BUILD_NUMBER'
                        }

                    }
                }
                stage('推送devops-web镜像') {
                    agent none
                    steps {
                        container('maven') {
                            sh 'docker login -u harbor仓库账号 -p harbor仓库密码 harbor仓库地址'
                            sh 'docker tag devops-web:latest harbor仓库地址/library/devops-web:SNAPSHOT-$BUILD_NUMBER'
                            sh 'docker push harbor仓库地址/library/devops-web:SNAPSHOT-$BUILD_NUMBER'
                        }
                    }
                }
            }
        }

        stage('并行部署') {
            parallel {
                stage('devops-service - 部署到devops环境') {
                  steps {
                    container ('maven') {
                        withCredentials([
                            kubeconfigFile(
                            credentialsId: env.KUBECONFIG_CREDENTIAL_ID,
                            variable: 'KUBECONFIG')
                            ]) {
                            sh 'docker login -u harbor仓库账号 -p harbor仓库密码 harbor仓库地址'
                            sh 'envsubst < devops-service/deploy.yml | kubectl apply -f -'
                        }
                    }
                  }
                }
                 stage('devops-web - 部署到devops环境') {
                    steps {
                        container ('maven') {
                            withCredentials([
                                kubeconfigFile(
                                credentialsId: env.KUBECONFIG_CREDENTIAL_ID,
                                variable: 'KUBECONFIG')
                                ]) {
                                sh 'docker login -u harbor仓库账号 -p harbor仓库密码 harbor仓库地址'
                                sh 'envsubst < devops-web/deploy.yml | kubectl apply -f -'
                            }
                        }
                    }
                 }
            }
        }

        //1、配置全系统的邮件:                   全系统的监控
        //2、修改ks-jenkins的配置,里面的邮件;   流水线发邮件
        stage('发送确认邮件') {
            agent none
            steps {
                mail(to: '1293780497@qq.com', subject: '构建结果', body: "构建成功了  $BUILD_NUMBER")
                sh 'echo 部署镜像: $REGISTRY/$HARBOR_NAMESPACE/devops-service:SNAPSHOT-$BUILD_NUMBER'
                sh 'echo 部署镜像: $REGISTRY/$HARBOR_NAMESPACE/devops-web:SNAPSHOT-$BUILD_NUMBER'
            }
        }

    }
    environment {
        GITHUB_ACCOUNT = 'kubesphere'
        APP_NAME = 'devops-devops'

        // 镜像仓库地址
        REGISTRY = 'harbor仓库地址'
        //  HARBOR命名空间,镜像上传位置
        HARBOR_NAMESPACE = 'devops'
        //  harbor凭证
        HARBOR_ID = 'harbor-id'
        KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    }
    parameters {
        string(name: 'TAG_NAME', defaultValue: '', description: '')
    }
}

devops.yaml文件

# 指定了使用的 Kubernetes API 版本为 apps/v1,表示这是一个应用程序相关的资源。
apiVersion: apps/v1
# 定义了资源类型为 Deployment,表示创建一个 Deployment 对象。
kind: Deployment
# 包含了关于 Deployment 的元数据信息,如标签和名称等。
metadata:
  # 用于标识 Deployment 的标签,这里设置了一个名为 app 的标签,值为 devops-web。
  labels:
    app: devops-web
  # 指定 Deployment 的名称为 devops-web
  name: devops-web
  # 指定 Deployment 所属的命名空间为 devops,命名空间用于对 Kubernetes 资源进行隔离和组织。
  namespace: devops   #一定要写名称空间
# 定义了 Deployment 的规格,包含了部署相关的配置信息。
spec:
  # 设置了 Deployment 的进度截止时间为 600 秒,超过该时间仍未完成部署则认为部署失败。
  progressDeadlineSeconds: 600
  # 指定了 Deployment 的副本数为 1,表示只创建一个 Pod 实例。
  replicas: 1
  # 通过标签选择器来选择要进行部署的 Pod,这里选择了标签为 app=devops-web 的 Pod。
  selector:
    matchLabels:
      app: devops-web
  # 定义了 Deployment 的更新策略,这里使用了滚动更新策略。
  strategy:
    # 定了滚动更新的配置,包括最大并发升级数和最大不可用实例数。
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
    #  RollingUpdate: 指定了更新策略的类型为滚动更新。
    type: RollingUpdate
  # 定义了要创建的 Pod 的模板。
  template:
    # 包含了 Pod 模板的元数据信息,如标签等。
    metadata:
      # 设置了 Pod 的标签,与 Deployment 的标签一致。
      labels:
        app: devops-web
    # 定义了 Pod 的规格,包含了容器、资源限制等配置信息
    spec:
      # 定义了用于拉取镜像的密钥,这里使用了名为 harbor-id 的密钥。
      imagePullSecrets:
        #提前在项目下配置访问harbor的账号密码
        - name: harbor-id
      # 定义了要在 Pod 中运行的容器列表
      containers:
        #  指定了容器的镜像,使用了变量 $REGISTRY 和 $HARBOR_NAMESPACE,以及构建号变量 $BUILD_NUMBER。
        - image: $REGISTRY/$HARBOR_NAMESPACE/devops-web:SNAPSHOT-$BUILD_NUMBER
 #         readinessProbe: # 定义了容器的就绪探针,用于检查容器是否已准备好接收流量。
 #           httpGet: # 指定了就绪探针的类型为 HTTP GET 请求,表示通过发送 HTTP GET 请求来检查容器的就绪状态。
 #             path: /actuator/health # 指定了要发送的 HTTP GET 请求的路径为 /actuator/health,即检查容器的健康检查端点。
 #             port: 8080 # 指定了要发送 HTTP GET 请求的目标端口为 8080,即容器的监听端口。
 #           timeoutSeconds: 10 # 设置了就绪探针的超时时间为 10 秒,即如果在 10 秒内没有收到响应,则认为探针失败
 #           failureThreshold: 30 # 设置了就绪探针的失败阈值为 30,即如果连续 30 次探针都失败,则认为容器不可用。
 #           periodSeconds: 5 # 设置了就绪探针的检查周期为 5 秒,即每隔 5 秒发送一次就绪探针。
          # 设置了镜像拉取策略为始终拉取
          imagePullPolicy: Always
          # 指定了容器的名称为 app
          name: app
          #  定义了容器暴露的端口信息,这里暴露了 TCP 端口 8080
          ports:
            - containerPort: 8080
              protocol: TCP
          # 设置了容器的资源限制,包括 CPU 和内存
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
          # 设置了容器终止时的消息输出路径。
          terminationMessagePath: /dev/termination-log
          # 设置了容器终止消息的输出策略为文件
          terminationMessagePolicy: File
      # 设置了 Pod 的 DNS 策略为 ClusterFirst,表示优先使用集群内部的 DNS 解析服务。
      dnsPolicy: ClusterFirst
      # 设置了 Pod 的重启策略为始终重启
      restartPolicy: Always
      # 设置了 Pod 终止时的优雅终止期限为 30 秒
      terminationGracePeriodSeconds: 30
---
# 指定了使用的 Kubernetes API 版本为 v1,表示这是一个核心 API 的资源。
apiVersion: v1
# 定义了资源类型为 Service,表示创建一个 Service 对象。
kind: Service
# 包含了关于 Service 的元数据信息,如标签和名称等。
metadata:
  # 用于标识 Service 的标签,这里设置了一个名为 app 的标签,值为 devops-web。
  labels:
    app: devops-web
  # 指定 Service 的名称为 devops-web。
  name: devops-web
  # 指定 Service 所属的命名空间为 devops,命名空间用于对 Kubernetes 资源进行隔离和组织。
  namespace: devops
# 定义了 Service 的规格,包含了服务相关的配置信息
spec:
  # 定义了 Service 暴露的端口信息
  ports:
    # 指定了端口的名称为 http
    - name: http
      # 指定了 Service 监听的端口为 80
      port: 80
      # 指定了端口的协议为 TCP
      protocol: TCP
      # 指定了将流量转发到后端 Pod 的目标端口为 8080
      targetPort: 8080
  # 通过标签选择器来选择要关联的后端 Pod,这里选择了标签为 app=devops-web 的 Pod
  selector:
    app: devops-web
  # 设置了会话亲和性为 None,表示每次请求都可被转发到不同的后端 Pod
  sessionAffinity: None
  # 设置了 Service 的类型为 ClusterIP,表示创建一个集群内部可访问的虚拟 IP 地址
  type: ClusterIP

搭建 DevOps 项目

创建凭证

image.png

  1. harbor-id
  2. sonar-token
  3. demo-kubeconfig
  4. gitlab-id:y_mcG4HwMzJVbtaKM2yD

创建devops项目

image.png

创建流水线

image.pngimage.png

编写流线文件

  1. 进入流水线项目

image.png

  1. 编辑流水线

image.png

  1. 拷贝java项目中流水线文件内容

image.png

  1. 点击确定生成可视化流水线

image.png

运行流线

image.png
查看日志进行调试:
image.png
当流水线运行成功后生成运行记录
image.png发布成功后会将项目发布到发布文件中指定的空间中 image.png

为流水线设置电子邮箱服务器

为 KubeSphere 流水线设置电子邮件服务器

设置QQ邮箱 SMTP服务器

  1. 登录qq邮箱->左上角设置->点击账号

image.png

  1. 向下滚动找到SMTP,扫码获取授权码

image.png

  • SMTP服务器:smtp.qq.com
  • SMTP端口号:465。必须填这个端口号,否则会报错。
  • 身份认证用户名:填完整的邮箱名,如:123456789@qq.com,包括@qq.com部分。
  • 身份认证密码:填上述的QQ邮箱授权码。注意,不是QQ邮箱的登录密码。
  • SMTP身份认证。选“是”。
  • SSL加密。选“是”。

配置jenkins邮箱服务器

image.png
找到如下内容修改

环境变量名称描述信息QQ邮箱服务
EMAIL_SMTP_HOSTSMTP 服务器地址smtp.qq.com
EMAIL_SMTP_PORTSMTP 服务器端口(如:25)465
EMAIL_FROM_ADDR电子邮件发件人地址1xxx97@qq.com
EMAIL_FROM_NAME电子邮件发件人姓名野心与梦
EMAIL_FROM_PASS电子邮件发件人密码bvbfxahppskajibc
EMAIL_USE_SSL是否启用 SSL 配置true

使用Webhook触发流水线

使用 Webhook 触发流水线
Generic Webhook Trigger

jenkins配置gitlab凭证

  1. 创建gitlab的token:y_mcG4HwMzJVbtaKM2yD
  2. 登录jenkins->左侧菜单:系统管理->向下滚动找到系统配置
  3. 找到gitlab server相关配置

image.png

  1. 添加凭证

image.png
image.png
令牌填写gitlab中生成的token
image.png

  1. 勾选Web Hook

image.png

Secrent Token设置(可选)

  1. 验证连通性

点击测试连接,出现Credentials verified for user root表示验证了用户root的凭据
image.png

  1. 最后单击保存

jenkins中配置webhook

  1. 选择jenkins中要配置webhook的项目

image.png

  1. 点击配置进行构建配置

image.png

gitlab中配置web hook

  1. 开启外部请求

image.png

  1. 配置项目webhook

image.png

  1. 测试自动发布

gitlab webhook配置页测试
image.png
修改gitlab中代码
本地修改提交

image.png

文章来源:https://blog.csdn.net/weixin_45690643/article/details/135392607
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。