5.云原生之DevOps和CICD

文章目录

  • 怎么理解DevOps?
  • 所需环境介绍
  • 创建devops java项目
    • DockerFile文件
    • Jenkinsfile
    • devops.yaml文件
  • 搭建 DevOps 项目
    • 创建凭证
    • 创建devops项目
    • 创建流水线
    • 编写流线文件
    • 运行流线
  • 为流水线设置电子邮箱服务器
    • 设置QQ邮箱 SMTP服务器
    • 配置jenkins邮箱服务器
  • 使用Webhook触发流水线
    • jenkins配置gitlab凭证
    • jenkins中配置webhook
    • gitlab中配置web hook

怎么理解DevOps?

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

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

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

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

所需环境介绍

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

创建devops java项目

5.云原生之DevOps和CICD_第1张图片

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

DockerFile文件

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

#作者
MAINTAINER zw <[email protected]>
#系统编码
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 项目

创建凭证

5.云原生之DevOps和CICD_第2张图片

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

5.云原生之DevOps和CICD_第3张图片

创建devops项目

5.云原生之DevOps和CICD_第4张图片

创建流水线

5.云原生之DevOps和CICD_第5张图片5.云原生之DevOps和CICD_第6张图片

编写流线文件

  1. 进入流水线项目

5.云原生之DevOps和CICD_第7张图片

  1. 编辑流水线

5.云原生之DevOps和CICD_第8张图片

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

5.云原生之DevOps和CICD_第9张图片

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

5.云原生之DevOps和CICD_第10张图片

运行流线

5.云原生之DevOps和CICD_第11张图片
查看日志进行调试:
5.云原生之DevOps和CICD_第12张图片
当流水线运行成功后生成运行记录
5.云原生之DevOps和CICD_第13张图片发布成功后会将项目发布到发布文件中指定的空间中 5.云原生之DevOps和CICD_第14张图片

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

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

设置QQ邮箱 SMTP服务器

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

5.云原生之DevOps和CICD_第15张图片

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

5.云原生之DevOps和CICD_第16张图片

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

配置jenkins邮箱服务器

5.云原生之DevOps和CICD_第17张图片
找到如下内容修改

环境变量名称 描述信息 QQ邮箱服务
EMAIL_SMTP_HOST SMTP 服务器地址 smtp.qq.com
EMAIL_SMTP_PORT SMTP 服务器端口(如:25) 465
EMAIL_FROM_ADDR 电子邮件发件人地址 [email protected]
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相关配置

5.云原生之DevOps和CICD_第18张图片

  1. 添加凭证

5.云原生之DevOps和CICD_第19张图片
5.云原生之DevOps和CICD_第20张图片
令牌填写gitlab中生成的token
5.云原生之DevOps和CICD_第21张图片

  1. 勾选Web Hook

5.云原生之DevOps和CICD_第22张图片

Secrent Token设置(可选)

  1. 验证连通性

点击测试连接,出现Credentials verified for user root表示验证了用户root的凭据
5.云原生之DevOps和CICD_第23张图片

  1. 最后单击保存

jenkins中配置webhook

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

5.云原生之DevOps和CICD_第24张图片

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

5.云原生之DevOps和CICD_第25张图片

gitlab中配置web hook

  1. 开启外部请求

5.云原生之DevOps和CICD_第26张图片

  1. 配置项目webhook

5.云原生之DevOps和CICD_第27张图片

  1. 测试自动发布

gitlab webhook配置页测试
5.云原生之DevOps和CICD_第28张图片
修改gitlab中代码
本地修改提交

5.云原生之DevOps和CICD_第29张图片

你可能感兴趣的:(私有云搭建实战,云原生,devops,servlet)