From 63e129f46f0d1ce9d9823e16ea2ff1c27c0e8eb7 Mon Sep 17 00:00:00 2001 From: Kuangyu Jing Date: Tue, 8 Jul 2025 06:34:04 +0900 Subject: [PATCH] feat: health check for ArgoCD --- argocd-ephemeralrunner-health.yaml | 76 +++++++++++++++++++++++++++ argocd-runner-health.yaml | 27 ++++++++++ docs/argocd-health-check.md | 83 ++++++++++++++++++++++++++++++ examples/argocd-health-values.yaml | 74 ++++++++++++++++++++++++++ 4 files changed, 260 insertions(+) create mode 100644 argocd-ephemeralrunner-health.yaml create mode 100644 argocd-runner-health.yaml create mode 100644 docs/argocd-health-check.md create mode 100644 examples/argocd-health-values.yaml diff --git a/argocd-ephemeralrunner-health.yaml b/argocd-ephemeralrunner-health.yaml new file mode 100644 index 00000000..5cdc8b12 --- /dev/null +++ b/argocd-ephemeralrunner-health.yaml @@ -0,0 +1,76 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cm + namespace: argocd +data: + # Health check for actions.summerwind.dev/v1alpha1 Runner + resource.customizations.health.actions.summerwind.dev_Runner: | + hs = {} + if obj.status ~= nil then + if obj.status.ready == true and obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Runner is ready and running" + elseif obj.status.phase == "Pending" or obj.status.phase == "Created" then + hs.status = "Progressing" + hs.message = "Runner is starting up" + elseif obj.status.phase == "Failed" then + hs.status = "Degraded" + hs.message = obj.status.message or "Runner has failed" + else + hs.status = "Progressing" + hs.message = "Runner status: " .. (obj.status.phase or "Unknown") + end + else + hs.status = "Progressing" + hs.message = "Waiting for runner status" + end + return hs + + # Health check for actions.github.com/v1alpha1 EphemeralRunner + resource.customizations.health.actions.github.com_EphemeralRunner: | + hs = {} + if obj.status ~= nil then + if obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "EphemeralRunner is running" + elseif obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "EphemeralRunner is pending" + elseif obj.status.phase == "Failed" then + hs.status = "Degraded" + hs.message = obj.status.message or "EphemeralRunner has failed" + elseif obj.status.phase == "Finished" then + hs.status = "Healthy" + hs.message = "EphemeralRunner has finished" + else + hs.status = "Progressing" + hs.message = "EphemeralRunner status: " .. (obj.status.phase or "Unknown") + end + else + hs.status = "Progressing" + hs.message = "Waiting for EphemeralRunner status" + end + return hs + + # Health check for actions.github.com/v1alpha1 AutoScalingRunnerSet + resource.customizations.health.actions.github.com_AutoScalingRunnerSet: | + hs = {} + if obj.status ~= nil then + if obj.status.currentReplicas ~= nil and obj.status.desiredReplicas ~= nil then + if obj.status.currentReplicas == obj.status.desiredReplicas then + hs.status = "Healthy" + hs.message = string.format("Runners: %d/%d", obj.status.currentReplicas, obj.status.desiredReplicas) + else + hs.status = "Progressing" + hs.message = string.format("Scaling runners: %d/%d", obj.status.currentReplicas, obj.status.desiredReplicas) + end + else + hs.status = "Progressing" + hs.message = "Initializing runner set" + end + else + hs.status = "Progressing" + hs.message = "Waiting for status" + end + return hs \ No newline at end of file diff --git a/argocd-runner-health.yaml b/argocd-runner-health.yaml new file mode 100644 index 00000000..9cf80aaa --- /dev/null +++ b/argocd-runner-health.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cm + namespace: argocd +data: + resource.customizations.health.actions.summerwind.dev_Runner: | + hs = {} + if obj.status ~= nil then + if obj.status.ready == true and obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Runner is ready and running" + elseif obj.status.phase == "Pending" or obj.status.phase == "Created" then + hs.status = "Progressing" + hs.message = "Runner is starting up" + elseif obj.status.phase == "Failed" then + hs.status = "Degraded" + hs.message = obj.status.message or "Runner has failed" + else + hs.status = "Progressing" + hs.message = "Runner status: " .. (obj.status.phase or "Unknown") + end + else + hs.status = "Progressing" + hs.message = "Waiting for runner status" + end + return hs \ No newline at end of file diff --git a/docs/argocd-health-check.md b/docs/argocd-health-check.md new file mode 100644 index 00000000..8f464a05 --- /dev/null +++ b/docs/argocd-health-check.md @@ -0,0 +1,83 @@ +# ArgoCD Health Check Configuration for Actions Runner Controller + +This document explains how to configure ArgoCD to properly recognize the health status of Runner resources. + +## Problem + +By default, ArgoCD doesn't understand the health status of custom resources like `Runner`. Even when a Runner Pod is up and running, ArgoCD may show the status as "Progressing" instead of "Healthy". + +## Solution + +Add a custom health check configuration to ArgoCD's ConfigMap to interpret the Runner resource's status fields. + +### 1. Apply the Custom Health Check + +Apply the following configuration to your ArgoCD installation: + +```bash +kubectl apply -f argocd-runner-health.yaml +``` + +Or, if you already have an `argocd-cm` ConfigMap, add the following to the `data` section: + +```yaml +data: + resource.customizations.health.actions.summerwind.dev_Runner: | + hs = {} + if obj.status ~= nil then + if obj.status.ready == true and obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Runner is ready and running" + elseif obj.status.phase == "Pending" or obj.status.phase == "Created" then + hs.status = "Progressing" + hs.message = "Runner is starting up" + elseif obj.status.phase == "Failed" then + hs.status = "Degraded" + hs.message = obj.status.message or "Runner has failed" + else + hs.status = "Progressing" + hs.message = "Runner status: " .. (obj.status.phase or "Unknown") + end + else + hs.status = "Progressing" + hs.message = "Waiting for runner status" + end + return hs +``` + +### 2. Restart ArgoCD Server + +After applying the configuration, restart the ArgoCD server to load the new health check: + +```bash +kubectl rollout restart deployment argocd-server -n argocd +``` + +## Health Status Mapping + +The custom health check maps Runner statuses to ArgoCD health statuses as follows: + +| Runner Status | ArgoCD Health Status | Description | +| -- | -- | -- | +| `ready: true` and `phase: Running` | Healthy | Runner is fully operational | +| `phase: Pending` or `Created` | Progressing | Runner is starting up | +| `phase: Failed` | Degraded | Runner has encountered an error | +| Other states | Progressing | Runner is in transition | + +## Verification + +After configuration, you can verify the health status in ArgoCD: + +1. Check the ArgoCD UI - Runner resources should show as "Healthy" when ready +2. Use the ArgoCD CLI: + ```bash + argocd app get --refresh + ``` + +## Alternative Approach: Patching the ConfigMap + +If you need to patch an existing ConfigMap: + +```bash +kubectl patch configmap argocd-cm -n argocd --type merge -p '{"data":{"resource.customizations.health.actions.summerwind.dev_Runner":"hs = {}\nif obj.status ~= nil then\n if obj.status.ready == true and obj.status.phase == \"Running\" then\n hs.status = \"Healthy\"\n hs.message = \"Runner is ready and running\"\n elseif obj.status.phase == \"Pending\" or obj.status.phase == \"Created\" then\n hs.status = \"Progressing\"\n hs.message = \"Runner is starting up\"\n elseif obj.status.phase == \"Failed\" then\n hs.status = \"Degraded\"\n hs.message = obj.status.message or \"Runner has failed\"\n else\n hs.status = \"Progressing\"\n hs.message = \"Runner status: \" .. (obj.status.phase or \"Unknown\")\n end\nelse\n hs.status = \"Progressing\"\n hs.message = \"Waiting for runner status\"\nend\nreturn hs"}}' +``` diff --git a/examples/argocd-health-values.yaml b/examples/argocd-health-values.yaml new file mode 100644 index 00000000..d948d2a0 --- /dev/null +++ b/examples/argocd-health-values.yaml @@ -0,0 +1,74 @@ +# Example values for configuring ArgoCD health checks when using Helm + +# If you're deploying ArgoCD using the official Helm chart, +# you can add these health checks to your values.yaml: + +server: + config: + resource.customizations.health.actions.summerwind.dev_Runner: | + hs = {} + if obj.status ~= nil then + if obj.status.ready == true and obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Runner is ready and running" + elseif obj.status.phase == "Pending" or obj.status.phase == "Created" then + hs.status = "Progressing" + hs.message = "Runner is starting up" + elseif obj.status.phase == "Failed" then + hs.status = "Degraded" + hs.message = obj.status.message or "Runner has failed" + else + hs.status = "Progressing" + hs.message = "Runner status: " .. (obj.status.phase or "Unknown") + end + else + hs.status = "Progressing" + hs.message = "Waiting for runner status" + end + return hs + + resource.customizations.health.actions.github.com_EphemeralRunner: | + hs = {} + if obj.status ~= nil then + if obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "EphemeralRunner is running" + elseif obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "EphemeralRunner is pending" + elseif obj.status.phase == "Failed" then + hs.status = "Degraded" + hs.message = obj.status.message or "EphemeralRunner has failed" + elseif obj.status.phase == "Finished" then + hs.status = "Healthy" + hs.message = "EphemeralRunner has finished" + else + hs.status = "Progressing" + hs.message = "EphemeralRunner status: " .. (obj.status.phase or "Unknown") + end + else + hs.status = "Progressing" + hs.message = "Waiting for EphemeralRunner status" + end + return hs + + resource.customizations.health.actions.github.com_AutoScalingRunnerSet: | + hs = {} + if obj.status ~= nil then + if obj.status.currentReplicas ~= nil and obj.status.desiredReplicas ~= nil then + if obj.status.currentReplicas == obj.status.desiredReplicas then + hs.status = "Healthy" + hs.message = string.format("Runners: %d/%d", obj.status.currentReplicas, obj.status.desiredReplicas) + else + hs.status = "Progressing" + hs.message = string.format("Scaling runners: %d/%d", obj.status.currentReplicas, obj.status.desiredReplicas) + end + else + hs.status = "Progressing" + hs.message = "Initializing runner set" + end + else + hs.status = "Progressing" + hs.message = "Waiting for status" + end + return hs \ No newline at end of file