使用 GitOps 进行防灾 MinIO

想象一下,您已经花费了无数小时来完善 Docker Swarm 设置,精心设计每项服务,并调整 CI/CD 管道以实现无缝自动化。现在,想象一下这个经过微调的系统被重置为原点,不是因为严重的故障或安全漏洞,而是因为数据中心工程师在硬件上按下神奇的“恢复出厂设置”的天真好奇心。这不是DevOps恐怖故事的开端,而是证明了精心设计的存储库和GitOps原则所实现的弹性和快速恢复。

在本文中,我们将深入探讨作为DevOps核心的自动化和冗余如何在重置可能带来灾难的情况下被证明是救星。我将分享 Docker、GitHub Actions 和 MinIO 的组合,以及意想不到的真实世界试验,强调了可靠且可重复的构建和部署过程的重要性。

通过这次体验,我们将探索版本控制配置的强大功能以及将映像推送到多个注册表的远见卓识,确保即使面对完整的系统擦除,恢复也只需几个命令即可完成。和我一起探索DevOps中弹性的深度,说明你如何保护你的系统,以应对生活可能给你带来的意外。

冗余和自动化的重要性

冗余和自动化是现代 DevOps 实践的基本支柱,对于保持连续性和确保高可用性至关重要。将 Docker 映像双重推送到 Docker Hub 和 GitHub Container Registry (GHCR.io) 的战略决策是由经过计算的风险管理和可访问性方法驱动的。

Docker Hub 作为主要的工件注册表,提供广泛的集成和公共可见性,用于广泛的分发和协作。它是即时项目检索和部署的首选注册表。但是,依赖单个注册表是一个漏洞;任何服务中断都可能停止部署和更新,从而导致潜在的停机。

相比之下,GHCR.io 默认情况下为 Docker 映像提供安全的专用存储解决方案,这与对某些部署工件的受控访问需求相一致。此注册表成为战略备份,确保即使 Docker Hub 遭到入侵或不可用,也有一个即时回退选项,而不会对 CI/CD 管道造成任何中断。

映像的自动化通过 GitHub Actions 推送到两个注册表。它确保最新版本始终可以从任一来源进行部署,从而有效地防止服务中断。这种有条不紊的冗余不是创建不必要的副本,而是以最短的恢复时间为突发事件做好准备。

在存储库所在的 GitHub 上构建,同时推送到两个注册表背后的逻辑很简单:它提供了一种无缝、自动化的方式来维护所有映像的专用备份,同时使公共注册表保持最新状态。这种双重方法是一种主动措施——精心设计的 DevOps 流程必须以战略冗余为核心。

针对复原能力的存储库增强功能

在追求弹性 DevOps 环境的过程中,持续改进至关重要。对原始存储库所做的增强既是反思性的,也是先发制人的,不仅旨在满足恢复需求,还旨在简化流程以满足任何未来的部署需求。

首先,对工作流程配置进行了细化,定义了每个作业和步骤,以确保效率和可靠性。为此,该 .github/workflows 目录丰富了用于多平台构建的新工作流,从而扩展了存储库的自动化功能。此设置不仅有助于一致的部署,还可以确保最新版本的应用程序已准备好从 Docker Hub 或 GHCR.io 中拉取。

在 cda-deploy-to-swarm 存储库中,该结构经过精心设计,以实现快速导航和易用性。该目录包括:

  • .github/workflows 文件夹,其中包含 CI/CD 自动化脚本。在这里,YAML 文件定义了在推送和拉取请求上运行的操作,包括生成和推送操作以及部署业务流程。

  • minio 目录包含为 MinIO 服务量身定制的自定义配置和 Docker Compose 文件,允许快速、标准化地设置对象存储功能。

  • nginx 目录设置了用于部署 NGINX Web 服务器的配置,有助于处理 HTTP 请求和充当反向代理。

  • weaviate 目录,其中包含部署 Weaviate 向量搜索引擎所需的元素,利用 Docker Compose 进行服务定义和部署。

  • 存储库根的核心是 docker-compose.yaml 文件,它定义了多容器应用程序服务,并将各个组件绑定在一个有凝聚力的整体中。

每一项改进和结构决策都是为了创建一个存储库,该存储库不仅可以从中断中恢复过来,而且还可以作为在 Docker Swarm 环境中部署服务的模块化、可扩展的基础。存储库结构的清晰度和组织性有助于快速识别组件和配置,从而减少恢复时间并促进部署过程的有效管理。有关本文中提到的特定文件的详细信息,请访问 MinIO 博客资产存储库。

使用 GitHub Actions 和 Docker Compose 实现高效的 CI/CD

在我们的 DevOps 工作流程中,GitHub Actions 在自动化 Docker 映像的构建过程方面发挥着关键作用,包括我们的自定义 MinIO 和 Weaviate 服务。这些操作配置为在特定事件(例如推送到主分支)时触发,确保每个更改都无缝集成到我们的部署管道中。

以下是该过程的展开方式:

1 . **GitHub Actions 工作流:**提交到存储库后,将启动我们的 GitHub Actions 工作流。这些工作流包含使用自定义 Dockerfile 构建 Docker 映像并将其推送到注册表的作业。这些图像被适当地标记,例如, cdaprod/cda-minio:latest .

2 . **用于部署的 Docker Compose:**在构建和推送过程之后, docker-compose.yaml 文件开始用于部署。它配置为从注册表中提取最新映像,以便在 Docker Swarm 环境中进行服务部署。

docker-compose.yaml 文件包含如下服务定义:

version: '3.8'

services:
  minio:
    image: cdaprod/cda-minio:latest
    # Other configurations ...

 weaviate:
    image: cdaprod/cda-weaviate:latest
    # Other configurations ...

 nginx:
    image: cdaprod/cda-nginx:latest
    # Other configurations ...

networks:
  app_network:
    driver: overlay

# Other definitions like volumes and secrets…

此方法通过分离映像构建和服务部署过程,大大简化了我们的部署策略。这也意味着我们不需要为不同的环境或场景提供多个 docker-compose 文件。

通过利用此 CI/CD 策略,我们能够为服务定义维护单一事实来源,并确保我们的部署过程尽可能简化和高效。我们的部署变成了一个自托管运行器,从我们的 GitHub Actions 工作流中执行一个docker-compose up command,剩下的工作由 Docker Compose 处理——拉取最新的映像、启动服务,并确保它们完全按照我们的定义进行配置。

使用 MinIO 说明自定义映像构建

为了进一步阐明 CI/CD 管道的构建过程,让我们仔细看看 MinIO 服务映像的自定义。我们的 GitHub Actions 工作流负责根据官方 minio/minio:latest 构建此映像,并根据我们的要求定制其他配置。

下面是概述生成步骤的 /minio/Dockerfile:

# Start with the official MinIO image as a base
ARG BASE_IMAGE=minio/minio:latest
FROM $BASE_IMAGE


# Copy over the custom entrypoint script
COPY entrypoint.sh /entrypoint.sh
# Ensure the script is executable
RUN chmod +x /entrypoint.sh


# Expose the ports MinIO will use
EXPOSE 9000 9001


# Use the custom entrypoint script to start MinIO
ENTRYPOINT ["/entrypoint.sh"]

使用入口点脚本增强自定义

自定义过程不会以 Dockerfile 。为了完全根据我们的运营需求定制我们的 MinIO 服务,我们利用了一个 entrypoint.sh 脚本。此脚本在容器启动时充当命令中心,执行预定义的命令,以配置超出默认设置的 MinIO 实例。

使用 entrypoint.sh 脚本的美妙之处在于它能够执行运行时配置。这些对于动态设置我们的环境至关重要,确保我们的 MinIO 服务不仅仅是一个普通的部署,而是为我们的用例定制的部署。

这种将 Dockerfile entrypoint.sh 脚本相结合的方法使我们能够构建容器,这些容器不仅在构建时考虑了我们的应用程序和服务,而且在部署它们时就可以在我们独特的生态系统中运行。

#!/bin/sh
set -e

# Start MinIO in the background
minio server /data --console-address ":9001" &

# Wait for the MinIO server to start
sleep 5

# Configure MinIO with the mc (MinIO Client) tool
mc alias set myminio http://localhost:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD}

# Before creating buckets, check if they already exist
if ! mc ls myminio/weaviate-backups; then
  mc mb myminio/weaviate-backups
fi

if ! mc ls myminio/cda-datasets; then
  mc mb myminio/cda-datasets
fi

# Keep the container running
tail -f /dev/null

Dockerfile 官方 MinIO 映像指定为基础,然后添加我们的自定义 entrypoint.sh 脚本。此脚本至关重要,因为它在启动后运行其他命令来配置 MinIO,例如使用 MinIO 客户端 ( mc ) 创建必要的存储桶。

在由我们的工作流程触发的图像构建阶段,我们使用它 Dockerfile 来创建 cdaprod/cda-minio:latest 图像。此映像封装了我们的自定义设置和脚本,该 docker-compose.yaml 文件稍后将使用这些设置和脚本在 Docker Swarm 中部署 MinIO 服务。

cdaprod/cda-minio:latest 之间的区别 minio/minio:latest 很小。前者是 MinIO 官方 Docker Hub 存储库中未更改的基础映像,而后者是我们的自定义版本,通过我们的 CI/CD 工作流构建和维护,确保任何特定配置和脚本都融入到我们部署的映像中。

深入了解工作流程

两个 GitHub Actions 工作流(构建和推送 Docker 映像和部署服务)构成了存储库中的核心自动化机制。以下是对每个方法的扩展解释。

构建和推送 Docker 映像工作流

此工作流在任何推送或 pull_request 分支 main 上触发,以确保最新的代码提交导致更新的 Docker 映像。

name: Build and Push Docker Images

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Login to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}

    - name: Build and push custom MinIO image
      uses: docker/build-push-action@v3
      with:
        context: ./minio
        file: ./minio/Dockerfile
        push: true
        tags: cdaprod/cda-minio:latest
        platforms: linux/amd64,linux/arm64

    - name: Build and push custom Weaviate image
      uses: docker/build-push-action@v3
      with:
        context: ./weaviate
        file: ./weaviate/Dockerfile
        push: true
        tags: cdaprod/cda-weaviate:latest
        platforms: linux/amd64,linux/arm64
        

作业生成和推送在 GitHub Actions 提供的最新 Ubuntu 运行器上执行。工作流包括以下步骤:

1 . **签出代码:**该 actions/checkout@v3 操作用于克隆存储库,以便工作流可以访问其内容。

2 . 设置 Docker Buildx: docker/setup-buildx-action@v2 用于安装和配置 Buildx,它扩展了 Docker,使其能够构建多平台映像、更高级的构建指标和不同的输出选项,同时利用 Docker 的 buildkit 库。

3 . **登录到 Docker Hub:**此步骤使用 docker/login-action@v2 、引用 DOCKERHUB_USERNAME 和 DOCKERHUB_TOKEN 机密登录到 Docker Hub 进行身份验证。这些机密安全地存储在存储库设置中,不会在工作流文件中公开。

4 . **构建并推送自定义 MinIO 映像:**用于 docker/build-push-action@v3 从 minio 上下文目录中指定的 Dockerfile 映像构建 MinIO 映像。它被标记,然后推送到 Docker Hub,确保映像可用于部署。platforms 参数指定映像应支持的 CPU 体系结构,以确保不同硬件设置之间的兼容性。

5 . **构建和推送自定义 Weaviate 映像:**同样,此步骤用于构建和推送具有适当标记和多架构支持的 Weaviate 映像。

部署服务工作流

此部署工作流是 CI/CD 管道的“持续部署”方面所必需的,当生成和推送 Docker 映像工作流在主分支上成功完成时,此工作流就会开始运行。

name: Deploy Services

on:
  workflow_run:
    workflows: ["Build and Push Docker Images"]
    branches: [main]
    types:
      - completed
  workflow_dispatch:

jobs:
  deploy:
    runs-on: self-hosted
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Deploy to Docker Swarm
        run: |
          docker stack deploy -c docker-compose.yaml cda_stack
          

1 . **签出存储库:**与生成工作流类似,它从签出代码开始。

2 . **设置 Docker Buildx:**尽管 Buildx 设置不用于部署,但如果堆栈部署过程中需要多节点构建,则将其包含在内,以便保持一致性和将来使用。

3 . **登录到 Docker Hub:**确保登录到 Docker Hub,以确保运行器可以毫无障碍地拉取部署所需的映像。

4 . **部署应用程序堆栈:**此关键步骤使用单个 docker-compose.yaml 应用程序堆栈来部署完整的应用程序堆栈。它将 MinIO、Weaviate 和 NGINX 的服务定义和配置组合到一个统一的部署命令中。环境变量和机密在 GitHub 机密中安全管理。

部署工作流将代码更改转换为实时服务,并通过 GitHub 机密处理敏感数据。它展示了部署复杂服务堆栈的能力,遵循基础架构即代码的原则,并且旨在随着应用程序基础架构的发展而发展。

DevOps 弹性的主动方法

在DevOps的世界里,系统的健壮性通常只在危机时期得到强调。最近的一次活动展示了我们实践中蕴含的力量;无意中启动了系统范围的重置,导致所有正在运行的服务中断。这远非一场灾难,而是验证我们在 MinIO 倡导的基础设施弹性的绝佳机会。

我们的存储库结构经过精心设计,利用 Docker Compose 和 GitHub Secrets 来编排我们的服务环境。这种战略设置简化了恢复过程,将原本复杂的恢复转变为一系列简单的自动化步骤:

1 . **初始化:**已针对此类突发事件配置的自托管运行器已启动,为恢复奠定了基础。

2 . **同步:**最新的服务代码是直接从我们的存储库中获取的,保证只有最新的配置在起作用。

3 . **配置:**安全存储为 GitHub 机密的环境变量无缝集成,无需手动设置。

4 . **编排:**服务的部署通过 Docker Compose 执行实现自动化,由 GitHub Actions 工作流主导,精确地恢复了整套服务。

在这次 IaC 演示中,我们的服务迅速恢复到其运行状态,突显了我们的 DevOps 方法的有效性。

构建弹性系统的关键见解

从意外的系统重置中快速恢复强调了现代软件开发和部署不可或缺的几个见解:

  • **自动化至关重要:**自动化恢复过程可最大限度地减少停机时间并消除人为错误,从而对系统故障做出快速而可靠的响应。

  • **统一事实来源:**GitOps 整合了基础架构和应用程序管理,简化了更改跟踪,并在必要时实现了轻松的回滚。

  • **持久性设计:**基础架构中的弹性是有意的,通过勤奋规划和实施 CI/CD 和 IaC 最佳实践来制定。

在MinIO,这些原则不仅仅是理论上的,而是嵌入到我们工作流程中的实用措施,确保我们的系统和服务在设计上具有弹性。对于开发人员和 DevOps 专业人员来说,信息很明确:投资于这些实践就是投资于基础架构未来的稳定性和成功。我们的集体经验充分说明了我们优雅而高效地管理中断的能力。

通过编纂我们的基础设施,并像对待我们的应用程序代码一样谨慎和关注它,我们可以大大减少在面对灾难时重建和重新部署我们的服务所需的时间和精力。此外,我们还强调了详尽的文档记录和定期自动备份的重要性。虽然强大的 CI/CD 管道可以促进快速恢复,但它不能替代维护代码、配置和数据的全面文档和可靠备份。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/733417.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

并行计算之SIMD与SPMD

SIMD (Single Instruction Multiple Data) SIMD,也就是单指令多数据计算,一条指令可以处理多个数据。通过向量寄存器存储多个数据元素,并使用单条指令同时对这些数据元素进行处理,从而提高了计算效率。 代码示例: fl…

数据库设计概述-数据库设计内容、数据库设计方法(基于E-R模型的规范设计方法)

一、引言 如何利用关系数据库理论设计一个满足应用系统需求的数据库 二、数据库设计内容 1、数据库设计是基于应用系统需求分析中对数据的需求,解决数据的抽象、数据的表达和数据的存储结构等问题 2、其目标是设计出一个满足应用要求、简洁、高效、规范合理的数…

昇思25天学习打卡营第4天|数据变换(Transforms)

一、简介: 数据变换是指将已有的数据转换成可以提供给模型直接训练和验证的数据格式,在深度学习中一般被称为数据预处理,之前在昇思25天学习打卡营第3天|数据集Dataset-CSDN博客 介绍数据集的时候已经有了一个简单的使用,下面将具…

mac赛车竞速游戏:弯道卡丁车车手 for Mac 中文版下载

《弯道卡丁车车手》是一款刺激的卡丁车竞速游戏,玩家扮演的是赛道上的卡丁车车手,需要在曲线崎岖的赛道上驾驶卡丁车,与其他车手展开激烈的竞速比赛。 游戏中有多种赛道可以选择,每个赛道都有不同的难度和特点,玩家需…

双例集合(三)——双例集合的实现类之TreeMap容器类

Map接口有两个实现类,一个是HashMap容器类,另一个是TreeMap容器类。TreeMap容器类的使用在API上于HashMap容器类没有太大的区别。它们的区别主要体现在两个方面,一个是底层实现方式上,HashMap是基于Hash算法来实现的吗&#xff0c…

Apple - Advanced Memory Management Programming Guide 内存管理

翻译整理自:Advanced Memory Management Programming Guide(Updated: 2012-07-17 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011i 文章目录 一、关于…

算法题--华为od机试考试(整数对最小和、素数之积、找城市)

目录 整数对最小和 题目描述 注意 输出描述 示例1 输入 输出 说明 解析 答案 素数之积 题目描述 输入描述 输出描述 示例1 输入 输出 说明 示例2 输入 输出 说明 解析 找城市 题目描述 输入 输出 示例1 输入 输出 示例2 输入 输出 说明 解析…

嵌入式通信协议-----UART协议详解(基于智芯Z20k11X)

目录 一、简介 1.概念 2.结构 3.特点 4.优缺点 二、协议帧组成 1.起始位 2.数据位 3.奇偶校验位 4.停止位 三、UART通信过程 四、USART与UART区别 五、代码实现 1.硬件框图 2.软件实现 一、简介 1.概念 USART(Universal Synchronous Asynchronous R…

相机的标定

文章目录 相机的标定标定步骤标定结果影响因素参数分析精度提升一、拍摄棋盘格二、提升标定精度 标定代码实现 相机的标定 双目相机的标定是确保它们能够准确聚焦和成像的关键步骤。以下是详细的标定步骤和可能的结果,同时考虑了不同光照条件和镜头光圈大小等因素对…

怎样去掉卷子上的答案并打印

当面对试卷答案的问题时,一个高效而简单的方法是利用图片编辑软件中的“消除笔”功能。这种方法要求我们首先将试卷拍摄成照片,然后利用该功能轻松擦除答案。尽管这一方法可能需要些许时间和耐心,但它确实为我们提供了一个可行的解决途径。 然…

Docker网络介绍

网络是虚拟化技术中最复杂的部分,也是Docker应用中的一个重要环节。 Docker中的网络主要解决容器与容器、容器与外部网络、外部网络与容器之间的互相通信的问题。 这些复杂情况的存在要求Docker有一个强大的网络功能去保障其网络的稳健性。因此,Docker…

windows10远程桌面端口,Windows 10远程桌面端口修改的两个方法

在Windows 10系统中,远程桌面功能允许用户通过网络从一台计算机远程访问和控制另一台计算机。默认情况下,远程桌面服务使用的端口是3389。然而,出于安全考虑,许多管理员和用户希望修改这一默认端口。本指南将详细介绍如何在Window…

柯桥商务英语培训|老外和你说Tom和Jack,可不是在说人名!所以是啥意思?

小明和小李,这两个人在中国相信没有谁不认识他们了。而且有关他们的梗更是传遍大街小巷。 例如:小明他爷爷活了103岁,小明做数学题,又或者是小李的老婆比小明小2岁等等。 其实在国外,也有这么两个人像小明、小李一样&a…

WPF/C#:显示分组数据的两种方式

前言 本文介绍自己在遇到WPF对数据进行分组显示的需求时&#xff0c;可以选择的两种方案。一种方案基于ICollectionView&#xff0c;另一种方案基于IGrouping。 基于ICollectionView实现 相关cs代码&#xff1a; [ObservableProperty] private ObservableCollection<Peo…

【mysql】常用操作:维护用户/开启远程/忘记密码/常用命令

一、维护用户 1.1 创建用户 -- 语法 > CREATE USER [username][host] IDENTIFIED BY [password];-- 例子&#xff1a; -- 添加用户user007&#xff0c;密码123456&#xff0c;并且只能在本地可以登录 > CREATE USER user007localhost IDENTIFIED BY 123456; -- 添加用户…

利用第三方服务对目标进行被动信息收集防止被发现(web安全白帽子)

利用第三方服务对目标进行被动信息收集防止被发现&#xff08;web安全白帽子&#xff09; 1 被动信息收集1.1 信息收集内容1.2 信息用途 2 信息收集-DNS2.1 DNS信息收集NSLOOKUP2.1.1 ping2.1.2 nslookup 2.2 DNS信息收集-DIG&#xff08;此命令查到的结果更复杂些&#xff0c;…

java中实现Callable方式创建线程

一、为啥要引入Callable 在前面讲了通过继承Thread和实现Runnable方式创建线程的区别&#xff0c;那为什么有了Runnable还要引入Callable?下面通过实现Runnable方式的弊端给出答案 实现Runnable方式的弊端&#xff1a; package java.lang; FunctionalInterface public inte…

C++基础知识——《缺省参数》和《函数重载》

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

pwn1_sctf_2016

首先找到后门 32位IDA 打开 这里fgets,他限定了位数,我们无法利用溢出 但是我们可以看见 最后还有个操作 他把我们里面的I,全部替换为了 you S大小为0x3c ---意思我们要输入0x3c/3 的I 能达到溢出的目的 再加上4 from pwn import * ghust remote("node5.buuoj.cn&q…

如何解决跨区域文件传输存在的安全管控问题?

⼤型企业和集团为扩⼤市场份额、优化资源配置&#xff0c;会在不同地区设⽴多级下属分⽀机构、研发中心、实验室等&#xff0c;存在研发数据横向或纵向流转的需求&#xff0c;研发数据进行跨区域文件传输的场景。跨区域可能是网络区域&#xff0c;也可能是地理区域&#xff0c;…