Merge branch 'master' into add-cilium
This commit is contained in:
@@ -5,197 +5,6 @@ assignees:
|
||||
title: Cluster Management Guide
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
This document describes several topics related to the lifecycle of a cluster: creating a new cluster,
|
||||
upgrading your cluster's
|
||||
master and worker nodes, performing node maintenance (e.g. kernel upgrades), and upgrading the Kubernetes API version of a
|
||||
running cluster.
|
||||
|
||||
## Creating and configuring a Cluster
|
||||
|
||||
To install Kubernetes on a set of machines, consult one of the existing [Getting Started guides](/docs/getting-started-guides/) depending on your environment.
|
||||
|
||||
## Upgrading a cluster
|
||||
|
||||
The current state of cluster upgrades is provider dependent, and some releases may require special care when upgrading. It is recommended that administrators consult both the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md), as well as the version specific upgrade notes prior to upgrading their clusters.
|
||||
|
||||
* [Upgrading to 1.6](/docs/admin/upgrade-1-6)
|
||||
|
||||
### Upgrading Google Compute Engine clusters
|
||||
|
||||
Google Compute Engine Open Source (GCE-OSS) support master upgrades by deleting and
|
||||
recreating the master, while maintaining the same Persistent Disk (PD) to ensure that data is retained across the
|
||||
upgrade.
|
||||
|
||||
Node upgrades for GCE use a [Managed Instance Group](https://cloud.google.com/compute/docs/instance-groups/), each node
|
||||
is sequentially destroyed and then recreated with new software. Any Pods that are running on that node need to be
|
||||
controlled by a Replication Controller, or manually re-created after the roll out.
|
||||
|
||||
Upgrades on open source Google Compute Engine (GCE) clusters are controlled by the `cluster/gce/upgrade.sh` script.
|
||||
|
||||
Get its usage by running `cluster/gce/upgrade.sh -h`.
|
||||
|
||||
For example, to upgrade just your master to a specific version (v1.0.2):
|
||||
|
||||
```shell
|
||||
cluster/gce/upgrade.sh -M v1.0.2
|
||||
```
|
||||
|
||||
Alternatively, to upgrade your entire cluster to the latest stable release:
|
||||
|
||||
```shell
|
||||
cluster/gce/upgrade.sh release/stable
|
||||
```
|
||||
|
||||
### Upgrading Google Container Engine (GKE) clusters
|
||||
|
||||
Google Container Engine automatically updates master components (e.g. `kube-apiserver`, `kube-scheduler`) to the latest
|
||||
version. It also handles upgrading the operating system and other components that the master runs on.
|
||||
|
||||
The node upgrade process is user-initiated and is described in the [GKE documentation.](https://cloud.google.com/container-engine/docs/clusters/upgrade)
|
||||
|
||||
### Upgrading clusters on other platforms
|
||||
|
||||
Different providers, and tools, will manage upgrades differently. It is recommended that you consult their main documentation regarding upgrades.
|
||||
|
||||
* [kops](https://github.com/kubernetes/kops)
|
||||
* [kargo](https://github.com/kubernetes-incubator/kargo)
|
||||
* [CoreOS Tectonic](https://coreos.com/tectonic/docs/latest/admin/upgrade.html)
|
||||
* ...
|
||||
|
||||
## Resizing a cluster
|
||||
|
||||
If your cluster runs short on resources you can easily add more machines to it if your cluster is running in [Node self-registration mode](/docs/admin/node/#self-registration-of-nodes).
|
||||
If you're using GCE or GKE it's done by resizing Instance Group managing your Nodes. It can be accomplished by modifying number of instances on `Compute > Compute Engine > Instance groups > your group > Edit group` [Google Cloud Console page](https://console.developers.google.com) or using gcloud CLI:
|
||||
|
||||
```shell
|
||||
gcloud compute instance-groups managed resize kubernetes-minion-group --size 42 --zone $ZONE
|
||||
```
|
||||
|
||||
Instance Group will take care of putting appropriate image on new machines and start them, while Kubelet will register its Node with API server to make it available for scheduling. If you scale the instance group down, system will randomly choose Nodes to kill.
|
||||
|
||||
In other environments you may need to configure the machine yourself and tell the Kubelet on which machine API server is running.
|
||||
|
||||
### Cluster autoscaling
|
||||
|
||||
If you are using GCE or GKE, you can configure your cluster so that it is automatically rescaled based on
|
||||
pod needs.
|
||||
|
||||
As described in [Compute Resource](/docs/user-guide/compute-resources/), users can reserve how much CPU and memory is allocated to pods.
|
||||
This information is used by the Kubernetes scheduler to find a place to run the pod. If there is
|
||||
no node that has enough free capacity (or doesn't match other pod requirements) then the pod has
|
||||
to wait until some pods are terminated or a new node is added.
|
||||
|
||||
Cluster autoscaler looks for the pods that cannot be scheduled and checks if adding a new node, similar
|
||||
to the other in the cluster, would help. If yes, then it resizes the cluster to accommodate the waiting pods.
|
||||
|
||||
Cluster autoscaler also scales down the cluster if it notices that some node is not needed anymore for
|
||||
an extended period of time (10min but it may change in the future).
|
||||
|
||||
Cluster autoscaler is configured per instance group (GCE) or node pool (GKE).
|
||||
|
||||
If you are using GCE then you can either enable it while creating a cluster with kube-up.sh script.
|
||||
To configure cluster autoscaler you have to set three environment variables:
|
||||
|
||||
* `KUBE_ENABLE_CLUSTER_AUTOSCALER` - it enables cluster autoscaler if set to true.
|
||||
* `KUBE_AUTOSCALER_MIN_NODES` - minimum number of nodes in the cluster.
|
||||
* `KUBE_AUTOSCALER_MAX_NODES` - maximum number of nodes in the cluster.
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
KUBE_ENABLE_CLUSTER_AUTOSCALER=true KUBE_AUTOSCALER_MIN_NODES=3 KUBE_AUTOSCALER_MAX_NODES=10 NUM_NODES=5 ./cluster/kube-up.sh
|
||||
```
|
||||
|
||||
On GKE you configure cluster autoscaler either on cluster creation or update or when creating a particular node pool
|
||||
(which you want to be autoscaled) by passing flags `--enable-autoscaling` `--min-nodes` and `--max-nodes`
|
||||
to the corresponding `gcloud` commands.
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
gcloud container clusters create mytestcluster --zone=us-central1-b --enable-autoscaling --min-nodes=3 --max-nodes=10 --num-nodes=5
|
||||
```
|
||||
|
||||
```shell
|
||||
gcloud container clusters update mytestcluster --enable-autoscaling --min-nodes=1 --max-nodes=15
|
||||
```
|
||||
|
||||
**Cluster autoscaler expects that nodes have not been manually modified (e.g. by adding labels via kubectl) as those properties would not be propagated to the new nodes within the same instance group.**
|
||||
|
||||
## Maintenance on a Node
|
||||
|
||||
If you need to reboot a node (such as for a kernel upgrade, libc upgrade, hardware repair, etc.), and the downtime is
|
||||
brief, then when the Kubelet restarts, it will attempt to restart the pods scheduled to it. If the reboot takes longer
|
||||
(the default time is 5 minutes, controlled by `--pod-eviction-timeout` on the controller-manager),
|
||||
then the node controller will terminate the pods that are bound to the unavailable node. If there is a corresponding
|
||||
replica set (or replication controller), then a new copy of the pod will be started on a different node. So, in the case where all
|
||||
pods are replicated, upgrades can be done without special coordination, assuming that not all nodes will go down at the same time.
|
||||
|
||||
If you want more control over the upgrading process, you may use the following workflow:
|
||||
|
||||
Use `kubectl drain` to gracefully terminate all pods on the node while marking the node as unschedulable:
|
||||
|
||||
```shell
|
||||
kubectl drain $NODENAME
|
||||
```
|
||||
|
||||
This keeps new pods from landing on the node while you are trying to get them off.
|
||||
|
||||
For pods with a replica set, the pod will be replaced by a new pod which will be scheduled to a new node. Additionally, if the pod is part of a service, then clients will automatically be redirected to the new pod.
|
||||
|
||||
For pods with no replica set, you need to bring up a new copy of the pod, and assuming it is not part of a service, redirect clients to it.
|
||||
|
||||
Perform maintenance work on the node.
|
||||
|
||||
Make the node schedulable again:
|
||||
|
||||
```shell
|
||||
kubectl uncordon $NODENAME
|
||||
```
|
||||
|
||||
If you deleted the node's VM instance and created a new one, then a new schedulable node resource will
|
||||
be created automatically (if you're using a cloud provider that supports
|
||||
node discovery; currently this is only Google Compute Engine, not including CoreOS on Google Compute Engine using kube-register). See [Node](/docs/admin/node) for more details.
|
||||
|
||||
## Advanced Topics
|
||||
|
||||
### Upgrading to a different API version
|
||||
|
||||
When a new API version is released, you may need to upgrade a cluster to support the new API version (e.g. switching from 'v1' to 'v2' when 'v2' is launched).
|
||||
|
||||
This is an infrequent event, but it requires careful management. There is a sequence of steps to upgrade to a new API version.
|
||||
|
||||
1. Turn on the new API version.
|
||||
1. Upgrade the cluster's storage to use the new version.
|
||||
1. Upgrade all config files. Identify users of the old API version endpoints.
|
||||
1. Update existing objects in the storage to new version by running `cluster/update-storage-objects.sh`.
|
||||
1. Turn off the old API version.
|
||||
|
||||
### Turn on or off an API version for your cluster
|
||||
|
||||
Specific API versions can be turned on or off by passing `--runtime-config=api/<version>` flag while bringing up the API server. For example: to turn off v1 API, pass `--runtime-config=api/v1=false`.
|
||||
runtime-config also supports 2 special keys: api/all and api/legacy to control all and legacy APIs respectively.
|
||||
For example, for turning off all API versions except v1, pass `--runtime-config=api/all=false,api/v1=true`.
|
||||
For the purposes of these flags, _legacy_ APIs are those APIs which have been explicitly deprecated (e.g. `v1beta3`).
|
||||
|
||||
### Switching your cluster's storage API version
|
||||
|
||||
The objects that are stored to disk for a cluster's internal representation of the Kubernetes resources active in the cluster are written using a particular version of the API.
|
||||
When the supported API changes, these objects may need to be rewritten in the newer API. Failure to do this will eventually result in resources that are no longer decodable or usable
|
||||
by the Kubernetes API server.
|
||||
|
||||
`KUBE_API_VERSIONS` environment variable for the `kube-apiserver` binary which controls the API versions that are supported in the cluster. The first version in the list is used as the cluster's storage version. Hence, to set a specific version as the storage version, bring it to the front of list of versions in the value of `KUBE_API_VERSIONS`. You need to restart the `kube-apiserver` binary
|
||||
for changes to this variable to take effect.
|
||||
|
||||
### Switching your config files to a new API version
|
||||
|
||||
You can use `kubectl convert` command to convert config files between different API versions.
|
||||
|
||||
```shell
|
||||
kubectl convert -f pod.yaml --output-version v1
|
||||
```
|
||||
|
||||
For more options, please refer to the usage of [kubectl convert](/docs/user-guide/kubectl/kubectl_convert/) command.
|
||||
[Cluster Management](/docs/concepts/cluster-administration/cluster-management/)
|
||||
|
||||
+2
-166
@@ -4,170 +4,6 @@ assignees:
|
||||
title: Daemon Sets
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
## What is a DaemonSet?
|
||||
|
||||
A _DaemonSet_ ensures that all (or some) nodes run a copy of a pod. As nodes are added to the
|
||||
cluster, pods are added to them. As nodes are removed from the cluster, those pods are garbage
|
||||
collected. Deleting a DaemonSet will clean up the pods it created.
|
||||
|
||||
Some typical uses of a DaemonSet are:
|
||||
|
||||
- running a cluster storage daemon, such as `glusterd`, `ceph`, on each node.
|
||||
- running a logs collection daemon on every node, such as `fluentd` or `logstash`.
|
||||
- running a node monitoring daemon on every node, such as [Prometheus Node Exporter](
|
||||
https://github.com/prometheus/node_exporter), `collectd`, New Relic agent, or Ganglia `gmond`.
|
||||
|
||||
In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon.
|
||||
A more complex setup might use multiple DaemonSets for a single type of daemon, but with
|
||||
different flags and/or different memory and cpu requests for different hardware types.
|
||||
|
||||
## Writing a DaemonSet Spec
|
||||
|
||||
### Required Fields
|
||||
|
||||
As with all other Kubernetes config, a DaemonSet needs `apiVersion`, `kind`, and `metadata` fields. For
|
||||
general information about working with config files, see [deploying applications](/docs/user-guide/deploying-applications/),
|
||||
[configuring containers](/docs/user-guide/configuring-containers/), and [working with resources](/docs/user-guide/working-with-resources/) documents.
|
||||
|
||||
A DaemonSet also needs a [`.spec`](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status) section.
|
||||
|
||||
### Pod Template
|
||||
|
||||
The `.spec.template` is the only required field of the `.spec`.
|
||||
|
||||
The `.spec.template` is a [pod template](/docs/user-guide/replication-controller/#pod-template).
|
||||
It has exactly the same schema as a [pod](/docs/user-guide/pods), except
|
||||
it is nested and does not have an `apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields for a pod, a pod template in a DaemonSet has to specify appropriate
|
||||
labels (see [pod selector](#pod-selector)).
|
||||
|
||||
A pod template in a DaemonSet must have a [`RestartPolicy`](/docs/user-guide/pod-states)
|
||||
equal to `Always`, or be unspecified, which defaults to `Always`.
|
||||
|
||||
### Pod Selector
|
||||
|
||||
The `.spec.selector` field is a pod selector. It works the same as the `.spec.selector` of
|
||||
a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) or other new resources.
|
||||
|
||||
The `spec.selector` is an object consisting of two fields:
|
||||
|
||||
* `matchLabels` - works the same as the `.spec.selector` of a [ReplicationController](/docs/user-guide/replication-controller/)
|
||||
* `matchExpressions` - allows to build more sophisticated selectors by specifying key,
|
||||
list of values and an operator that relates the key and values.
|
||||
|
||||
When the two are specified the result is ANDed.
|
||||
|
||||
If the `.spec.selector` is specified, it must match the `.spec.template.metadata.labels`. If not
|
||||
specified, they are defaulted to be equal. Config with these not matching will be rejected by the API.
|
||||
|
||||
Also you should not normally create any pods whose labels match this selector, either directly, via
|
||||
another DaemonSet, or via other controller such as ReplicationController. Otherwise, the DaemonSet
|
||||
controller will think that those pods were created by it. Kubernetes will not stop you from doing
|
||||
this. One case where you might want to do this is manually create a pod with a different value on
|
||||
a node for testing.
|
||||
|
||||
### Running Pods on Only Some Nodes
|
||||
|
||||
If you specify a `.spec.template.spec.nodeSelector`, then the DaemonSet controller will
|
||||
create pods on nodes which match that [node
|
||||
selector](/docs/user-guide/node-selection/). Likewise if you specify a `.spec.template.spec.affinity`
|
||||
then DaemonSet controller will create pods on nodes which match that [node affinity](../../user-guide/node-selection/index.md).
|
||||
If you do not specify either, then the DaemonSet controller will create pods on all nodes.
|
||||
|
||||
## How Daemon Pods are Scheduled
|
||||
|
||||
Normally, the machine that a pod runs on is selected by the Kubernetes scheduler. However, pods
|
||||
created by the Daemon controller have the machine already selected (`.spec.nodeName` is specified
|
||||
when the pod is created, so it is ignored by the scheduler). Therefore:
|
||||
|
||||
- the [`unschedulable`](/docs/admin/node/#manual-node-administration) field of a node is not respected
|
||||
by the DaemonSet controller.
|
||||
- DaemonSet controller can make pods even when the scheduler has not been started, which can help cluster
|
||||
bootstrap.
|
||||
|
||||
Daemon pods do respect [taints and tolerations](/docs/user-guide/node-selection/index.md#taints-and-tolerations-beta-feature), but they are
|
||||
created with `NoExecute` tolerations for the `node.alpha.kubernetes.io/notReady` and `node.alpha.kubernetes.io/unreachable`
|
||||
taints with no `tolerationSeconds`. This ensures that when the `TaintBasedEvictions` alpha feature is enabled,
|
||||
they will not be evicted when there are node problems such as a network partition. (When the
|
||||
`TaintBasedEvictions` feature is not enabled, they are also not evicted in these scenarios, but
|
||||
due to hard-coded behavior of the NodeController rather than due to tolerations).
|
||||
|
||||
|
||||
## Communicating with Daemon Pods
|
||||
|
||||
Some possible patterns for communicating with pods in a DaemonSet are:
|
||||
|
||||
- **Push**: Pods in the DaemonSet are configured to send updates to another service, such
|
||||
as a stats database. They do not have clients.
|
||||
- **NodeIP and Known Port**: Pods in the DaemonSet use a `hostPort`, so that the pods are reachable via the node IPs. Clients know the list of nodes ips somehow, and know the port by convention.
|
||||
- **DNS**: Create a [headless service](/docs/user-guide/services/#headless-services) with the same pod selector,
|
||||
and then discover DaemonSets using the `endpoints` resource or retrieve multiple A records from
|
||||
DNS.
|
||||
- **Service**: Create a service with the same pod selector, and use the service to reach a
|
||||
daemon on a random node. (No way to reach specific node.)
|
||||
|
||||
## Updating a DaemonSet
|
||||
|
||||
If node labels are changed, the DaemonSet will promptly add pods to newly matching nodes and delete
|
||||
pods from newly not-matching nodes.
|
||||
|
||||
You can modify the pods that a DaemonSet creates. However, pods do not allow all
|
||||
fields to be updated. Also, the DaemonSet controller will use the original template the next
|
||||
time a node (even with the same name) is created.
|
||||
|
||||
|
||||
You can delete a DaemonSet. If you specify `--cascade=false` with `kubectl`, then the pods
|
||||
will be left on the nodes. You can then create a new DaemonSet with a different template.
|
||||
the new DaemonSet with the different template will recognize all the existing pods as having
|
||||
matching labels. It will not modify or delete them despite a mismatch in the pod template.
|
||||
You will need to force new pod creation by deleting the pod or deleting the node.
|
||||
|
||||
In Kubernetes version 1.6 and later, you can [perform a rolling update](/docs/tasks/manage-daemon/update-daemon-set/) on a DaemonSet.
|
||||
|
||||
Future releases of Kubernetes will support controlled updating of nodes.
|
||||
|
||||
## Alternatives to DaemonSet
|
||||
|
||||
### Init Scripts
|
||||
|
||||
It is certainly possible to run daemon processes by directly starting them on a node (e.g. using
|
||||
`init`, `upstartd`, or `systemd`). This is perfectly fine. However, there are several advantages to
|
||||
running such processes via a DaemonSet:
|
||||
|
||||
- Ability to monitor and manage logs for daemons in the same way as applications.
|
||||
- Same config language and tools (e.g. pod templates, `kubectl`) for daemons and applications.
|
||||
- Future versions of Kubernetes will likely support integration between DaemonSet-created
|
||||
pods and node upgrade workflows.
|
||||
- Running daemons in containers with resource limits increases isolation between daemons from app
|
||||
containers. However, this can also be accomplished by running the daemons in a container but not in a pod
|
||||
(e.g. start directly via Docker).
|
||||
|
||||
### Bare Pods
|
||||
|
||||
It is possible to create pods directly which specify a particular node to run on. However,
|
||||
a DaemonSet replaces pods that are deleted or terminated for any reason, such as in the case of
|
||||
node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, you should
|
||||
use a DaemonSet rather than creating individual pods.
|
||||
|
||||
### Static Pods
|
||||
|
||||
It is possible to create pods by writing a file to a certain directory watched by Kubelet. These
|
||||
are called [static pods](/docs/admin/static-pods/).
|
||||
Unlike DaemonSet, static pods cannot be managed with kubectl
|
||||
or other Kubernetes API clients. Static pods do not depend on the apiserver, making them useful
|
||||
in cluster bootstrapping cases. Also, static pods may be deprecated in the future.
|
||||
|
||||
### Replication Controller
|
||||
|
||||
DaemonSet are similar to [Replication Controllers](/docs/user-guide/replication-controller) in that
|
||||
they both create pods, and those pods have processes which are not expected to terminate (e.g. web servers,
|
||||
storage servers).
|
||||
|
||||
Use a replication controller for stateless services, like frontends, where scaling up and down the
|
||||
number of replicas and rolling out updates are more important than controlling exactly which host
|
||||
the pod runs on. Use a Daemon Controller when it is important that a copy of a pod always run on
|
||||
all or certain hosts, and when it needs to start before other pods.
|
||||
[DaemonSets](/docs/concepts/workloads/controllers/daemonset/)
|
||||
|
||||
@@ -84,7 +84,7 @@ sudo docker run -it --rm --privileged --net=host \
|
||||
gcr.io/google_containers/node-test:0.2
|
||||
```
|
||||
|
||||
Node conformance test is a containerized version of [node e2e test](https://github.com/kubernetes/kubernetes/blob/{{page.version}}/docs/devel/e2e-node-tests.md).
|
||||
Node conformance test is a containerized version of [node e2e test](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-node-tests.md).
|
||||
By default, it runs all conformance tests.
|
||||
|
||||
Theoretically, you can run any node e2e test if you configure the container and
|
||||
|
||||
+2
-251
@@ -5,255 +5,6 @@ assignees:
|
||||
title: Nodes
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
## What is a node?
|
||||
|
||||
A `node` is a worker machine in Kubernetes, previously known as a `minion`. A node
|
||||
may be a VM or physical machine, depending on the cluster. Each node has
|
||||
the services necessary to run [pods](/docs/user-guide/pods) and is managed by the master
|
||||
components. The services on a node include Docker, kubelet and kube-proxy. See
|
||||
[The Kubernetes Node](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/architecture.md#the-kubernetes-node) section in the
|
||||
architecture design doc for more details.
|
||||
|
||||
## Node Status
|
||||
|
||||
A node's status contains the following information:
|
||||
|
||||
* [Addresses](#Addresses)
|
||||
* ~~[Phase](#Phase)~~ **deprecated**
|
||||
* [Condition](#Condition)
|
||||
* [Capacity](#Capacity)
|
||||
* [Info](#Info)
|
||||
|
||||
Each section is described in detail below.
|
||||
|
||||
### Addresses
|
||||
|
||||
The usage of these fields varies depending on your cloud provider or bare metal configuration.
|
||||
|
||||
* HostName: The hostname as reported by the node's kernel. Can be overridden via the kubelet `--hostname-override` parameter.
|
||||
* ExternalIP: Typically the IP address of the node that is externally routable (available from outside the cluster).
|
||||
* InternalIP: Typically the IP address of the node that is routable only within the cluster.
|
||||
|
||||
### Phase
|
||||
|
||||
Deprecated: node phase is no longer used.
|
||||
|
||||
### Condition
|
||||
|
||||
The `conditions` field describes the status of all `Running` nodes.
|
||||
|
||||
| Node Condition | Description |
|
||||
|----------------|-------------|
|
||||
| `OutOfDisk` | `True` if there is insufficient free space on the node for adding new pods, otherwise `False` |
|
||||
| `Ready` | `True` if the node is healthy and ready to accept pods, `False` if the node is not healthy and is not accepting pods, and `Unknown` if the node controller has not heard from the node in the last 40 seconds |
|
||||
|
||||
The node condition is represented as a JSON object. For example, the following response describes a healthy node.
|
||||
|
||||
```json
|
||||
"conditions": [
|
||||
{
|
||||
"kind": "Ready",
|
||||
"status": "True"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
If the Status of the Ready condition is "Unknown" or "False" for longer than the `pod-eviction-timeout`, an argument passed to the [kube-controller-manager](/docs/admin/kube-controller-manager/), all of the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on it. The decision to delete the pods cannot be communicated to the kubelet until it re-establishes communication with the apiserver. In the meantime, the pods which are scheduled for deletion may continue to run on the partitioned node.
|
||||
|
||||
In versions of Kubernetes prior to 1.5, the node controller would [force delete](/docs/user-guide/pods/#force-deletion-of-pods) these unreachable pods from the apiserver. However, in 1.5 and higher, the node controller does not force delete pods until it is confirmed that they have stopped running in the cluster. One can see these pods which may be running on an unreachable node as being in the "Terminating" or "Unknown" states. In cases where Kubernetes cannot deduce from the underlying infrastructure if a node has permanently left a cluster, the cluster administrator may need to delete the node object by hand. Deleting the node object from Kubernetes causes all the Pod objects running on it to be deleted from the apiserver, freeing up their names.
|
||||
|
||||
### Capacity
|
||||
|
||||
Describes the resources available on the node: CPU, memory and the maximum
|
||||
number of pods that can be scheduled onto the node.
|
||||
|
||||
### Info
|
||||
|
||||
General information about the node, such as kernel version, Kubernetes version
|
||||
(kubelet and kube-proxy version), Docker version (if used), OS name.
|
||||
The information is gathered by Kubelet from the node.
|
||||
|
||||
## Management
|
||||
|
||||
Unlike [pods](/docs/user-guide/pods) and [services](/docs/user-guide/services),
|
||||
a node is not inherently created by Kubernetes: it is created externally by cloud
|
||||
providers like Google Compute Engine, or exists in your pool of physical or virtual
|
||||
machines. What this means is that when Kubernetes creates a node, it is really
|
||||
just creating an object that represents the node. After creation, Kubernetes
|
||||
will check whether the node is valid or not. For example, if you try to create
|
||||
a node from the following content:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "10.240.79.157",
|
||||
"labels": {
|
||||
"name": "my-first-k8s-node"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Kubernetes will create a node object internally (the representation), and
|
||||
validate the node by health checking based on the `metadata.name` field (we
|
||||
assume `metadata.name` can be resolved). If the node is valid, i.e. all necessary
|
||||
services are running, it is eligible to run a pod; otherwise, it will be
|
||||
ignored for any cluster activity until it becomes valid. Note that Kubernetes
|
||||
will keep the object for the invalid node unless it is explicitly deleted by
|
||||
the client, and it will keep checking to see if it becomes valid.
|
||||
|
||||
Currently, there are three components that interact with the Kubernetes node
|
||||
interface: node controller, kubelet, and kubectl.
|
||||
|
||||
### Node Controller
|
||||
|
||||
The node controller is a Kubernetes master component which manages various
|
||||
aspects of nodes.
|
||||
|
||||
The node controller has multiple roles in a node's life. The first is assigning a
|
||||
CIDR block to the node when it is registered (if CIDR assignment is turned on).
|
||||
|
||||
The second is keeping the node controller's internal list of nodes up to date with
|
||||
the cloud provider's list of available machines. When running in a cloud
|
||||
environment, whenever a node is unhealthy the node controller asks the cloud
|
||||
provider if the VM for that node is still available. If not, the node
|
||||
controller deletes the node from its list of nodes.
|
||||
|
||||
The third is monitoring the nodes' health. The node controller is
|
||||
responsible for updating the NodeReady condition of NodeStatus to
|
||||
ConditionUnknown when a node becomes unreachable (i.e. the node controller stops
|
||||
receiving heartbeats for some reason, e.g. due to the node being down), and then later evicting
|
||||
all the pods from the node (using graceful termination) if the node continues
|
||||
to be unreachable. (The default timeouts are 40s to start reporting
|
||||
ConditionUnknown and 5m after that to start evicting pods.) The node controller
|
||||
checks the state of each node every `--node-monitor-period` seconds.
|
||||
|
||||
In Kubernetes 1.4, we updated the logic of the node controller to better handle
|
||||
cases when a big number of nodes have problems with reaching the master
|
||||
(e.g. because the master has networking problem). Starting with 1.4, the node
|
||||
controller will look at the state of all nodes in the cluster when making a
|
||||
decision about pod eviction.
|
||||
|
||||
In most cases, node controller limits the eviction rate to
|
||||
`--node-eviction-rate` (default 0.1) per second, meaning it won't evict pods
|
||||
from more than 1 node per 10 seconds.
|
||||
|
||||
The node eviction behavior changes when a node in a given availability zone
|
||||
becomes unhealthy. The node controller checks what percentage of nodes in the zone
|
||||
are unhealthy (NodeReady condition is ConditionUnknown or ConditionFalse) at
|
||||
the same time. If the fraction of unhealthy nodes is at least
|
||||
`--unhealthy-zone-threshold` (default 0.55) then the eviction rate is reduced:
|
||||
if the cluster is small (i.e. has less than or equal to
|
||||
`--large-cluster-size-threshold` nodes - default 50) then evictions are
|
||||
stopped, otherwise the eviction rate is reduced to
|
||||
`--secondary-node-eviction-rate` (default 0.01) per second. The reason these
|
||||
policies are implemented per availability zone is because one availability zone
|
||||
might become partitioned from the master while the others remain connected. If
|
||||
your cluster does not span multiple cloud provider availability zones, then
|
||||
there is only one availability zone (the whole cluster).
|
||||
|
||||
A key reason for spreading your nodes across availability zones is so that the
|
||||
workload can be shifted to healthy zones when one entire zone goes down.
|
||||
Therefore, if all nodes in a zone are unhealthy then node controller evicts at
|
||||
the normal rate `--node-eviction-rate`. The corner case is when all zones are
|
||||
completely unhealthy (i.e. there are no healthy nodes in the cluster). In such
|
||||
case, the node controller assumes that there's some problem with master
|
||||
connectivity and stops all evictions until some connectivity is restored.
|
||||
|
||||
Starting in Kubernetes 1.6, the NodeController is also responsible for evicting
|
||||
pods that are running on nodes with `NoExecute` taints, when the pods do not tolerate
|
||||
the taints. Additionally, as an alpha feature that is disabled by default, the
|
||||
NodeController is responsible for adding taints corresponding to node problems like
|
||||
node unreachable or not ready. See [this documentation](/docs/user-guide/node-selection/index.md#taints-and-tolerations-beta-feature)
|
||||
for details about `NoExecute` taints and the alpha feature.
|
||||
|
||||
### Self-Registration of Nodes
|
||||
|
||||
When the kubelet flag `--register-node` is true (the default), the kubelet will attempt to
|
||||
register itself with the API server. This is the preferred pattern, used by most distros.
|
||||
|
||||
For self-registration, the kubelet is started with the following options:
|
||||
|
||||
- `--api-servers` - Location of the apiservers.
|
||||
- `--kubeconfig` - Path to credentials to authenticate itself to the apiserver.
|
||||
- `--cloud-provider` - How to talk to a cloud provider to read metadata about itself.
|
||||
- `--register-node` - Automatically register with the API server.
|
||||
- `--register-with-taints` - Register the node with the given list of taints (comma seperated `<key>=<value>:<effect>`). No-op if `register-node` is false.
|
||||
- `--node-ip` IP address of the node.
|
||||
- `--node-labels` - Labels to add when registering the node in the cluster.
|
||||
- `--node-status-update-frequency` - Specifies how often kubelet posts node status to master.
|
||||
|
||||
Currently, any kubelet is authorized to create/modify any node resource, but in practice it only creates/modifies
|
||||
its own. (In the future, we plan to only allow a kubelet to modify its own node resource.)
|
||||
|
||||
#### Manual Node Administration
|
||||
|
||||
A cluster administrator can create and modify node objects.
|
||||
|
||||
If the administrator wishes to create node objects manually, set the kubelet flag
|
||||
`--register-node=false`.
|
||||
|
||||
The administrator can modify node resources (regardless of the setting of `--register-node`).
|
||||
Modifications include setting labels on the node and marking it unschedulable.
|
||||
|
||||
Labels on nodes can be used in conjunction with node selectors on pods to control scheduling,
|
||||
e.g. to constrain a pod to only be eligible to run on a subset of the nodes.
|
||||
|
||||
Marking a node as unschedulable will prevent new pods from being scheduled to that
|
||||
node, but will not affect any existing pods on the node. This is useful as a
|
||||
preparatory step before a node reboot, etc. For example, to mark a node
|
||||
unschedulable, run this command:
|
||||
|
||||
```shell
|
||||
kubectl cordon $NODENAME
|
||||
```
|
||||
|
||||
Note that pods which are created by a daemonSet controller bypass the Kubernetes scheduler,
|
||||
and do not respect the unschedulable attribute on a node. The assumption is that daemons belong on
|
||||
the machine even if it is being drained of applications in preparation for a reboot.
|
||||
|
||||
### Node capacity
|
||||
|
||||
The capacity of the node (number of cpus and amount of memory) is part of the node object.
|
||||
Normally, nodes register themselves and report their capacity when creating the node object. If
|
||||
you are doing [manual node administration](#manual-node-administration), then you need to set node
|
||||
capacity when adding a node.
|
||||
|
||||
The Kubernetes scheduler ensures that there are enough resources for all the pods on a node. It
|
||||
checks that the sum of the limits of containers on the node is no greater than the node capacity. It
|
||||
includes all containers started by the kubelet, but not containers started directly by Docker nor
|
||||
processes not in containers.
|
||||
|
||||
If you want to explicitly reserve resources for non-pod processes, you can create a placeholder
|
||||
pod. Use the following template:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: resource-reserver
|
||||
spec:
|
||||
containers:
|
||||
- name: sleep-forever
|
||||
image: gcr.io/google_containers/pause:0.8.0
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
```
|
||||
|
||||
Set the `cpu` and `memory` values to the amount of resources you want to reserve.
|
||||
Place the file in the manifest directory (`--config=DIR` flag of kubelet). Do this
|
||||
on each kubelet where you want to reserve resources.
|
||||
|
||||
|
||||
## API Object
|
||||
|
||||
Node is a top-level resource in the Kubernetes REST API. More details about the
|
||||
API object can be found at: [Node API
|
||||
object](/docs/api-reference/v1.6/#node-v1-core).
|
||||
[Nodes](/docs/concepts/nodes/node/)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
assignees:
|
||||
- mml
|
||||
title: Cluster Management Guide
|
||||
title: Cluster Management Guide for Version 1.6
|
||||
---
|
||||
|
||||
* TOC
|
||||
@@ -23,4 +23,4 @@ startup:
|
||||
$ kube-apiserver --storage-backend='etcd2' $(EXISTING_ARGS)
|
||||
```
|
||||
|
||||
However, for long-term maintenance of the cluster, we recommend that the operator plan an outage window in order to perform a [v2->v3 data upgrade](https://coreos.com/etcd/docs/latest/upgrades/upgrade_3_0.html).
|
||||
However, for long-term maintenance of the cluster, we recommend that the operator plan an outage window in order to perform a [v2->v3 data upgrade](https://coreos.com/etcd/docs/latest/upgrades/upgrade_3_0.html).
|
||||
|
||||
Reference in New Issue
Block a user