Python DevOps 实用指南(二)

原文:annas-archive.org/md5/0228db3442938136abc9262d5596d201

译者:飞龙

协议:CC BY-NC-SA 4.0

第九章:使用 Python 进行 CI/CD 流水线

我在职业生涯中错过了超过 9,000 次投篮。我输掉了将近 300 场比赛。有 26 次我被信任去投决胜球,但未中。我在生活中屡战屡败。这就是为什么我成功的原因。

– 迈克尔·乔丹

在过去,当我还是个年轻的大学毕业生(大约两年前),在被教如何制作网站之后,最经常提到的术语是持续集成/持续交付CI/CD)。CI/CD 是我大学课程中没有教授的内容。大多数大学课程都没有;这不足以成为一个学术练习。但是,如果你是一名 DevOps 工程师,这就是你的全部工作。这是你的职责。而 Python 是提升工作效率的绝佳工具。

我经常将 Python 描述为一个伟大的促进者,即一种使所有其他工具更好的工具。这是我们将在本章进一步探讨的概念。Python 是一种非常善待犯错者的语言;相信我,我犯过很多错误。它具有许多功能,可以减少您错误的影响。它还有错误消息,可以简化和有效地追踪错误。如果我们从开发者的角度来讨论实际应用程序开发,每个人都有自己的观点,这在一定程度上是有效的。但正如我在本书中所说的那样,Python 在能够为 DevOps 工程师提供的功能方面显著领先。

因此,当我们探索如何为客户提供旅程时,这就是我们将要学习的内容:

  • CI/CD 的哲学和概念及其在创造过程中的演变

  • 使用 Python 进行的基本 CI/CD 任务,可以帮助您理解 CI/CD,它为项目带来了什么,以及其实施的重要性

  • 如何使用 Python 开发和增强开发团队内部的协作能力,利用其灵活的特性

  • 如何使用 Python 增强和自动化最神圣的 DevOps 传统:回滚

要完成这些任务,您需要准备好一些工具。在我们开始之前,有一些事情是必须设置的。

技术要求

在这一章中,我们有一个简短的清单,列出了您需要的一切:

  • 用于书籍库的 GitHub 账户

  • 一个 Todoist 账户

  • 一个 Microsoft 账户

  • 一个 AWS 账户

  • 能够容忍大量的讽刺和糟糕的幽默感

我们当然也有一个相应的 GitHub 代码库,在这里您可以参考本书中的编码内容:github.com/PacktPublishing/Hands-On-Python-for-DevOps/.

CI/CD 的起源和哲学

人们常问我一个问题:“你是从开发者做起的,怎么会走到今天这一步?”我在本书的几个章节中已经在一定程度上回答过这个问题,但简而言之,我是因为必要性才走到了这里。如今,开发应用程序的人从一开始就被教会如何做,而不清楚背后的所有理论,只知道如何使用它。这样做没问题;你不需要深入了解,除非你愿意,但请知道,过去并非如此。曾经有人必须弄明白所有这些事情(事实上,是几个不同的人)。我认为我的个人经历更能反映出那些弄清楚这些事情的人,而不是你典型的现代 DevOps 学员。所以,我将以三个场景的简短对话回顾这段旅程,场景里我将对着虚空大喊(我们可以称之为 DevOps Doug,听起来很有趣)。我们从持续集成(CI)开始。

场景 1 – 持续集成

那是一个深夜,我正在家里做我常规的 200 个俯卧撑和 300 个仰卧起坐时,突然意识到我真的很擅长写代码。这本不应该是一个启示,回想起来其实很明显,但在做出这个发现之后,我决定——作为一个慷慨的人——我想将我的编码天赋与世界分享,于是我打电话给我的老朋友 Doug,请他帮忙。

Me: 你好,我需要帮助。我有这么多代码,我想和我的朋友们分享。

Doug: 这个很简单。你只需创建、克隆、初始化、拉取、修改,然后推送 Git 仓库。听起来很简单,对吧?

Me: 什么是仓库?为什么我不能直接把代码发给他们,然后他们修改后再发回给我?

Doug: 嗯……

于是开始了长时间的讨论和大量的阐述,关于什么是版本控制、仓库如何工作、为什么要使用分支以及什么是拉取请求。如果我开始详细讲解这些内容,我得再写一本书。

Doug: 这样回答了你所有的问题吗?

Me: 是的,我理解它,我也明白它为什么有用,但为什么它是现在这种方式?

Doug: 做得更多,你就能学得更多。

旅程继续,就像集成一样,但要长得多,有时也非常无聊。我们跳过那些无聊的部分。

所以,我开始学得更多,并意识到版本控制有多么重要。我还意识到,实际上很少有年轻开发者能真正花时间去完全理解它。有些人甚至因此放弃了。但持续集成(CI)的目的很明确。它清楚地记录了代码修改的历史,并提供了小幅度的改进,这些改进在其他改进的基础上逐步叠加,形成了一系列可以查看、版本化并理解的小改动历史。它增加了组织性和理解,这些都是在提高速度之前你需要首先具备的东西。

随着我不断发展,我的技能也在发展,我的好奇心也在进化。我开始想,“这真的对项目中的其他人有帮助吗?”于是我问了他们,他们确认了确实有帮助。我觉得继续问下去不太礼貌(而且他们可能也没有进一步研究),于是我开始在网上寻找更高级的资料。接下来的这段关于持续交付的对话,倒是挺有意思的。

场景 2 – 持续交付

在 Doug 把我推下 DevOps 的河流一段时间后,我发现自己遇到了一个障碍。如果这是个实际的障碍,我完全不在乎,每天做 400 个仰卧起坐和 649 个(没错,正好是这么多)引体向上,我完全能应对。但这个障碍存在于计算机的世界中,它有一个收费站,拒绝任何不符合要求的代码。厌倦了我的代码被自动拒绝,我决定去和收费站的工作人员谈谈,结果,我发现那竟然是我的老朋友 Doug。

: Doug,你是怎么到这儿的?

Doug: 我一直都在这里。

: (显得有些困惑) 好吧… 那么,每次我推送我的代码时,它就会更新应用程序的测试版本吗?

Doug: 没错,前提是你的代码通过了测试并成功部署。否则,它会恢复到项目的旧版本,并告诉你出了什么问题。

: 好吧,你不能只相信我说的嘛?

Doug: 我很乐意,但上次我们这么做的时候,一只斑马从服务器房间里飞出来,开始咬人。斑马可凶了。

: 怎么会有一只斑马……

Doug: 这不是重点。重点是,这个系统不仅仅是为了启动东西,好吗?它存在是因为它为每个人简化并确保了流程。一旦开发者推送了代码,对他们来说就结束了。如果这段代码出错,他们会继续处理。DevOps 的人只是为了让这个过程尽可能简单。

: 好的,这个设置简单吗?

Doug: 不行。

这是我学习所有测试和安全原则、如何推送代码、创建审批工作流等一系列内容的蒙太奇部分,这些内容你在本书中已经看到过了。这绝对不是一段容易的旅程,但它是值得的。

: 好吧,这没关系,对吧?

Doug: 定义 全部

: (叹气) 好的,还有什么剩下的吗?

Doug: 多做一点,你就会学得更多。

因此,这段旅程继续着,每次都揭示出更多的问题。说实话,挺无聊的。但我很快意识到,这样其实是有原因的……

好吧,当真相揭示给我时,我意识到这实际上就是正确的方式。通过反复试验找到什么有效,什么无效的方式。一个基于现实问题及其解决方案的方法。一个更加务实的方式,它让混乱中有了秩序。但我也意识到,过度的秩序也是问题(如果是政府做的,我们叫它官僚主义)。有很多必要的步骤,但每当有变动时,总会产生一些不必要的步骤。这个过程需要自我适应。一个有趣的概念。而且它需要在创造价值的同时进行自我调整。但要创新,你必须自动化。而这就是持续部署的故事。

场景 3 – 持续部署

有一天,我坐在办公室里,按照平常的流程喝着咖啡,回复着几封邮件,推送着一些代码,突然间我感到脊背一凉,仿佛有人要进来颠覆我的生活…

道格: 嘿!

: 道格!你怎么进来的?那扇门锁着呢。

道格: 我是你想象中的人物,你永远逃不掉。我在这,你在干什么?

: (把那个令人不安的想法推到一边)好吧,算了。我已经创建了这个可爱的流水线,把代码推送进去。我已经为此工作了三个月。现在我要把它发布到生产环境中。

道格: 你一整周都没发布版本?你到底在干什么?

: 我的工作…?

道格: 哦,我明白了。那就糟糕了。孩子,听清楚了。如果你做的工作是“做工作”,那就说明你做得不好。

: 那我该做什么工作呢?

道格: 不是你的。

: 😐

道格: 你的工作是自动化你的工作,确保尽可能少地依赖人工判断。你必须成为一个艺术家,努力用尽可能少的笔触画出你的杰作。你现在已经进入了持续部署的领域。

: 如果我不断部署,那什么时候才算是开发?

道格: 诀窍是:你不部署你的应用。你需要创建一个持续部署它的部署。

: 什么?那我要是弄错了怎么办?

道格: 这就是另一个诀窍:不要害怕犯错。这就是 DevOps 和 CI/CD 流程成功的原因;你可以快速识别错误,回滚并重构。你不会因为失败而被束缚。

: 我明白了,但这些是我们真正的用户啊…

道格:没有比经验更好的老师了。如果你想学到任何有意义的东西,就必须将你的产品交给用户。他们会遇到一些小问题吗?当然,但几乎每个应用程序都会有这种情况,对吧?当你持续部署时,当你拥有了那条流水线,你就有了改变它并帮助用户的能力。不是明天,不是下周,而是现在。这就是 CD 和 CD 之间的区别(是的,我知道这很混乱)。持续交付某物和交付给客户是两件不同的事,其中一件远比另一件更有价值。

:这没道理,但我会试试的,没问题。

道格:做得更多,你就能学到更多。

就这样,和道格的这次交流结束了。虽然很有启发性,但像往常一样,给我留下了比答案更多的问题。从那以后他再也没出现过,但我知道他在那儿,什么时候我最不需要他时,他就会出现,带我穿越 道格宇宙,踏上另一段疯狂的旅程…

那真是道格关于 DevOps 的一番长篇大论,不是吗?但这本质上就是两种 CD 的区别——它们之间的哲学差异,就像半自动步枪和自动步枪的区别。每一种都有其用途。它们可以被看作是彼此的延伸,而且它们都有自己的位置。

既然我们已经把所有这些理论搞清楚了(这很好,因为这个领域仍在发展和演变),我们可以进入有趣的部分了。让我们做一些任务,帮助我们更清晰地了解如何使用 Python 来实现这些雄心勃勃的目标。我们就做一个简单的,几乎不需要任何设置就能完成的任务。因为就像某人曾告诉我(我记不清是谁了):“做得更多,你就能 学到更多。”

Python CI/CD 基础 – 自动化一个基本任务

DevOps 的一个重要但常被忽视的部分是,整个过程强迫你生产的文档的彻底性。这些文档不必庞大;它们不必详细到让人困惑,使人们在阅读或编写文档时三思而后行。它必须清晰、简洁且直截了当。最重要的是,它必须存在。说真的,最后这一点比你想象的还要稀缺。

那么,我们如何使用 Python 来促进文档生成过程呢?好吧,我们可以使用一个叫做 pip 的小库:

pip install sphinx

完成此步骤后,进入项目的根目录并使用以下命令初始化 Sphinx:

sphinx-quickstart

系统会为你提供一些设置选项。你现在可以将这些设置保留为默认值,以便获取示例文档。稍后你可以在 conf.py 文件中更改这些设置。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_1.jpg

图 9.1 – Sphinx 快速启动菜单

这将创建一个初始的目录结构,可以以 HTML 或 LaTeX 等多种文档格式构建。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_2.jpg

图 9.2 – 完成 Sphinx 设置

现在,让我们写一点 Python 代码,和 Sphinx 生成器一起使用。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_3.jpg

图 9.3 – 待文档化的初始代码

你会注意到代码注释中的细节。这些细节是 Sphinx 在创建文档时参考的内容。这就是开源项目如此重视代码注释的原因。如果你在库中遇到这些注释,你现在知道为什么了。接下来,运行以下命令来构建 HTML 文件作为文档:

make html

这将生成一个文档 HTML 文件,你可以托管它,它看起来大致是这样的:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_4.jpg

图 9.4 – 文档 HTML 页面

当然,这个过程是手动完成的。但通过正确的文档化实践,它可以通过运行上述命令的工作流来实现自动化。

无论你是经验丰富的 DevOps 工程师,还是新手,你都知道,DevOps 工程师必须做的一件事(在这一部分中已经介绍过)就是与开发人员合作,要求他们做一些能够让自动化流程和其他 DevOps 流程更加顺畅的事情。获得开发人员信任的一个方法是通过某种方式让他们的工作变得更轻松,以此证明你的价值,同时,做一个好同事。你可以通过礼貌待人,咖啡喝完后再做一杯,为他们开门……以及在下一部分中提到的,帮他们简化生活的方式来做到这一点。

与开发人员和基础设施团队合作交付你的产品

作为一个 DevOps 工程师意味着你需要成为团队中的终极合作者。这也意味着你必须与团队中的几乎每个人保持社交关系,并且让他们对你有好感。老实说,这并不难;只要笑一笑他们尴尬的笑话,聊上几句闲话,你就会突然成为大家的朋友。如果你愿意,带领大家一起合作并不难。然而,有时确实很难让他们的努力与自己的协调一致。这就是我们为什么需要协作工具的原因。除了普通的 GitHub,我们还有各种各样的工具来支持你使用的开发模式。Jira、Slack、Zoom、Google Chat、Teams……我可以一直说下去。经常发生的情况是,很多团队使用多个协作工具。所以,问题就变成了,如何让这些协作工具彼此协作呢?

工具本身提供了许多连接器,但有时它们的功能需要通过一些代码和 API 调用来实现。我们现在将使用 Python 来连接两个非常常见的生产力工具:Todoist 和 Microsoft To Do。你可能听说过或者使用过其中一个或两个工具。

Todoist 是一个简单的待办事项应用程序。它没有什么特别的,它与其他类似的应用程序(如 Jira 或 Trello)非常相似。Microsoft To Do 也是如此,只不过它集成到了 Microsoft 365 中。

首先,我们从 Todoist API 中提取任务列表。为此,我们需要创建一个 Todoist 账户,并通过 UI 添加一些任务:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_5.jpg

图 9.5 – Todoist 仪表板

这里只是一些带有截止日期的任务。现在,让我们获取 API 令牌来调用这个 API。在你的账户的 todoist 库下:

pip install todoist_api_python

接下来,编写一个脚本,将你的 API 令牌集成并列出所有任务。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_6.jpg

图 9.6 – 获取 Todoist 任务的代码

很简单,稍微加点语法糖,你就能得到如下的任务列表:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_09_7.jpg

图 9.7 – 从 Todoist API 提取的数据

这只是一个小示例,但你可以看到内容、描述和到期日期,这些正是我们关注的重点。现在,我们将尝试用 Microsoft To Do 做同样的事情。为此,我们只需要调用 API 端点。Python 中也有一个用于 Microsoft To Do 的库,但它仍处于实验阶段。

你需要从 Microsoft 获取一个授权令牌,可以通过调用 API 来获得,示例如下:learn.microsoft.com/en-us/graph/auth-v2-user?context=graph%2Fapi%2F1.0&view=graph-rest-1.0&tabs=curl。我没有包括这个过程,因为它已经很清晰地在这里描述了。如果你希望自动生成令牌,可以稍后将其集成到代码中。现在,让我们修改代码,使用我们从 Todoist 获取的内容、描述和到期日期:

from todoist_api_python.api import TodoistAPIimport jsonfrom datetime import datetime, timezoneimport requests#API tokensapi = TodoistAPI("<your_api_token_here>")access_token = "<Your_Microsoft_token_here>"#Endpoint for your default task listTODO_API_ENDPOINT = YOUR_TODO_ENDPOINThttps://graph.microsoft.com/v1.0/me/todo/lists/@default/tasks#Function to create task in Microsoft Tododef create_todo_task(title,date):    headers = {'Authorization': 'Bearer '+access_token,        'Content-Type': 'application/json'}    payload = {'title': title,        'dueDateTime': date}    response = requests.post(TODO_API_ENDPOINT, headers=headers, json=payload)    return response.json() if response.status_code == 201 else Nonetry:     #Get task in JSON form     tasks = json.dumps(api.get_tasks(),default=lambda o: o.__dict__,sort_keys=True, indent=4)    #Parse tasks    for task in tasks:        title = task["content"]        date = task["due"]["date"].replace(tzinfo=timezone.utc).astimezone(tz=None)        #Create tasks based on information        create_todo_task(title, date)except Exception as error:    print(error)

就这么简单。我们可以使用这段代码将任务从 Todoist 转移到 Microsoft To Do。我们甚至可以利用我们前几章中的基于微服务的架构(例如在第八章理解事件驱动架构中)来使用 Webhook 和事件,使这个过程更加高效。说到事件,在很多服务器中,最常见的事件之一就是故障发生。在故障发生时,需要一个回滚策略。我们来看看 Python 如何帮助实现这一点。

执行回滚

我在本书中多次提到:犯错误是可以的。因为大多数错误都是可以恢复的。有些错误不能恢复,但如果你保持清醒,它们其实很容易被识别。在 DevOps 中,这同样适用。你可以撤销你的错误。通常,问题变成了你能多快、多安静、多有效地做到这一点。这正是回滚所做的。它们有助于识别和修正问题。

回滚可以手动执行,也可以自动执行。有时手动回滚太慢,且需要人们实际上意识到某个事件或错误,这在团队比如休假时可能需要很长时间才能发现。在这种情况下——以及许多其他情况——基于指标的自动回滚是必要的。正如我们所知道的,Python 在这方面做得非常好。

部署回滚有很多种方式:蓝绿部署(50% 的流量在旧实例上,50% 在新实例上),金丝雀部署(极少数用户会获得新特性以便在生产环境中进行测试),以及其他各种方法。我的一个最喜欢的方式是红黑部署。在这种部署方式中,应用程序有两个实例:当前实例(红色)和未来实例(黑色)。你将终端从红色切换到黑色。如果这样不行,你可以将其切回到红色。听起来简单吧?无论如何,这里有一个示意图:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_9_8.jpg

图 9.8 – 红黑部署示意图

所以,记住,红对黑,你没事,黑对红,你完蛋。哦,等一下,那是珊瑚蛇的说法。但这里的概念其实很简单。这是一种可以很容易处理的故障转移类型。大多数 DNS 服务都内建了这种功能。但这并不意味着它不能从编码的角度来处理。我们尝试以这种方式处理它的原因,是为了给自己更多的控制权,并为未来可能的变更(比如一次性故障转移多个站点)留出空间。那么,让我们从编码角度尝试一下,使用 AWS Route 53 上的 Lambda 微服务执行故障转移:

import boto3def  lambda_handler(event, context):     domain_name = '<your_domain_name_here>'    default_endpoint = '<your_endpoint_here>'    # Initialize the Route 53 client    client = boto3.client('route53')    # Get the hosted zone ID for the domain    response = client.list_hosted_zones_by_name(DNSName=domain_name)    hosted_zone_id = response['HostedZoneId']    # Update the Route 53 record set to point to the default endpoint    changes= {        'Changes': [            {                'Action': 'UPSERT',                'ResourceRecordSet': {                    'Name': domain_name,                    'Type': 'A',                    'TTL': 300,                    'ResourceRecords': [{'Value': default_endpoint}]                }            }        ]    }       client.change_resource_record_sets(        HostedZoneId=hosted_zone_id,        ChangeBatch=changes    )        return {        'statusCode': 200,        'body': "Nothing, really, no one's gonna see this}"    }

好吧,这就是代码。将它放到一个 Lambda 函数中,并设置适当的触发条件,当你需要时就可以随时重置为默认值。当然,你也可以使用常规的 Route 53 来做这件事,但这种方法提供了更多修改的选项。修改是 CI/CD 过程中的一个非常重要的部分,因为没有什么是永恒不变的。

总结

那么,让我们总结一下你在本章中学到的内容。你已经了解了 DevOps 的哲学和方法论,它就像一条源源不断的河流,始终在变化之中。你还学到了在进行 CI/CD 工作时,你必须采用类似的哲学。在下一节中,你学习了一个可以在 Python 中执行的基本 CI/CD 任务。接下来的部分,你学会了如何通过简化开发人员的日常任务并确保他们拥有所有必要的便利和生产力工具,来帮助开发人员。随后,我们还学习了如何执行回滚,并介绍了一种非常独特的简单回滚技术。

如果你能坚持看到现在,感谢你。你已经阅读了本书的九章,而我依然能够吸引你的注意力。我想我一定做得还不错,对吧?也许?好吧,我们来展望下一章——其实是下一节——因为我们将变得更加雄心勃勃。我们将探讨一些大公司如何在日常工作中使用 Python。听起来很刺激吧!

第三部分:让我们更进一步,构建更大

在本部分中,我们将提升我们的 DevOps 和 Python 技能与知识,探索一些关于该主题的高级概念。

本部分包含以下章节:

  • 第十章全球一些最大公司的常见 DevOps 使用案例

  • 第十一章MLOps 和 DataOps

  • 第十二章Python 如何与 IaC 概念集成

  • 第十三章提升 DevOps 技能的工具

第十章:一些全球最大公司的常见 DevOps 用例

看到个人和组织实现他们原本可能认为超出自己能力范围的目标,我感到非常满意。

– Don W. Wilson

在本书中,我要求你对我和我写的内容充满信任。我还要求你对DevOps过程以及它最终带来的成果有更大的信任。随着新章节的开始,我想现在是时候让我付诸实践,展示一下背后的工作原理。

本章内容全部基于公开信息,这些信息要么由实施该用例的公司提供,要么由为其提供咨询的公司提供。它们可以在各大云公司客户成功案例页面上公开查找。这些商业信息被自愿公开,目的是作为示范,帮助其他企业和行业中的人们改善自己的工作负载。

我将使用这些用例作为示范,展示你如何运用 DevOps,并如何使用 Python 来支持它们的应用。我不想在这一部分使用假设的情况,因为那样会显得不真诚。然而,我使用这些案例的方式是为了展示如何使用 Python 来复制这些用例,而不是它们是否实际使用了 Python。它们可能用过,但这并不重要。

本章的主要动机是向你展示,DevOps 的理念在实际场景中已经得到了应用,创造了真正的客户价值。这也为你在 DevOps 学习旅程和本书过程中所学的技能提供了依据。

所以,废话不多说,在这一章中,你将了解以下内容:

  • 一个亚马逊网络服务AWS)的用例,帮助弥合了业务分析师与数据工程师之间的鸿沟

  • 一个 Azure 用例,节省了大量编码时间,并帮助提高了部署效率

  • 两个谷歌云平台GCP)的用例,涉及运动联盟找到解决方案,使他们的联盟更具可访问性

AWS 用例 – 三星电子

三星在很多方面都使用了云和 DevOps 原则。鉴于三星的庞大规模,这一点是显而易见的。因此,我没有对它们进行正式介绍,因为,嗯,你知道三星是什么。我们将讨论的特定案例非常有趣:它涉及到让普通的业务分析师参与机器学习ML),同时也让那些懂得编写 ML 算法和应用的人员最大限度地发挥他们的能力。这是一种双管齐下的方法,充分发挥两者的能力,增强它们之间的反馈并促进合作。下图展示了三星原始的数据分析工作流程:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_1.jpg

图 10.1 – 三星原始的数据分析工作流

那么,让我们来分析三星所面临的情况,以及他们用来解决问题的方法。

场景

三星的分析团队由两个不同的部分组成:业务分析师和数据科学家。业务分析师从理解人类行为的角度,分析三星消费电子产品提供的问题和数据,进而改善产品和预测客户行为。

为此,他们需要数据,海量的数据,并且需要能够处理这些数据的能力。这时,数据科学家发挥了作用;他们将分析师的直觉转化为可以解决的案例,从而提供具体的数据。他们创建了数据分析和机器学习算法,提供业务分析师可以用来为产品提供推荐和建议的洞察力,同时还会向数据科学团队提供反馈。

然而,这种合作关系并不像大家想象的那样顺利;由于多种因素,两个团队之间存在差距,主要原因是尽管两个团队相互依赖,但在工作方式上存在差异。

除此之外,数据科学家们还需要在不同的数据集上执行重复性的任务,以确保向业务分析师提供正确的输出。这导致数据科学家没有时间去尝试其他机器学习算法和他们可能想要实现的各种技术,也使得业务分析师在他们负责的数据上失去了显著的控制权,这意味着他们无法全面了解数据,无法进行有效的分析。

需求变成了找到一种方法来协调数据和算法,使得业务分析师可以使用常见的算法,同时数据科学家也能对其进行调整。这将创造一个环境,使得数据科学家不必等待业务分析师,反之亦然,从而为双方释放出时间和资源。

头脑风暴

现在,你可能会问,如果你对这个过程不熟悉,在现代社会中,业务分析师如果不会写代码,他们是做什么的呢?嗯,这比你想象的要普遍得多。分析师的工作并不是编写代码或解析数据(尽管这通常是他们会做的事情);他们的工作是分析摆在他们面前的信息,并利用这些信息提供某种推荐、洞察或解决方案。

问题的核心在于,两个团队之间存在着沟通和理解的鸿沟,而要弥补这一差距没有重大人员变动几乎是不可能的。而这种人员变动通常不符合公司的最佳利益。

您需要确保一个团队不依赖于另一个团队,并能根据他们收到的信息而不是信息来源的人操作(松耦合,记住?)。因此,一个理想的解决方案是找到一种方法,让两个团队能够同时处理相同的数据,而不需要通过不必要的沟通来阻碍彼此,这正是他们找到的解决方案。

解决方案

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_2.jpg

图 10.2 - 三星的新数据分析工作流程

解决方案基本上是这样的:会有一个数据的单一来源,数据分析师和数据科学家都可以从中工作;数据科学家会为分析师提供访问用户界面的权限,以执行他们想要的数据操作。科学家们随后会调整这些操作和算法,试图在不需要分析师联系他们获取当前运行算法版本结果的情况下获得更好的结果。这本质上就像是为数据分析师内部使用创建的应用程序,由数据科学家构建。

存在不同的技能和思维方式是有其原因的,这就是为什么团队中需要有不同角色和视角的原因。在这种情况下唯一需要做的事情就是确保所有这些角色都处于可以成功的位置。通过为这两种角色提供一个平台和工作流程,使他们感到舒适,找到了一种合理的方式让整个团队能够最优化地工作。三星通过使数据集中化,并使两个团队都能访问数据,而且两个团队都不需要依赖彼此来取得进展,同时找到了一种方式使彼此能够互补和支持。

接下来,我们将看一个使用案例,在这个案例中,公司不得不处理具有类似技能水平但经验不同的人员,并同时应对业务需求和生产力。

Azure 使用案例 - Intertech

在搜索使用案例和场景时,我完全爱上了 Intertech 通过 DevOps 转型的力量所做的事情。它使用 Azure 的事实并不像它如何使用 Azure 和 GitHub 服务来现代化和革新其管道那样重要。这个使用案例就是 DevOps 应该为公司带来的价值。它还解决了本书后面部分(我们现在所在的部分)将变得非常相关的内容:生成式 AI。让我们来看一看旧 Intertech 工作流程:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_3.jpg

图 10.3 - 旧 Intertech 工作流程

这个图表展示了一种沉没成本谬论,这种谬论会导致生产力的严重损失。它代表了 Intertech 在运作上效率低下,浪费了大量本不该处理的任务上的核心人员。所以,我们来看看 Intertech 是如何应对这个问题的。

我们先从 Intertech 说起。他们是一家 IT 运营公司,支持土耳其一些最大商业客户的基础设施和运营需求。现在,你可以想象,这种运营在很多层面上会相当难以管理。问题并不大;实际上,它们是微小的割伤和针刺,但这些往往是最令人烦恼的痛苦。它们既令人恼火又分散注意力,如果你让它们存在,它们会偷走你的注意力。在这一部分,我们将讨论心理和身体上的痛苦,以及 Intertech 的优秀员工如何努力减少这些痛苦。

场景

Intertech 致力于为土耳其一些最大公司创建和维护解决方案。请记住这两个词:创建和维护。这是开发任何软件解决方案的两个基本部分,但它们是完全不同的。创建某物意味着赋予它生命;你在给它“生命”,这是痛苦且漫长的,但它是美好的。维护某物就像是给你刚出生的孩子换尿布。这是令人讨厌的,但你得对它负责,而这个孩子是不会自己照顾自己的,无论它多么独立或成熟(大多数孩子并非如此)。记住这个类比,它会贯穿接下来的各个小节。多年以后,如果我在为这本书写第二版的时候依旧在给它“换尿布”,我也会记住这一点。

所以,Intertech 面临的困难是:在开发新项目的同时,如何维持旧项目。而维持旧项目的任务虽然琐碎,却需要大量的人力、工时和精力,这些本可以用来探索新的价值传递方式。解决问题的思维循环,从最初的问题到最终找到解决方案,通常需要宝贵的时间和智力努力,而这些努力往往远低于解决问题者的能力。基本上,它迫使聪明的人去做一些愚蠢的任务。

那么,在思考这个问题的解决方案时,我们首先应该想到什么呢?也许有一种方法可以在不需要过多思考和研究的情况下找到解决方案。当然,这种方法不适用于那些需要真正集中精力的关键任务,但适用于那些琐碎的任务,比如需要搜索一堆术语然后找到合适的 Stack Overflow 页面,再将其复制粘贴到解决方案中,最后运行几次确认其有效性。也许有一种工具可以整合所有这些信息,为简单的日常问题生成一个简洁的解决方案,从而为我们节省时间。也许这种工具的名字与人工智能有些相似?好吧,没有什么能和人工智能押韵。AI,就是我所说的。

头脑风暴

好吧,到现在你大概已经知道我想说什么了,那么让我分享一下我个人的经验,讲讲我通常如何在日常生活中使用生成性 AI。这是一个非常有用的工具,像你们这些读这本书的人都会证明这一点,除非你是坚决反对 AI 的人,或者你脑袋里储存了所有世界上的信息。如果你是后者,联系我告诉我黑道家族结局到底发生了什么。

我使用生成性 AI 来制定解决方案的步骤,并将其框架化,以便我可以根据我给出的上下文进行理解和修改,或者根据它尚未训练过的内容进行修改。这比每次需要解决问题时都去查找教程容易多了,而当教程不完整时,还得去找另一个教程。通过像 ChatGPT 这样的生成性 AI,局面发生了变化;现在我可以不耐烦,而生成性 AI 则能耐心地处理我的请求。这非常棒,因为说实话,思考是很累人的,特别是当你不得不一次又一次地思考同样的事情时。它会让你的大脑麻木,降低生产力。Intertech 的人们得出了相同的结论。

如果你想继续使用孩子的类比,这就像有一股神奇的力量,它会自动给孩子换尿布,并把尿布围绕在孩子身上,只等你把别针别上去。所以,从这个角度来看,如果有一个重复的任务出现,并且任务足够简单,它就会通过各种方式妨碍生产力。在这种情况下,生成性 AI 可以来拯救我们。任何使用过它的人都知道 ChatGPT 在这方面有多么有用。实际上,凭我的个人经验,ChatGPT 对我最有帮助的事情就是解释我粘贴进去的代码行。因为我无法像 AI 那样迅速收集信息,这通常会比 ChatGPT 所需的几秒钟更长。因此,既然我们已经证明了生成性 AI 解决方案的有效性,让我们来看看 Intertech——他们也得出了类似的结论——是如何将这些概念融入到他们的 DevOps 和 Azure 工作负载及任务中的。

解决方案

Intertech 创建的解决方案围绕着 GitHub Copilot 和 Azure OpenAI 集成展开。Copilot 在经过某个特定代码库的训练后,只要给出正确的提示,它就能简单地编写所需的脚本。Intertech 将 Copilot 集成到开发人员使用的集成开发环境IDE)中,这样开发人员写一两行代码后,Copilot 就会推测他们的意图并完成大部分剩余代码。开发人员只需验证几个测试,瞧,一套高效的代码交付系统就完成了,节省了时间和思考力。下图展示了该解决方案:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_4.jpg

图 10.4 – 具有生成式 AI 的新 Intertech 工作流程

图中的解决方案可以分解为以下步骤:

  1. 当初级开发人员对遗留系统进行维护时,他们使用已经在该系统的代码库上进行训练的 Copilot 实例。

  2. 这使得他们能够以易于阅读的形式查询并找到他们在代码库中寻找的答案。

  3. Copilot 还帮助自动完成代码,并保持与代码库其余部分风格的一致性。

  4. 高级开发人员在大多数情况下不参与这一过程,这样他们可以专注于较新的项目和系统。

由于大多数维护工作都由高级开发人员完成,因为他们曾参与过旧项目,这些开发人员(由于经验丰富,他们的时间更为宝贵)需要亲自处理许多问题以解决它们。即便这些问题交给了初级开发人员,他们仍然会向高级开发人员请教大量建议,这虽然并非负面行为,但仍在一定程度上阻碍了高级开发人员。

为了减少初级开发人员对高级开发人员的依赖,公司将 Azure OpenAI 聊天机器人集成到了他们的 IDE 中。这些聊天机器人能够从代码和项目文档中抓取并推断出信息,并解答大多数初级开发人员的疑问。这样不仅减少了高级人员在代码维护上的时间消耗,还通过个性化的“保姆”引导初级开发人员完成代码库。一个惊人的结果是,公司内部的邮件数量减少了 50%,这是一个值得注意的数字。难道你不想要减少 50% 的邮件,同时保持甚至提高生产力吗?更不用说,不用参加会议、避免重复做老事所释放出来的时间。这种价值乘数效应能将公司推向更高的水平。

说到价值,到目前为止我们所看到的价值都是基于事实表和计算机代码,但在下一部分,我们将看到 DevOps 如何在更具物理感知的环境中创造价值,以体育为例。

Google Cloud 用例 – MLB 与 AFL

如果你有一件事要了解我,那就是我非常喜欢体育。我热爱体育,喜欢学习新运动,就像我热衷于跟随多年来一直关注的老运动一样。

我已经跟随美国职业棒球大联盟MLB)多年,在这期间,棒球一直是数据分析的运动。现代大多数球队在选拔球员时都受到数据分析的驱动,球员的表现通过对他们比赛中收集的多个指标进行统计分析来衡量。你可能看过电影*《点球成金》*(或者读过迈克尔·刘易斯的书),它讲述了统计方法在选择棒球球员中的应用,以及这些方法如何帮助奥克兰运动家队在 90 年代末和 2000 年代初取得成功。

在 MLB 中,引入分析数据的结果之一是对比赛本身以及完成一场比赛所需时间的分析。为了简化比赛流程,MLB 引入了投球计时器,给球员仅有 15 秒的时间来投球。如下图所示,计时器需要在整个场馆内同步,并且与电视直播中的计时器保持同步。这种同步性为 MLB 实施其最新规则带来了独特的挑战:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_5.jpg

图 10.5 – 原始 MLB 比赛计时系统

我还想看看其他可能以某种方式使用数据分析和 Google Cloud 并将其集成到他们联盟基础设施中的体育联赛(或许采用了不同于 MLB 的方法)。在我的搜索中,我找到了一个完美的例子,就是澳大利亚足球联赛AFL)。以下图展示了 AFL 的教练员广播情况:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_6.jpg

图 10.6 – AFL 教练员的广播情况

当我开始研究时,我几乎对澳大利亚规则足球(也叫做澳式足球)或 AFL 一无所知,除了知道大决赛当天是澳大利亚的公共假期。然而,在我的研究中,我确实发现了一点,那就是这两家公司都在使用先进的数据分析来寻找改善比赛观赏方式的方法,并分析是否有可能使比赛玩法和球员表现更加出色。

鉴于我对体育和所有围绕体育的“极客”内容充满热情,这一小节对我来说似乎是不可避免的。那么,让我们深入探讨,看看在这些用例中我们可以发现哪些 DevOps 和数据洞察。

场景

让我们从棒球开始;我喜欢棒球。它是坚忍不拔之人的运动;它是时间静止的运动。如果你有 23 个小时的空闲时间,请务必看看 Ken Burns 的《棒球》纪录片系列;你不会后悔的。但整体而言,棒球和尤其是 MLB 在过去几年中遭遇了一些挫折。休斯顿太空人有涉及作弊的丑闻,由于比赛时间过长,现场观众和电视观众的参与度下降。为了解决这些问题,同时保持比赛的完整性,MLB 转向了数据。他们利用各队单独使用的分析工具,并决定将其转向整个联盟。他们从整个赛季(包括 2430 场常规赛和季后赛)的所有比赛中收集与比赛、观众参与度相关的统计数据,并决定创建基础设施解决方案,以加强他们将要实施的解决方案。他们在这方面使用了 Google Cloud:既用于数据分析,也用于解决方案的实施。

澳大利亚足球规则是澳大利亚的头号运动。在这片下方的土地上,它是观众最多、影响最大的运动。它也是澳大利亚最具身体对抗性的运动,作为一个经常观看体育比赛和从事数据科学的人来说,一个体育运动在人类之间的身体接触越频繁,分析起来就越困难。在这里,数据需要在更加物理的层面上进行分解,关注于人体本身。这种方法使得澳式足球联盟能够开发出一套利用机器学习与人工教练相结合的系统,为那些依然对这项运动充满激情的弱势群体和不同能力的人提供训练方案。

这两个体育联盟面临了两个截然不同的问题,都需要完全不同的解决方法,但它们都在 Google Cloud 上采用了 DevOps 原则来解决。让我们看看它们是如何做到的。

集思广益

MLB 的问题影响了比赛及观众的观赛体验。人们讨厌浪费时间,也讨厌慢节奏的比赛。任何看过 NBA 季后赛最后两分钟比赛的人都知道这一点。MLB 通过观察每局所花的时间以及这些局中最耗时的部分来解决这个问题。他们发现投手投球前的准备时间和封杀时间延缓了比赛进程。这促成了投球计时器的诞生,一个记录投手在两次投球之间可以等待的时间的计时器。他们认为,投球之间的时间是比赛变慢的主要原因,并相信投球计时器能解决这个问题。该方案结合了 GCP 和 DevOps 原则,结合 GCP 服务和本地计时硬件来实现。作为一个球迷,我对此也非常感激。我们将在下一节讨论解决方案的完整内容。

AFL 的问题在于青少年参与度以及某些人在尝试参与这项运动时的身体局限性。澳大利亚还是一个面积广大的国家,人口分布非常广泛,这意味着需要接受澳式橄榄球训练的人们,尤其是偏远地区的人,需要远程进行训练和指导。目标便是尽可能覆盖更多人,并尽可能多地收集数据,以确保其准确性,同时还要能接触到在某些沟通形式上有障碍的人群。这个问题需要设备之间的通信方式,并且要求使用机器学习算法,特别是用于跟踪运动员在运动中使用的球,以便进行训练。

所以,考虑到这些问题,以及我们可能采取的解决方法,我们现在可以开始提出一些解决方案,帮助这些组织实现他们的目标。让我们看看他们究竟做了什么来达成这些目标。

解决方案

MLB 问题的解决方案涉及使用 Google Cloud 的 Anthos 服务网格将所有投球计时器协调在一起。集中式但分布式的计时器增强了比赛的完整性和这些新规则的执行。

MLB 的问题在于同步性。目标是将遍布整个体育场的比赛计时器同步,以协调它们的时间。在这里,Google 使用了其 Anthos 服务网格(如以下图所示),作为云端设备与棒球场地上本地设备之间的连接器。这使得投手的计时器可以在任何地方都清晰且准确,无延迟地显示,确保新系统的公平性。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_7.jpg

图 10.7 – Anthos 同步游戏时钟用于 MLB

引入比赛计时器使得平均棒球比赛时间缩短了 24 分钟。这是非常重要的,我认为这是我在如此非技术性场景中看到的 DevOps 思想最具意义的应用。让我们来做一下计算:每场比赛减少了 24 分钟,这使得比赛的平均观众人数从 26,843 增加到 29,295,取得了显著的成效。那么,究竟节省了多少时间呢?好吧,这是 24 分钟 x 29,295 人 x 2,430 场常规赛比赛。总共节省了 1,708,484,400 分钟,约等于 28,474,740 小时,1,186,447.5 天,或者 3,250 年。这是相当可观的节省,而球迷们也感受到了这一点,这就是为什么观众人数上升的原因。所有这一切都得益于能够协调松散耦合的基础设施。

AFL 问题的解决方法要求交付能够在网络不稳定时进行运动追踪的 ML 模型。这意味着任何使用的 ML 模型都必须使用移动设备端的计算能力,并且足够轻量,以免影响设备的正常运行。谷歌的开发团队曾帮助印度 印度超级联赛 (IPL) 提供过类似的教学解决方案。因此,他们最终得出的解决方案是一款名为 Footy Skills 的应用。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_10_8.jpg

图 10.8 – AFL 教练指导广播系统

该应用使用了两个 ML 模型:一个用于根据大小、形状和颜色检测澳式橄榄球,另一个用于确定其空间深度和位置。它们还增加了一些功能,帮助听力和视觉受损的运动员以及使用轮椅的运动员参与比赛。

总结

这一章确实是一段奇妙的旅程。即使在我写的这本书中一些奇怪的内容面前,它依然独具特色。但我可以诚实地说,写这一章是一次愉快的经历,因为在写作过程中,我有机会研究了许多独特的解决方案。

我们从 AWS 解决方案开始,这展示了当你将人们放置在一个能够发挥他们技能并与其他技能结合而不是相互冲突的位置时,会发生什么。它还展示了 DevOps 解决方案如何不仅仅促进技术发展,也促进了这些技术背后的人才。

在 Azure 的应用案例中,我们了解了 AI 和 ML 与 DevOps 相结合如何提高从事创造性工作的团队的生产力。我们看到生成式 AI 如何被用来帮助开发者,减少关键人员需要完成的琐碎和重复性工作,并腾出时间和沟通渠道,使团队更加高效。

在第一个 GCP 使用案例中,大联盟棒球(MLB)需要一种方法来证明改变已经存在超过一个世纪的棒球规则是合理的。他们使用了可靠的数据和确凿的事实来做到这一点。这些事实通过收集整个赛季的棒球数据来提供。随后,他们利用这些数据和其他松耦合的协同技术来实现他们改变规则的愿景。通过数据和技术协调,他们创造了一个对他们有利且深受球迷喜爱的规则:这是一个几乎闻所未闻的壮举。

在第二个 GCP 使用案例中,澳大利亚足球联盟(AFL)通过将机器学习模型与 DevOps 原则结合,直接部署到遍布澳大利亚的设备上,从而扩展了其可用性和包容性,使得澳大利亚最偏远地区的人们也能接触到优秀的教练和教学,帮助他们提升体育水平。这为 AFL 提供了一个宝贵的增长和拓展平台,尤其是在他们的粉丝和未来球员之间。

总结来说,这些 DevOps 技术在现实生活中非常有用。许多解决方案如果没有 Python 也无法实现,特别是那些涉及机器学习和人工智能的解决方案。而这只是 DevOps 能带给你高度的起点。在下一章中,我们将更深入地探讨 DevOps 的数据科学方面,Python 与数据的结合,以及 MLOps

第十一章:MLOps 和 DataOps

未来很快将成为过去

– 乔治·卡林

我本来打算使用一些生成性 AI 来编写本章节的内容,但那样的话,内容会更像是自传而非技术书籍,因为生成性 AI 就变成了共同作者。我会尽量做一个非常客观的观察者,并公正地处理这个热门话题。我希望这能让我在未来可能由 AI 主宰的世界中占据一个有利位置。在过去的一个世纪里,机器学习和 AI 领域取得如此巨大的进展有很多原因:诺姆·乔姆斯基、艾伦·图灵、计算机本身的发明、科幻小说,以及人类对宇宙中新生命的永恒渴望。但在过去的几年里,这些概念作为可行产品和服务的交付,离不开 DevOps 的支持。毕竟,你觉得ChatGPT是怎么在大约五秒钟内,瞬间回答你四段问题,并且每分钟为一百万多人做到这一点的呢?

现在,本书中的所有章节和概念都让我们回到一个事实,那就是 DevOps 的核心是提供价值并使事情能够正常运行。当 DevOps 的焦点转向数据时,这一点并没有改变。在这种情况下,Python 变得更加有用,因为它是数据操作员的语言。如今,大多数人和数据开发环境默认使用 Python,因为它提供了进行数据处理和分析所需的工具。大多数高效的DataOps工作负载都会在某种程度上使用 Python。很多人会在运行脚本和任何需要编写的支持性操作脚本中都使用 Python。我们还将讨论MLOps以及帮助交付和优化机器学习模型和算法的操作。所有这些内容将在你阅读完技术 要求部分后,在本章节中进行讲解。

总结一下,在本章节中,你将学到以下内容:

  • 当涉及到 DataOps/MLOps 时,与常规 DevOps 的做法相比,存在着哪些不同?

  • 处理各种不同数据挑战的做法

  • ChatGPT 交付到你电脑屏幕背后的操作

技术要求

以下是一些帮助你跟上本章活动的要求:

MLOps 和 DataOps 与常规 DevOps 的区别

我们在任何技术行业中经常会遇到的一个问题是:数据角色和非数据角色之间的区别是什么?软件工程师和数据工程师、数据分析师和会计师,或者 DJ 和音乐作曲家之间的区别是什么?这是雇主经常提问的问题;人们猜测是否有一种是另一种的子集,或者它们是否完全不同。即使在瑞典语中,dator表示“计算机”,科学被翻译为vetenskap,而计算机科学则被称为datavetenskap,因此在某个时候,设计并更新瑞典语言的实体认为这两者之间几乎没有什么区别。

我们现在通过几个常见的 DevOps 用例来解释这些内容,这些用例可以应用到数据操作(DataOps)和机器学习操作(MLOps)这两个更具体的领域。在 DataOps 中,我们将介绍一个简单的方法,这个方法帮助我在使用 JSON 文件时,节省了很多 Python 中的数据连接操作。在 MLOps 中,我们将重点关注 GPU 方面,这是 MLOps 工程师可能需要处理的主要硬件。

DataOps 用例——JSON 连接

这是一个非常简单的小技巧,但它并不像你想象的那样为人所知。我真心认为,如果我能通过这一部分帮助到一个正在处理数据的人,那么我就算成功了。JSON 的操作是数据操作中非常重要的一个方面,尤其在 NoSQL 用例中非常显著,但在其他一些场景中也很常见。自然地操作 JSON 给 Python 带来了相较于许多其他编程语言的重大优势。它最有用的应用之一就是管道(|)操作符。这个小操作符可以用于执行连接、联合,甚至是数字的按位操作。它是 Python 使这些小数据操作变得更加易用的许多方式之一。

所以,我们将从仅仅一个连接 JSON 的函数开始:

a = {"one":1, "two":2}b = {"one":"one", "two":2, "three":3}print(a|b)

就这样。这就是代码,下面是代码的输出:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_1.jpg

图 11.1 – JSON 连接的输出

你会看到第二个 JSON 的键值会覆盖第一个 JSON 中的值,如果它们有相同的公共值,那么它们会保持不变,任何额外的值会被合并到整体 JSON 中。所以,记住这一点,每当你遇到 JSON 合并的问题时(而且这个问题可能会很常见),你就可以使用这个小技巧。现在,我们来看看另一个技巧,它肯定能帮助所有游戏硬件爱好者。它也会帮助其他人,但我特别提到硬件爱好者,因为他们拍了最多的 YouTube 视频,我希望能得到一些曝光。

MLOps 用例——超频 GPU

在这个 AI 艺术的现代时代,最高水平的图像生成可能需要大量的处理能力。对于任何类型的图形渲染,只有在没有其他选择的情况下才会使用 CPU,并且通常不建议用于较大的渲染。对于机器学习的 TensorFlow 算法,Google 的专有 TPU 是常见的选择。但同样,对于任何涉及图像生成或处理的任务,拥有一块好的 GPU 是非常有用的。如果出现了需要 GPU 额外能量才能完成任务的罕见情况,超频可能是必需的。

很多时候,GPU 处理器都有自己的驱动程序,而这些驱动程序也带有各自的命令行工具。在使用超频或其他 GPU 功能之前和之后执行这些命令可能会很麻烦。相反,通过使用 Python 内建的subprocess模块,我们可以自动超频或执行任何其他 GPU 相关的任务。对于这个例子,我们将使用 NVIDIA 的命令行工具,它可能是目前最流行的 GPU 品牌。NVIDIA 有一个命令行工具叫做nvidia-smi,它也包含了一个超频功能,这正是我们要调用的工具。现在,让我们写出能够帮助我们超频 GPU 的代码块:

import subprocessdef overclock_gpu():    # Set the new clock frequency for memory and graphics    new_clock_memory= <your_clock_frequency_in_MHz>    new_clock_graphics= <your_clock_frequency_in_MHz>    # Run NVIDIA command to overclock GPU    command = "nvidia-smi –i 0 --applications-clocks {new_clock_memory},{new_clock_graphics}"    subprocess.run(command, shell=True)if __name__ == "__main__":    overclock_gpu()

运行上面的代码后,将会对设备上设置的任何 NVIDIA GPU 进行超频。这将使得图像处理和生成等过程变得更快。这在对这些资源有更高需求时很有用,并且无法将这些需求转移到其他资源上时。所以下面的代码可以根据某些条件临时对 GPU 进行超频。一旦超频完成,你可以通过运行以下命令(无论是在脚本中还是外部)将其恢复到默认设置:

nvidia-smi –- reset-applications-clocks

这就是如何使用 Python 操作 GPU 的方式。这个部分的内容大多是学习如何操作数据及其相关方面。然而,数据本身也因为多种原因可能变得难以处理。一个主要的原因可能是数据的数量,可能会非常庞大。接下来的部分将会讲述如何找到应对来自各种来源的数据的方法,避免被大量数据压倒。

处理速度、体积和种类

在任何关于如何处理数据的教程中,通常都会简单介绍三维(three Vs)速度(velocity)体积(volume)种类(variety))。这三种方式描述了数据复杂性的扩展方式。在处理数据时,每种方式都会提出独特的问题,而你需要处理的大量数据可能是这三者的组合。速度指的是数据在一段时间内的流入速度,体积是数据的数量,种类则是呈现的数据的多样性。

因此,这一部分将根据三个 V 进行划分,每个小节中都将为可能出现的共同问题提供解决方案。这样一来,您将了解 Python 如何帮助处理如此大量的数据。让我们从容量开始,因为这是最简单的,而且当谈到大数据时,可能是人们首先想到的。

容量

数据的量是一件相当简单的事情。它表示一定量的数据,其中大多数(如果不是全部)将是相同类型的数据。如果我们要处理大量数据,将需要理解数据的时间敏感性以及我们手头的资源。通常处理的数据量根据数据是基于宽度还是长度而不同(即一行数据是否有很多字段或者数据行数非常多)。这两种情况需要不同的解决方案,有时甚至需要专门的数据库。还有可能数据集根本不是数字和字母,而是音频或视频文件。在本节中,我们将使用一个示例,在拥有包含大量字段/列的数据库或数据文件时会非常有用。

要开始,我们需要一个大容量数据集,因此我们将使用一个名为Mockaroo的应用程序,该应用程序允许您使用生成式 AI 生成数据字段和样本数据(在本章非常合适)。让我们转到 Mockaroo 网站,为我们的样本数据生成几个字段:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_2.jpg

图 11.2 – Mockaroo 模式

我们用 Mockaroo 生成的数据集如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_3.jpg

图 11.3 – Mockaroo 创建的样本 CSV

上述图示仅显示了其一小部分;它是 1,000 行中有 20 个非常大字段。让我们编写脚本来解析它:

import csvdef read_large_csv(file_path):    with open(file_path, 'r') as csv_file:        csv_reader = csv.reader(csv_file)        next(csv_reader, None)        for row in csv_reader:            yield rowcsv_file_path = 'MOCK_DATA.csv'for row in read_large_csv(csv_file_path):    print(row)

脚本在读取 CSV 文件方面可能看起来有点多余,但之所以这样是为了确保 CSV 中的所有行不会同时加载到操作系统的内存中。这种方法将减少数据内存的负荷,是在内存无法容纳大量数据的系统中读取大量数据的绝佳方式。其原理是读取一行数据,然后释放内存中的数据再读取其他行。这是在读取高容量数据时有效管理内存的方式,从而使读取速度更快、更顺畅,正如本图所示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_4.jpg

图 11.4 – 生成器背后的工作流程

现在,这已经足够简单了,但是当每次只有一行数据时,但是持续不断,例如流数据时会发生什么?所有这些都需要在其传入时进行实时处理。我们该如何实现这一点?让我们找出答案。

速度

处理数据速度是一个值得数十亿美元投资的问题。即使在今天,最大的在线视频流平台也在努力持续地发送直播数据。当然,造成这一现象的原因有很多,但事实是,许多解决方案没有正确的预算和质量组合,因此无法始终保持一致。不过,我们可以做到非常接近。

在这个练习中,我们将使用很多人称之为数据流的未来,甚至可能是现在的技术:Apache Flink。这是一个由 Apache 软件基金会开发的流式和批处理框架,旨在实现平滑快速的数据流。与许多由 Apache 软件基金会管理的框架不同,它是专门为基金会维护而创建的,而不是由某公司创建并开源以便于维护的项目。

Flink 本身不提供任何数据存储解决方案,它的工作是将传入的数据处理后存储到指定位置。它提供 Java、Python 和 Scala 的 API,并且支持所有云平台。

要开始使用 Python,你需要通过以下命令安装 pyflink

pip install apache-flink

如果你还没有安装 pandas,请同时安装:

pip install pandas

好的,现在让我们编写一些代码,将来自一堆 JSON 行的数据流转存到 CSV 表格中。这只是一个展示 Flink 工作流的示例程序,但它确实有效地实现了这个目的:

from pyflink.common import Rowfrom pyflink.datastream import StreamExecutionEnvironmentfrom pyflink.table import StreamTableEnvironment, DataTypesfrom pyflink.table.descriptors import FileSystem, Json, Schemaimport pandas as pd#Function to usedef flink_input(input_data):    # Set up the Flink environment    env = StreamExecutionEnvironment.get_execution_environment()    t_env = StreamTableEnvironment.create(env)    # Define the CSV file to output to along with temporary table name    t_env.connect(FileSystem().path('output.csv')) \        .with_format(Json().fail_on_missing_field(True)) \        .with_schema(Schema().field('data', DataTypes.STRING())) \        .create_temporary_table('output_table')    # Convert multiple JSON values into PyFlink CSV rows    input_rows = [Row(json.dumps(json_obj)) for json_obj in input_data]    df = pd.DataFrame([r[0] for r in input_rows], columns=['data'])    # Insert the rows into the output table which in turn inserts them into the CSV file    t_env.from_pandas(df).insert_into('output_table')    # Execute the Flink job    env.execute('CSVJob')input_data = [{'key1': 'value1'}, {'key2': 'value2'}, {'key3': 'value3'}]flink_input(input_data)

在这段代码中,你会看到 JSON 行通过临时表插入到 CSV 中,临时表作为插入数据的过渡。当插入临时表时,它也会将数据插入到 CSV 文件中。

这对 Flink 功能的解释相当简单,它的工作是处理基本相同的上下文,但同时处理数百万条流数据。所以,代码的扩展版本看起来相似,本质上执行相同的功能,唯一不同的是,它将在更多数据上执行这些操作。Flink 可以执行许多其他操作,数量庞大(这也是它如此受欢迎的原因之一),它们都遵循类似的模式,并可以与大多数现有的数据源集成。

现在,我们将处理数据中的一个常见复杂问题,事实上,这是一个总是需要以某种形式处理的问题。下一节讲的是多样性。

多样性

多样性是有趣的,可能也是大多数数据工作者面临的最复杂的负担。数据可以以各种形状和大小出现,并且通常以最出人意料的方式出现。许多黑客尝试通过将有效的 SQL 查询作为表单字段添加,从而发起 SQL 注入攻击,如果数据输入正确匹配,这些查询就会被执行。一个优质的质量保证测试员总是尝试各种测试,试图通过使用他们不应能输入到某些字段中的数据类型,来让很多应用程序陷入困境。但通常——当普通人有机会使用键盘时——会发生的是,人们会以某种方式意外地打破系统中的许多安全措施,从而暴露出之前未知的系统漏洞或问题。

所以,现在我们将进入一个可能会发生这种情况的示例,这在许多较为宽松的 NoSQL 数据库中尤为明显,这些数据库可能没有内建所有标准的数据格式化功能。我们将尝试在 JSON 文件中插入表情符号。表情符号通常使用 UTF-8 格式表示,但这种格式虽然在网页上很常见,通常在使用更不常规格式的数据库时,仍需要手动设置。

我们将使用 Google Colab 来进行这个练习,因为它对于像这样的简洁概念验证更加高效。让我们从添加一个包含表情符号的 JSON 变量开始:

user_data = {'username': 'user_with_emoji😊',}

接下来,我们将首先不使用任何 UTF-8 格式,将其插入到一个文件中:

import jsonwith open('sample.json', 'w') as file:json.dump(user_data, file)

这将生成如下格式的示例 JSON:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_5.jpg

图 11.5 – 使用非 UTF-8 格式存储表情符号

这个 JSON 在转换回网页时,将需要额外的解析步骤,这可能会减慢网页的加载速度。为了避免这种情况,我们可以找到一种方法,以表情符号输入的方式存储它。代码的最终输出将看起来更正确,如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_6.jpg

图 11.6 – 使用 UTF-8 格式存储表情符号

这样就好多了,从长远来看,也会更加可持续。在 Google Colab 中的整体代码看起来如下:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_7.jpg

图 11.7 – 用于基于 UTF-8 存储表情符号的 Colab 笔记本

这些只是一些简单的示例,帮助你入门如何优化大数据工作。我们已经讨论了很多关于数据的内容,也提到了机器学习的一些内容。但现在让我们把这一切总结一下,讨论一下最热门的话题:ChatGPT。接下来,我们将讨论 ChatGPT 背后的 DevOps 是如何工作的,以及当前类似的开源系统是如何广泛可用的。

ChatGPT 背后的操作

ChatGPT – 在我写这本书的过程中 – 从一个热门话题变成了生活中的一部分,有时几乎成为了信息工具的第二天性。它处理数据的方式以及它的本质一直是引发大量争议的话题。但我经常被我的一些不在行业内的朋友问到的是,它是怎么工作的?他们看到它几乎无缝地提供信息,无论用户的任何需求是什么,并且在聊天中将这些信息作为历史记录保留下来,以便以后回答问题。它还做得非常迅速。所以,大家都想知道它是怎么做到的。

让我们从 ChatGPT 是什么开始:它是一个大型语言模型LLM),这是一个非常大的神经网络,几乎接近于通用语言理解(即理解问题或查询并返回适当的解决方案的能力)。虽然 ChatGPT 目前是最大的热点,但这项技术实际上已经存在了几年,最初主要用于更具领域特定的聊天机器人。然而,最新的 LLM 已经被开发得可以讨论几乎任何话题,并在某些领域有轻微的知识专长。即便如此,ChatGPT 背后的概念非常简单:你给它提供的更多数据,它能容纳得更多,它就会变得更好。

当前的免费商业模型 GPT-3.5 由大约 1750 亿个参数组成,分布在 96 个神经网络层中。它是通过将超过 5000 亿个单词作为标记(数字)输入,并使用神经网络以模拟人类语言的方式找出这些标记之间的关联来实现的。用于这些标记的参考集就是互联网。就是这么简单,它将互联网的所有文本和数据拿来,利用这些来重建人类的互动和创造力。现在,你们中的大多数人可能已经看过 GPT-3/3.5 能做什么,而 GPT-4 则进一步提升了这个概念,使用了总计 1.7 万亿的数据点。正如我们在下图中所看到的,这就是向神经网络添加一些参数,直到它生成一个连贯的输出:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_11_8.jpg

图 11.8 – ChatGPT 的工作流程

如图所示,你输入提示并获得由训练好的神经网络生成的答案。就是这么简单。现在,你可能会想,发生了什么呢?这个问题的答案非常有趣,但可以归结为一句简洁的话:我们不知道。

事实上,神经网络是一个谜,因为它们是围绕我们自己的神经元构建和建模的,因此它们不是由人类训练的;它们自我训练,以实现最佳的成功,类似于人类在通过考试时会找到最适合自己的学习方法。因此,我们并不真正知道这些神经网络的核心是什么;我们只知道我们可以训练它们,让它们变得擅长于对话。

你也可以在家里训练一个类似的模型。一些公司已经开发出了更压缩版本的 LLM,可以部署在较小的服务器上,比如 Meta 的 LLaMA。但即便如此,你也可以在任何你偏好的云服务提供商和像 Hugging Face 这样的开源网站上找到源源不断的生成型 AI 模型,随时使用并尝试,以帮助你更好地理解。

总结

DataOps 或 MLOps 工程师的旅程其实就是一个 DevOps 工程师,他对数据和机器学习概念有所了解。就这么简单。但正如我们在这一章中看到的,这些概念的应用确实非常有用。

首先,我们讨论了 DevOps 和这些相关领域之间的异同,以及它们如何相互连接。通过这一点,我们成功地展示了一些实际的用例,这些用例在将 Python 与 DataOps 和 MLOps 配合使用时非常有用。

接下来,我们讨论了如何处理所谓的大数据。我们分析了哪些因素使得数据如此庞大,并且通过每个用例逐一解决这些方面。

最后,我们讨论了 ChatGPT 以及它如何在全球范围内为用户提供所有服务。我们讨论了它复杂性背后的简单性和神秘感,以及加速生成型 AI 发展的开源大型语言模型(LLMs)的新时代。

在下一章中,我们将深入探讨 DevOps 工具箱中或许最强大的工具——基础设施即代码IaC),以及 Python 在这一领域中的应用。

第十二章:Python 如何与 IaC 概念集成

你永远不要在没有登顶之前测量山的高度。到达山顶时,你会发现它其实并不高。

—— 达格·哈马舍尔德

因此,在我们接近这一倒数第二章时,我们将讨论基础设施即代码IaC)这一话题。它的确是一个热门话题,已经在 IT 界掀起了风暴。这是对如今应用程序和工作负载资源比以往任何时候都要多的现实的回应,剩下要做的就是以最优化的方式排列它们。当然,你可能会发现手动完成一次就能成功。但如果要一遍又一遍地做,而且还保证不会出错?那简直是无稽之谈,是对人力的浪费。

基于这些观察,IaC 的概念应运而生。它提出,如果资源的创建、配置和更新以代码的形式进行标准化,并且常量和变量按有序的方式排列,那么你就可以标准化资源的复制,使得备份、故障转移、重新部署以及许多其他操作变得更加容易。

当然,IaC(基础设施即代码)也有其反对者,因为所有好的技术都会有批评者。他们认为它过于快速、强大,可能会导致云账单飙升,并且部署的资源可能变得难以解开,且不易于自定义。

这是一个有趣的观点,但当我看到 IaC 时,我想到了亚当·斯密在《国富论》中的开篇,他谈到劳动分工如何比任何其他因素更能提高生产力。IaC 概念也做到了这一点,其中劳动(资源)与构建它们的方案分离,使得它们可以一遍又一遍地重复生产。

Python 作为一种语言对于 IaC 非常友好,可能是仅次于 Go 的第二种语言。Python 中有许多本地的 IaC 库和栈(我们将在后面讲解),此外,还有与非 Python 编写的 IaC 工具交互的模块和 API。Python 的灵活性以及 IaC 所需的松散但严格的复制需求,使得 Python 在快速发展的 IaC 趋势中占据了如此重要的位置。

本章将帮助你理解 IaC 中的一个概念,这个概念被认为是 DevOps 的独特之处,是为了解决 DevOps 工作负载中对自动化和标准化的持续需求而创造的。它将帮助你理解为什么 DevOps 和编码需要如此紧密地联系在一起。这就是为什么,在本章中,你将学习以下内容:

  • SaltStack的基础知识,以及它是如何用 Python 构建的,还包括如何在代码和命令行级别评估 SaltStack 模块

  • Ansible的基础知识,以及如何创建你自己的自动化 Ansible 模块

  • 如何使用 Python 与其他 IaC 工具(如 Terraform)进行交互,在已经构建的自动化之上添加更多自动化功能

技术要求

为了将本章的内容推进到逻辑上的结论,您需要满足一些技术要求:

使用 Python 的 Salt 库进行自动化和定制

我们谈论所有这些我们想要构建的炫酷架构和框架,谈论我们想要使用的各种工具,所有这些工作流程,它们很有趣,非常令人兴奋,但许多 DevOps 的核心还是服务器管理;即 DevOps 的运营部分。它在今天的世界中依然重要,且随着人们的使用,它将永远保持相关。

现代的服务器管理要求根据所托管应用的需求创建现代的、定制化的环境。它还要求具备大量的自动化特性,以便维护并根据当前的情况保持优化状态。

收音机从未被电视取代,电视也很可能不会完全被流媒体取代。一切都会变化、进化或减少,但本质和使用它所需的技能始终会以某种方式保持相关。这就是为什么服务器管理工具永远存在,并且它们会不断发展的原因。

这就是 Salt 库(与 SaltStack 互换使用)的用途。它本质上由一个中央服务器组成,可以用来向所有连接到它的服务器发送命令。要求是 minion(待管理的服务器)必须配置为接收来自主服务器(负责管理的服务器)的命令。这是一个相当简单的概念,通过使用最精良的 Python 代码来实现。

那么,让我们开始吧。我们将从安装 Salt 服务器和 minion 开始,然后,我们将看看如何根据需要自定义构成 Salt 的 Python 代码。

Salt 库的架构如我们所说,包括一个主服务器和多个 minion。所以,让我们从创建与这个配置相匹配的服务器开始:

  1. 我们将在 GCP 中创建一个主服务器和一个 minion,并在 AWS 中创建一个 minion,以展示跨云功能。在本练习中,我们使用 Ubuntu 作为主要的操作系统OS),但其他操作系统同样适用。我们将在 GCP 中创建一个 minion 和一个 Salt 主实例:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_1.jpg

图 12.1 – GCP 中的 Salt 实例

  1. 我们还将在 AWS 中添加一个 minion 实例:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_2.jpg

图 12.2 – AWS 中的 Salt 实例

  1. 现在,我们可以通过 SSH 连接到 salt-master 实例并安装 Salt 主库:

    salt-master --version to run a check on the installation and get the version, similar to the following:
    

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_3.jpg

图 12.3 – Salt master 版本

  1. 接下来,在两个 minion 实例中使用以下命令安装 Salt minion 库:

    salt-minion --version in order to verify installation and get the version, similar to the following:
    

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_4.jpg

图 12.4 – Salt minion 版本

  1. 接下来,返回到 Salt master 并运行以下命令:

    sudo nano /etc/salt/master
    
  2. 完成后,我们将在底部插入以下行,以处理 master 与 minion 之间的接口:

    interface: 0.0.0.0
    publish_port: 4505
    ret_port: 4506
    auto_accept: True
    
  3. 接下来,我们将运行sudo systemctl start salt-master来初始化 Salt master 系统模块,然后运行sudo systemctl status salt-master命令来获取 Salt master 的状态。当我们运行该命令时,得到的结果如下:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_5.jpg

图 12.5 – 运行 Salt master 服务器

这是正在运行的 Salt master;现在,我们需要配置我们的 minions。

配置 minions 的步骤与配置 master 类似,但有一些不同之处,我们将在这里探讨:

  1. 在每个 minion 上,运行sudo nano /etc/salt/minion,然后在nano文件中输入以下内容:

    master: <salt_master_ip>
    

    salt_master_ip替换为你的 Salt master 服务器的 IP 地址。

  2. 然后,运行sudo systemctl start salt-minion,这将初始化 minion。接着,运行sudo systemctl status salt-minion来检查 minion 是否在运行:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_6.jpg

图 12.6 – 运行 Salt minion

  1. 现在,在 Salt master 上,你可以运行一个小示例命令,如下所示:

    sudo salt '*' test.ping
    

这就是基本的内容。现在,让我们深入看一下 Python 代码的细节。

让我们拆解一个特定的 Salt 模块,以便学习其背后的细节:

  1. 每个 Salt 模块都是一个可以调用的 Python 函数。我们以文档中的一个模块为例,在这里是网络连接模块:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_7.jpg

图 12.7 – 来自文档的 Salt 模块

这是很棒的文档!它显示了该功能及其 CLI 版本。

  1. 让我们来看一下这个功能:

    connect function takes a hostname compulsorily and it takes a port number optionally. It also includes **kwargs, which is just a large number of arguments such as proto and timeout that the function may have. The following command connects to a DNS instance:
    
    

    connect 函数。代码中的等效内容如下所示:

    connect("google-public-dns-a.google.com", port = 53, proto = "udp", timeout = 3)
    

    这两个命令是等效的,但你可以看到从命令行运行它们的实用性,因为这些命令在命令行中执行比作为函数调用要更为方便。这对于许多命令行工具都适用,也是它们存在的原因之一。

    
    

接下来,我们将了解 Ansible,它的执行思想与 Salt 类似,但采用了略微不同的方法,同时仍然使用 Python。

Ansible 是如何工作的,以及其背后的 Python 代码

本节的大部分内容将会是你在上一节看到的相似内容,类似的工具、相似的实现等等。但像 SaltStack 一样,这也是基础设施即代码(IaC)领域中一个重要且常见的工具,这就是为什么它值得我们这么详细介绍的原因。Ansible 功能强大,学习曲线可能没有 SaltStack 那么陡峭,而且它对那些喜欢清晰打包好的代码且不需要太多修改的用户来说更为友好。哦,另外它是用 Python 编写的。

Ansible 由 IBM 在其 Red Hat 品牌下运行和维护(我喜欢现在技术公司为其更为“前卫”的产品命名一些DC Vertigo风格的品牌,这真的使我所说的它是艺术的观点更加成立)。它旨在通过 SSH 密钥对访问服务器,从而维护和管理服务器。这简化了一些操作,例如当你控制一台服务器时,所有相关的服务器都在同一个虚拟私有 VPC)中。

Ansible 在可以控制的操作系统方面更加灵活,但在本练习中,我们将使用旧而可靠的 Ubuntu。所有这些背景介绍结束后,让我们进入 Ansible 的细节,给你一个它如何工作的简单示例。

我们将重用在 Salt 实验中使用的相同实例,所以让我们从主实例开始:

  1. 让我们首先通过 pip 在系统上安装 Ansible:

    pip as well, though that is not a frequent occurrence. Let’s run this command and install Ansible:
    

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_8.jpg

图 12.8 - Ansible 安装成功

  1. 完成后,创建一个目录作为通用的 Ansible 配置目录,并进入该目录:

    mkdir ansible_project
    cd ansible_project
    
  2. 接下来的步骤是创建一个 inventory.ini 文件,它将起到与 SaltStack 中主 IP 相反的作用,将被控制的服务器的 IP 地址放入控制服务器中。

  3. 运行 sudo nano inventory.ini,这将创建一个清单文件,并在其中列出你希望运行的 IP 地址:

    [myhosts]
    <IP_1>
    <IP_2>
    
  4. 现在,你可以运行 ansible-inventory -i inventory.ini --list 命令,这将给你以下主机列表:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_9.jpg

图 12.9 - Ansible 清单

  1. 接下来,你可以通过以下命令对这些主机进行 ping 测试,以检查连接状态:

    ansible myhosts -m ping -i inventory.ini
    
  2. 现在,你可以通过集中命令服务器运行 playbooks 和 runbooks,甚至可以通过更改清单列表来将主机分组到不同的舰队中。

这些就是 Ansible 的基础;现在,让我们深入了解一下并查看 Ansible CLI 背后的 Python,正如我们在 SaltStack 中所做的那样。我们将通过创建一个自定义模块来使用 Ansible。这次我们会保持本地操作,但这基本上就是你如何通过 Ansible 运行自定义操作的方法。

现在,让我们创建一个由我们自定义的 Ansible 模块:

  1. 在你已安装 Ansible 的环境中,创建一个 hello_ansible.py 文件,并将以下代码添加到文件中:

    from ansible.module_utils.basic import AnsibleModule
    def join_strings(string_1, string_2):
        return string_1+string_2
    def main():
        module_args = dict(
            string_1=dict(type='str', required=True),
            string_2=dict(type='str', required=True),
        )
        result = dict(changed=False, message="" )
        module = AnsibleModule(
            argument_spec=module_args,
            supports_check_mode=True
        )
        string_1 = module.params['string_1']
        string_2 = module.params['string_2']
        result["message"] = string_1 + " " + string_2
        module.exit_json(**result)
    if __name__ == '__main__':
        main()
    

    这给我们提供了将要执行的 Python 代码,现在我们需要将 Python 代码的权限更改为可执行的。我们可以使用以下命令来实现这一点:

    chmod +x hello_ansible.py
    
  2. 接下来,我们需要制作一个剧本来在本地运行该函数,为此,我们可以创建一个名为hello.yml的剧本,并向其中添加一些代码:

    ---
    - hosts: localhost
      gather_facts: false
      tasks:
        - name: Hello World
          add_numbers:
            string_1: Hello
            string_2: Ansible
          register: result
        - debug:
            var: result
    
  3. 现在,执行 YAML 文件:

    ansible-playbook -M . hello.yml
    

    这将为你提供一个字符串形式的结果,如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_12_10.jpg

图 12.10 – 我们的 Ansible 模块的结果

这就是如何创建一个自定义的 Ansible 模块。这个模块将返回你输入的两个字符串的和,可能是你使用模块时能够做的最基本的操作。但其他一切都是相同的,即使是更复杂的操作。只需将代码中的join_strings替换为你选择的函数,并添加执行该函数所需的变量,最后返回结果值。例如,它可以是一个重新启动服务器或运行特定 CLI 命令的函数;几乎可以是你在使用的操作系统中可以执行的任何命令行操作。

现在,即便如此,这在可用资源及其使用方式方面仍然略显不足。它适用于更传统的系统,但对于需要非常规架构的系统,像 Terraform 这样的工具更为合适。接下来,我们将讨论如何使用 Terraform 与 Python 结合,进一步实现 IaC 自动化。

使用 Python 自动化 IaC 的自动化

基础设施即代码(IaC)已经变得越来越受欢迎,且以人们从未想象过的方式发展。当前最流行的 IaC 框架无疑是 Terraform。Terraform 不仅适用于服务器及其他更为稳定的资源,它同样适用于 API 和更松散的基础设施。基本上,任何可以在主要云平台中使用的资源,都有一个 Terraform API 可以使用。Terraform 在许多方面都是终极自动化工具,并且可以通过 Python 进一步实现自动化。

Terraform 当然是用 Go 语言编写的,这非常好,因为 Go 是 Python 的一个非常好的补充。两者各有所长,一个弥补另一个的不足。Go 适合单一实现,而 Python 在扩大该实现的有效性方面非常出色。基本上,Go 是子弹,Python 是枪,这是一个有效的组合。我们将在本节中充分利用这一组合。

Terraform 的创建者 HashiCorp 已经创建了允许 Python 与 Terraform 交互的 API。这些 API 被打包在cdktf库中,并由 HashiCorp 在多种语言中发布。让我们看看安装和运行cdktf库所需的步骤:

  1. 你首先需要安装 NPM、NodeJS 和 Terraform CLI,才能安装cdktf-cli

    npm install -g cdktf-cli
    
  2. 接下来,你可以使用cdktf创建一个 Python 环境:

    cdktf init --template=python
    
  3. 这将创建一个新的 Python 模板,之后可以用来运行 Terraform 模板。在模板中,你可以在stacks文件夹中找到main.py文件。在该文件夹中,你可以添加以下脚本:

    from constructs import Construct
    from cdktf import App, TerraformStack
    from imports.aws import AwsProvider, S3Bucket
    class MyStack(TerraformStack):
        def __init__(self, scope: Construct, ns: str):
            super().__init__(scope, ns)
            AwsProvider(self, 'Aws', region='us-east-1')
            S3Bucket(
                self,
                '<Terraform_Function_Name>',
                bucket=<'Bucket_Name_Here>',
                acl='private'
            )
    app = App()
    MyStack(app, "python-cdktf")
    app.synth()
    
  4. 这段代码足够简单,易于理解;它的工作方式与 IaC 模块完全相同,在你执行程序时创建一个名称为指定名称的 S3 存储桶。要执行程序,运行以下命令:

    cdktf deploy
    
  5. 如果你想撤销程序并仅删除你创建的资源,你只需运行以下命令:

    cdktf destroy
    

这基本上就是你需要做的所有事情。Terraform 的 AWS、Google Cloud 和 Azure 模块通常会随着安装一起提供,使用cdktf安装时,相应的 Python 库也会包含在内。你可以在 HashiCorp 的 GitHub 和官方网站上找到这些库的文档以及它们的功能。HashiCorp 对其产品能做什么非常明确,尽管有时将所有这些信息整理到一个地方可能会有些困难。所以,通过这些参考资料,你几乎可以创建任何你想要的资源;一切都取决于你的想象力。

总结

所以,这就是本章的内容,虽然比你可能习惯的章节要严肃一些,但这确实是严肃的事情。IaC 是一个值得认真对待的概念;它非常强大,可以解决许多需要应用 DevOps 原则的问题。

我们最初查看了使用 Python 在 SaltStack 中应用 IaC 的非常基础的案例。它虽然相当基础,但对于简单项目来说非常有效。我们通过深入了解 SaltStack 的内部原理,理解了它 Python 模块背后的逻辑。

之后,我们查看了稍微灵活一些的 Ansible,发现了它所提供的所有便利功能以及自定义的可能性。

最后,我们看了 Terraform 和cdktf,它与 Python Terraform 及资源模块一起使用,用于执行 Terraform 的资源创建。

所有这些内容希望能够帮助你获得一个新的视角,了解 IaC,并理解它在 DevOps 中的重要性以及它与 Python 的集成。

总结来说,IaC 是强大的、广阔的,且值得学习。在下一章中,我们将把你在这里和前几章学到的所有内容提升到一个更高的层次。

第十三章:将你的 DevOps 提升到新水平的工具

我所做的就是劝说你们所有人,无论老幼,不要只顾自己的人身安全或财产,而是主要关心灵魂的最大改善。

– 苏格拉底

好的,我们到了,最后一章,我们共同旅程的最后一站。过程非常愉快;希望你学到了些东西——我在教授你并试图帮助你进行你的旅程时也经历了许多快乐。整本书对我来说也是一段旅程。现在我们将以一些工具结束,本章将帮助你进一步推进你自己的 DevOps 和 Python 之旅。

将本章视为一个尾声:快速浏览本书中发生的一切,并回顾所有你所学到的知识,并将其放入实际的背景中。在《指环王》中,当战争结束时,我们看到所有角色都有自己生活继续的结局。这也是我写本章的目标,给你留下些能够激发你好奇心的东西,鼓励你进一步走上 DevOps 的道路,并自己去了解你能够实现什么。

说到个人感受,我可以说,在写这本书的过程中,我也在许多方面发生了变化。我在书中提到的协作概念帮助我与所有使这本书成为可能的优秀人士进行了很好的合作。它帮助我在某种程度上成长,并推动了我的能力的边界,让我明白了作为一名作者的责任。

我们所进行的旅程会改变我们,通常是变得更好。它们迫使我们面对自己是谁,以及我们想做什么。我在写这本书的过程中所进行的旅程让我更加欣赏我之前拥有的知识以及在本书研究过程中获得的知识。它让我成为了一名职业作家,虽然这本书不会像它对我一样成为你生活中的重要部分,但我希望它也能帮助你在自己的旅程中有所推进。

所以,最后一次,在本章中,你将学习以下内容:

  • 允许你将更复杂的自动化变为现实的高级自动化工具

  • 用于结合监控和数据分析工作负载并运用两项技能的高级监控工具

  • 当事件和警报真的失控时的高级事件响应策略

技术要求

要跟随本章,你将需要以下内容:

  • grafana.com上的 Grafana 账户

  • 一个 AWS 账户,能够使用 AWS Step Functions 和 Compute Engine

  • 一个 GitHub 账户,用于使用本书代码库中的代码 (github.com/PacktPublishing/Hands-On-Python-for-DevOps)

  • 启用了 Google Kubernetes API 的 Google Cloud Platform 项目

  • 你在学习过程中达到这一阶段所获得的成就感

高级自动化工具

在本书中,我强调了自动化的价值,它对于 DevOps 领域的重要性以及提高整体生产力的作用。只要小心使用并理解你的使用场景,自动化是很难过度的。在本书中,我们已经扩展了我们的工具箱,让我们可以在多个场景中自动化任务。我们甚至弄清楚了如何自动化那些自动化任务。但现在,让我们看看一个可能会将这个过程推进到更高层次的工具。它也恰好是我个人的最爱之一。

AWS Step Functions 是我总是非常兴奋地讨论和使用的工具。每当我寻找自动化工作流工具的金标准时,我总是想到它。我看到的任何其他表现良好的自动化工具,都具有与 Step Functions 非常相似的功能和可用性。当然,其他主要云服务也有可以替代的等效服务,并且在那些环境中也能很好地工作,但我更喜欢 Step Functions 的用户体验,并且它是最容易在这个工作流中解释的工具。

让我们来看一下 Step Functions 中的一些步骤(以及步骤中的步骤):

  1. 登录到你的 AWS 账户,在控制台中搜索 Step Functions

  2. 进入 Step Functions 页面,在右上角点击 Create state machine

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_01.jpg

图 13.1 – 创建状态机

Step Functions 工作流由动作组成,动作是服务的调用,完全基于它们的 API 参数;还有流程,流程决定数据的流向。

我们将演示的示例函数完全由流程组成,因为使用动作仅需要调用 API,你可以在任何需要的地方应用它们。以下是该流程的示意图:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_02.jpg

图 13.2 – 状态机图

这是直接从 Step Functions 控制台导出的,你可以在这里看到:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_03.jpg

图 13.3 – 状态机控制台

它也已经以代码格式导出,并放置在本书的 GitHub 仓库中以供使用。

我们可以像这样分解图中的内容 图 13.2

  1. 并行状态运行两个不同的功能,PingPong

  2. 它们都产生介于用户输入的起始值和结束值之间的随机数。

  3. 完成后,会比较这两个数字,看看哪一个大于另一个。

  4. 如果 Ping 大于 Pong,状态机会停止执行;否则,它将执行并行状态。

  5. 一旦保存了状态机,你可以访问它并使用 Start execution 按钮运行它。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_04.jpg

图 13.4 – 在状态机上启动执行

  1. 你会被问到在此状态机中希望输入什么。在这种情况下,我们将选择起始数字为 5,结束数字为 100

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_05.jpg

图 13.5 – 启动状态机所需的参数

  1. 该机器将继续直到 PingPong 给出相等的值,对于像这样的较小数字,约需两秒钟。

  2. Step Functions 记录了它通过的所有状态以及结果:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_06.jpg

图 13.6 – 状态机中发生的事件

这个特定的应用看起来相当普通,但它是一个很好的概念验证,展示了如何使用 Step Functions 来创建工作流。一个实际应用的例子可以是我们以前用过的简单例子:删除 S3 存储桶中的所有对象。AWS 的用户界面中没有清晰的方式一次性删除所有对象;你需要一个一个地删除。但通过 Step Functions(它与每个 AWS 服务都集成),你可以选择并行列出并删除 S3 存储桶中的所有对象。如果你愿意的话。现在,我们将转向监控这些应用,了解如何进一步优化它们。

高级监控工具

监控的目的一直是确保你所说的工作项仍然在正常运行。而实际情况往往是,它们不会正常工作。这可能是你的错,也可能不是;故障的概念会妨碍解决问题。对工作负载进行适当的监控为更容易地解决问题提供了途径。

最简单的工作负载可以进行监控,并且对于接收到的信息的反应可以实现自动化,这样大部分时间你甚至无需参与处理问题。对于更复杂的工作负载,保持监控仍然很重要,以便能够快速响应任何情况,并且实时获得更多关于情况的信息。

通常情况下,随着你的解决方案变得越来越复杂,它开始使用更多的工具。更多的工具和服务意味着需要更多的监控,而且监控的复杂度也会增加。如果你的监控来自多个地方,它会变得相当麻烦。因此,一个好的解决方案是将监控集中在一个可以存储和管理所有数据的中心位置。

这时,Grafana 就派上用场了,它是我想要谈论的工具,因为它不仅提供了极为广泛的监控选项,还提供了令人惊叹的部署选项,允许你对 Grafana 实例进行管理或定制,这意味着它是针对两类人群的解决方案:那些偏好自制解决方案的人和那些偏好现成解决方案的人。

当我第一次开始研究 Grafana 时,我正在写一篇关于如何通过一个云的监控服务来监控多个计算实例的博客。我发现,虽然这相对简单,但仍然存在一些尴尬的问题。大多数时候,选择一个云平台往往会在其他服务上带来一些复杂问题。很多这些问题都被 Grafana 解决了,并且得益于它所投入的所有精力与工作。

那么,让我们深入了解使用 Grafana 的免费账户等级:

  1. 首先,创建一个 Grafana 账户。它是完全免费的,并且提供了很多单点登录(SSO)选项,这是我非常喜欢的。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_07.jpg

图 13.7 – Grafana 注册

  1. 然后,它会要求你输入个人监控子域名的 URL 以及部署实例的区域。设置好这些后,你就可以开始了。

  2. 或者,你也可以从这里下载并安装 Grafana 到自定义服务器:grafana.com/grafana/download?edition=oss。它几乎提供了所有操作系统的安装说明。

  3. 让我们来看看我们的仪表盘:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_08.jpg

图 13.8 – Grafana 仪表盘

如你所见,Grafana 为我们提供了许多监控选项、集成和数据源。在这个练习中,我们将使用一个非常普遍的数据源,几乎任何人都能访问:Google 表格。

  1. 在控制台的搜索标签页中,搜索Google Sheets。接着,你需要安装插件。它位于最右侧的蓝色按钮:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_09.jpg

图 13.9 – Google 表格连接器

  1. 然后,等待插件安装完成,并从同一页面添加新的数据源。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_10.jpg

图 13.10 – 激活 Google 表格连接器

  1. 然后,Grafana 会要求你为要访问的 Google 表格实例创建身份验证凭据,并会提供适当的操作说明。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_11.jpg

图 13.11 – Grafana 在其仪表盘上提供的说明

在这种情况下,从安全角度来看,JWT 令牌选项可能是最好的。你不希望随便放置 API 密钥,因此请按以下步骤操作:

  1. 按照给出的步骤创建一个服务账户,并将该服务账户的电子邮件地址授权访问你的示例 Google 表格。

  2. 一旦你上传了 JWT 密钥,你就可以访问该服务账户可以访问的所有内容。我使用了一个包含一些示例网页流量数据的 Google 表格,但你可以使用任何你想要的表格进行此操作。

该仪表盘的缓存时间已设置为零秒,这意味着它会在 Google 表格中的信息发生变化时自动刷新。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_12.jpg

图 13.12 – 可添加到仪表盘的样本探索

然后你可以将此探索添加到新的监控仪表盘中。如图 13.12所示,你可以选择添加按钮,然后选择添加到 仪表盘选项。

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_13.jpg

图 13.13 – 创建带有面板的新仪表盘

  1. 这将创建一个包含你的数据表的新仪表盘。现在我们可以在其上添加一些数据可视化。在新的仪表盘中,点击添加,然后选择可视化。你会看到一个类似于 Google Sheets 表格的面板,在这里你可以添加像这样的图表:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_14.jpg

图 13.14 – 通过可视化生成的条形图

你可以看到我们有一个高度可自定义的图表,包含所有以可视化形式呈现的信息。

一旦你完成了可视化,返回到你新创建的仪表盘。你的最终可视化将像这样:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_15.jpg

图 13.15 – 最终的 Grafana 仪表盘

同样,这会随着数据的变化而改变。

到目前为止,我们已经看到了处理事件和自动化的事件。那么,当发生一个无法通过重置来解决的事件时会发生什么呢?当你处于不利的局面,被迫进行损害控制时又会怎样呢?好吧,我们将在下一部分找到答案。

高级事件响应策略

事件响应应该简单且有条理,应该解决最初导致事件发生的问题。但是,再次强调,不管我们如何努力,它永远不会那么简单。有时候你正在处理一个你不太熟悉的系统。有时候你所在的团队经验不足,无法提供有意义的帮助。这些情况由于时间和人员的限制是不可避免的,并且在很大程度上超出了我们的控制范围。在这种情况下,我们只能利用现有的资源应对。

但有一种情况非常常见,会造成广泛的损害,以至于对事件的响应不再是关于恢复损害,而是关于从已经造成的损害中恢复。这种情况通常发生在任何形式的事件长时间没有被报告或监控时。当发生数据泄露,或者系统中存在未知/未发现的错误时,这种情况尤其常见。

那么,当你遇到这种情况时,你该怎么办?首先,不要慌张。但也不要想“不要慌张”——那会让你更慌!以逻辑的方式面对问题。我现在会给你一些关于如何处理这种情况的见解。这是基于我过去面对的情况,以及我从各个地方学到的解决问题的经验。我认为这是一种很好的解决很多问题的方法,无论是 IT 问题还是其他问题。那么,接下来我们就开始吧。

步骤 0:阅读

因为:你没有 做过够多。

说真的,很多错误仅仅通过阅读错误信息或者故障的输出就能解决。相信你所看到的,它会给你回报;问题的解决方案就在你眼前。好吧,至少是解决方案的第一步。但如果你想走到那里,你需要阅读并理解解决这个问题的过程。你不能在没有了解所有细节的情况下就跳到第一步。

步骤 1:如果是一个单一的问题, 谷歌它

因为:你不是 一个人。

这是非常严肃的建议。90%你遇到的错误都可以通过谷歌搜索解决。这是因为别人可能也遇到过你面临的问题,他们可能也已经得到了正确的解决方案。你很有可能在Stack Overflow论坛、GitHub 仓库的评论、一个不太知名的 YouTube 视频或者类似的地方找到解决方案。你可能会想:“这不可能这么简单——我怎么可能仅仅通过谷歌就能解决我最大的难题。”马上停下这种想法!我曾经看到有人花了整整两个小时尝试一个迁移桥,我们在看完一个 YouTube 教程后五分钟就搞定了。事情就是这样——别浪费时间,寻找快速、知情的解决方案。它们能处理那些小问题,信我,大多数问题都是小问题。

步骤 2:如果是多个问题,就多次谷歌(或者,现在可以 用 ChatGPT)

因为:一个大问题是几个小问题 合成的一个。

这是真的:任何问题都可以分解成最小的组成部分,并在那个层面上解决。这是基本的逻辑;如果你有一个大问题,把它转化成更小的问题,然后去谷歌一下。如果它是一个真的大问题,或者将问题分解的过程琐碎且会占用你大量时间,你现在可以使用 ChatGPT 来解决;它在这方面相当不错。将大量无用的文字转化成更小、更有用的版本,可能是 ChatGPT 最擅长的事情。好好利用它,充分利用这些你手头的强大工具。

步骤 3:遵循归纳和演绎的方法

因为:它能解决你所遇到的任何日常问题

解决方案和解决问题与产生想法截然不同。想法像是来自上帝的闪电,它们是我们系统中的幽灵,从最奇怪的地方冒出来。抓住一个想法并将其付诸实践是一种虚无的体验,就像是一次宗教启示。解决方案不是这样的。它们简单、基础,且—如果你懂得如何解决问题—更容易处理。其逻辑可以用两个词来概括:归纳和演绎。

我解决过的每一个重大问题,只要我能接触到样本环境,我都会用这种逻辑来解决。这是我在《禅与摩托车维修艺术》一书中学到的理念,书中的叙述者通过这两种方法解决最平凡的问题,并将这些概念与量子物理和禅宗相联系。这些概念并不复杂,但所有问题的解决都可以在它们的框架内定义。

归纳是重现导致问题的元素,以准确了解问题发生的位置。在事件管理中,这对于在样本应用程序中重现事件并通过分解步骤找出问题所在非常有用。

演绎是从结果出发,回溯到开始。这种方法适用于错误的逻辑无法重现,或者事件已经发生,但不知道如何发生。在这种情况下,你从最终结果开始,推理出可能导致这些结果的原因。

因此,将这些结果总结成图表,你可以这样来看待它们:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/hsn-py-dop/img/B21320_13_16.jpg

图 13.16 – 解决任何 IT 问题的步骤

这就是你解决所有问题的方法。试着在几个问题上应用看看,看看你能走多远。如果你想了解创意的形成过程,嗯,它们是相当随机的,但它们可以通过类似这些方法的手段被明确并转化为行动点。现在,你已经学会了一切。明智地使用你的知识吧。

总结

好的,这不仅仅是本章的结束,也是整本书的结束。作为这本书的读者,你的旅程结束了,而我作为首次作者的旅程也结束了。这是一次不小的历程。总体来说,谈到这一章,它比许多其他章节更加抽象,代码内容也相对较少,但那是因为我已经意识到一件事:所有这些系统归根结底都是代码。你接触到的每一件事,都一定是以某种方式被编码过的;关键在于你是否能够理解并操控背后的逻辑。

在关于步骤函数的部分,你学习了一个非常有用的自动化工具,但你也学到,这是一种以视觉化方式使用编码逻辑,并将这种方式整合进许多强大工具和服务的手段。

在高级监控部分,我们学习了一个强大的监控和可视化工具——Grafana,以及集中监控的重要性,通过集中管理,避免了从多个位置查看数据并解析数据的繁琐过程,而是有一个统一的位置来管理所有工作负载。

最后,你了解了我解决问题的方法,确实是一种有效的方式,如果我自己说的话。希望你能有机会在自己的工作负载中应用这个方法。这是一种元代码,一种不依赖于任何平台或技术,但能够在所有平台上有效工作的算法。

所以,我必须向你告别了。我们已经走到了尽头,但请将其视为开始的结束,因为接下来发生的才是最重要的部分。这将定义你是谁以及你将做什么。现在是时候将所有这些知识应用到你自己日常事务中了。记住:力量掌握在你手中;是时候 使用它

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值