ArgoCD 原生不支持健康度自动回滚?用 argocd-notifications 实现告警触发式回滚
在持续部署(CD)流程中,自动化回滚是保障生产环境稳定性的关键一环。虽然 ArgoCD 提供了强大的应用健康度检查,但其原生功能并不支持在检测到应用不健康时自动触发回滚操作。这是一个常见的运维痛点。
然而,我们可以通过 ArgoCD 生态系统中的另一个重要组件——argocd-notifications,来巧妙地实现这一目标。其核心思路是:将健康度检查的失败事件,通过 Webhook 通知到外部系统,再由该系统执行回滚操作。
下面我将详细介绍如何配置和实现这一方案。
核心原理:事件驱动的工作流
整个流程可以概括为:
- 健康度检查:ArgoCD 定期检查部署应用的健康状态(例如,Pod 是否就绪,服务端点是否可访问)。
- 事件触发:当健康度检查从
Healthy变为Degraded或Missing时,ArgoCD 会生成一个事件。 - 通知分发:
argocd-notifications监听这些事件,并通过配置的Trigger和Template将事件信息包装成通知。 - Webhook 发送:配置一个
Trigger,使其在收到特定健康度事件时,向一个外部 Webhook URL 发送 HTTP POST 请求。请求体中可以包含应用名称、健康度状态、时间戳等关键信息。 - 外部执行回滚:一个独立的、轻量级的 Webhook 服务(例如,一个用 Python Flask 或 Go 编写的简单服务)接收该请求,然后调用 ArgoCD 的 API(或
argocdCLI)来执行回滚操作。
实现步骤
1. 部署 argocd-notifications
如果你尚未部署,首先需要安装 argocd-notifications。通常它与 ArgoCD 部署在同一命名空间。
# 假设你已经有一个可用的 ArgoCD 实例
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/master/manifests/install.yaml
2. 配置 Webhook 服务
你需要一个简单的服务来接收通知并执行回滚。这里提供一个 Python Flask 示例:
# webhook_receiver.py
from flask import Flask, request, jsonify
import subprocess
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/argocd/rollback', methods=['POST'])
def handle_rollback():
data = request.json
app_name = data.get('app_name')
# 这里可以添加更多验证,比如签名验证
if not app_name:
return jsonify({"error": "Missing app_name"}), 400
logging.info(f"Received rollback request for app: {app_name}")
# 执行回滚命令(确保运行此服务的Pod有权限访问ArgoCD API或CLI)
# 方式1: 使用 argocd CLI
# cmd = ["argocd", "app", "rollback", app_name, "--grpc-web"]
# 方式2: 使用 ArgoCD REST API (更推荐)
# 这里为了简化,展示CLI方式,生产环境建议使用API并配置认证
try:
# 注意:实际部署时,需要配置argocd的认证信息
# 示例命令,需根据实际环境调整
result = subprocess.run(
["argocd", "app", "rollback", app_name, "-n", "default"],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
logging.info(f"Rollback successful for {app_name}")
return jsonify({"status": "success", "message": f"Rollback triggered for {app_name}"}), 200
else:
logging.error(f"Rollback failed: {result.stderr}")
return jsonify({"status": "error", "message": result.stderr}), 500
except Exception as e:
logging.error(f"Error executing rollback: {str(e)}")
return jsonify({"status": "error", "message": str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
将此服务部署为一个 Kubernetes Service,并暴露一个 ClusterIP 端口(例如 http://rollback-service:5000/argocd/rollback)。
3. 配置 argocd-notifications
这是最关键的一步。你需要创建 ConfigMap 和 Secret 来配置 argocd-notifications。
a. 创建 Secret (用于存储 Webhook URL)
apiVersion: v1
kind: Secret
metadata:
name: argocd-notifications-secret
namespace: argocd
type: Opaque
stringData:
# 将上面部署的Webhook服务地址填入
webhook-url: "http://rollback-service.default.svc.cluster.local:5000/argocd/rollback"
b. 创建 ConfigMap (定义触发器和模板)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
# 1. 定义模板:将事件数据格式化为JSON,用于发送给Webhook
template.rollback-webhook: |
webhook:
# 使用上面创建的Secret中的URL
url: $webhook-url
body: |
{
"app_name": "{{.app.metadata.name}}",
"health_status": "{{.app.status.health.status}}",
"sync_status": "{{.app.status.sync.status}}",
"timestamp": "{{.app.status.operationState.startedAt}}",
"message": "Application health degraded, triggering rollback."
}
# 2. 定义触发器:当应用健康度变为Degraded或Missing时触发
trigger.on-health-degraded: |
- send:
- rollback-webhook
- when: app.status.health.status in ['Degraded', 'Missing']
oncePer: app.metadata.name
# 3. (可选) 定义订阅,让通知器知道要监听哪些应用
# 通常,我们通过 Annotation 订阅特定应用
c. 为需要监控的应用添加订阅 Annotation
在需要实现此功能的 ArgoCD Application 资源上,添加以下 Annotation:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-critical-app
namespace: argocd
annotations:
# 订阅到 on-health-degraded 触发器
notifications.argoproj.io/subscribe.on-health-degraded: ""
# (可选) 指定订阅者,可以是邮箱、Slack等,这里我们只关心Webhook
# notifications.argoproj.io/subscribe.on-health-degraded: "my-team-email"
spec:
# ... 应用配置
4. 重启或更新配置
配置更改后,需要重启 argocd-notifications 的 Pod 以使配置生效。
kubectl rollout restart deployment/argocd-notifications-controller -n argocd
最佳实践与注意事项
- 安全第一:生产环境务必对 Webhook 进行认证(如使用 Secret Token 验证),防止未授权调用。可以在
argocd-notifications的template中通过headers字段传递认证信息。 - 幂等性:确保回滚操作是幂等的,即重复执行不会产生负面影响。ArgoCD 的
app rollback命令是幂等的。 - 避免循环:确保回滚操作本身不会再次触发健康度告警。例如,如果回滚到的版本本身就不健康,可能会导致无限循环。建议在 Webhook 服务中增加逻辑,例如设置一个冷却时间或检查最近的回滚历史。
- 监控与日志:为你的 Webhook 服务和
argocd-notifications配置详细的日志,以便追踪每次告警和回滚的执行情况。 - 测试:在非生产环境充分测试整个流程。可以通过手动将应用标记为
Degraded(例如,删除一个必需的 Pod)来触发告警,观察 Webhook 是否收到请求并正确执行回滚。 - 替代方案:对于更复杂的工作流(如需要人工审批、多步骤回滚),可以考虑将
argocd-notifications的 Webhook 指向一个更强大的工作流引擎,如 Argo Workflows 或 Tekton,由它们来编排后续的回滚和验证步骤。
通过上述配置,我们就成功地将 ArgoCD 的健康度检查与自动化回滚能力结合起来,构建了一个响应式的、事件驱动的部署后自愈系统。这极大地提升了运维效率和系统稳定性。