update dynamic kubelet config docs for v1.11 (#8766)

* update dynamic kubelet config docs for v1.11

* Substantial copyedit

* Address feedback
This commit is contained in:
Michael Taufen
2018-06-13 10:53:28 -07:00
committed by Misty Linville
parent 0c1970eaaf
commit bf668921f4
@@ -7,31 +7,28 @@ content_template: templates/task
--- ---
{{% capture overview %}} {{% capture overview %}}
{{< feature-state state="alpha" >}} {{< feature-state for_k8s_version="v1.11" state="beta" >}}
As of Kubernetes 1.8, the new
[Dynamic Kubelet Configuration](https://github.com/kubernetes/features/issues/281) [Dynamic Kubelet Configuration](https://github.com/kubernetes/features/issues/281)
feature is available in alpha. This allows you to change the configuration of allows you to change the configuration of each Kubelet in a live Kubernetes
Kubelets in a live Kubernetes cluster via first-class Kubernetes concepts. cluster by deploying a ConfigMap and configuring each Node to use it.
Specifically, this feature allows you to configure individual Nodes' Kubelets
via ConfigMaps.
{{< warning >}} {{< warning >}}
**Warning:** All Kubelet configuration parameters may be changed dynamically, **Warning:** All Kubelet configuration parameters can be changed dynamically,
but not all parameters are safe to change dynamically. This feature is intended but this is unsafe for some parameters. Before deciding to change a parameter
for system experts who have a strong understanding of how configuration changes dynamically, you need a strong understanding of how that change will affect your
will affect behavior. No documentation currently exists which plainly lists cluster's behavior. Always carefully test configuration changes on a small set
"safe to change" fields, but we plan to add it before this feature graduates of nodes before rolling them out cluster-wide. Advice on configuring specific
from alpha. fields is available in the inline `KubeletConfiguration`
[type documentation](https://github.com/kubernetes/kubernetes/blob/release-1.11/pkg/kubelet/apis/kubeletconfig/v1beta1/types.go).
{{< /warning >}} {{< /warning >}}
{{% /capture %}} {{% /capture %}}
{{% capture prerequisites %}} {{% capture prerequisites %}}
- A live Kubernetes cluster with both Master and Node at v1.8 or higher must be - Kubernetes v1.11 or higher on both the Master and the Nodes
running, with the `DynamicKubeletConfig` feature gate enabled and the Kubelet's - kubectl v1.11 or higher, configured to communicate with the cluster
`--dynamic-config-dir` flag set to a writable directory on the Node. - The Kubelet's `--dynamic-config-dir` flag must be set to a writable
This flag must be set to enable Dynamic Kubelet Configuration. directory on the Node.
- The kubectl command-line tool must be also v1.8 or higher, and must be
configured to communicate with the cluster.
{{% /capture %}} {{% /capture %}}
{{% capture steps %}} {{% capture steps %}}
@@ -50,20 +47,19 @@ Kubelet's configuration.
Each Kubelet watches a configuration reference on its respective Node object. Each Kubelet watches a configuration reference on its respective Node object.
When this reference changes, the Kubelet downloads the new configuration, When this reference changes, the Kubelet downloads the new configuration,
updates a local reference to refer to the file, and exits. updates a local reference to refer to the file, and exits.
For the feature to work correctly, you must be running a process manager For the feature to work correctly, you must be running an OS-level service
(like systemd) which will restart the Kubelet when it exits. When the Kubelet is manager (such as systemd), which will restart the Kubelet if it exits. When the
restarted, it will begin using the new configuration. Kubelet is restarted, it will begin using the new configuration.
The new configuration completely overrides configuration provided by `--config`, The new configuration completely overrides configuration provided by `--config`,
and is overridden by command-line flags. Unspecified values in the new configuration and is overridden by command-line flags. Unspecified values in the new configuration
will receive default values appropriate to the configuration version will receive default values appropriate to the configuration version
(e.g. `kubelet.config.k8s.io/v1beta1`), unless overridden by flags. (e.g. `kubelet.config.k8s.io/v1beta1`), unless overridden by flags.
The status of the Node's Kubelet configuration is reported via the `KubeletConfigOK` The status of the Node's Kubelet configuration is reported via
condition in the Node status. Once you have updated a Node to use the new `Node.Spec.Status.Config`. Once you have updated a Node to use the new
ConfigMap, you can observe this condition to confirm that the Node is using the ConfigMap, you can observe this status to confirm that the Node is using the
intended configuration. A table describing the possible conditions can be found intended configuration.
at the end of this article.
This document describes editing Nodes using `kubectl edit`. This document describes editing Nodes using `kubectl edit`.
There are other ways to modify a Node's spec, including `kubectl patch`, for There are other ways to modify a Node's spec, including `kubectl patch`, for
@@ -72,16 +68,19 @@ example, which facilitate scripted workflows.
This document only describes a single Node consuming each ConfigMap. Keep in This document only describes a single Node consuming each ConfigMap. Keep in
mind that it is also valid for multiple Nodes to consume the same ConfigMap. mind that it is also valid for multiple Nodes to consume the same ConfigMap.
### Node Authorizer Workarounds {{< warning >}}
**Warning:** While it is *possible* to change the configuration by
updating the ConfigMap in-place, this causes all Kubelets configured with
that ConfigMap to update simultaneously. It is much safer to treat ConfigMaps
as immutable by convention, aided by `kubectl`'s `--append-hash` option,
and incrementally roll out updates to `Node.Spec.ConfigSource`.
{{< /warning >}}
The Node Authorizer does not yet pay attention to which ConfigMaps are assigned ### Automatic RBAC rules for Node Authorizer
to which Nodes. If you currently use the Node authorizer, your Kubelets will not
be automatically granted permission to download their respective ConfigMaps.
The temporary workaround used in this document is to manually create the RBAC Previously, you were required to manually create RBAC rules
Roles and RoleBindings for each ConfigMap. The Node Authorizer will be extended to allow Nodes to access their assigned ConfigMaps. The Node Authorizer now
before the Dynamic Kubelet Configuration feature graduates from alpha, so doing automatically configures these rules.
this in production should never be necessary.
### Generating a file that contains the current configuration ### Generating a file that contains the current configuration
@@ -92,54 +91,62 @@ and debug issues. The compromise, however, is that you must start with knowledge
of the existing configuration to ensure that you only change the fields you of the existing configuration to ensure that you only change the fields you
intend to change. intend to change.
In the future, the Kubelet will be bootstrapped from a file on disk Ideally, the Kubelet would be bootstrapped from a file on disk
and you could edit this file (which could also be version-controlled),
to create the first Kubelet ConfigMap
(see [Set Kubelet parameters via a config file](/docs/tasks/administer-cluster/kubelet-config-file)), (see [Set Kubelet parameters via a config file](/docs/tasks/administer-cluster/kubelet-config-file)),
and you will simply edit a copy of this file (which, as a best practice, should Currently, the Kubelet is bootstrapped with **a combination of this file and command-line flags**
live in version control) while creating the first Kubelet ConfigMap. Today, that can override the configuration in the file.
however, the Kubelet is still bootstrapped with command-line flags. Fortunately, As a workaround, you can generate a config file containing a Node's current
there is a dirty trick you can use to generate a config file containing a Node's configuration by accessing the Kubelet server's `configz` endpoint via the
current configuration. The trick involves accessing the Kubelet server's `configz` kubectl proxy. This endpoint, in its current implementation, is intended to be
endpoint via the kubectl proxy. This endpoint, in its current implementation, is used only as a debugging aid. Do not rely on the behavior of this endpoint for
intended to be used only as a debugging aid, which is part of why this is a production scenarios. The examples below use the `jq` command to streamline
dirty trick. The endpoint may be improved in the future, but until then working with JSON. To follow the tasks as written, you need to have `jq`
it should not be relied on for production scenarios. installed, but you can adapt the tasks if you prefer to extract the
This trick also requires the `jq` command to be installed on your machine, `kubeletconfig` subobject manually.
for unpacking and editing the JSON response from the endpoint.
Do the following to generate the file: #### Generate the configuration file
1. Pick a Node to reconfigure. We will refer to this Node's name as NODE_NAME. 1. Choose a Node to reconfigure. In this example, the name of this Node is
2. Start the kubectl proxy in the background with `kubectl proxy --port=8001 &` referred to as `NODE_NAME`.
3. Run the following command to download and unpack the configuration from the 2. Start the kubectl proxy in the background using the following command:
configz endpoint: ```bash
kubectl proxy --port=8001 &
```
3. Run the following command to download and unpack the configuration from the
`configz` endpoint. The command is long, so be careful when copying and
pasting. **If you use zsh**, replace the `${NODE_NAME}` in the URL with the
actual name of the node, because zsh automatically escapes opening curly
braces, which causes the command to fail.
``` ```bash
$ export NODE_NAME=the-name-of-the-node-you-are-reconfiguring NODE_NAME="the-name-of-the-node-you-are-reconfiguring"; curl -sSL "http://localhost:8001/api/v1/nodes/${NODE_NAME}/proxy/configz" | jq '.kubeletconfig|.kind="KubeletConfiguration"|.apiVersion="kubelet.config.k8s.io/v1beta1"' > kubelet_configz_${NODE_NAME}
$ curl -sSL http://localhost:8001/api/v1/nodes/${NODE_NAME}/proxy/configz | jq '.kubeletconfig|.kind="KubeletConfiguration"|.apiVersion="kubelet.config.k8s.io/v1beta1"' > kubelet_configz_${NODE_NAME} ```
```
Note that we have to manually add the `kind` and `apiVersion` to the downloaded {{< note >}}
object, as these are not reported by the configz endpoint. This is one of the You need to manually add the `kind` and `apiVersion` to the downloaded
limitations of the endpoint. object, because they are not reported by the `configz` endpoint.
{{< /note >}}
### Edit the configuration file #### Edit the configuration file
Using your editor of choice, change one of the parameters in the Using a text editor, change one of the parameters in the
`kubelet_configz_${NODE_NAME}` file from the previous step. A QPS parameter, file generated by the previous procedure. For example, you
`eventRecordQPS` for example, is a good candidate. might edit the QPS parameter `eventRecordQPS`.
### Push the configuration file to the control plane #### Push the configuration file to the control plane
Push the edited configuration file to the control plane with the Push the edited configuration file to the control plane with the
following command: following command:
``` ```bash
$ kubectl -n kube-system create configmap my-node-config --from-file=kubelet=kubelet_configz_${NODE_NAME} --append-hash -o yaml kubectl -n kube-system create configmap my-node-config --from-file=kubelet=kubelet_configz_${NODE_NAME} --append-hash -o yaml
``` ```
You should see a response similar to: This is an example of a valid response:
``` ```none
apiVersion: v1 apiVersion: v1
data: data:
kubelet: | kubelet: |
@@ -154,304 +161,204 @@ metadata:
uid: 946d785e-998a-11e7-a8dd-42010a800006 uid: 946d785e-998a-11e7-a8dd-42010a800006
``` ```
Note that the configuration data must appear under the ConfigMap's The ConfigMap is created in the `kube-system` namespace because this
`kubelet` key. ConfigMap configures a Kubelet, which is Kubernetes system component.
We create the ConfigMap in the `kube-system` namespace, which is appropriate
because this ConfigMap configures a Kubernetes system component - the Kubelet.
The `--append-hash` option appends a short checksum of the ConfigMap contents The `--append-hash` option appends a short checksum of the ConfigMap contents
to the name. This is convenient for an edit->push workflow, as it will to the name. This is convenient for an edit-then-push workflow, because it
automatically, yet deterministically, generate new names for new ConfigMaps. automatically, yet deterministically, generates new names for new ConfigMaps.
The name that includes this generated hash is referred to as `CONFIG_MAP_NAME`
in the following examples.
We use the `-o yaml` output format so that the name, namespace, and uid are all #### Set the Node to use the new configuration
reported following creation. We will need these in the next step. We will refer
to the name as CONFIG_MAP_NAME and the uid as CONFIG_MAP_UID.
### Authorize your Node to read the new ConfigMap
Now that you've created a new ConfigMap, you need to authorize your node to
read it. First, create a Role for your new ConfigMap with the
following commands:
```
$ export CONFIG_MAP_NAME=name-from-previous-output
$ kubectl -n kube-system create role ${CONFIG_MAP_NAME}-reader --verb=get --resource=configmap --resource-name=${CONFIG_MAP_NAME}
```
Next, create a RoleBinding to associate your Node with the new Role:
```
$ kubectl -n kube-system create rolebinding ${CONFIG_MAP_NAME}-reader --role=${CONFIG_MAP_NAME}-reader --user=system:node:${NODE_NAME}
```
Once the Node Authorizer is updated to do this automatically, you will
be able to skip this step.
### Set the Node to use the new configuration
Edit the Node's reference to point to the new ConfigMap with the Edit the Node's reference to point to the new ConfigMap with the
following command: following command:
``` ```bash
kubectl edit node ${NODE_NAME} kubectl edit node ${NODE_NAME}
``` ```
Once in your editor, add the following YAML under `spec`: In your text editor, add the following YAML under `spec`:
``` ```yaml
configSource: configSource:
configMapRef: configMap:
name: CONFIG_MAP_NAME name: CONFIG_MAP_NAME
namespace: kube-system namespace: kube-system
uid: CONFIG_MAP_UID kubeletConfigKey: kubelet
``` ```
Be sure to specify all three of `name`, `namespace`, and `uid`. You must specify all three of `name`, `namespace`, and `kubeletConfigKey`.
The `kubeletConfigKey` parameter shows the Kubelet which key of the ConfigMap
contains its config.
### Observe that the Node begins using the new configuration #### Observe that the Node begins using the new configuration
Retrieve the Node with `kubectl get node ${NODE_NAME} -o yaml`, and look for the Retrieve the Node using the `kubectl get node ${NODE_NAME} -o yaml` command and inspect
`KubeletConfigOK` condition in `status.conditions`. You should see the message `Node.Status.Config`. The config sources corresponding to the `active`,
`Using current (UID: CONFIG_MAP_UID)` when the Kubelet starts using the new `assigned`, and `lastKnownGood` configurations are reported in the status.
configuration.
For convenience, you can use the following command (using `jq`) to filter down - The `active` configuration is the version the Kubelet is currently running with.
to the `KubeletConfigOK` condition: - The `assigned` configuration is the latest version the Kubelet has resolved based on
`Node.Spec.ConfigSource`.
- The `lastKnownGood` configuration is the version the
Kubelet will fall back to if an invalid config is assigned in `Node.Spec.ConfigSource`.
The`lastKnownGood` configuration might not be present if it is set to its default value,
the local config deployed with the node. The status will update `lastKnownGood` to
match a valid `assigned` config after the Kubelet becomes comfortable with the config.
The details of how the Kubelet determines a config should become the `lastKnownGood` are
not guaranteed by the API, but is currently implemented as a 10-minute grace period.
You can use the following command (using `jq`) to filter down
to the config status:
```bash
kubectl get no ${NODE_NAME} -o json | jq '.status.config'
``` ```
$ kubectl get no ${NODE_NAME} -o json | jq '.status.conditions|map(select(.type=="KubeletConfigOK"))'
[ The following is an example response:
{
"lastHeartbeatTime": "2017-09-20T18:08:29Z", ```json
"lastTransitionTime": "2017-09-20T18:08:17Z", {
"message": "using current: /api/v1/namespaces/kube-system/configmaps/my-node-config-gkt4c2m4b2", "active": {
"reason": "passing all checks", "configMap": {
"status": "True", "kubeletConfigKey": "kubelet",
"type": "KubeletConfigOK" "name": "my-node-config-9mbkccg2cc",
"namespace": "kube-system",
"resourceVersion": "1326",
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002"
}
},
"assigned": {
"configMap": {
"kubeletConfigKey": "kubelet",
"name": "my-node-config-9mbkccg2cc",
"namespace": "kube-system",
"resourceVersion": "1326",
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002"
}
},
"lastKnownGood": {
"configMap": {
"kubeletConfigKey": "kubelet",
"name": "my-node-config-9mbkccg2cc",
"namespace": "kube-system",
"resourceVersion": "1326",
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002"
}
} }
] }
```
If something goes wrong, you may see one of several different error conditions,
detailed in the table of KubeletConfigOK conditions, below. When this happens, you
should check the Kubelet's log for more details.
### Edit the configuration file again
To change the configuration again, we simply repeat the above workflow.
Try editing the `kubelet` file, changing the previously changed parameter to a
new value.
### Push the newly edited configuration to the control plane
Push the new configuration to the control plane in a new ConfigMap with the
following command:
```
$ kubectl create configmap my-node-config --namespace=kube-system --from-file=kubelet=kubelet_configz_${NODE_NAME} --append-hash -o yaml
``` ```
This new ConfigMap will get a new name, as we have changed the contents. If an error occurs, the Kubelet reports it in the `Node.Status.Config.Error`
We will refer to the new name as NEW_CONFIG_MAP_NAME and the new uid structure. Possible errors are listed in
as NEW_CONFIG_MAP_UID. [Understanding Node.Status.Config.Error messages](#understanding-node-status-config-error-messages).
You can search for the identical text in the Kubelet log for additional details
and context about the error.
### Authorize your Node to read the new ConfigMap #### Make more changes
Now that you've created a new ConfigMap, you need to authorize your node to Follow the workflow above to make more changes and push them again. Each time
read it. First, create a Role for your new ConfigMap with the you push a ConfigMap with new contents, the --append-hash kubectl option creates
following commands: the ConfigMap with a new name. The safest rollout strategy is to first create a
new ConfigMap, and then update the Node to use the new ConfigMap.
``` #### Reset the Node to use its local default configuration
$ export NEW_CONFIG_MAP_NAME=name-from-previous-output
$ kubectl -n kube-system create role ${NEW_CONFIG_MAP_NAME}-reader --verb=get --resource=configmap --resource-name=${NEW_CONFIG_MAP_NAME}
```
Next, create a RoleBinding to associate your Node with the new Role: To reset the Node to use the configuration it was provisioned with, edit the
Node using `kubectl edit node ${NODE_NAME}` and remove the
`Node.Spec.ConfigSource` field.
``` #### Observe that the Node is using its local default configuration
$ kubectl -n kube-system create rolebinding ${NEW_CONFIG_MAP_NAME}-reader --role=${NEW_CONFIG_MAP_NAME}-reader --user=system:node:${NODE_NAME}
```
Once the Node Authorizer is updated to do this automatically, you will After removing this subfield, `Node.Status.Config` eventually becomes
be able to skip this step. empty, since all config sources have been reset to `nil`, which indicates that
the local default config is `assigned`, `active`, and `lastKnownGood`, and no
### Configure the Node to use the new configuration error is reported.
Once more, edit the Node's `spec.configSource` with
`kubectl edit node ${NODE_NAME}`. Your new `spec.configSource` should look like
the following, with `name` and `uid` substituted as necessary:
```
configSource:
configMapRef:
name: ${NEW_CONFIG_MAP_NAME}
namespace: kube-system
uid: ${NEW_CONFIG_MAP_UID}
```
### Observe that the Kubelet is using the new configuration
Once more, retrieve the Node with `kubectl get node ${NODE_NAME} -o yaml`, and
look for the `KubeletConfigOK` condition in `status.conditions`. You should see the message
`using current: /api/v1/namespaces/kube-system/configmaps/${NEW_CONFIG_MAP_NAME}` when the Kubelet starts using the
new configuration.
### Deauthorize your Node from reading the old ConfigMap
Once you know your Node is using the new configuration and are confident that
the new configuration has not caused any problems, it is a good idea to
deauthorize the node from reading the old ConfigMap. Run the following
commands to remove the RoleBinding and Role:
```
$ kubectl -n kube-system delete rolebinding ${CONFIG_MAP_NAME}-reader
$ kubectl -n kube-system delete role ${CONFIG_MAP_NAME}-reader
```
Note that this does not necessarily prevent the Node from reverting to the old
configuration, as it may locally cache the old ConfigMap for an indefinite
period of time.
You may optionally also choose to remove the old ConfigMap:
```
$ kubectl -n kube-system delete configmap ${CONFIG_MAP_NAME}
```
Once the Node Authorizer is updated to do this automatically, you will
be able to skip this step.
### Reset the Node to use its local default configuration
Finally, if you wish to reset the Node to use the configuration it was
provisioned with, simply edit the Node with `kubectl edit node ${NODE_NAME}` and
remove the `spec.configSource` subfield.
### Observe that the Node is using its local default configuration
After removing this subfield, you should eventually observe that the KubeletConfigOK
condition's message reverts to `using current: local`.
### Deauthorize your Node from reading the old ConfigMap
Once you know your Node is using the default configuration again, it is a good
idea to deauthorize the node from reading the old ConfigMap. Run the following
commands to remove the RoleBinding and Role:
```
$ kubectl -n kube-system delete rolebinding ${NEW_CONFIG_MAP_NAME}-reader
$ kubectl -n kube-system delete role ${NEW_CONFIG_MAP_NAME}-reader
```
Note that this does not necessarily prevent the Node from reverting to the old
ConfigMap, as it may locally cache the old ConfigMap for an indefinite
period of time.
You may optionally also choose to remove the old ConfigMap:
```
$ kubectl -n kube-system delete configmap ${NEW_CONFIG_MAP_NAME}
```
Once the Node Authorizer is updated to do this automatically, you will
be able to skip this step.
{{% /capture %}} {{% /capture %}}
{{% capture discussion %}} {{% capture discussion %}}
## Kubectl Patch Example ## Kubectl Patch Example
As mentioned above, there are many ways to change a Node's configSource.
Here is an example command that uses `kubectl patch`:
``` You can change a Node's configSource using several different mechanisms.
kubectl patch node ${NODE_NAME} -p "{\"spec\":{\"configSource\":{\"configMapRef\":{\"name\":\"${CONFIG_MAP_NAME}\",\"namespace\":\"kube-system\",\"uid\":\"${CONFIG_MAP_UID}\"}}}}" This example uses `kubectl patch`:
```bash
kubectl patch node ${NODE_NAME} -p "{\"spec\":{\"configSource\":{\"configMap\":{\"name\":\"${CONFIG_MAP_NAME}\",\"namespace\":\"kube-system\",\"kubeletConfigKey\":\"kubelet\"}}}}"
``` ```
## Understanding KubeletConfigOK Conditions ## Understanding how the Kubelet checkpoints config
The following table describes several of the `KubeletConfigOK` Node conditions you When a new config is assigned to the Node, the Kubelet downloads and unpacks the
might encounter in a cluster that has Dynamic Kubelet Config enabled. If you config payload as a set of files on the local disk. The Kubelet also records metadata
observe a condition with `status=False`, you should check the Kubelet log for that locally tracks the assigned and last-known-good config sources, so that the
more error details by searching for the message or reason text. Kubelet knows which config to use across restarts, even if the API server becomes
unavailable. After checkpointing a config and the relevant metadata, the Kubelet
exits if it detects that the assigned config has changed. When the Kubelet is
restarted by the OS-level service manager (such as `systemd`), it reads the new
metadata and uses the new config.
The recorded metadata is fully resolved, meaning that it contains all necessary
information to choose a specific config version - typically a `UID` and `ResourceVersion`.
This is in contrast to `Node.Spec.ConfigSource`, where the intended config is declared
via the idempotent `namespace/name` that identifies the target ConfigMap; the Kubelet
tries to use the latest version of this ConfigMap.
When you are debugging problems on a node, you can inspect the Kubelet's config
metadata and checkpoints. The structure of the Kubelet's checkpointing directory is:
```none
- --dynamic-config-dir (root for managing dynamic config)
| - meta
| - assigned (encoded kubeletconfig/v1beta1.SerializedNodeConfigSource object, indicating the assigned config)
| - last-known-good (encoded kubeletconfig/v1beta1.SerializedNodeConfigSource object, indicating the last-known-good config)
| - checkpoints
| - uid1 (dir for versions of object identified by uid1)
| - resourceVersion1 (dir for unpacked files from resourceVersion1 of object with uid1)
| - ...
| - ...
```
## Understanding Node.Status.Config.Error messages
The following table describes error messages that can occur
when using Dynamic Kubelet Config. You can search for the identical text
in the Kubelet log for additional details and context about the error.
<table> <table>
<table align="left"> <table align="left">
<tr> <tr>
<th>Possible Messages</th> <th>Error Message</th>
<th>Possible Reasons</th> <th>Possible Causes</th>
<th>Status</th>
</tr> </tr>
<tr> <tr>
<td><p>using current: local</p></td> <td><p>failed to load config, see Kubelet log for details</p></td>
<td><p>when the config source is nil, the Kubelet uses its local config</p></td> <td><p>The Kubelet likely could not parse the downloaded config payload, or encountered a filesystem error attempting to load the payload from disk.</p></td>
<td><p>True</p></td>
</tr> </tr>
<tr> <tr>
<td><p>using current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</p></td> <td><p>failed to validate config, see Kubelet log for details</p></td>
<td><p>passing all checks</p></td> <td><p>The configuration in the payload, combined with any command-line flag overrides, and the sum of feature gates from flags, the config file, and the remote payload, was determined to be invalid by the Kubelet.</p></td>
<td><p>True</p></td>
</tr> </tr>
<tr> <tr>
<td><p>using last-known-good: local</p></td> <td><p>invalid NodeConfigSource, exactly one subfield must be non-nil, but all were nil</p></td>
<td> <td><p>Since Node.Spec.ConfigSource is validated by the API server to contain at least one non-nil subfield, this likely means that the Kubelet is older than the API server and does not recognize a newer source type.</p></td>
<ul>
<li>failed to load current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</li>
<li>failed to parse current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</li>
<li>failed to validate current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</li>
</ul>
</td>
<td><p>False</p></td>
</tr> </tr>
<tr> <tr>
<td><p>using last-known-good: /api/v1/namespaces/${LAST_KNOWN_GOOD_CONFIG_MAP_NAMESPACE}/configmaps/${LAST_KNOWN_GOOD_CONFIG_MAP_NAME}</p></td> <td><p>failed to sync: failed to download config, see Kubelet log for details</p></td>
<td> <td><p>The Kubelet could not download the config. It is possible that Node.Spec.ConfigSource could not be resolved to a concrete API object, or that network errors disrupted the download attempt. The Kubelet will retry the download when in this error state.</p></td>
<ul>
<li>failed to load current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</li>
<li>failed to parse current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</li>
<li>failed to validate current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</li>
</ul>
</td>
<td><p>False</p></td>
</tr> </tr>
<tr> <tr>
<td> <td><p>failed to sync: internal failure, see Kubelet log for details</p></td>
<p> <td><p>The Kubelet encountered some internal problem and failed to update its config as a result. Examples include filesystem errors and reading objects from the internal informer cache.</p></td>
The reasons in the next column could potentially appear for any of </tr>
the above messages. <tr>
</p> <td><p>internal failure, see Kubelet log for details</p></td>
<p> <td><p>The Kubelet encountered some internal problem while manipulating config, outside of the configuration sync loop.</p></td>
This condition indicates that the Kubelet is having trouble
reconciling `spec.configSource`, and thus no change to the in-use
configuration has occurred.
</p>
<p>
The "failed to sync" reasons are specific to the failure that
occurred, and the next column does not necessarily contain all
possible failure reasons.
</p>
</td>
<td>
<p>failed to sync, reason:</p>
<ul>
<li>failed to read Node from informer object cache</li>
<li>failed to reset to local config</li>
<li>invalid NodeConfigSource, exactly one subfield must be non-nil, but all were nil</li>
<li>invalid ObjectReference, all of UID, Name, and Namespace must be specified</li>
<li>invalid ConfigSource.ConfigMapRef.UID: ${UID} does not match ${API_PATH}.UID: ${UID_OF_CONFIG_MAP_AT_API_PATH}</li>
<li>failed to determine whether object ${API_PATH} with UID ${UID} was already checkpointed</li>
<li>failed to download ConfigMap with name ${NAME} from namespace ${NAMESPACE}</li>
<li>failed to save config checkpoint for object ${API_PATH} with UID ${UID}</li>
<li>failed to set current config checkpoint to local config</li>
<li>failed to set current config checkpoint to object ${API_PATH} with UID ${UID}</li>
</ul>
</td>
<td><p>False</p></td>
</tr> </tr>
</table> </table>
{{% /capture %}} {{% /capture %}}