From 011ed380b5a1d491e3d6ed2dbeac935b108ec884 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Fri, 6 Mar 2020 14:29:19 +0000 Subject: [PATCH] Add documentation for MachineHealthChecks --- docs/book/src/SUMMARY.md | 2 + .../controllers/machine-health-check.md | 12 +++ .../machinehealthcheck-controller.plantuml | 35 +++++++ .../images/machinehealthcheck-controller.png | Bin 0 -> 49934 bytes docs/book/src/tasks/healthcheck.md | 95 ++++++++++++++++++ docs/book/src/user/concepts.md | 9 ++ 6 files changed, 153 insertions(+) create mode 100644 docs/book/src/developer/architecture/controllers/machine-health-check.md create mode 100644 docs/book/src/images/machinehealthcheck-controller.plantuml create mode 100644 docs/book/src/images/machinehealthcheck-controller.png create mode 100644 docs/book/src/tasks/healthcheck.md diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 845250d1b4de..dbd725f6db70 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -10,6 +10,7 @@ - [Using Custom Certificates](./tasks/certs/using-custom-certificates.md) - [Generating a Kubeconfig](./tasks/certs/generate-kubeconfig.md) - [Upgrade](./tasks/upgrade.md) + - [Configure a MachineHealthCheck](./tasks/healthcheck.md) - [clusterctl CLI](./clusterctl/overview.md) - [clusterctl Commands](clusterctl/commands/commands.md) - [init](clusterctl/commands/init.md) @@ -30,6 +31,7 @@ - [Machine](./developer/architecture/controllers/machine.md) - [MachineSet](./developer/architecture/controllers/machine-set.md) - [MachineDeployment](./developer/architecture/controllers/machine-deployment.md) + - [MachineHealthCheck](./developer/architecture/controllers/machine-health-check.md) - [Control Plane](./developer/architecture/controllers/control-plane.md) - [Provider Implementers](./developer/providers/implementers.md) - [v1alpha1 to v1alpha2](./developer/providers/v1alpha1-to-v1alpha2.md) diff --git a/docs/book/src/developer/architecture/controllers/machine-health-check.md b/docs/book/src/developer/architecture/controllers/machine-health-check.md new file mode 100644 index 000000000000..827bf68f06f2 --- /dev/null +++ b/docs/book/src/developer/architecture/controllers/machine-health-check.md @@ -0,0 +1,12 @@ +# MachineHealthCheck + +A MachineHealthCheck is responsible for remediating unhealthy [Machines](./machine.md). + +Its main responsibilities are: +* Checking the health of Nodes in [target clusters] against a list of unhealthy conditions +* Remediating Machine's for Nodes determined to be unhealthy + +![](../../../images/machinehealthcheck-controller.png) + + +[target clusters]: ../../../reference/glossary.md#target-cluster diff --git a/docs/book/src/images/machinehealthcheck-controller.plantuml b/docs/book/src/images/machinehealthcheck-controller.plantuml new file mode 100644 index 000000000000..2481d302e7ff --- /dev/null +++ b/docs/book/src/images/machinehealthcheck-controller.plantuml @@ -0,0 +1,35 @@ + +@startuml machinehealthcheck-controller + +start; +:Machine Health Check controller; +repeat + repeat + :MachineHealthCheck controller enqueues a Reconcile call; + if (Nodes being watched in remote cluster) then (no) + :Watch nodes in remote cluster; + else (yes) + endif + :Find targets: Machines matched by selector plus respective Nodes; + :Health check targets: Determine which Machines require remediation; + repeat while (Remediations are allowed (current unhealthy <= max unhealthy)) is (no) + -> yes; + repeat + if (Target requires remediation) then (yes) + if (Machine is owned by a MachineSet) then (yes) + if (Machine is a Control Plane Machine) then (no) + #LightBlue:Delete Machine; + else (yes) + endif + else (no) + endif + else (no) + endif + repeat while (more Targets) is (yes) + -> no; +repeat while (Targets likely to go unhealthy) is (yes: requeue with minimum + time before timeout as delay) +-> no; +stop; + +@enduml diff --git a/docs/book/src/images/machinehealthcheck-controller.png b/docs/book/src/images/machinehealthcheck-controller.png new file mode 100644 index 0000000000000000000000000000000000000000..1c9a60d4478f93143413e78e0fb991bd72ff8aab GIT binary patch literal 49934 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 literal 0 HcmV?d00001 diff --git a/docs/book/src/tasks/healthcheck.md b/docs/book/src/tasks/healthcheck.md new file mode 100644 index 000000000000..bc82857babd1 --- /dev/null +++ b/docs/book/src/tasks/healthcheck.md @@ -0,0 +1,95 @@ +# Configure a MachineHealthCheck + +## Prerequisites + +Before attempting to configure a MachineHealthCheck, you should have a working [management cluster] with at least one MachineDeployment or MachineSet deployed. + +## What is a MachineHealthCheck? + +A MachineHealthCheck is a resource within the Cluster API which allows users to define conditions under which Machine's within a Cluster should be considered unhealthy. + +When defining a MachineHealthCheck, users specify a timeout for each of the conditions that they define to check on the Machine's Node, +if any of these conditions is met for the duration of the timeout, the Machine will be remediated. +The action of remediating a Machine should trigger a new Machine to be created, to replace the failed one. + +## Creating a MachineHealthCheck + +Use the following example as a basis for creating a MachineHealthCheck: + +```yaml +apiVersion: cluster.x-k8s.io/v1alpha3 +kind: MachineHealthCheck +metadata: + name: capi-quickstart-node-unhealthy-5m +spec: + # clusterName is required to associate this MachineHealthCheck with a particular cluster + clusterName: capi-quickstart + # (Optional) maxUnhealthy prevents further remediation if the cluster is already partially unhealthy + maxUnhealthy: 40% + # (Optional) nodeStartupTimeout determines how long a MachineHealthCheck should wait for + # a Node to join the cluster, before considering a Machine unhealthy + nodeStartupTimeout: 10m + # selector is used to determine which Machines should be health checked + selector: + matchLabels: + nodepool: nodepool-0 + # Conditions to check on Nodes for matched Machines, if any condition is matched for the duration of its tiemout, the Machine is considered unhealthy + unhealthyConditions: + - type: Ready + status: Unknown + timeout: 300s + - type: Ready + status: "False" + timeout: 300s +``` + +## Remediation short-circuiting + +To ensure that MachineHealthChecks only remediate Machines when the cluster is healthy, +short-circuiting is implemented to prevent further remediation via the `maxUnhealthy` field within the MachineHealthCheck spec. + +If the user defines a value for the `maxUnhealthy` field (either an absolute number or a percentage of the total Machines checked by this MachineHealthCheck), +before remediating any Machines, the MachineHealthCheck will compare the value of `maxUnhealthy` with the number of Machines it has determined to be unhealthy. +If the number of unhealthy Machines exceeds the limit set by `maxUnhealthy`, remediation will **not** be performed. + + + +#### With an absolute value + +If `maxUnhealthy` is set to `2`: +- If 2 or fewer nodes are unhealthy, remediation will be performed +- If 3 or more nodes are unhealthy, remediation will not be performed + +These values are independent of how many Machines are being checked by the MachineHealthCheck. + +#### With percentages + +If `maxUnhealthy` is set to `40%` and there are 25 Machines being checked: +- If 10 or fewer nodes are unhealthy, remediation will be performed +- If 11 or more nodes are unhealthy, remediation will not be performed + +If `maxUnhealthy` is set to `40%` and there are 6 Machines being checked: +- If 2 or fewer nodes are unhealthy, remediation will be performed +- If 3 or more nodes are unhealthy, remediation will not be performed + +Note, when the percentage is not a whole number, the allowed number is rounded down. + +## Limitations and Caveats of a MachineHealthCheck + +Before deploying a MachineHealthCheck, please familiarise yourself with the following limitations and caveats: + +- Only Machines owned by a MachineSet will be remediated by a MachineHealthCheck +- Control Plane Machines are currently not supported and will **not** be remediated if they are unhealthy +- If the Node for a Machine is removed from the cluster, a MachineHealthCheck will consider this Machine unhealthy and remediate it immediately +- If no Node joins the cluster for a Node after the `NodeStartupTimeout`, the Machine will be remediated +- If a Machine fails for any reason (if the FailureReason is set), the Machine will be remediated immediately + + +[management cluster]: ../reference/glossary.md#management-cluster diff --git a/docs/book/src/user/concepts.md b/docs/book/src/user/concepts.md index b2bcccf7ae3e..728daa549464 100644 --- a/docs/book/src/user/concepts.md +++ b/docs/book/src/user/concepts.md @@ -60,6 +60,15 @@ MachineSets work similar to regular POD [ReplicaSets](https://kubernetes.io/docs +### MachineHealthCheck + +A "MachineHealthCheck" defines a set of conditions for Nodes which allow the user to specify when a Node should be considered unhealthy. +If the Node matches the unhealthy conditions for a given user configured time, the MachineHealthCheck initiates remediation of the Node. + +Remediation of Nodes is performed by deleting the Machine that created the Node. +MachineHealthChecks will only remediate Nodes if they are owned by a MachineSet, +this ensures that the Kubernetes cluster does not lose capacity, as the MachineSet will create a new Machine to replace the failed Machine. + ### BootstrapData BootstrapData contains the machine or node role specific initialization data (usually cloud-init) used by the infrastructure provider to bootstrap a machine into a node.