在这里插入图片描述

DevOps介绍

DevOps 这个词,其实就是 Development和Operations的组合词组合。它的英文发音是 /de'vɒps/,类似于"迪沃普斯"

DevOps是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动惯例。通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

优势

速度

在这里插入图片描述

高速运转,让您可以更快速地针对客户进行创新、更好地适应不断变化的市场,同时更有效地推动业务成果。DevOps 模式能够帮助您的开发人员和运营团队实现这些目标。例如,微服务持续交付 能够让团队充分掌控服务,然后更快速地发布更新。

img

快速交付

提高发布的频率和速度,以便您能够更快速地进行创新并完善产品。您发布新功能和修复错误的速度越快,就越能快速地响应客户需求并建立竞争优势。持续集成持续交付 是自动执行软件发布流程(从构建到部署)的两项实践经验。

img

可靠性

确保应用程序更新和基础设施变更的品质,以便您能够在保持最终用户优质体验的同时,更加快速可靠地进行交付。使用持续集成持续交付 等实践经验来测试每次变更是否安全以及能够正常运行。监控和日志记录 实践经验能够帮助您实时了解当前的性能。

img

规模

大规模运行和管理您的基础设施及开发流程。自动化和一致性可在降低风险的同时,帮助您有效管理复杂或不断变化的系统。例如,基础设施即代码 能够帮助您以一种可重复且更有效的方式来管理部署、测试和生产环境。

img

增强合作

建立一个适应 DevOps 文化模式的更高效的团队,强调主人翁精神和责任感。开发人员和运营团队密切合作,共同承担诸多责任,并将各自的工作流程相互融合。这有助于减少效率低下的工作,同时节约大家的时间(例如,缩短开发人员和运营团队之间的交接时间,编写将运行环境考虑在内的代码)。

img

安全性

在快速运转的同时保持控制力和合规性。利用自动实施的合规性策略、精细控制和配置管理技术,您可以在不牺牲安全性的前提下采用 DevOps 模式。例如,利用基础设施即代码和策略即代码,您可以大规模定义并追踪合规性。

DevOps 实践经验

最佳实践

持续集成

持续集成

持续集成是一种软件开发实践经验,采用持续集成时,开发人员会定期将他们的代码变更合并到一个中央存储库中,之后系统会自动运行构建和测试操作。持续集成的主要目标是更快发现并解决错误,提高软件质量,并缩短验证和发布新软件更新所需的时间。

持续交付

持续交付

持续交付是一种软件开发实践。通过持续交付,系统可以自动构建和测试代码更改,并为将其发布到生产环境做好准备。持续交付可以在构建阶段后将所有代码变更都部署到测试环境和/或生产环境中,从而实现对持续集成的扩展。当持续交付得以正确实施时,开发人员将始终能够获得一个已通过标准化测试流程的部署就绪型构建工件。

微服务

微服务

微服务架构是一种将单个应用程序构建为一系列小服务的设计方法。其中每个服务均按各自的流程运行,并利用一种轻型机制(通常为基于 HTTP 的应用程序编程接口 (API))通过一个明确定义的接口与其他服务进行通信。微服务围绕着业务能力进行构建,每项服务均限定到单个目的。您可以使用不同的框架或编程语言来编写微服务,并将其作为单个服务或一组服务进行独立部署。

基础设施即代码

基础设施即代码

基础设施即代码是一种实践经验,其中基础设施通过代码和软件部署技术(例如版本控制和持续集成)得以预置和管理。借助 API 驱动型模式,开发人员和系统管理员能够以编程方式与基础设施进行大规模互动,而无需手动设置和配置资源。因此,工程师可以使用基于代码的工具来连接基础设施,并且能够以处理应用程序代码的方式来处理基础设施。基础设施和服务器由代码进行定义,因此可以使用标准化模式进行快速部署、使用最新补丁和版本进行更新,或者以可重复的方式进行复制。

配置管理

开发人员和系统管理员使用代码将操作系统和主机配置、操作性任务等自动化。代码的使用实现了配置变更的可重复性和标准化。它将开发人员和系统管理员从手动配置操作系统、系统应用程序或服务器软件的任务中解放出来。

策略即代码

由于基础设施及其配置全都通过云进行代码编写,所以组织可以动态地大规模监控与实现合规性。因此,组织可以自动跟踪、验证和重新配置由代码描述的基础设施。这样一来,组织能够更加轻松地掌控资源变更,并确保安全措施以分布式方式得到妥善执行(例如,采用 PCI-DSS 或 HIPAA 确保信息安全性或合规性)。这使组织内部的团队能够更快速地运作,因为不合规的资源可能被自动标记为需要进一步调查,甚至被自动纠正为合规资源。

监控和日志记录

监控和日志记录

组织对各项指标和日志进行监控,以了解应用程序和基础设施性能如何影响其产品的最终用户体验。通过对应用程序和基础设施生成的数据进行采集、分类和分析,组织可以了解变更或更新如何影响用户,同时深入了解出现问题或意外变故的根本原因。由于服务必须全天候持续可用,而且应用程序和基础设施的更新频率不断提高,因此主动监控变得日益重要。此外,创建警报或对这些数据执行实时分析也能帮助组织更主动地监控其服务。
沟通与合作

沟通与合作

增强组织内部的沟通与合作是 DevOps 文化的一个重要方面。DevOps 工具的使用和软件交付流程的自动化能够以物理方式将开发和运行的工作流程及职责结合起来,从而建立团队之间的相互协作。在此基础上,这些团队树立了强大的文化规范,提倡信息共享和通过聊天应用程序、问题或项目追踪系统以及 Wikis 来促进沟通。这有助于加快开发人员、运营团队甚至其他团队(如营销团队或销售团队)之间的沟通,从而使组织的各个部门围绕共同的目标和项目更紧密地结合在一起。

常用工具

Jenkins

Jenkins(读:[ˈdʒɛŋkɪnz])是很多软件开发团队在走向 DevOps 时会用的自动化工具。它是开源的 CI/CD 服务器,帮助用户自动化交付流水线的不同阶段。Jenkins 之所以流行的主要原因是其巨大的插件生态系统。目前,它提供 1000 多个插件,因此它可以和几乎所有 DevOps 工具集成
使用 Jenkins 很容易, Docker 安装开箱即用。用户可以通过浏览器搭建并且配置 Jenkins 服务器。如果你是第一次使用它,可以选择安装最常用的插件。当然也可以创建自定义配置。使用 Jenkins 用户可以尽快迭代并部署新代码。它还帮助用户度量流水线里每一步是否成功

Gitlab

GitLab 是一个用于仓库管理系统的开源项目。使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
可通过 Web 界面进行访问公开的或者私人项目。

harbor

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。

Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的LinuxWindows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

Kubernetes

Kubernetes是一种可自动实施 Linux 容器操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。将运行 Linux 容器的多组主机聚集在一起,由 Kubernetes 帮助您轻松高效地管理这些集群。

kuboard

KuboardKubernetes 的一款图形化管理工具,使用Kuboard,用户无需编写YAML 文件,就可以完成应用程序的部署和管理。

微服务部署架构图

在这里插入图片描述

服务器基于 Ubuntu 22.04 版本

实战

安装

jenkins

jenkins 安装

GitLab

GitLab安装

harbor

docker-compose 安装 harbor

Docker 安装

Ubuntu Docker 安装

Kubernetes 安装

Kubernetes 1.24 安装( cri 使用 containerd )

Kuboard 安装

安装 Kuboard v3 - 内建用户库

配置

jenkins 插件

安装 Publish Over SSH 插件

在这里插入图片描述

配置远程部署服务器SSH
在这里插入图片描述

安装NodeJS 插件

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

配置Maven 插件

在这里插入图片描述

kuboard 配置

创建namespace

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

创建harbor仓库secret

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

构建

创建列表视图

在这里插入图片描述

创建自由风格任务

在这里插入图片描述

丢弃旧的构建

只保留30天内,最近10条记录
在这里插入图片描述

参数化构建

docker镜像tag

在这里插入图片描述

docker镜像仓库项目信息

在这里插入图片描述

docker仓库用户名

在这里插入图片描述

docker仓库密码

在这里插入图片描述

docker仓库地址

在这里插入图片描述

k8s 命名空间

在这里插入图片描述

k8s 镜像仓库证书

和 kuboard 中创建harbor仓库secret名称一致
在这里插入图片描述

源码管理

在这里插入图片描述

轮询 SCM

每天构建(如果有提交代码)
在这里插入图片描述

构建环境配置

构建前删除工作空间:保障每次构建前干净的工作空间
日志输出带时间戳
Node和npm配置
![在这里插入图片描述](https://img-blog.csdnimg.cn/411167b63e3541038496d30ac2300fe4.png

前端执行构建

CI
执行yarn build 生成dist

在这里插入图片描述

yarn config set registry https://registry.npm.taobao.org/
yarn install
yarn build
CD
生成docker 镜像,生成 k8s 部署 deployment 和 service 文件

在这里插入图片描述

CONTAINER_NAME="sc-ui"
CURRENT_DATE=$(date +%Y%m%d%H%M%S)

REPOSITORY_PATH=${DOCKER_REPOSITORY_PATH}
USERNAME=${DOCKER_USERNAME}
PASSWORD=${DOCKER_PASSWORD}

PROJECT=${DOCKER_PROJECT}
IMAGES_NAME=${REPOSITORY_PATH}/${PROJECT}/${CONTAINER_NAME}:${DOCKER_IMAGE_TAG}_${CURRENT_DATE}

# 构建Docker镜像
echo "start build Dockerfile"
docker build -t $IMAGES_NAME -f Dockerfile .
echo "end build Dockerfile"

# 推送Docker镜像
echo "start login register"
docker login --username=${USERNAME} --password=${PASSWORD} ${REPOSITORY_PATH}
echo "end login register"

echo "start push"
docker push $IMAGES_NAME
echo "end push"

#删除本地镜像
echo "start rmi"
docker rmi $IMAGES_NAME
echo "end rmi"


echo "start touch deployment.yaml"
touch ${CONTAINER_NAME}-deployment.yaml && echo \
"---\n"\
"apiVersion: apps/v1\n"\
"kind: Deployment\n"\
"metadata:\n"\
"  annotations: {}\n"\
"  labels:\n"\
"    k8s.kuboard.cn/layer: web\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  name: $CONTAINER_NAME\n"\
"  namespace: $K8S_NAMESPACE\n"\
"spec:\n"\
"  progressDeadlineSeconds: 600\n"\
"  replicas: 1\n"\
"  revisionHistoryLimit: 10\n"\
"  selector:\n"\
"    matchLabels:\n"\
"      k8s.kuboard.cn/layer: svc\n"\
"      k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  strategy:\n"\
"    rollingUpdate:\n"\
"      maxSurge: 25%\n"\
"      maxUnavailable: 25%\n"\
"    type: RollingUpdate\n"\
"  template:\n"\
"    metadata:\n"\
"      creationTimestamp: null\n"\
"      labels:\n"\
"        k8s.kuboard.cn/layer: svc\n"\
"        k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"    spec:\n"\
"      containers:\n"\
"        - image: >-\n"\
"            $IMAGES_NAME\n"\
"          imagePullPolicy: IfNotPresent\n"\
"          name: $CONTAINER_NAME\n"\
"          resources: {}\n"\
"          terminationMessagePath: /dev/termination-log\n"\
"          terminationMessagePolicy: File\n"\
"      dnsPolicy: ClusterFirst\n"\
"      imagePullSecrets:\n"\
"        - name: $IMAGE_PULL_SECRETS\n"\
"      restartPolicy: Always\n"\
"      schedulerName: default-scheduler\n"\
"      securityContext: {}\n"\
"      terminationGracePeriodSeconds: 30\n"\
"\n"\
"---\n"\
"apiVersion: v1\n"\
"kind: Service\n"\
"metadata:\n"\
"  annotations: {}\n"\
"  labels:\n"\
"    k8s.kuboard.cn/layer: web\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  name: $CONTAINER_NAME\n"\
"  namespace: $K8S_NAMESPACE\n"\
"spec:\n"\
"  ipFamilies:\n"\
"    - IPv4\n"\
"  ipFamilyPolicy: SingleStack\n"\
"  ports:\n"\
"    - name: sc-ui\n"\
"      nodePort: 5104\n"\
"      port: 30002\n"\
"      protocol: TCP\n"\
"      targetPort: 30002\n"\
"  selector:\n"\
"    k8s.kuboard.cn/layer: svc\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  sessionAffinity: None\n"\
"  type: NodePort\n"\
>> ${CONTAINER_NAME}-deployment.yaml
echo "end touch deployment.yaml"
远程部署服务器,执行部署

选择 远程部署服务器SSH ,把生成的 ${CONTAINER_NAME}-deployment.yaml 文件上传,并在远程机器执行
在这里插入图片描述

sudo chmod 775 /home/david/workspaces/cicd/k8s/sc-ui-deployment.yaml && sudo kubectl apply -f /home/david/workspaces/cicd/k8s/sc-ui-deployment.yaml
构建日志

在这里插入图片描述

构建镜像

在这里插入图片描述

部署结果

使用kuboard查看

kuboard 实战教程

部署(Deployment)

在这里插入图片描述

服务(Service)

在这里插入图片描述

后端执行构建

CI
执行Maven 生成jar

在这里插入图片描述

clean
install -Pdev -Dmaven.test.skip=true
CD
生成docker 镜像,生成 k8s 部署 deployment 和 service 文件

在这里插入图片描述

#!/bin/sh -l
cd sc-gateway

CONTAINER_NAME="sc-gateway"
CONTAINER_PORT=9999
CURRENT_DATE=$(date +%Y%m%d%H%M%S)

REPOSITORY_PATH=${DOCKER_REPOSITORY_PATH}
USERNAME=${DOCKER_USERNAME}
PASSWORD=${DOCKER_PASSWORD}

PROJECT=${DOCKER_PROJECT}
IMAGES_NAME=${REPOSITORY_PATH}/${PROJECT}/${CONTAINER_NAME}:${DOCKER_IMAGE_TAG}_${CURRENT_DATE}

# 构建Docker镜像
echo "start build Dockerfile"
docker build -t $IMAGES_NAME -f Dockerfile .
echo "end build Dockerfile"


# 推送Docker镜像
echo "start login"
docker login --username=${USERNAME} --password=${PASSWORD} ${REPOSITORY_PATH}
echo "end login"

echo "start push"
docker push $IMAGES_NAME
echo "end push"

#删除本地镜像
echo "start rmi"
docker rmi $IMAGES_NAME
echo "end rmi"

echo "start touch deployment.yaml"
touch ${CONTAINER_NAME}-deployment.yaml && echo \
"---\n"\
"apiVersion: apps/v1\n"\
"kind: Deployment\n"\
"metadata:\n"\
"  annotations: {}\n"\
"  labels:\n"\
"    k8s.kuboard.cn/layer: gateway\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  name: $CONTAINER_NAME\n"\
"  namespace: $K8S_NAMESPACE\n"\
"spec:\n"\
"  progressDeadlineSeconds: 600\n"\
"  replicas: 1\n"\
"  revisionHistoryLimit: 10\n"\
"  selector:\n"\
"    matchLabels:\n"\
"      k8s.kuboard.cn/layer: gateway\n"\
"      k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  strategy:\n"\
"    rollingUpdate:\n"\
"      maxSurge: 25%\n"\
"      maxUnavailable: 25%\n"\
"    type: RollingUpdate\n"\
"  template:\n"\
"    metadata:\n"\
"      creationTimestamp: null\n"\
"      labels:\n"\
"        k8s.kuboard.cn/layer: gateway\n"\
"        k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"    spec:\n"\
"      containers:\n"\
"        - image: >-\n"\
"            $IMAGES_NAME\n"\
"          imagePullPolicy: IfNotPresent\n"\
"          name: $CONTAINER_NAME\n"\
"          ports:\n"\
"            - containerPort: $CONTAINER_PORT\n"\
"              name: $CONTAINER_NAME\n"\
"              protocol: TCP\n"\
"          resources:\n"\
"            limits:\n"\
"              memory: 2Gi\n"\
"            requests:\n"\
"              memory: 200Mi\n"\
"          livenessProbe:\n"\
"            failureThreshold: 3\n"\
"            httpGet:\n"\
"              path: /actuator/health\n"\
"              port: $CONTAINER_PORT\n"\
"              scheme: HTTP\n"\
"            periodSeconds: 10\n"\
"            successThreshold: 1\n"\
"            timeoutSeconds: 1\n"\
"          readinessProbe:\n"\
"            failureThreshold: 3\n"\
"            httpGet:\n"\
"              path: /actuator/health\n"\
"              port: $CONTAINER_PORT\n"\
"              scheme: HTTP\n"\
"            periodSeconds: 10\n"\
"            successThreshold: 1\n"\
"            timeoutSeconds: 1\n"\
"          startupProbe:\n"\
"            failureThreshold: 20\n"\
"            httpGet:\n"\
"              path: /actuator/health\n"\
"              port: $CONTAINER_PORT\n"\
"              scheme: HTTP\n"\
"            initialDelaySeconds: 30\n"\
"            periodSeconds: 10\n"\
"            successThreshold: 1\n"\
"            timeoutSeconds: 1\n"\
"          terminationMessagePath: /dev/termination-log\n"\
"          terminationMessagePolicy: File\n"\
"      dnsPolicy: ClusterFirst\n"\
"      imagePullSecrets:\n"\
"        - name: $IMAGE_PULL_SECRETS\n"\
"      restartPolicy: Always\n"\
"      schedulerName: default-scheduler\n"\
"      securityContext: {}\n"\
"      terminationGracePeriodSeconds: 30\n"\
"\n"\
"---\n"\
"apiVersion: v1\n"\
"kind: Service\n"\
"metadata:\n"\
"  annotations: {}\n"\
"  labels:\n"\
"    k8s.kuboard.cn/layer: gateway\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  name: $CONTAINER_NAME\n"\
"  namespace: $K8S_NAMESPACE\n"\
"spec:\n"\
"  externalTrafficPolicy: Cluster\n"\
"  internalTrafficPolicy: Cluster\n"\
"  ipFamilies:\n"\
"    - IPv4\n"\
"  ipFamilyPolicy: SingleStack\n"\
"  ports:\n"\
"    - name: $CONTAINER_NAME\n"\
"      nodePort: $CONTAINER_PORT\n"\
"      port: $CONTAINER_PORT\n"\
"      protocol: TCP\n"\
"      targetPort: $CONTAINER_PORT\n"\
"  selector:\n"\
"    k8s.kuboard.cn/layer: gateway\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  sessionAffinity: None\n"\
"  type: NodePort\n"\
"---\n"\
"apiVersion: networking.k8s.io/v1\n"\
"kind: Ingress\n"\
"metadata:\n"\
"  annotations: {}\n"\
"  labels:\n"\
"    k8s.kuboard.cn/layer: gateway\n"\
"    k8s.kuboard.cn/name: $CONTAINER_NAME\n"\
"  name: $CONTAINER_NAME\n"\
"  namespace: $K8S_NAMESPACE\n"\
"spec:\n"\
"  ingressClassName: nginx\n"\
"  rules:\n"\
"    - host: k8s.yunloong.cn\n"\
"      http:\n"\
"        paths:\n"\
"          - backend:\n"\
"              service:\n"\
"                name: $CONTAINER_NAME\n"\
"                port:\n"\
"                  number: $CONTAINER_PORT\n"\
"            path: /$CONTAINER_NAME\n"\
"            pathType: Prefix\n"\
"  tls:\n"\
"    - hosts:\n"\
"        - k8s.yunloong.cn\n"\
"      secretName: k8s.yunloong.cntls\n"\
>> ${CONTAINER_NAME}-deployment.yaml
echo "end touch deployment.yaml"
远程部署服务器,执行部署

选择 远程部署服务器SSH ,把生成的 ${CONTAINER_NAME}-deployment.yaml 文件上传,并在远程机器执行
在这里插入图片描述

sudo chmod 775 /home/david/workspaces/cicd/k8s/sc-gateway-deployment.yaml && sudo kubectl apply -f /home/david/workspaces/cicd/k8s/sc-gateway-deployment.yaml
构建日志

在这里插入图片描述

构建镜像

在这里插入图片描述

部署结果

使用kuboard查看

部署(Deployment)

在这里插入图片描述

服务(Service)

在这里插入图片描述

参考 在-k8s-上部署-springblade
jenkins + docker 自动部署

Logo

开源、云原生的融合云平台

更多推荐