使用 Sensu 和 Ansible 进行代码监控
使用 Sensu 和 Ansible 进行代码监控
一个全面的基础设施即代码 (IaC) 计划应包括监控和可观察性。将被管理基础设施的主动监控纳入其中,将形成一种共生关系,在这种关系中,故障会自动检测到,从而实现事件驱动的代码更改和新部署。
在这篇文章中,我将回顾我和 Tadej Borovšak (XLAB Steampunk 的 Ansible 布道师,我们在 Sensu Go 的认证 Ansible 内容集合方面与他们合作) 共同举办的一场网络研讨会。您将了解代码监控如何作为 IaC 工作流的反馈循环,从而改进整体自动化解决方案,以及如何使用 Sensu Go 的认证 Ansible 内容集合 (包括演示) 自动化您的监控。
在深入研究之前,请先简要了解一下 Sensu。
关于 Sensu
Sensu 是一个交钥匙的可观察性管道,它在任何云 (从裸机到云原生) 上提供代码监控。Sensu 为 DevOps 和 SRE 团队提供了一个灵活的可观察性平台,使他们能够重用现有的监控和可观察性工具,并与最佳的解决方案 (如 Red Hat Ansible 自动化平台) 集成。
使用 Sensu,您可以重用现有的工具 (如 Nagios 插件),以及监控短暂的云基础设施 (如 Red Hat OpenShift)。Sensu 通过弥合可观察性方面的差距来帮助您消除数据孤岛,将各种工具整合在一起,通过同一个管道将指标、日志和跟踪整合在一起,然后根据您的组织需求进行分发。您还可以使用内置的自动修复或与 Red Hat Ansible 自动化平台等产品的集成来自动执行诊断和自我修复。
为什么监控 + 自动化?
简而言之,监控是您几乎需要持续进行的操作,以提供有关故障和缺陷的实际信息。自动化是指对某事采取行动,它不一定是连续操作。如果发生故障,您可以自动化其修复,那么就可以节省宝贵的人工时间。
通过将被管理基础设施的主动监控纳入其中,您可以享受共生关系的好处,在这种关系中,新的指标和故障会在响应代码更改和新部署时自动收集和检测到。我们将这个概念定义为 代码监控,它是对整个应用生命周期进行统一视图和管理的关键。
使用代码监控,您可以像使用 Ansible 自动化声明基础设施即代码一样声明监控工作负载。基础设施即代码和代码监控在不同的轨道上运行,服务于不同的目的。使用 Sensu Go 的 Ansible 内容集合,您可以轻松地部署监控,启动后端集群,并将您的代理作为配置的一部分部署到基础设施中。从那里开始,代码监控方面将接管:您可以更新您的监控,无需 在每次要进行少量监控更改时都重新配置现有基础设施。
使用 Sensu Go 的 Ansible 内容集合进行 Sensu 自动化
Sensu Go 的 Ansible 内容集合使您更轻松地创建一个全面运行的 Sensu Go 监控代理和后端的自动化部署。以下演示展示了一个最小的 Sensu 设置:如何安装后端和两个代理,以及建立更安全的连接,因为我们将从后端传递敏感信息到代理。
Ansible 用户可能熟悉“清单”一词。在本例中,我们的清单文件包含两个定义的组:后端组和代理组。清单文件中的信息告诉 Ansible 如何通过 SSH 安全地连接我们的主机。
--- all: vars: ansible_ssh_common_args: > -o IdentitiesOnly=yes -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i demo children: backends: hosts: backend: ansible_host: 192.168.50.20 ansible_user: vagrant agents: hosts: agent0: ansible_host: 192.168.50.30 ansible_user: vagrant agent1: ansible_host: 192.168.50.31 ansible_user: vagrant
https://gist.github.com/tadeboro/00cabf8fa79f4c9c90cda8cdf9645f32#file-inventory-yaml
我们还需要一种方法来指定我们希望资源处于何种状态。这就是 Ansible Playbook 的作用,我们将使用它来设置后端。它是一个 YAML 文件,既可以被人阅读,也可以由机器执行。
--- - name: Install, configure and run Sensu backend hosts: backends become: true tasks: - name: Setup secret environment variables ansible.builtin.template: src: secrets.j2 dest: /etc/sysconfig/sensu-backend vars: secrets: MY_SECRET: value-is-here - name: Install backend include_role: name: sensu.sensu_go.backend vars: version: 6.1.0 cluster_admin_username: >- {{ lookup('ansible.builtin.env', 'SENSU_USER') }} cluster_admin_password: >- {{ lookup('ansible.builtin.env', 'SENSU_PASSWORD') }} # mTLS stuff agent_auth_cert_file: certs/backend.pem agent_auth_key_file: certs/backend-key.pem agent_auth_trusted_ca_file: certs/ca.pem
https://gist.github.com/tadeboro/00cabf8fa79f4c9c90cda8cdf9645f32#file-backend-yaml
我们将使用此剧本执行两个主要功能
- 在后端设置环境变量,我们将在这里存储敏感信息。我们将使用 Sensu 的内置机密管理 来安全地存储和共享这些信息。
- 安装和配置 Sensu 后端。对于安装,我们将使用后端 Ansible 角色,并使用文件中指定的变量对其进行参数化。在本示例中,我们指定要安装的 URL、如何初始化数据库以及如何设置安全连接,以确保后端和代理之间的通信安全。
值得注意的是,此示例展示了如何将敏感信息保留在剧本之外,使其完全安全地共享并提交到版本控制系统。
我们将输入以下命令来执行剧本
ansible-playbook -i inventory.yaml backend.yaml
尽管剧本相对较短,但 Ansible 实际执行的操作相当复杂:向发行版添加存储库、安装组件、复制 TLS 证书,以及使用指定的用户帐户和密码配置和初始化后端。不到半分钟,我们就启动了运行中的 Sensu Go 后端!
我们登录 Sensu Web UI,但目前还不会看到任何内容,因为我们还需要设置代理,我们将使用代理剧本进行准备。
--- - name: Install, configure and run Sensu agent hosts: agents become: true tasks: - name: Install agent include_role: name: sensu.sensu_go.agent vars: version: 6.1.0 # mTLS stuff cert_file: certs/backend.pem key_file: certs/backend-key.pem trusted_ca_file: certs/ca.pem agent_config: name: "{{ inventory_hostname }}" backend-url: - wss://{{ hostvars['backend']['ansible_host'] }}:8081
https://gist.github.com/tadeboro/00cabf8fa79f4c9c90cda8cdf9645f32#file-agent-yaml
它与我们的后端剧本非常相似;主要区别在于主机参数和角色名称,因为我们正在执行剧本以在主机上安装 Sensu 代理。在后端剧本中,我们使用默认配置;在代理中,我们需要指定一个名称,以便我们知道如何引用此代理。我们还需要指定后端位置。我们没有将后端的地址硬编码到剧本中,而是告诉 Ansible 从清单文件获取这些信息,这使我们能够重用已存储在 Ansible 清单文件中的信息。
要执行代理剧本并安装代理,我运行相同的命令 (将文件名替换掉)
ansible-playbook -i inventory.yaml agent.yaml
和以前一样,Ansible 会负责安装代理所需的一切,并且安装会在两台机器上同时进行。
切换到 Sensu Web UI 中的默认命名空间,在“实体”下,您可以看到我们的两个实体已准备就绪。
现在,我们需要为我们观察的事件进行配置。
注意:从 Sensu Go 6 开始,订阅可以在运行时更新,无需重新启动代理。
这是我们的 Sensu 配置文件
--- - name: Manage Sensu Go resources hosts: localhost gather_facts: false tasks: - name: Configure agent subscriptions sensu.sensu_go.entity: name: agent0 entity_class: agent subscriptions: - demo - name: Enable env secrets provider sensu.sensu_go.secrets_provider_env: state: present - name: Configures custom secret sensu.sensu_go.secret: name: my-secret provider: env id: MY_SECRET - name: Create a check that uses secret sensu.sensu_go.check: name: secret-check command: echo $SECRET secrets: - name: SECRET secret: my-secret subscriptions: demo interval: 10 publish: true
https://gist.github.com/tadeboro/00cabf8fa79f4c9c90cda8cdf9645f32#file-config-yaml
这里我们告诉代理监听“demo”订阅,并执行来自该订阅的任何操作。为了将机密引入检查,我们需要确保我们的机密提供程序已准备好,并注册一个机密,该机密将从后端上的机密环境变量中获取其值。最后,我们创建一个简单的检查,该检查会回显我们的机密。
我们运行配置剧本
ansible-playbook -i inventory.yaml config.yaml
在 Sensu Web UI 中查看,我们可以看到我们的代理获得了“demo”订阅。转到“事件”并列出所有事件,您可以看到 agent-0 执行了机密检查,并且我们的机密值“value-is-here”安全地从后端传递到了代理。
如您所见,我们的 Ansible 内容集合使您能够简洁地描述您的基础设施,让 Ansible 处理设置的复杂细节。
观看下面的完整演示
https://www.youtube.com/watch?v=ShN867iRFvQ
Sensu 演示:构建监控工作流
Ansible 部署 Sensu 平台后,我们使用 Sensu 的内置配置实用程序 - sensuctl CLI。使用 sensuctl,我们可以管理以下 Sensu API 资源:
- 实体:代理 + 代理
- 检查:代理运行的计划监控工作负载
- 可观察性管道:过滤 + 转换 + 处理
- 事件:Sensu Go 管道处理的基础数据结构
- 订阅:松散地将检查与实体耦合
- 资产:可共享的二进制文件,用于支持监控工作负载;Sensu 在运行时安装,无需预先配置主机
在第一个演示中,我将构建一个监控工作流,以创建一个 NGINX 服务并监控它以确保它正常运行。
与我们之前的演示一样,我有一组 Ansible 剧本,可以快速创建后端和单个代理。在这里,我还使用 sensuctl (管理 Sensu 中资源的命令行工具) 设置了检查。Sensu Web UI 和 sensuctl 都与同一个 REST API 交互 - sensuctl 只是管理 Sensu 的另一种方式。
我们为代理配置了与后端通信的功能,并使用 Ansible 内容集合为此次演示定义了一个新的命名空间 - 通过与 Sensu API 交互来设置一个新的命名空间。我还设置了 基于角色的访问控制 (RBAC),它允许我为用户提供仅用于审计的访问权限(即,他们不需要对命名空间具有写入权限)。然后,我在代理运行的同一主机上设置了一个 NGINX 主机。
NGINX 服务启动并运行后,我使用 sensuctl configure --insecure-skip-tls-verify
设置了 CLI 客户端(为了演示目的;在生产环境中不要使用此标志!)。使用 sensuctl entity list,我可以看到所有可用的实体和订阅(在我们的演示中,是 webinar-agent0)。我们还没有定义任何检查,因此 sensuctl check list 不会显示任何内容。我在这里使用声明式 YAML 文件来定义一个名为 check-http 的检查命令,它本质上是检查我们的 NGINX 服务是否正常运行,使用 Sensu 的动态运行时资产 提供该命令。我在此示例中使用的 Ansible 处理程序 使 Red Hat Ansible Tower 在该服务出现故障时尝试修复问题。
现在,当我运行 sensuctl check list 时,我看到了我们的 check-http。它处于发布状态 false,因此我们有机会在运行检查之前定义和测试检查。要运行一次检查,我运行 sensuctl execute check-http。(我一开始遇到了错误,因为我需要添加资产。)您可以通过 Sensu Go 的 Ansible 集合处理所有这些资源(而不是使用 sensuctl)。
我设置了一个 NTP 检查,确保它使用监控插件运行时资产(这些资产只是从 Nagios 插件中衍生出来的监控插件构建)。我们还有 NGINX 检查,它通过一个 Ruby 运行时环境进行,我们不需要预先配置;Ruby 环境与该插件匹配。同样,如果您想将所有内容都保存在 Ansible Playbook 中,则可以通过 Ansible 集合处理所有内容。
NTP 和 NGINX 检查处于已发布状态,并以一定间隔运行 - 它们不需要单独执行。现在,当您查看事件列表时,您会看到两个检查都在运行。由于运行时资产存在,这些命令(如 sensuctl check list)作为最初完成的配置的一部分存在于代理中,而无需我安装任何额外的 RPM 包或二进制文件。
就是这样:一个真正适用于服务的监控工作流程!
观看下面的完整演示
https://www.youtube.com/watch?v=ShN867iRFvQ
开始自动化吧!
让我们回顾一下到目前为止我们已经涵盖的内容:我们使用 Ansible 内容集合自动化了 Sensu 后端和代理部署,并创建了一些监控代码(例如 check-http.yaml)来监控服务并使用 Ansible Automation Platform 自动化修复。现在,让我们通过我们的新的最佳实践工作流程 SensuFlow 将此监控代码与我们的 CI/CD 管道连接起来,从而实现自动化管理。SensuFlow 与包含监控代码子目录的代码仓库协同工作,这些子目录映射到 Sensu 命名空间。SensuFlow 提供以下自动化:
- 测试 sensu-backend 是否可用
- 提供的测试身份验证
- 在管理下创建命名空间(如果 RBAC 策略允许)
- 对资源定义进行 linting,以确保必需的元数据
- 根据标签选择标准修剪已删除/已重命名的 Sensu 资源
- 创建和/或修改 Sensu 资源
使用 SensuFlow 很容易上手,它需要一个 RBAC 配置文件(具有用户名和密码的用户、ClusterRole 和 ClusterRoleBinding)以及 Sensu 后端 API URL,用于配置将在 CI/CD 管道中运行的 Sensu CLI。SensuFlow 还有一组可选的环境变量,可让您自定义几种操作行为,例如 sensuctl prune 用于删除不再由仓库中的文件表示的 Sensu 资源的标签选择标准(例如,如果监控代码模板被删除或重命名)。
要详细了解 sensuctl prune,请查看我们有关 https://sensu.io/blog/keep-your-configs-in-good-order-with-sensuctl-prune 的博客文章
SensuFlow 旨在与 CI/CD 平台无关,可以在您的开发环境中本地使用(只要安装了 sensuctl、yq 和 jq)。但我们也正在积极开发一个适用于 GitHub Action CI/CD 平台的参考实现,该实现可用于任何 GitHub 仓库。SensuFlow GitHub Action 有效地提供了 GitHub 和 Sensu Go 之间的直接集成!
看一下这个 作为代码的监控示例仓库,它配置为在提交到主分支时运行 SensuFlow GitHub action。此仓库包含多个 Sensu 资源,包括上面提到的 Red Hat Ansible Tower 修复示例中的检查和处理程序,但现在使用 SensuFlow 来自动化 Sensu 中的更改。
要详细了解作为代码的监控和 SensuFlow,请查看我们最近发布的关于此主题的博客文章和网络研讨会
- 作为代码的监控:它是什么以及为什么需要它(The New Stack 上的博客文章)
- 使用 Sensu 可观测性进行作为代码的监控(白皮书))
- 使用 Sensu Go 和 Sensu Flow 实践作为代码的监控(网络研讨会)\
希望这篇文章能让您了解使用作为代码的监控概念以及 Sensu Go 的 Ansible 集合可以做些什么。要进一步学习,请查看我们 关于使用 Sensu Ansible Tower 集成实现自修复工作流的网络研讨会。