From c96ed15f7a77182886385805d5dad72ed02622a0 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Thu, 11 Jul 2019 08:34:25 +0100 Subject: [PATCH] Add reference documentation for built-in controllers --- .../en/docs/reference/controllers/_index.md | 5 + .../controllers/admission-pod-preset.md | 57 +++++++ .../en/docs/reference/controllers/built-in.md | 155 +++++++++++++++++ .../controllers/certificate-approver.md | 37 ++++ .../controllers/certificate-cleaner.md | 27 +++ .../certificate-root-ca-publisher.md | 28 +++ .../controllers/certificate-signer.md | 31 ++++ .../controllers/clusterrole-aggregation.md | 30 ++++ .../en/docs/reference/controllers/cronjob.md | 44 +++++ .../docs/reference/controllers/daemonset.md | 106 ++++++++++++ .../docs/reference/controllers/deployment.md | 114 +++++++++++++ .../en/docs/reference/controllers/endpoint.md | 32 ++++ .../controllers/garbage-collector.md | 38 +++++ .../controllers/horizontal-pod-autoscaler.md | 159 ++++++++++++++++++ .../en/docs/reference/controllers/ingress.md | 73 ++++++++ content/en/docs/reference/controllers/job.md | 40 +++++ .../docs/reference/controllers/namespace.md | 23 +++ .../controllers/node-ip-address-management.md | 23 +++ .../reference/controllers/node-lifecycle.md | 30 ++++ content/en/docs/reference/controllers/node.md | 50 ++++++ .../controllers/pod-disruption-budget.md | 45 +++++ .../controllers/pod-garbage-collector.md | 24 +++ .../docs/reference/controllers/replicaset.md | 67 ++++++++ .../controllers/replicationcontroller.md | 82 +++++++++ .../reference/controllers/resource-quota.md | 36 ++++ .../en/docs/reference/controllers/service.md | 39 +++++ .../controllers/serviceaccount-token.md | 26 +++ .../reference/controllers/serviceaccount.md | 23 +++ .../docs/reference/controllers/statefulset.md | 37 ++++ .../controllers/ttl-after-finished.md | 53 ++++++ content/en/docs/reference/controllers/ttl.md | 27 +++ .../controllers/volume-attach-detach.md | 39 +++++ .../controllers/volume-persistentvolume.md | 33 ++++ ...volume-persistentvolumeclaim-protection.md | 31 ++++ 34 files changed, 1664 insertions(+) create mode 100755 content/en/docs/reference/controllers/_index.md create mode 100644 content/en/docs/reference/controllers/admission-pod-preset.md create mode 100644 content/en/docs/reference/controllers/built-in.md create mode 100644 content/en/docs/reference/controllers/certificate-approver.md create mode 100644 content/en/docs/reference/controllers/certificate-cleaner.md create mode 100644 content/en/docs/reference/controllers/certificate-root-ca-publisher.md create mode 100644 content/en/docs/reference/controllers/certificate-signer.md create mode 100644 content/en/docs/reference/controllers/clusterrole-aggregation.md create mode 100644 content/en/docs/reference/controllers/cronjob.md create mode 100644 content/en/docs/reference/controllers/daemonset.md create mode 100644 content/en/docs/reference/controllers/deployment.md create mode 100644 content/en/docs/reference/controllers/endpoint.md create mode 100644 content/en/docs/reference/controllers/garbage-collector.md create mode 100644 content/en/docs/reference/controllers/horizontal-pod-autoscaler.md create mode 100644 content/en/docs/reference/controllers/ingress.md create mode 100644 content/en/docs/reference/controllers/job.md create mode 100644 content/en/docs/reference/controllers/namespace.md create mode 100644 content/en/docs/reference/controllers/node-ip-address-management.md create mode 100644 content/en/docs/reference/controllers/node-lifecycle.md create mode 100644 content/en/docs/reference/controllers/node.md create mode 100644 content/en/docs/reference/controllers/pod-disruption-budget.md create mode 100644 content/en/docs/reference/controllers/pod-garbage-collector.md create mode 100644 content/en/docs/reference/controllers/replicaset.md create mode 100644 content/en/docs/reference/controllers/replicationcontroller.md create mode 100644 content/en/docs/reference/controllers/resource-quota.md create mode 100644 content/en/docs/reference/controllers/service.md create mode 100644 content/en/docs/reference/controllers/serviceaccount-token.md create mode 100644 content/en/docs/reference/controllers/serviceaccount.md create mode 100644 content/en/docs/reference/controllers/statefulset.md create mode 100644 content/en/docs/reference/controllers/ttl-after-finished.md create mode 100644 content/en/docs/reference/controllers/ttl.md create mode 100644 content/en/docs/reference/controllers/volume-attach-detach.md create mode 100644 content/en/docs/reference/controllers/volume-persistentvolume.md create mode 100644 content/en/docs/reference/controllers/volume-persistentvolumeclaim-protection.md diff --git a/content/en/docs/reference/controllers/_index.md b/content/en/docs/reference/controllers/_index.md new file mode 100755 index 0000000000000..6aaa7405b532c --- /dev/null +++ b/content/en/docs/reference/controllers/_index.md @@ -0,0 +1,5 @@ +--- +title: "Controllers" +weight: 20 +--- + diff --git a/content/en/docs/reference/controllers/admission-pod-preset.md b/content/en/docs/reference/controllers/admission-pod-preset.md new file mode 100644 index 0000000000000..fa47e7827a692 --- /dev/null +++ b/content/en/docs/reference/controllers/admission-pod-preset.md @@ -0,0 +1,57 @@ +--- +title: PodPreset controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The PodPreset admission controller injects configuration data into +{{< glossary_tooltip text="pods" term_id="pod" >}} when they are created. + +The configuration data can include {{< glossary_tooltip text="Secrets" term_id="secret" >}}, +{{< glossary_tooltip text="Volumes" term_id="volume" >}}, volume mounts, +and {{< glossary_tooltip text="environment variables" term_id="container-env-variables" >}}. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +This is a mutating +[admission controller](/docs/reference/access-authn-authz/admission-controllers/#what-are-they) +that acts on Pod creation requests. + +When a pod creation request arrives for processing, the controller: + +1. Retrieves all `PodPresets` available for use. +1. Checks if the label selectors of any `PodPreset` match the labels on the + Pod being created. +1. Attempts to merge the various resources defined by the `PodPreset` into the + Pod being created. +1. On error, throws an event documenting the merge error on the Pod, and then + allows creation of the the Pod _without_ any injected resources from the `PodPreset`. +1. Annotates the resulting modified Pod spec to indicate that it has been + modified by a `PodPreset`. The annotation is of the form + `podpreset.admission.kubernetes.io/podpreset-: ""`. + +Each Pod can be matched by zero or more Pod Presets; and each `PodPreset` can be +applied to zero or more pods. When a `PodPreset` is applied to one or more +Pods, Kubernetes modifies the Pod Spec. For changes to `Env`, `EnvFrom`, and +`VolumeMounts`, Kubernetes modifies the container spec for all containers in +the Pod; for changes to `Volume`, Kubernetes modifies the Pod Spec. + +{{< note >}} +A Pod Preset is capable of modifying the following fields in a Pod spec when appropriate: +- The `.spec.containers` field. +- The `initContainers` field (requires Kubernetes version 1.14.0 or later). +{{< /note >}} + +{{% /capture %}} + +{{% capture whatsnext %}} + +* Learn how to [enable PodPreset](/docs/concepts/workloads/pods/podpreset/#enable-pod-preset) +* Try to [inject information into Pods Using a PodPreset](/docs/tasks/inject-data-application/podpreset/) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/built-in.md b/content/en/docs/reference/controllers/built-in.md new file mode 100644 index 0000000000000..75939779745da --- /dev/null +++ b/content/en/docs/reference/controllers/built-in.md @@ -0,0 +1,155 @@ +--- +title: Built-in controllers +content_template: templates/concept +weight: 10 +--- + +{{% capture overview %}} + +This page lists the {{< glossary_tooltip text="controllers" term_id="controller" >}} +that come as part of Kubernetes itself. +{{% /capture %}} + + +{{% capture body %}} + +Kubernetes comes with a number of built-in controllers that run as part +of the {{< glossary_tooltip term_id="kube-controller-manager" >}}. + +If your cluster is deployed against a cloud service provider, you can +use the cloud-controller-manager to run additional provider-specific +controllers such as +[Route](/docs/concepts/architecture/cloud-controller/#route-controller). + +The cloud controller manager provides an abstract API (in Go) that +allows cloud vendors to plug in their custom implementation. + +The built-in {{< glossary_tooltip term_id="kube-scheduler" text="scheduler" >}} +is itself a specialized controller. The scheduler's purpose is to reconcile the +desired set of running Pods and match that against the available Nodes, +optimizing against discovered constraints. +{{< glossary_tooltip term_id="kubelet" >}} will update the actual state each +time it starts or stops a scheduled Pod. + +Because its work is essential to Kubernetes' operation, the scheduler +runs separately from the kube-controller-manager. This separation helps +with control plane performance. + +The controllers that run inside kube-controller-manager are: + +## Controllers for running workloads on Kubernetes {#controllers-workloads} + +* [CronJob controller](/docs/reference/controllers/cronjob/) +* [DaemonSet controller](/docs/reference/controllers/daemonset/) +* [Deployment controller](/docs/reference/controllers/deployment/) +* [Job controller](/docs/reference/controllers/job/) +* [ReplicaSet controller](/docs/reference/controllers/replicaset/) +* [StatefulSet controller](/docs/reference/controllers/statefulset/) +* [Service controller](/docs/reference/controllers/service/) + +## Pod management controllers {#controllers-pod-management} + +* [Horizontal Pod Autoscaler](/docs/reference/controllers/horizontal-pod-autoscaler/) +* [PodDisruptionBudget controller](/docs/reference/controllers/poddisruptionbudget/) +* [PodPreset controller](/docs/reference/access-authn-authz/admission-controllers/#podpreset) + +## Resource management controllers {#controllers-resource-management} + +* [Resource quota controller](/docs/reference/access-authn-authz/admission-controllers/#resourcequota) + +## Certificate controllers {#controllers-certificates} + +* [Root CA controller](/docs/reference/controllers/certificate-root-ca-publisher/) + +There are also a set of three controllers that work together to provide signed +{{< glossary_tooltip text="certificates" term_id="certificate" >}} on demand, for use within your cluster: + +[Certificate signer](/docs/reference/controllers/certificate-signer) +: A controller that signs certificates based on a certificate signing request (CSR), + once approved. The issued certificates will have a signing chain back to the root CA. + +[Certificate signature approver](/docs/reference/controllers/certificate-approver/) +: An automated approver for valid certificate signing requests. Requests are approved + automatically if the request came from a Node known to Kubernetes. + +[CSR cleaner](/docs/reference/controllers/certificate-cleaner/) +: The CSRs within your cluster have a lifetime. This controller removes CSRs that have + expired without being approved. + +{{< note >}} +If you wanted to have something that isn't a Node use a signing request to obtain valid +cluster certificates, you can implement that in your own custom controller. +The built-in controller will automatically know not to intervene, because it only acts +on signing requests that come from nodes. +{{< /note >}} + +## Storage controllers {#controllers-storage} + +There are a set of built-in controllers for storage management. + +* [Volume attach / detach controller](/docs/reference/controllers/volume-attach-detach/) +* [PersistentVolume controller](/docs/reference/controllers/volume-persistentvolume/) +* [PersistentVolumeClaim controller](/docs/reference/controllers/volume-persistentvolumeclaim/) +* [PersistentVolumeClaim in-use protection controller](/docs/reference/controllers/volume-persistentvolumeclaim-protection/) + +## Networking controllers {#controllers-networking} + +* [Endpoint controller](/docs/reference/controllers/endpoint) +* [Service controller](/docs/reference/controllers/service) +* [Node IP address management controller](/docs/reference/controllers/node-ipam/) + +## Cluster orchestration controllers {#controllers-cluster-orchestration} + +* [ServiceAccount controller](/docs/reference/controllers/serviceaccount/) +* [ServiceAccount token controller](/docs/reference/controllers/serviceaccount-token/) +* [ClusterRole aggregation controller](/docs/reference/controllers/clusterrole-aggregation) + +## Garbage collection & expiry controllers {#controllers-gc-expiry} + +### Time-to-live (TTL) controller {#controller-ttl} + +The [TTL controller](/docs/reference/controllers/ttl/) sets TTL +annotations on Nodes based on cluster size. +kubelet consumes these annotations as a hint about how long it can cache +object data that it has fetched from the +{{< glossary_tooltip text="API server" term_id="kube-apiserver" >}}. + +### TTL-after-finished controller {#controller-ttl-after-finished} + +The [TTL-after-finished controller](/docs/reference/controllers/ttl-after-finished) +cleans up finished task objects; currently, just Jobs. + +### Garbage collector {#controller-garbagecollector} + +The [garbage collector](/docs/reference/controllers/garbage-collector/) watches +for changes to objects that have dependencies, and spots objects that are eligible +for garbage collection. Once identified these are queued for (attempts at) deletion. + +Other controllers can rely on this behavior to take care of cascading deletion +of objects via parent-child relationships. + +### Pod garbage collector {#controller-pod-garbage-collector} + +The [pod garbage collector](/docs/reference/controllers/pod-garbage-collector/) +takes care of cleaning up {{< glossary_tooltip text="Pods" term_id="pod" >}} that +are terminated, so that the resources for tracking those Pods can be reclaimed. + +### Certificate signing request cleaner {#controller-certificate-cleaner} + +The [CSR cleaner](/docs/reference/controllers/certificate-cleaner/) +removes old certificate signing requests that haven't been approved and signed. + +### Node lifecycle controller {#controller-node-lifecycle} + +The [node lifecycle controller](/docs/reference/controllers/node-lifecycle) +observes the behavior of kubelet on a node, and sets (potentially also removes) +{{< glossary_tooltip text="taints" term_id="taint" >}} on Nodes that reflect its +findings. + +### Namespace lifecycle controller {#controller-namespace} + +When you (or any Kubernetes API client) remove a {{< glossary_tooltip term_id="namespace" >}}, +the [namespace controller](/docs/reference/controllers/namespace/) makes sure that objects in +that namespace are removed before the namespace itself is removed. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/certificate-approver.md b/content/en/docs/reference/controllers/certificate-approver.md new file mode 100644 index 0000000000000..6293c4fc44e79 --- /dev/null +++ b/content/en/docs/reference/controllers/certificate-approver.md @@ -0,0 +1,37 @@ +--- +title: Certificate signature approver +content_template: templates/concept +--- + +{{% capture overview %}} + +The CertificateSigningRequest approver controller (aka CSR approver) is +part of a set of built-in controllers for certificate management. + +{{% /capture %}} + + +{{% capture body %}} +The CSR approver is built in to kube-controller-manager. + +## Controller behavior + +This controller acts specifically on CertificateSigningRequests (CSR) that come from +kubelet (or that purport to come from kubelet). + +When kubelet is setting up on a new node, kubelet will generate a CSR and submit it +to the Kubernetes API server using its +[bootstrap](/docs/reference/access-authn-authz/bootstrap-tokens/) +authentication and authorization. + +This controller watches for CertificateSigningRequests from kubelet. For each submitted +CertificateSigningRequest, this controller creates a SubjectAccessReview to verify +whether this Node's kubelet is allowed to have its certificate signed. + +If the request is authentic and the SubjectAccessReview passes, the controller marks the +CSR as approved. This approval allows the Certificate signer to issue a certificate. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about the [certificate signer](/docs/reference/controllers/certificate-signer/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/certificate-cleaner.md b/content/en/docs/reference/controllers/certificate-cleaner.md new file mode 100644 index 0000000000000..aa5a7e088367d --- /dev/null +++ b/content/en/docs/reference/controllers/certificate-cleaner.md @@ -0,0 +1,27 @@ +--- +title: Certificate signing request cleaner +content_template: templates/concept +--- + +{{% capture overview %}} + +This controller removes certificate signing requests that have expired without being approved. + +{{% /capture %}} + +{{% capture body %}} + +The CSR cleaner is built in to kube-controller-manager. + +## Controller behavior + +This controller watches for CertificateSigningRequest (CSR) objects and their approvals. + +After a CSR has been in the system for a certain amount of time, without being approved, +this controller will delete it. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about the [certificate approver](/docs/reference/controllers/certificate-approver/) +* Read about the [certificate signer](/docs/reference/controllers/certificate-signer/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/certificate-root-ca-publisher.md b/content/en/docs/reference/controllers/certificate-root-ca-publisher.md new file mode 100644 index 0000000000000..4a9ebf95101bd --- /dev/null +++ b/content/en/docs/reference/controllers/certificate-root-ca-publisher.md @@ -0,0 +1,28 @@ +--- +title: Root CA controller +content_template: templates/concept +--- + +{{% capture overview %}} + +Kubernetes clusters have a [certificate authority](/docs/concepts/cluster-administration/certificates/) +(CA) that the control plane uses to authenticate different components. This +controller manages a ConfigMap in every configured namespace, so that Pods +in that namespace have access to the cluster's root CA and can validate other +components' identity. + +{{% /capture %}} + +{{% capture body %}} + +The root CA controller is built in to kube-controller-manager. + +## Controller behavior + +This controller watches for namespaces being created. For every new namespace the +controller adds a ConfigMap containing the cluster's root certificate. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about the [certificate approver](/docs/reference/controllers/certificate-approver/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/certificate-signer.md b/content/en/docs/reference/controllers/certificate-signer.md new file mode 100644 index 0000000000000..41b14e945e4e5 --- /dev/null +++ b/content/en/docs/reference/controllers/certificate-signer.md @@ -0,0 +1,31 @@ +--- +title: Certificate signer controller +content_template: templates/concept +--- + +{{% capture overview %}} + +A controller that signs {{< glossary_tooltip text="certificates" term_id="certificate" >}}, +based on a certificate signing request (CSR), once approved. The issued +certificates will have a signing chain back to the cluster's root CA. + +{{% /capture %}} + +{{% capture body %}} + +The certificate signer is built in to kube-controller-manager. You can add your own controller, +either to work alongside this built-in controller, or to work in its place. + +## Controller behavior + +This controller watches for CertificateSigningRequest (CSR) objects and their approvals. +When the certificate signer sees an approved request, it signs the request using the +configured certificate and key (typically, this will be the cluster root CA). + +The controller stores the issued certificate in the `status.certificate` field of the +CertificateSigningRequest object. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about the [certificate approver](/docs/reference/controllers/certificate-approver/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/clusterrole-aggregation.md b/content/en/docs/reference/controllers/clusterrole-aggregation.md new file mode 100644 index 0000000000000..c2cb2031d5bc8 --- /dev/null +++ b/content/en/docs/reference/controllers/clusterrole-aggregation.md @@ -0,0 +1,30 @@ +--- +title: ClusterRole aggregation controller +content_template: templates/concept +--- + +{{% capture overview %}} + +This controller implements the `aggregationRule` property for [ClusterRoles](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole), which are used in connection with +{{< glossary_tooltip text="Role-Based Access Control" term_id="rbac" >}} (RBAC). + + +{{% /capture %}} + +{{% capture body %}} + +The ClusterRole aggregation controller is built in to kube-controller-manager. + +## Controller behavior + +This controller manages the permissions of aggregated ClusterRoles. The controller +watches ClusterRoles for changes. + +If the controller sees changes (add / remove / update) to a ClusterRole that matches +the clusterRoleSelectors for any existing ClusterRole, it will calcluate the rules +for the ClusterRole that had clusterRoleSelectors set. + +See [Aggregated ClusterRoles](/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles) +for more information on this. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/cronjob.md b/content/en/docs/reference/controllers/cronjob.md new file mode 100644 index 0000000000000..33489c33e81c2 --- /dev/null +++ b/content/en/docs/reference/controllers/cronjob.md @@ -0,0 +1,44 @@ +--- +title: Cron job controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The cron job controller creates {{< glossary_tooltip text="Jobs" term_id="job" >}} for a +{{< glossary_tooltip term_id="cronjob" >}} on a time-based schedule. + +{{< note >}} +All `schedule:` times for CronJobs are based on the timezone of the Kubernetes control plane. +{{< /note >}} + + +{{% /capture %}} + + +{{% capture body %}} + +The CronJob controller is built in to kube-controller-manager. + +## Controller behavior + +The cron job controller creates a Job object _about_ once per execution time +of its schedule. In certain circumstances, the controller might create one +job, or none. + +For every CronJob, the CronJob controller checks how many schedules it +missed in the duration from its last scheduled time until now. If there +are too many, then it does not start the Job and instead logs an error. + +The CronJob controller is only responsible for creating Jobs that match a +CronJob's schedule. The [Job controller](/docs/reference/controllers/job/) +takes care of running Jobs by creating Pods. + +{{% /capture %}} + +{{% capture whatsnext %}} + +* Read about [CronJobs](/docs/concepts/workloads/controllers/cron-jobs/) +* Learn about [running automated tasks with cron jobs](/docs/tasks/job/automated-tasks-with-cron-jobs). + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/daemonset.md b/content/en/docs/reference/controllers/daemonset.md new file mode 100644 index 0000000000000..4879704631220 --- /dev/null +++ b/content/en/docs/reference/controllers/daemonset.md @@ -0,0 +1,106 @@ +--- +title: DaemonSet controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The DaemonSet controller manages Pods configured via a +{{< glossary_tooltip term_id="daemonset" >}} object, to make sure that some +(or all) Nodes run a copy of a Pod. + +{{% /capture %}} + + +{{% capture body %}} + +The DaemonSet controller is built in to kube-controller-manager. + +## Controller behavior + +The DaemonSet controller ensures that all eligible nodes run a copy of a Pod, +by creating Pods with a Node assignment (one Pod for each eligible Node). + +This controller creates one Pod for each Node that the DaemonSet matches. +It creates new Pods in batches, doubling the batch size each time a request +succeeds. This helps to avoid sending a very large number of API requests that +will ultimately all fail with the same error. + +To track changes efficiently, this controller labels new Pods using a hash +of the the DaemonSet the Pod belongs to. + +If it's managing a Pod on a Node that no longer matches the DaemonSet, +or where the Node no longer exists, the controller will remove that Pod. + +If a DaemonSet's Pods fail the controller recreates them, applying a rate +limit to avoid a hot loop of killing and then recreating broken Pods. + +## How DaemonSet Pods are scheduled + +### Scheduled by DaemonSet controller (disabled by default since v1.12) {#scheduled-by-daemonset-controller} + +For most Pods, the main Kubernetes scheduler allocates each Pod to a Node. +However, when the DaemonSet controller creates Pods these already have a node +specified. The scheduler will see that `spec.nodeName` is set and will ignore +that Pod for scheduler. +Therefore: + + - The DaemonSet controller does not respect the + [`unschedulable`](/docs/admin/node/#manual-node-administration) field of Nodes. + - The DaemonSet controller can make Pods even when the scheduler has not been + started. This can help with cluster bootstrap. + +### Scheduled by default scheduler (enabled by default since v1.12) {#scheduled-by-default-scheduler} + +{{< feature-state state="beta" for-kubernetes-version="1.12" >}} + +A DaemonSet ensures that all eligible nodes run a copy of a Pod. Normally, the +Kubernetes scheduler selects the node that a Pod runs on. However, this controller +ceates Pods for DaemonSets with the aim of having each Pod run on a specific Node. +That introduces the following issues: + + * Inconsistent Pod behavior: Normal Pods waiting to be scheduled are created + and in `Pending` state, but DaemonSet pods are not created in `Pending` + state. This is confusing to the user. + * [Pod preemption](/docs/concepts/configuration/pod-priority-preemption/) + is handled by default scheduler. When preemption is enabled, the DaemonSet controller + will make scheduling decisions without considering pod priority and preemption. + +If you have the +[feature gate](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/) +ScheduleDaemonSetPods enabled, your cluster will schedule DaemonSets using the +default scheduler instead of via this controller. +With ScheduleDaemonSetPods enabled, the DaemonSet controller users +[node affinity`](/docs/concepts/configuration/assign-pod-node/#node-affinity) +so that the Pods it creates are scheduled onto the correct node. + +Specifically, the controller acts as if the pod template in the DaemonSet contained +a `RequiredDuringSchedulingIgnoredDuringExecution` node affinity that +requires `nodeName` to be the target Node where the controller is scheduling +a particular Pod. +To be clear: the controller does not make any changes to the DaemonSet's actual +`spec.template`. + +If the DaemonSet controller is handling an existing Pod for a DaemonSet, it +will make sure that `nodeAffinity` matches the Node where the Pod is executing, +and that there is only ever one Pod running on a Node for a given DaemonSet. + +### Taints and Tolerations + +This controller automatically adds the following +{{< glossary_tooltip text="tolerations" term_id="toleration" >}} to +Pods that it creates: + +| Toleration | Effect | +| ---------------------------------------- | ---------- | +| `node.kubernetes.io/not-ready` | NoExecute | +| `node.kubernetes.io/unreachable` | NoExecute | +| `node.kubernetes.io/disk-pressure` | NoSchedule | +| `node.kubernetes.io/memory-pressure` | NoSchedule | +| `node.kubernetes.io/unschedulable` | NoSchedule | +| `node.kubernetes.io/network-unavailable` | NoSchedule | + +The default scheduler is therefore willing to place a DaemonSet's Pods +onto Nodes that are not ready to accept workload Pods. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/deployment.md b/content/en/docs/reference/controllers/deployment.md new file mode 100644 index 0000000000000..090686111840d --- /dev/null +++ b/content/en/docs/reference/controllers/deployment.md @@ -0,0 +1,114 @@ +--- +title: Deployment controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip term_id="deployment" >}} controller +enables declarative updates for [Pods](/docs/concepts/workloads/pods/pod/) and +[ReplicaSets](/docs/concepts/workloads/controllers/replicaset/). + +You describe a _desired state_ in a Deployment object, and the Deployment +controller changes the actual state to the desired state at a controlled +rate. You can define Deployments to create new ReplicaSets, or to remove +existing Deployments and adopt all their resources with new Deployments. + +{{% /capture %}} + +{{% capture body %}} + +The deployment controller is built in to kube-controller-manager. + +## Controller behavior + +The Deployment controller creates and manages a ReplicaSet that in turn, +via the ReplicaSet controller, manages a set of Pods to run a containerized +application. +Each time the Deployment controller observes a new Deployment object, +it creates a new ReplicaSet to bring up the desired Pods (unless there is +already a ReplicaSet doing just that). + +The Deployment controller gives each ReplicaSet a name that it derives from +the name of the Pod in the Deployment's replicaset template. The Deployment +controller also sets a label on the Pods (via the ReplicaSet's pod template) +based on a hash of the pod template. + +The Deployment controller adds this `pod-template-hash` label to every +ReplicaSet that it is managing. + +To enable declarative updates, the Deployment controller tracks a +`deployment.kubernetes.io/revision-history` annotation on each Deployment object. +When you update a Deployment's pod template, this triggers an update +(see [Revision history](#revision-history)). + +With the default `RollingUpdate` strategy, the Deployment controller +gradually scales up the new replica set and scales down existing ReplicaSets. +You can also use the `Recreate` update strategy; in this case, the Deployment +controller removes the existing ReplicaSet outright and adds a new one. + +If you undo a rollout (eg with `kubectl`, the Deployment controller spots +that `deployment.kubernetes.io/revision` has changed and switches to running +with the relevant entry in its revision history. +(Assuming that the switch has updated the pod template), the Deployment controller +creates a new ReplicaSet based on the revision you're rolling back to, and gradually +migrates the load onto Pods from the new ReplicaSet. + +By default, a Deployment controller makes sure that at most 25% of Pods are +unavailable during a rollout. The controller also limits the total number of +Pods during a rollout; by default, the limit is 125% of the Deployment's +desired replica count. + +If you update a Deployment while an existing rollout is +[in progress](#tracking-progress), the Deployment controller will create a new +ReplicaSet as per the update and start scaling that up. The ReplicaSet +connected to the previous rollout, the one that was in progress just +now, will get scaled down. This is because the Deployment controller +will recognise the old ReplicaSet as superseded. + +If a rollout creates only bad (failing) Pods, the Deployment controller detects +this and aborts the rollout. It will stop scaling up the new ReplicaSet but will +*not* automatically fix a misconfigured pod template. + +### Revision history + +The Deployment controller tracks revisions to the Deployment object, up to +a configurable number of history revisions. The default is 0, ie to retain +all history. +When a Deployment's spec changes, the controller records a new history entry +and removes any existing history entries beyond the tracking limit. + +### Tracking progress + +The deployment controller marks a Deployment as _progressing_ when one of the following tasks is performed: + +* The Deployment creates a new ReplicaSet. +* The Deployment is scaling up its newest ReplicaSet. +* The Deployment is scaling down its older ReplicaSet(s). +* New Pods, relevant to the Deployment but not previously known to the controller, become ready or available (ready for at least [MinReadySeconds](#min-ready-seconds)). + +The deployment controller marks a Deployment as _complete_ when it has the following characteristics: + +* All of the replicas associated with the Deployment have been updated to the latest version you've specified, meaning any +updates you've requested have been completed. +* All of the replicas associated with the Deployment are available. +* No old replicas for the Deployment are running. + +When processing a Deployment with `spec.paused` set, the controller adds a condition +with `Reason=DeploymentPaused`. The Deployment controller skips progress +checking for Deployments with that condition set. + +### Tracking failure(s) {#tracking-failure} + +The Deployment controller keeps track of whether its newest ReplicaSet is +deploying OK. If you set `.spec.progressDeadlineSeconds` for a Deployment, +and the ReplicaSet does not come up OK within that interval, the Deployment +controller adds a Condition to the Deployment, with +condition `Type=Progressing, Status=False` and +`Reason=ProgressDeadlineExceeded`. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about [Deployments](/docs/concepts/workloads/controllers/deployment/) +* Read about [ReplicaSets](/docs/concepts/workloads/controllers/replicaset/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/endpoint.md b/content/en/docs/reference/controllers/endpoint.md new file mode 100644 index 0000000000000..13c9d44552d3b --- /dev/null +++ b/content/en/docs/reference/controllers/endpoint.md @@ -0,0 +1,32 @@ +--- +title: Endpoint controller +content_template: templates/concept +--- + +{{% capture overview %}} + +This controller makes sure that {{< glossary_tooltip text="Services" term_id="service" >}} +have an Endpoint for each Pod that matches the Services' label selector. + +{{% /capture %}} + +{{% capture body %}} + +The endpoint controller is built in to kube-controller-manager. + +## Controller behavior + +The controller watches for Service and Pod objects. For each Service, this +controller normally adds or removes Endpoints so that the each Pod has a matching +Endpoint. + +If you define a Service without a selector, this controller will *not* create +Endpoints for that Service. You can instead manually map the service to the +network address and port where it’s running, by adding an Endpoint object manually. + +{{% /capture %}} +{{% capture whatsnext %}} + +* Read about the [Service controller](/docs/reference/controllers/service/) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/garbage-collector.md b/content/en/docs/reference/controllers/garbage-collector.md new file mode 100644 index 0000000000000..66d47adfe356b --- /dev/null +++ b/content/en/docs/reference/controllers/garbage-collector.md @@ -0,0 +1,38 @@ +--- +title: Garbage Collector +content_template: templates/concept +--- + +{{% capture overview %}} + +The Kubernetes garbage collector is a built-in controller. It deletes certain +objects that once had an owner, but no longer have an owner. + +{{% /capture %}} + + +{{% capture body %}} + +## Controller behavior + +This controller watches for changes to objects that have dependencies, and +spots objects that are eligible for garbage collection. Once identified these +are queued for (attempts at) deletion. + +Other controllers can rely on this behavior to take care of cascading deletion +of objects via parent-child relationships. + +For example: if you remove a {{< glossary_tooltip term_id="deployment" >}} +that relies on a {{< glossary_tooltip term_id="replica-set" >}} to ensure +the right number of {{< glossary_tooltip text="Pods" term_id="pod" >}} are +running, removing that Deployment will schedule removal of the ReplicaSet. + +{{% /capture %}} + +{{% capture whatsnext %}} + +* Read [Garbage collection design document 1](https://git.k8s.io/community/contributors/design-proposals/api-machinery/garbage-collection.md) + +* Read [Garbage collection design document 2](https://git.k8s.io/community/contributors/design-proposals/api-machinery/synchronous-garbage-collection.md) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/horizontal-pod-autoscaler.md b/content/en/docs/reference/controllers/horizontal-pod-autoscaler.md new file mode 100644 index 0000000000000..709a9202ce1ae --- /dev/null +++ b/content/en/docs/reference/controllers/horizontal-pod-autoscaler.md @@ -0,0 +1,159 @@ +--- +title: Horizontal Pod Autoscaler +content_template: templates/concept +--- + +{{% capture overview %}} + +The Horizontal Pod Autoscaler automatically scales the number of Pods +in a {{< glossary_tooltip text="Deployment" term_id="deployment" >}}, {{< glossary_tooltip text="StatefulSet" term_id="statefulset" >}} or other scalable resource. +This controller scales the number of Pods based on observed CPU utilization (or, with +[custom metrics](https://git.k8s.io/community/contributors/design-proposals/instrumentation/custom-metrics-api.md) +support, on some other application-provided metrics). + +{{% /capture %}} +{{% capture body %}} + +## Automatic scaling + +The controller periodically adjusts the number of replicas in a Deployment, +so as to to match the observed average resource utilization to the target you specified. + +![Horizontal Pod Autoscaler diagram](/images/docs/horizontal-pod-autoscaler.svg) + +The Horizontal Pod Autoscaler runs as a control loop with a period controlled +by kube-controller-manager's `--horizontal-pod-autoscaler-sync-period` flag. +The default synchronization period is 15 seconds. + +During each period, the Horizontal Pod Autoscaler queries the resource utilization against the +metrics specified in each HorizontalPodAutoscaler definition. The Horizontal Pod Autoscaler +obtains the metrics from either the resource metrics API (for per-pod resource metrics), +or the custom metrics API (for all other metrics). + +* For per-pod resource metrics (like CPU), this controller fetches the metrics + from the resource metrics API for each Pod that the HorizontalPodAutoscaler object + targets. + Then, if a target utilization value is set, the controller calculates the utilization + value as a percentage of the equivalent resource request on the containers in + each pod. If a target raw value is set, the raw metric values are used directly. + The controller then takes the mean of the utilization or the raw value (depending on the type + of target specified) across all targeted pods, and produces a ratio used to scale + the number of desired replicas. + + If some of the Pod's containers do not have the relevant resource request set, + CPU utilization for the pod will not be defined and the autoscaler will + not take any action for that metric. See [algorithm + details](#algorithm-details) for more information about + how the autoscaling algorithm works. + +* For per-pod custom metrics, the controller functions similarly to per-pod resource metrics, + except that it works with raw values, not utilization values. + +* For object metrics and external metrics, a single metric is fetched, which describes + the object in question. This metric is compared to the target + value, to produce a ratio as above. In the `autoscaling/v2beta2` API + version, this value can optionally be divided by the number of pods before the + comparison is made. + +The HorizontalPodAutoscaler normally fetches metrics from a series of aggregated APIs (`metrics.k8s.io`, +`custom.metrics.k8s.io`, and `external.metrics.k8s.io`). The `metrics.k8s.io` API is usually provided by +metrics-server, which you needs to launch separately. See +[metrics-server](/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#metrics-server) +for instructions. + +The autoscaler accesses corresponding scalable resources (such as Deployments and ReplicaSets) +by using the scale sub-resource. Scale is an interface that allows you to dynamically set the +number of replicas and examine each of their current states. + +## Algorithm Details + +From the most basic perspective, the Horizontal Pod Autoscaler controller +operates on the ratio between desired metric value and current metric +value: + +``` +desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )] +``` + +For example, if the current metric value is `200m`, and the desired value +is `100m`, the number of replicas will be doubled, since `200.0 / 100.0 == +2.0` If the current value is instead `50m`, we'll halve the number of +replicas, since `50.0 / 100.0 == 0.5`. We'll skip scaling if the ratio is +sufficiently close to 1.0 (within a globally-configurable tolerance, from +the `--horizontal-pod-autoscaler-tolerance` flag, which defaults to 0.1). + +When a `targetAverageValue` or `targetAverageUtilization` is specified, +the `currentMetricValue` is computed by taking the average of the given +metric across all Pods in the HorizontalPodAutoscaler's scale target. +Before checking the tolerance and deciding on the final values, we take +pod readiness and missing metrics into consideration, however. + +The controller ignores failed Pods and Pods with a deletion timestamp set. +If Pods have a deletion timestamp set, it means they are in the process +of being shut down. + +If a particular Pod is missing metrics, it is set aside for later; Pods +with missing metrics will be used to adjust the final scaling amount. + +When scaling on CPU, if any Pod has yet to become ready (i.e. it's still +initializing) *or* the most recent metric point for the Pod was recorded +before the Pod became ready, that Pod is set aside as well. + +Due to technical constraints, the HorizontalPodAutoscaler controller +cannot exactly determine the first time a pod becomes ready when +determining whether to set aside certain CPU metrics. Instead, it +considers a Pod "not yet ready" if it's unready and transitioned to +unready within a short, configurable window of time since it started. +This value is configured with the `--horizontal-pod-autoscaler-initial-readiness-delay` flag, and its default is 30 +seconds. Once a pod has become ready, it considers any transition to +ready to be the first if it occurred within a longer, configurable time +since it started. This value is configured with the `--horizontal-pod-autoscaler-cpu-initialization-period` flag, and its +default is 5 minutes. + +The `currentMetricValue / desiredMetricValue` base scale ratio is then +calculated using the remaining pods not set aside or discarded from above. + +If there were any missing metrics, we recompute the average more +conservatively, assuming those pods were consuming 100% of the desired +value in case of a scale down, and 0% in case of a scale up. This dampens +the magnitude of any potential scale. + +Furthermore, if any not-yet-ready pods were present, and we would have +scaled up without factoring in missing metrics or not-yet-ready pods, we +conservatively assume the not-yet-ready pods are consuming 0% of the +desired metric, further dampening the magnitude of a scale up. + +After factoring in the not-yet-ready pods and missing metrics, we +recalculate the usage ratio. If the new ratio reverses the scale +direction, or is within the tolerance, we skip scaling. Otherwise, we use +the new ratio to scale. + +{{< note >}} +The *original* value for the average utilization is reported +back via the HorizontalPodAutoscaler status, without factoring in the +not-yet-ready pods or missing metrics, even when the new usage ratio is +used. +{{< /note >}} + +### Multiple metrics + +If multiple metrics are specified in a HorizontalPodAutoscaler, this +calculation is done for each metric, and then the largest of the desired +replica counts is chosen. If any of those metrics cannot be converted +into a desired replica count (e.g. due to an error fetching the metrics +from the metrics APIs), scaling is skipped. + +Finally, just before HPA scales the target, the scale recommendation is recorded. The +controller considers all recommendations within a configurable window choosing the +highest recommendation from within that window. You can configure this value via the +`--horizontal-pod-autoscaler-downscale-stabilization` flag, which defaults to 5 minutes. + +This means that scaledowns will occur gradually, smoothing out the impact of rapidly +fluctuating metric values. + +{{% /capture %}} +{{% capture whatsnext %}} + +* Read the design proposal for [scale subresources](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#scale-subresource) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/ingress.md b/content/en/docs/reference/controllers/ingress.md new file mode 100644 index 0000000000000..f660132a95338 --- /dev/null +++ b/content/en/docs/reference/controllers/ingress.md @@ -0,0 +1,73 @@ +--- +title: Ingress controllers +content_template: templates/concept +--- + +{{% capture overview %}} + +{{< feature-state for_k8s_version="v1.1" state="beta" >}} + +In order for the Ingress resource to work, the cluster must have at least +one ingress {{< glossary_tooltip term_id="controller" text="controller">}} running. + +Unlike the controllers which run as part of the `kube-controller-manager` binary, Ingress controllers +are not started automatically with a cluster. Use this page to choose the ingress controller implementation(s) +that best fit your cluster. + +The Kubernetes project currently supports and maintains [GCE](https://git.k8s.io/ingress-gce/README.md) and + [nginx](https://git.k8s.io/ingress-nginx/README.md) controllers. + +{{% /capture %}} + +{{% capture body %}} + +## Third-party ingress controllers {#additional-controllers} + +* [Ambassador](https://www.getambassador.io/) API Gateway is an [Envoy](https://www.envoyproxy.io)-based ingress + controller with [community](https://www.getambassador.io/docs) or + [commercial](https://www.getambassador.io/pro/) support from [Datawire](https://www.datawire.io/). +* [Citrix Kubernetes Ingress Controller](https://github.com/citrix/citrix-k8s-ingress-controller) for use with with Citrix hardware (MPX), virtualized (VPX) and free [containerized (CPX) ADC](https://www.citrix.com/products/citrix-adc/cpx-express.html). You can use it for [bare metal](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment/baremetal) or [cloud](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment) deployments. +* [Contour](https://github.com/heptio/contour) is an [Envoy](https://www.envoyproxy.io) based ingress controller. +* [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest) from + [F5 Networks](https://f5.com/). +* [Gloo](https://gloo.solo.io) is an open-source ingress controller based on [Envoy](https://www.envoyproxy.io) which offers API Gateway functionality. You can get enterprise support for Gloo from [solo.io](https://www.solo.io). +* [HAProxy Technologies](https://www.haproxy.com/) offers support and maintenance for + the [HAProxy Ingress Controller for +Kubernetes](https://github.com/haproxytech/kubernetes-ingress). + See the [official documentation](https://www.haproxy.com/documentation/hapee/1-9r1/traffic-management/kubernetes-ingress-controller/). +* [Kong Ingress Controller for Kubernetes](https://github.com/Kong/kubernetes-ingress-controller). You can choose + either the [community](https://discuss.konghq.com/c/kubernetes) or + [commercial](https://konghq.com/kong-enterprise/) support and maintenance. +* [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller). + from [NGINX, Inc.](https://www.nginx.com/) +* [Traefik](https://traefik.io/) is a fully featured ingress controller + ([Let's Encrypt](https://letsencrypt.org), secrets, http2, WebSockets). You can use a [community edition](https://traefik.io/#community) or choose commercial support from by [Containous](https://containo.us/services). +* [Voyager](https://appscode.com/products/voyager/) is based on [HAProxy](http://www.haproxy.org/). You can get support from [AppsCode Inc.](https://appscode.com) + +If you use Istio, you can use it to [control ingress traffic](https://istio.io/docs/tasks/traffic-management/ingress/) via Istio's custom resources. +The outcome you'll get is broadly equivalent to deploying a suitable Ingress controller. + +## Using multiple Ingress controllers + +You may deploy [any number of ingress controllers](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) +within a cluster. When you create an ingress, you should annotate each ingress with the appropriate +[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster) +to indicate which ingress controller should be used if more than one exists within your cluster. + +If you do not define a class, your cloud provider may use a default ingress provider. + +Ideally, all ingress controllers should fulfill this specification, but the various ingress +controllers operate slightly differently. + +{{< note >}} +Make sure you review your ingress controller's documentation to understand the caveats of choosing it. +{{< /note >}} + +{{% /capture %}} + +{{% capture whatsnext %}} + +* Learn more about [Ingress](/docs/concepts/services-networking/ingress/). +* [Set up Ingress on Minikube with the NGINX Controller](/docs/tasks/access-application-cluster/ingress-minikube). + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/job.md b/content/en/docs/reference/controllers/job.md new file mode 100644 index 0000000000000..33aafaee98d49 --- /dev/null +++ b/content/en/docs/reference/controllers/job.md @@ -0,0 +1,40 @@ +--- +title: Job controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip term_id="job" >}} controller creates +{{< glossary_tooltip term_id="pod" text="Pods" >}} to run each +Job to completion. + +As its pods successfully complete, the controller tracks successful completions. +When a specified number of successful completions is reached, the Job +controller updates the Job object to mark it complete. + +{{% /capture %}} + + +{{% capture body %}} + +The job controller is built in to kube-controller-manager. It creates +one or more Pods to run each Job to completion. + +## Cleanup for finished Jobs + +Finished Jobs are usually no longer needed in the system. +This controller leaves Job objects in place even after they are finished. +If another controller, such as the +[CronJob controller](/docs/reference/controllers/cron-jobs/), +is managing Job objects, then the other controller is responsible for +the Jobs it created and can clean them up. + +The [TTL after finished controller](/docs/reference/controllers/ttlafterfinished/) +provides an alternative cleanup mechanism for finished resources, +such as Jobs. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about [Jobs](/docs/concepts/workloads/controllers/job-run-to-completion/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/namespace.md b/content/en/docs/reference/controllers/namespace.md new file mode 100644 index 0000000000000..ba0cd459e1f70 --- /dev/null +++ b/content/en/docs/reference/controllers/namespace.md @@ -0,0 +1,23 @@ +--- +title: Namespace controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip term_id="namespace" >}} controller handles +cleanup when a Namespace is removed. + +{{% /capture %}} + +{{% capture body %}} + +The namespace controller is built in to kube-controller-manager. + +## Controller behavior + +When you (or any Kubernetes API client) remove a namespace, this +controller makes sure that objects in that namespace are removed before +the namespace itself is removed. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/node-ip-address-management.md b/content/en/docs/reference/controllers/node-ip-address-management.md new file mode 100644 index 0000000000000..31e4c158270d0 --- /dev/null +++ b/content/en/docs/reference/controllers/node-ip-address-management.md @@ -0,0 +1,23 @@ +--- +title: Node IPAM controller +content_template: templates/concept +--- + +{{% capture overview %}} + +This controller implements IP address management to ensure that +Nodes have blocks of IP addresses available to be assigned +to Pods. + +{{% /capture %}} + +{{% capture body %}} + +{{< note >}} +The network configuration for your cluster, and the choice of +{{< glossary_tooltip text="CNI" term_id="cni" >}} plugin(s) will +determine whether and how this controller sets `podCIDR` for Nodes in +the cluster. +{{< /note >}} + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/node-lifecycle.md b/content/en/docs/reference/controllers/node-lifecycle.md new file mode 100644 index 0000000000000..3c642846d1b4e --- /dev/null +++ b/content/en/docs/reference/controllers/node-lifecycle.md @@ -0,0 +1,30 @@ +--- +title: Node lifecycle controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The Node lifecycle controller automates managing +{{< glossary_tooltip text="taints" term_id="taint" >}} on +{{< glossary_tooltip text="Nodes" term_id="node" >}}. + +{{% /capture %}} + +{{% capture body %}} + +The node lifecycle controller is built in to kube-controller-manager. + +## Controller behavior + +This controller observes the behavior of kubelet on a node, and sets (potentially +also removes) {{< glossary_tooltip text="taints" term_id="taint" >}} on Nodes +that reflect its findings. + +For example: if kubelet stops reporting that a worker node is healthy, the +controller can apply a taint to prevent scheduling new Pods there. + +If there is a significant problem—maybe the entire node has crashed—then +the controller triggers evictions for the Pods on the affected node. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/node.md b/content/en/docs/reference/controllers/node.md new file mode 100644 index 0000000000000..cf4259a69be27 --- /dev/null +++ b/content/en/docs/reference/controllers/node.md @@ -0,0 +1,50 @@ +--- +title: Node controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The node controller is a Kubernetes master component which manages various +aspects of nodes. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +The node controller has multiple roles in a node's life. + +### Roles + +1. If CIDR assignment is enabled, this controller assigns a CIDR block to each + new Node when it is registered. +2. This controller tracks and caches the cloud provider's list of available machines. + When running in a cloud environment, and a node becomes unhealthy, the node + controller queries the cloud provider's API to discover whether the server + representing the unhealthy Node is still available. If the cloud provider API + shows the server is gone / missing, the node controller stops tracking the Node. +3. This controller watches running Nodes and updates the + [conditions](/docs/concepts/architecture/nodes/#condition) field if the kubelet on + a server stops sending heartbeats. + Heartbeats come in 2 kinds: + - changes to the associated Lease resource in the `kube-node-lease` namespace + - updates to the Node's `.nodeStatus` field + + Either kind of heartbeat counts as a sign that the Node is still alive. + If a Node becomes unreachable (the node controller hasn't seen the heartbeats + for at least `--node-monitor-grace-period` seconds), this controller sets the Node's + condition to `Unknown`. +4. When something sets a condition on a Node, this controller additionally + {{< glossary_tooltip text="taints" term_id="taint" >}} the Node with taints inside + `node.kubernetes.io/`. For example, `node.kubernetes.io/unreachable` is the taint that + matches the `Unknown` condition. + + If / when the condition changes, this controller updates the taints to match. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about [nodes](/docs/concepts/architecture/nodes/) +* Read about the [Node API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core). +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/pod-disruption-budget.md b/content/en/docs/reference/controllers/pod-disruption-budget.md new file mode 100644 index 0000000000000..b462942c79a4f --- /dev/null +++ b/content/en/docs/reference/controllers/pod-disruption-budget.md @@ -0,0 +1,45 @@ +--- +title: PodDisruptionBudget controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The PodDisruptionBudget controller implements managed control over disruptions +to applications running on your cluster. + +{{% /capture %}} + +{{% capture body %}} + +The PodDisruptionBudget controller is built in to kube-controller-manager. + +## Controller behavior + +Where a PodDisruptionBudget matches a label selector, the PodDisruptionBudget +controller finds the resource that manages those Pods (eg a Deployment) and +sets either `maxUnavailable` or `minAvailable` for the managing resource +(for the example, that means the Deployment object). + + +### Pod disruption budgets for custom resources +The PodDisruptionBudget controller has special behaviour if managing +Deployment, ReplicationController, ReplicaSet, and StatefulSet, when the PDB +selector matching the PodDisruptionBudget’s selector. + +You can use a PDB with pods controlled by another type of controller, by an “operator”, +or bare pods. In that case, the PodDisruptionBudget controller requires that +that you have set `.spec.minAvailable` to an integer value. You can't use +percentages or set `.spec.maxUnavailable`. + +You can use a selector which selects a subset or superset of the pods +belonging to a built-in controller. However, when there are multiple +PDBs in a namespace, you must be careful not to create PDBs whose +selectors overlap. + +{{% /capture %}} +{{% capture whatsnext %}} + +* Read about the [scale subresource](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#scale-subresource) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/pod-garbage-collector.md b/content/en/docs/reference/controllers/pod-garbage-collector.md new file mode 100644 index 0000000000000..e4f98ae9e22a2 --- /dev/null +++ b/content/en/docs/reference/controllers/pod-garbage-collector.md @@ -0,0 +1,24 @@ +--- +title: Pod garbage collector +content_template: templates/concept +--- + +{{% capture overview %}} + +The Pod garbage collector handles cleanup of +terminated {{< glossary_tooltip text="Pods" term_id="pod" >}}. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +This controller takes care of cleaning up Pods that are terminated, so +that the resources for tracking those Pods can be reclaimed. + +The controller tracks the number of Pods eligible for cleanup and activates +onces that number passes a defined threshold. This controller only ever removes Pods +that are already terminated. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/replicaset.md b/content/en/docs/reference/controllers/replicaset.md new file mode 100644 index 0000000000000..5c8542faee1fa --- /dev/null +++ b/content/en/docs/reference/controllers/replicaset.md @@ -0,0 +1,67 @@ +--- +title: ReplicaSet controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The ReplicaSet controller maintains a stable number of replica Pods for +each {{< glossary_tooltip text="ReplicaSet" term_id="replica-set" >}}. + +{{% /capture %}} + +{{% capture body %}} + +The replicaset controller is built in to kube-controller-manager. + +## Controller behavior + +The controller watches for ReplicaSet objects. For each ReplicaSet, this +controller adds or removes Pods so that the right number of Pods are running +for each ReplicaSet. + +When you define a ReplicaSet you provide fields including a desired number of +replicas, a template for Pods that the controller should create, and a +{{< glossary_tooltip term_id="selector" >}} that the controller can use to find +the Pods it is managing. + +If there are more Pods running for a ReplicaSet than the desired count, the +controller selects a Pod from the replica set and deletes it. If there are too +few replicas, the controller will create a new Pod based on the Pod template +for that ReplicaSet. + +Pods for a ReplicaSet must have a +[restart policy](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) +of `Always`. + +When the controller creates Pods, it sets the [metadata.ownerReferences](/docs/reference/controllers/garbage-collector/#owners-and-dependents) for each new Pod, so that the Pod is owned +by the ReplicaSet that is responsible for it existing. + +The replica set controller uses the owner reference to track the Pods that it +is managing on behalf of a given ReplicaSet. When the controller finds a Pod +with no ownerReference set that matches the selector for a current ReplicaSet, +the replica set controller updates the Pod's ownerReference. The discovered +Pod becomes owned by the ReplicaSet. + +If you update a ReplicaSet that has already created Pods with one template, +and change the pod template inside the ReplicaSet, existing Pods will stay +running and will continue to match the ReplicaSet's selector. If / when the +ReplicaSet controller creates new Pods, those new Pods will be based on the +updated selector and may well be different from the older Pods. + +### Scaling + +If you change the number of replicas for a ReplicaSet, the controller reacts +accordingly. It will add or remove Pods if necessary. + +If the ReplicSet's replica count is unset, the controller defaults to running +a single Pod. + +{{% /capture %}} +{{% capture whatsnext %}} + +* Read about the [Deployment controller](/docs/reference/controllers/deployment/) +* Read about the [ReplicationController controller](/docs/reference/controllers/replicationcontroller/) + (ReplicaSet and Deployment replaced the now-deprecated ReplicationController resource) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/replicationcontroller.md b/content/en/docs/reference/controllers/replicationcontroller.md new file mode 100644 index 0000000000000..8dac524078b23 --- /dev/null +++ b/content/en/docs/reference/controllers/replicationcontroller.md @@ -0,0 +1,82 @@ +--- +title: Replication controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The replication controller ensures that a specified number of pod replicas are running at any one +time. +You can set up a ReplicationController object in order to make sure that a pod or a homogeneous set +of pods is always up and available. + +{{< note >}} +You should set up replication using a [Deployment](/docs/concepts/workloads/controllers/deployment/) that configures a [ReplicaSet](/docs/concepts/workloads/replicaset/). ReplicationController is available but deprecated. +{{< /note >}} + +{{% /capture %}} + + +{{% capture body %}} + +## ReplicationController objects + +Each controller in Kubernetes works with a particular set of objects. The _replication controller_ +manages Pod objects based on its configuration object, named _ReplicationController_. + +## How the replication controller works + +The replication controller works similarly to the replica set controller. For a given replication +configuration, the controller matches the running number of pods to the configuration. +If there are too many pods, the replication controller terminates the extra pods. +If there are too few, the replication controller starts more pods. + +Unlike manually created pods, pods managed via a ReplicationController +object are automatically replaced if they fail, are deleted, or are +terminated. + +To deploy an application (whether it uses one Pod or several), you can use ReplicationController +to act as a supervisor and make sure that the right number of Pods are running for your app. +(In Kubernetes {{< param "version" >}}, Deployment is a better choice). +The replication controller is similar to a process supervisor. Instead of supervising individual +processes on a single server, the replication controller supervises multiple pods +across multiple nodes. + +ReplicationController is often abbreviated to "rc" or "rcs" in discussion, and as a shortcut in +kubectl commands. + +### Rolling updates + +The replication controller is designed to facilitate rolling updates to +a service by replacing pods one-by-one. (For Kubernetes {{< param "version" >}}, +you should consider using a Deployment to manage ReplicaSet objects instead). + +You can create a new ReplicationController object with a single replica, +scale out the new ReplicationController object whilst scaling in the old +ReplicationController object, and then finally delete the old ReplicationController +object once is reaches 0 replicaes. + +If you're using ReplicationController objects, rolling updates are implemented +client-side in {{< glossary_tooltip term_id="kubectl" >}}. +You can learn more about rolling updates from the [`kubectl rolling-update` task](/docs/tasks/run-application/rolling-update-replication-controller/) page. + +## Replication controller responsibilities + +The replication controller simply ensures that the desired number +of pods matches its label selector and are operational. The controller +counts all matching pods that aren't Terminated. + +The replication controller does *not* check Pod readiness nor liveness. + +The ReplicationController object was intended to be a composable building-block +primitive. You should consider using resources such as Deployment, that build +upon the replacement for ReplicationController: ReplicaSet. + +{{% /capture %}} + +{{% capture whatsnext %}} + +* Read about the [ReplicaSet controller](/docs/reference/controllers/replicaset/) +* Learn to [Run a Stateless Application Using a Deployment](/docs/tasks/run-application/run-stateless-application-deployment/) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/resource-quota.md b/content/en/docs/reference/controllers/resource-quota.md new file mode 100644 index 0000000000000..b77d6548abc0d --- /dev/null +++ b/content/en/docs/reference/controllers/resource-quota.md @@ -0,0 +1,36 @@ +--- +title: Resource quota controller +content_template: templates/concept +--- + +{{% capture overview %}} + +This controller limits the quantity of objects that can be created in a namespace +by object type, as well as the total amount of compute resources that may be +consumed by resources in that namespace. + +Acting as an [admission controller](/docs/reference/access-authn-authz/admission-controllers/), +this component will reject requests that would take the amount of resource past +any configured limit. The controller tracks the actual amount of resouce in real +so that an admission decision can be made promptly. + +{{% /capture %}} + +{{% capture body %}} + +The resource quota controller is built in to kube-controller-manager. + +## Controller behavior + +Acting as an [admission controller](/docs/reference/access-authn-authz/admission-controllers/), +this component will reject requests that would take the amount of resource past +any configured limit. The controller tracks the actual amount of resouce in real +so that an admission decision can be made promptly. + +{{% /capture %}} + +{{% capture whatsnext %}} +* Read about [Resource Quotas](/docs/concepts/policy/resource-quotas/) +* Read the [design document for resourceQuota](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md) + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/service.md b/content/en/docs/reference/controllers/service.md new file mode 100644 index 0000000000000..bc072b27830da --- /dev/null +++ b/content/en/docs/reference/controllers/service.md @@ -0,0 +1,39 @@ +--- +title: Service controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip term_id="service" >}} controller manages network +access to a set of Pods via one or more Endpoints. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +For each Service, the controller continuously scans for Pods that match that +Service's {{< glossary_tooltip term_id="selector" >}}, and will then POST any +updates to an Endpoint object with the same name as the Service. + +Unless the Service controller idenfifies a “headless” Service (with `.spec.clusterIP` +explicitly set to `None`) then this controller will attempt to set up access to +the Service. For example, the Service controller might assign an IP address for +external access, or it might defer to another controller to ensure that an address +gets assigned. + +Using a Service resource you can set up several different mechanisms to handle +incoming network traffic to your application. Depending on your cluster and its +environment, this may involve the cloud-controller-manager as well as cloud-specific +controller behaviors. + +{{% /capture %}} +{{% capture whatsnext %}} + +* Read about the [Endpoint controller](/docs/reference/controllers/endpoint/) +* Read about the [Service](/docs/concepts/services-networking/service/) concept +* Read about the [Ingress](/docs/concepts/services-networking/ingress/) concept + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/serviceaccount-token.md b/content/en/docs/reference/controllers/serviceaccount-token.md new file mode 100644 index 0000000000000..18e00b182fda7 --- /dev/null +++ b/content/en/docs/reference/controllers/serviceaccount-token.md @@ -0,0 +1,26 @@ +--- +title: ServiceAccount token controller +content_template: templates/concept +--- + +{{% capture overview %}} + +One of a pair of controllers for the {{< glossary_tooltip text="ServiceAccount" term_id="service-account" >}} +resource. + +{{% /capture %}} + +{{% capture body %}} + +The ServiceAccount token controller is built in to kube-controller-manager. + +## Controller behavior + +This controller issues API access tokens for each service account and places them into +an associated {{< glossary_tooltip term_id="secret" >}}. Pods that can access that Secret +can use the token to identify as the relevant ServiceAccount. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about the [ServiceAccount controller](/docs/reference/controllers/serviceaccount/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/serviceaccount.md b/content/en/docs/reference/controllers/serviceaccount.md new file mode 100644 index 0000000000000..01106917e59ef --- /dev/null +++ b/content/en/docs/reference/controllers/serviceaccount.md @@ -0,0 +1,23 @@ +--- +title: ServiceAccount controller +content_template: templates/concept +--- + +{{% capture overview %}} + +One of a pair of controllers for the {{< glossary_tooltip text="ServiceAccount" term_id="service-account" >}} +resource. + +{{% /capture %}} + +{{% capture body %}} + +The service account controller is built in to kube-controller-manager. + +## Controller behavior + +This controller ensures that each Namespace contains a default service account. +{{% /capture %}} +{{% capture whatsnext %}} +* Read about the [ServiceAccount token controller](/docs/reference/controllers/serviceaccount-token/) +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/statefulset.md b/content/en/docs/reference/controllers/statefulset.md new file mode 100644 index 0000000000000..f16aadda38ce2 --- /dev/null +++ b/content/en/docs/reference/controllers/statefulset.md @@ -0,0 +1,37 @@ +--- +title: StatefulSet controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The StatefulSet controller ensures that a {{< glossary_tooltip term_id="StatefulSet" >}} +is running on a suitable set of Nodes. + +{{% /capture %}} + +{{% capture body %}} + +The StatefulSet controller is built in to kube-controller-manager. + +## Controller behavior + +The controller creates a number of Pods for each StatefulSet that it observes, +based on the count of replicas configured for that StatefulSet. The controller +creates these Pods *sequentially*. + +When the StatefulSet controller creates a Pod, it adds a label, `statefulset.kubernetes.io/pod-name`, +that is set to the name of the Pod. This label gives each Pod a durable, stable +network identity, that allows you to attach a Service to a specific Pod in +the StatefulSet. +The controller constructs the pod name label valuebased on a pattern: +`$(statefulset name)-$(ordinal)`. + +{{% /capture %}} +{{% capture whatsnext %}} + +* Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set/). +* Read about [force deleting StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/). + +{{% /capture %}} + diff --git a/content/en/docs/reference/controllers/ttl-after-finished.md b/content/en/docs/reference/controllers/ttl-after-finished.md new file mode 100644 index 0000000000000..024aa91df4ad6 --- /dev/null +++ b/content/en/docs/reference/controllers/ttl-after-finished.md @@ -0,0 +1,53 @@ +--- +title: TTL-after-finished controller +content_template: templates/concept +--- + +{{% capture overview %}} + +{{< feature-state for_k8s_version="v1.12" state="alpha" >}} + +The TTL-after-finished controller provides a Time-To-Live mechanism to limit the lifetime of resource +objects that have finished execution. + +The TTL controller only handles {{< glossary_tooltip text="Jobs" term_id="job" >}} for now. +In the future it may be able to handle other resources that will finish execution, such as +Pods and custom resources. + +{{% /capture %}} + + +{{% capture body %}} + +## Enabling the TTL-after-finished controller + +You can use the TTL-after-finished controller by enabling the +[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) +`TTLAfterFinished`. + +## Controller behavior + +For now, the TTL-after-finished controller only supports Jobs. You can use this feature to automate +cleaning up finished Jobs (either `Complete` or `Failed`) by specifying the +`.spec.ttlSecondsAfterFinished` field of a Job. +See [Job](/docs/concepts/workloads/controllers/job-run-to-completion/#clean-up-finished-jobs-automatically) for more details. + +The TTL-after-finished controller will assume that a resource is eligible to be cleaned up +from TTL seconds after the resource has finished, in other words, when the TTL has expired. When the +TTL controller cleans up a resource, it will delete it cascadingly, i.e. delete +its dependent objects together with it. Note that when the resource is deleted, +its lifecycle guarantees, such as finalizers, will be honored. + +## Time skew + +Because the TTL-after-finished controller uses timestamps stored in the Kubernetes resources to +determine whether the TTL has expired or not, this feature is sensitive to time +skew in your cluster. If the clocks in a cluster are out of synchronization, +the TTL-after-finished controller could clean up resource objects at the wrong time. + +{{< note >}} +You should ensure that all Nodes, and also your control plane, are using a time +synchronization system such as NTP. +{{< /note >}} + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/ttl.md b/content/en/docs/reference/controllers/ttl.md new file mode 100644 index 0000000000000..402021857bbaf --- /dev/null +++ b/content/en/docs/reference/controllers/ttl.md @@ -0,0 +1,27 @@ +--- +title: Time-to-live (TTL) controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The Time-to-live (TTL) controller sets sets TTL annotations on Nodes based on cluster size. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +This controller sets sets TTL annotations on Nodes based on cluster size. +{{< glossary_tooltip term_id="kubelet" >}} consumes these annotations as a +hint about how long it can cache object data that it has fetched from the +{{< glossary_tooltip text="API server" term_id="kube-apiserver" >}}. + +{{< comment >}} +This controller is an implementation detail; if kubelet were able to +subscribe to watch resources that are linked to Pods on that node, +kubelet could use those notifications for cache invalidation instead. +{{< /comment >}} + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/volume-attach-detach.md b/content/en/docs/reference/controllers/volume-attach-detach.md new file mode 100644 index 0000000000000..e37e1be45cc8c --- /dev/null +++ b/content/en/docs/reference/controllers/volume-attach-detach.md @@ -0,0 +1,39 @@ +--- +title: Volume attach / detach controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip text="Volume" term_id="volume" >}} +attach / detach controller is part of a set of built-in controllers for storage management. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +The volume attach / detach controller is responsible for attaching and detaching +all Volumes across a cluster. This controller watches the API server for Pod +creation and termination. + +Once a new pod is scheduled, the volume attach / detach controller works out what +volumes need to be attached and signals this (via the API server) to kubelet and +to storage services. The controller updates `.status.volumesAttached` on the +Node where the Pod is scheduled, and kubelet updates `.status.volumesInUse` once +it starts using the Volume (ie, mounting it for a container in a Pod). + +When a pod is terminated, the controller makes sure that the existing attached +volumes are detached. After signalling for kubelet to unmount the volume, the +volume attach / detach controller waits for graceful unmount before attempting +to detach it. + +Different nodes might have different ways of attaching volumes, and different +Volumes can have different values for VolumeNodeAffinity, so the decision +around volume attachment happens after scheduling. + +To learn more about how Kubernetes manages storage and makes this storage +available to Pods, refer to the [storage](/docs/concepts/storage/persistent-volumes/) documentation. + +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/volume-persistentvolume.md b/content/en/docs/reference/controllers/volume-persistentvolume.md new file mode 100644 index 0000000000000..8a76a496b3b5f --- /dev/null +++ b/content/en/docs/reference/controllers/volume-persistentvolume.md @@ -0,0 +1,33 @@ +--- +title: PersistentVolume controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip text="PersistentVolume" term_id="persistent-volume" >}} +controller is part of a set of built-in controllers for storage management. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +This controller ensures, where possible, that each PersistentVolumeClaim +is [bound](/docs/concepts/storage/persistent-volumes/#binding) +to a suitable PersistentVolume. This can include provisioning a new PersistentVolume, +with help from other components such as a {{< glossary_tooltip text="CSI" term_id="csi" >}} +driver. + +When PersistentVolumes become eligible for +[reclamation](/docs/concepts/storage/persistent-volumes/#reclaiming), this +controller takes part in ensuring that the appropriate reclaim action takes place. + + +{{% /capture %}} +{{% capture whatsnext %}} +* Read the [storage](/docs/concepts/storage/persistent-volumes/) documentation to + learn about how Kubernetes manages {{< glossary_tooltip text="Volumes" term_id="volume" >}} and + related resources. +{{% /capture %}} diff --git a/content/en/docs/reference/controllers/volume-persistentvolumeclaim-protection.md b/content/en/docs/reference/controllers/volume-persistentvolumeclaim-protection.md new file mode 100644 index 0000000000000..37487659e124e --- /dev/null +++ b/content/en/docs/reference/controllers/volume-persistentvolumeclaim-protection.md @@ -0,0 +1,31 @@ +--- +title: PVC in-use protection controller +content_template: templates/concept +--- + +{{% capture overview %}} + +The {{< glossary_tooltip text="PersistentVolumeClaim" term_id="persistent-volume-claim" >}} +protection controller is part of a set of built-in controllers for storage management. + +{{% /capture %}} + +{{% capture body %}} + +## Controller behavior + +The PVC protection controller watches for PersistentVolumeClaims and Pods. The +controller acts as a backstop for the related +[admission controller](/docs/reference/access-authn-authz/admission-controllers/#storageobjectinuseprotection) +and makes sure that all PVCs have a finalizer set. The finalizer is there to block PVC +deletion for any PVC that's used by a running Pod. + +When a PVC becomes a candidate for deletion, the PVC protection controller +checks if the PVC is still in use. If the PVC is still in use then the finalizer +stays in place. If / when the PVC stops being used, this controller removes +the storage object in-use protection finalizer, so that the PVC can be deleted. + +{{% /capture %}} +{{% capture whatsnext %}} +* Read about [storage object in-use protection](/docs/concepts/storage/persistent-volumes/#storage-object-in-use-protection) +{{% /capture %}}