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 的主要优点是易于安装和使用、提供了丰富的管理功能、支持多种身份验证和授权机制。 |
不同企业中项目目录结构存在差异,该差异影响Jenkinsfile流水线文件中的内容,该项目采取比较通用的多模块项目,项目只存在二级模块。
# 只包含了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 镜像,它们之间存在以下区别:
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: '')
}
}
# 指定了使用的 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
查看日志进行调试:
当流水线运行成功后生成运行记录
发布成功后会将项目发布到发布文件中指定的空间中
- SMTP服务器:smtp.qq.com
- SMTP端口号:465。必须填这个端口号,否则会报错。
- 身份认证用户名:填完整的邮箱名,如:123456789@qq.com,包括@qq.com部分。
- 身份认证密码:填上述的QQ邮箱授权码。注意,不是QQ邮箱的登录密码。
- SMTP身份认证。选“是”。
- SSL加密。选“是”。
找到如下内容修改
环境变量名称 | 描述信息 | QQ邮箱服务 |
---|---|---|
EMAIL_SMTP_HOST | SMTP 服务器地址 | smtp.qq.com |
EMAIL_SMTP_PORT | SMTP 服务器端口(如:25) | 465 |
EMAIL_FROM_ADDR | 电子邮件发件人地址 | 1xxx97@qq.com |
EMAIL_FROM_NAME | 电子邮件发件人姓名 | 野心与梦 |
EMAIL_FROM_PASS | 电子邮件发件人密码 | bvbfxahppskajibc |
EMAIL_USE_SSL | 是否启用 SSL 配置 | true |
使用 Webhook 触发流水线
Generic Webhook Trigger
令牌填写gitlab中生成的token
Secrent Token设置(可选)
点击测试连接,出现Credentials verified for user root表示验证了用户root的凭据
gitlab webhook配置页测试
修改gitlab中代码
本地修改提交