Release docs for Kubernetes 1.11 (#9171)

* Seperate priority and preemption (#8144)

* Doc about PID pressure condition. (#8211)

* Doc about PID pressure condition.

Signed-off-by: Da K. Ma <klaus1982.cn@gmail.com>

* "so" -> "too"

* Update version selector for 1.11

* StorageObjectInUseProtection is GA (#8291)

* Feature gate: StorageObjectInUseProtection is GA

Update feature gate reference for 1.11

* Trivial commit to re-trigger Netlify

* CRIContainerLogRotation is Beta in 1.11 (#8665)

* Seperate priority and preemption (#8144)

* CRIContainerLogRotation is Beta in 1.11

xref: kubernetes/kubernetes#64046

* Bring StorageObjectInUseProtection feature to GA (#8159)

* StorageObjectInUseProtection is GA (#8291)

* Feature gate: StorageObjectInUseProtection is GA

Update feature gate reference for 1.11

* Trivial commit to re-trigger Netlify

* Bring StorageObjectInUseProtection feature to GA

StorageObjectInUseProtection is Beta in K8s 1.10.

It's brought to GA in K8s 1.11.

* Fixed typo and added feature state tags.

* Remove KUBE_API_VERSIONS doc (#8292)

The support to the KUBER_API_VERSIONS environment variable is completely
dropped (no deprecation). This PR removes the related doc in
release-1.11.

xref: kubernetes/kubernetes#63165

* Remove InitialResources from admission controllers (#8293)

The feature (was experimental) is dropped in 1.11.

xref: kubernetes/kubernetes#58784

* Remove docs related to in-tree support to GPU (#8294)

* Remove docs related to in-tree support to GPU

The in-tree support to GPU is completely removed in release 1.11.
This PR removes the related docs in release-1.11 branch.

xref: kubernetes/kubernetes#61498

* Update content updated by PR to Hugo syntax

Signed-off-by: Misty Stanley-Jones <mistyhacks@google.com>

* Update the doc about extra volume in kubeadm config (#8453)

Signed-off-by: Xianglin Gao <xianglin.gxl@alibaba-inc.com>

* Update CRD Subresources for 1.11 (#8519)

* coredns: update notes in administer-cluster/coredns.md (#8697)

CoreDNS is installed by default in 1.11.
Add notes on how to install kube-dns instead.

Update notes about CoreDNS->CoreDNS upgrades as in 1.11
the Corefile is retained.

Add example on upgrading from kube-dns to CoreDNS.

* kubeadm-alpha: CoreDNS related changes (#8727)

Update note about CoreDNS feature gate.

This change also updates a tab as a kubeadm sub-command
will change.

It looks for a new generated file:
generated/kubeadm_alpha_phase_addon_coredns.md
instead of:
generated/kubeadm_alpha_phase_addon_kube-dns.md

* Update cloud controller manager docs to beta 1.11 (#8756)

* Update cloud controller manager docs to beta 1.11

* Use Hugo shortcode for feature state

* kubeadm-upgrade: include new command `kubeadm upgrade diff` (#8617)

Also:
- Include note that this was added in 1.11.
- Modify the note about upgrade guidance.

* independent: update CoreDNS mentions for kubeadm (#8753)

Give CoreDNS instead of kube-dns examples in:
- docs/setup/independent/create-cluster-kubeadm.md
- docs/setup/independent/troubleshooting-kubeadm.md

* update 1.11 --server-print info (#8870)

* update 1.11 --server-print info

* Copyedit

* Mark ExpandPersistentVolumes feature to beta (#8778)

* Update version selector for 1.11

* Mark ExpandPersistentVolumes Beta

xref: kubernetes/kubernetes#64288

* fix shortcode, add placeholder files to fix deploy failures (#8874)

* declare ipvs ga (#8850)

* kubeadm: update info about CoreDNS in kubeadm-init.md (#8728)

Add info to install kube-dns instead of CoreDNS, as CoreDNS
is the default DNS server in 1.11.

Add notes that kubeadm config images can be used to list and pull
the required images in 1.11.

* kubeadm: update implementation-details.md about CoreDNS (#8829)

- Replace examples from kube-dns to CoreDNS
- Add notes about the CoreDNS feature gate status in 1.11
- Add note that the service name for CoreDNS is also
called `kube-dns`

* Update block device support for 1.11 (#8895)

* Update block device support for 1.11

* Copyedits

* Fix typo 'fiber channel' (#8957)

Signed-off-by: Misty Stanley-Jones <mistyhacks@google.com>

* kubeadm-upgrade: add the 'node [config]' sub-command (#8960)

- Add includes for the generated pages
- Include placeholder generated pages

* kubeadm-init: update the example for the MasterConfiguration (#8958)

- include godocs link for MasterConfiguration
- include example MasterConfiguration
- add note that `kubeadm config print-default` can be used

* kubeadm-config: include new commands (#8862)

Add notes and includes for these new commands in 1.11:
- kubeadm config print-default
- kubeadm config migrate
- kubeadm config images list
- kubeadm config images pull

Include placeholder generated files for the above.

* administer-cluster/coredns: include more changes (#8985)

It was requested that for this page a couple of methods
should be outlined:
- manual installation for CoreDNS explained at the Kubernetes
section of the GitHub project for CoreDNS
- installation and upgrade via kubeadm

Make the above changes and also add a section "About CoreDNS".

This commit also lowercases a section title.

* Update CRD subresources doc for 1.11 (#8918)

* Add docs for volume expansion and online resizing (#8896)

* Add docs for volume expansion going beta

* Copyedit

* Address feedback

* Update exec plugin docs with TLS credentials (#8826)

* Update exec plugin docs with TLS credentials

kubernetes/kubernetes#61803 implements TLS client credential support for
1.11.

* Copyedit

* More copyedits for clarification

* Additional copyedit

* Change token->credential

* NodeRestriction admission prevents kubelet taint removal (#8911)

* dns-custom-namerserver: break down the page into mutliple sections (#8900)

* dns-custom-namerserver: break down the page into mutliple sections

This page is currently about kube-dns and is a bit outdated.
Introduce the heading `# Customizing kube-dns`.

Introduce a separate section about CoreDNS.

* Copyedits, fix headings for customizing DNS

Hey Lubomir,
I coypedited pretty heavily because this workflow is so much easier for docs and because I'm trying to help improve everything touching kubeadm as much as possible.

But there's one outstanding issue wrt headings and intro content: you can't add a heading 1 to a topic to do what you wanted to do. The page title in the front matter is rendered as a heading 1 and everything else has to start at heading 2. (We still need to doc this better in the docs contributing content, I know.)

Instead, I think we need to rewrite the top-of-page intro content to explain better the relationship between kube-dns and CoreDNS. I'm happy to write something, but I thought I'd push this commit first so you can see what I'm doing.

Hope it's all clear -- ping here or on Slack with any questions ~ Jennifer

* Interim fix for talking about CoreDNS

* Fix CoreDNS details

* PSP readOnly hostPath (#8898)

* Add documentation for crictl (#8880)

* Add documentation for crictl

* Copyedit

Signed-off-by: Misty Stanley-Jones <mistyhacks@google.com>

* Final copyedit

* VolumeSubpathEnvExpansion alpha feature (#8835)

* Note that Heapster is deprecated (#8827)

* Note that Heapster is deprecated

This notes that Heapster is deprecated, and migrates the relevant
docs to talk about metrics-server or other solutions by default.

* Copyedits and improvements

Signed-off-by: Misty Stanley-Jones <mistyhacks@google.com>

* Address feedback

* fix shortcode to troubleshoot deploy (#9057)

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

* update dynamic kubelet config docs for v1.11

* Substantial copyedit

* Address feedback

* Reference doc for kubeadm (release-1.11) (#9044)

* Reference doc for kubeadm (release-1.11)

* fix shortcode to troubleshoot deploy (#9057)

* Reference doc for kube-components (release-1.11) (#9045)

* Reference doc for kube-components (release-1.11)

* Update cloud-controller-manager.md

* fix shortcode to troubleshoot deploy (#9057)

* Documentation on lowercasing kubeadm init apiserver SANs (#9059)

* Documentation on lowercasing kubeadm init apiserver SANs

* fix shortcode to troubleshoot deploy (#9057)

* Clarification in dynamic Kubelet config doc (#9061)

* Promote sysctls to Beta (#8804)

* Promote sysctls to Beta

* Copyedits

Signed-off-by: Misty Stanley-Jones <mistyhacks@google.com>

* Review comments

* Address feedback

* More feedback

* kubectl reference docs for 1.11 (#9080)

* Update Kubernetes API 1.11 ref docs (#8977)

* Update v1alpha1 to v1beta1.

* Adjust left nav for 1.11 ref docs.

* Trim list of old ref docs.

* Update Federation API ref docs for 1.11. (#9064)

* Update Federation API ref docs for 1.11.

* Add titles.

* Update definitions.html

* CRD versioning Public Documentation (#8834)

* CRD versioning Public Documentation

* Copyedit

Signed-off-by: Misty Stanley-Jones <mistyhacks@google.com>

* Address feedback

* More rewrites

* Address feedback

* Update main CRD page in light of versioning

* Reorg CRD docs

* Further reorg

* Tweak title

* CSI documentation update for raw block volume support (#8927)

* CSI documetation update for raw block volume support

* minor edits for "CSI raw block volume support"

Some small grammar and style nits.

* minor CSIBlockVolume edits

* Update kubectl component ref page for 1.11. (#9094)

* Update kubectl component ref page for 1.11.

* Add title. Replace stevepe with username.

* crd versioning doc: fix nits (#9142)

* Update `DynamicKubeletConfig` feature to beta (#9110)

xref: kubernetes/kubernetes#64275

* Documentation for dynamic volume limits based on node type (#8871)

* add cos for storage limits

* Update docs specific for aws and gce

* fix some minor things

* Update storage-limits.md

* Add k8s version to feature-state shortcode

* The Doc update for ScheduleDaemonSetPods (#8842)

Signed-off-by: Da K. Ma <klaus1982.cn@gmail.com>

* Update docs related to PersistentVolumeLabel admission control (#9109)

The said admission controller is disabled by default in 1.11
(kubernetes/kubernetes#64326) and scheduled to be removed in future
release.

* client exec auth: updates for 1.11 (#9154)

* Updates HA kubeadm docs (#9066)

* Updates HA kubeadm docs

Signed-off-by: Chuck Ha <ha.chuck@gmail.com>

* kubeadm HA - Add stacked control plane steps

* ssh instructions and some typos in the bash scripts

Signed-off-by: Chuck Ha <ha.chuck@gmail.com>

* Fix typos and copypasta errors

* Fix rebase issues

* Integrate more changes

Signed-off-by: Chuck Ha <ha.chuck@gmail.com>

* copyedits, layout and formatting fixes

* final copyedits

* Adds a sanity check for load balancer connection

Signed-off-by: Chuck Ha <ha.chuck@gmail.com>

* formatting fixes, copyedits

* fix typos, formatting

* Document the Pod Ready++ feature (#9180)

Closes: #9107
Xref: kubernetes/kubernetes#64057

* Mention 'KubeletPluginsWatcher' feature (#9177)

* Mention 'KubeletPluginsWatcher' feature

This feature is more developers oriented than users oriented, so simply
mention it in the feature gate should be fine.
In future, when the design doc is migrated from Google doc to the
kubernetes/community repo, we can add links to it for users who want to
dig deeper.

Closes: #9108
Xref: kubernetes/kubernetes#63328, kubernetes/kubernetes#64605

* Copyedit

* Amend dynamic volume list docs (#9181)

The dynamic volume list feature has been documented but the feature gate
related was not there yet.

Closes: #9105

* Document for service account projection (#9182)

This adds docs for the service account projection feature.

Xref: kubernetes/kubernetes#63819, kubernetes/community#1973
Closes: #9102

* Update pod priority and preemption user docs (#9172)

* Update pod priority and preemption user docs

* Copyedit

* Documentation on setting node name with Kubeadm (#8925)

* Documentation on setting node name with Kubeadm

* copyedit

* Add kubeadm upgrade docs for 1.11 (#9089)

* Add kubeadm upgrade docs for 1.11

* Initial docs review feedback

* Add 1-11 to outline

* Fix formatting on tab blocks

* Move file to correct location

* Add `kubeadm upgrade node config` step

* Overzealous ediffing

* copyedit, fix lists and headings

* clarify --force flag for fixing bad state

* Get TOML ready for 1.11 release

* Blog post for 1.11 release (#9254)

* Blog post for 1.11 release

* Update 2018-06-26-kubernetes-1.11-release-announcement.md

* Update 2018-06-26-kubernetes-1.11-release-announcement.md

* Update 2018-06-26-kubernetes-1.11-release-announcement.md
This commit is contained in:
Misty Linville
2018-06-27 15:26:18 -07:00
committed by k8s-ci-robot
parent e091e29a5d
commit 5f30e7d4c3
171 changed files with 126686 additions and 6525 deletions
@@ -5,6 +5,7 @@ reviewers:
- cheftako
- chenopis
content_template: templates/task
weight: 10
---
{{% capture overview %}}
@@ -0,0 +1,5 @@
---
title: "Use Custom Resources"
weight: 10
---
@@ -0,0 +1,202 @@
---
title: Versions of CustomResourceDefinitions
reviewers:
- mbohlool
- sttts
- liggitt
content_template: templates/task
weight: 30
---
{{% capture overview %}}
This page explains how to add versioning information to
[CustomResourceDefinitions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#customresourcedefinition-v1beta1-apiextensions), to indicate the stability
level of your CustomResourceDefinitions. It also describes how to upgrade an
object from one version to another.
{{< note >}}
**Note**: All specified versions must use the same schema. The is no schema
conversion between versions.
{{< /note >}}
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* Make sure your Kubernetes cluster has a master version of 1.11.0 or higher.
* Read about [custom resources](/docs/concepts/api-extension/custom-resources/).
{{% /capture %}}
{{% capture steps %}}
## Overview
The CustomResourceDefinition API supports a `versions` field that you can use to
support multiple versions of custom resources that you have developed, and
indicate the stability of a given custom resource. All versions must currently
use the same schema, so if you need to add a field, you must add it to all
versions.
{{< note >}}
Earlier iterations included a `version` field instead of `versions`. The
`version` field is deprecated and optional, but if it is not empty, it must
match the first item in the `versions` field.
{{< /note >}}
## Specify multiple versions
This example shows a CustomResourceDefinition with two versions. The comments in
the YAML provide more context.
```yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
group: example.com
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1beta1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
- name: v1
served: true
storage: false
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: crontabs
# singular name to be used as an alias on the CLI and for display
singular: crontab
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: CronTab
# shortNames allow shorter string to match your resource on the CLI
shortNames:
- ct
```
You can save the CustomResourceDefinition in a YAML file, then use
`kubectl create` to create it.
```shell
kubectl create -f my-versioned-crontab.yaml
```
After creation, the API server starts to serve each enabled version at an HTTP
REST endpoint. In the above example, the API versions are available at
`/apis/example.com/v1beta1` and `/apis/example.com/v1`.
### Version priority
Regardless of the order in which versions are defined in a
CustomResourceDefinition, the version with the highest priority is used by
kubectl as the default version to access objects. The priority is determined
by parsing the _name_ field to determine the version number, the stability
(GA, Beta, or Alpha), and the sequence within that stability level.
The algorithm used for sorting the versions is designed to sort versions in the
same way that the Kubernetes project sorts Kubernetes versions. Versions start with a
`v` followed by a number, an optional `beta` or `alpha` designation, and
optional additional numeric versioning information. Broadly, a version string might look
like `v2` or `v2beta1`. Versions are sorted using the following algorithm:
- Entries that follow Kubernetes version patterns are sorted before those that
do not.
- For entries that follow Kubernetes version patterns, the numeric portions of
the version string is sorted largest to smallest.
- If the strings `beta` or `alpha` follow the first numeric portion, they sorted
in that order, after the equivalent string without the `beta` or `alpha`
suffix (which is presumed to be the GA version).
- If another number follows the `beta`, or `alpha`, those numbers are also
sorted from largest to smallest.
- Strings that don't fit the above format are sorted alphabetically and the
numeric portions are not treated specially. Notice that in the example below,
`foo1` is sorted above `foo10`. This is different from the sorting of the
numeric portion of entries that do follow the Kubernetes version patterns.
This might make sense if you look at the following sorted version list:
```none
- v10
- v2
- v1
- v11beta2
- v10beta3
- v3beta1
- v12alpha1
- v11alpha2
- foo1
- foo10
```
For the example in [Specify multiple versions](#specify-multiple-versions), the
version sort order is `v1`, followed by `v1beta1`. This causes the kubectl
command to use `v1` as the default version unless the provided object specifies
the version.
## Writing, reading, and updating versioned CustomResourceDefinition objects
When an object is written, it is persisted at the version designated as the
storage version at the time of the write. If the storage version changes,
existing objects are never converted automatically. However, newly-created
or updated objects are written at the new storage version. It is possible for an
object to have been written at a version that is no longer served.
When you read an object, you specify the version as part of the path. If you
specify a version that is different from the object's persisted version,
Kubernetes returns the object to you at the version you requested, but the
persisted object is neither changed on disk, nor converted in any way
(other than changing the `apiVersion` string) while serving the request.
You can request an object at any version that is currently served.
If you update an existing object, it is rewritten at the version that is
currently the storage version. This is the only way that objects can change from
one version to another.
To illustrate this, consider the following hypothetical series of events:
1. The storage version is `v1beta1`. You create an object. It is persisted in
storage at version `v1beta1`
2. You add version `v1` to your CustomResourceDefinition and designate it as
the storage version.
3. You read your object at version `v1beta1`, then you read the object again at
version `v1`. Both returned objects are identical except for the apiVersion
field.
4. You create a new object. It is persisted in storage at version `v1`. You now
have two objects, one of which is at `v1beta1`, and the other of which is at
`v1`.
5. You update the first object. It is now persisted at version `v1` since that
is the current storage version.
### Previous storage versions
The API server records each version which has ever been marked as the storage
version in the status field `storedVersions`. Objects may have been persisted
at any version that has ever been designated as a storage version. No objects
can exist in storage at a version that has never been a storage version.
## Upgrade existing objects to a new stored version
When deprecating versions and dropping support, devise a storage upgrade
procedure. The following is an example procedure to upgrade from `v1beta1`
to `v1`.
1. Set `v1` as the storage in the CustomResourceDefinition file and apply it
using kubectl. The `storedVersions` is now `v1beta1, v1`.
2. Write an upgrade procedure to list all existing objects and write them with
the same content. This forces the backend to write objects in the current
storage version, which is `v1`.
3. Update the CustomResourceDefinition `Status` by removing `v1beta1` from
`storedVersions` field.
{{% /capture %}}
@@ -4,11 +4,12 @@ reviewers:
- deads2k
- enisoc
content_template: templates/task
weight: 20
---
{{% capture overview %}}
This page shows how to install a
[custom resource](/docs/concepts/api-extension/custom-resources/)
[custom resource](/docs/concepts/extend-kubernetes/api-extension/custom-resources/)
into the Kubernetes API by creating a
[CustomResourceDefinition](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#customresourcedefinition-v1beta1-apiextensions).
{{% /capture %}}
@@ -27,10 +28,11 @@ into the Kubernetes API by creating a
## Create a CustomResourceDefinition
When you create a new CustomResourceDefinition (CRD), the Kubernetes API Server
reacts by creating a new RESTful resource path, either namespaced or cluster-scoped,
as specified in the CRD's `scope` field. As with existing built-in objects, deleting a
namespace deletes all custom objects in that namespace.
CustomResourceDefinitions themselves are non-namespaced and are available to all namespaces.
creates a new RESTful resource path for each version you specify. The CRD can be
either namespaced or cluster-scoped, as specified in the CRD's `scope` field. As
with existing built-in objects, deleting a namespace deletes all custom objects
in that namespace. CustomResourceDefinitions themselves are non-namespaced and
are available to all namespaces.
For example, if you save the following CustomResourceDefinition to `resourcedefinition.yaml`:
@@ -43,8 +45,13 @@ metadata:
spec:
# group name to use for REST API: /apis/<group>/<version>
group: stable.example.com
# version name to use for REST API: /apis/<group>/<version>
version: v1
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
# either Namespaced or Cluster
scope: Namespaced
names:
@@ -75,7 +82,7 @@ This endpoint URL can then be used to create and manage custom objects.
The `kind` of these objects will be `CronTab` from the spec of the
CustomResourceDefinition object you created above.
Please note that it might take a few seconds for the endpoint to be created.
It might take a few seconds for the endpoint to be created.
You can watch the `Established` condition of your CustomResourceDefinition
to be true or watch the discovery information of the API server for your
resource to show up.
@@ -120,9 +127,8 @@ NAME AGE
my-new-cron-object 6s
```
Note that resource names are not case-sensitive when using kubectl,
and you can use either the singular or plural forms defined in the CRD,
as well as any short names.
Resource names are not case-sensitive when using kubectl, and you can use either
the singular or plural forms defined in the CRD, as well as any short names.
You can also view the raw YAML data:
@@ -173,6 +179,12 @@ Error from server (NotFound): Unable to list "crontabs": the server could not fi
If you later recreate the same CustomResourceDefinition, it will start out empty.
## Serving multiple versions of a CRD
See [Custom resource definition versioning](custom-resource-definition-versioning)
for more information about serving multiple versions of your
CustomResourceDefinition and migrating your objects from one version to another.
{{% /capture %}}
{{% capture discussion %}}
@@ -245,6 +257,10 @@ metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
version: v1
scope: Namespaced
names:
@@ -333,18 +349,15 @@ crontab "my-new-cron-object" created
### Subresources
Custom resources support `/status` and `/scale` subresources.
This feature is __alpha__ in v1.10 and may change in backward incompatible ways.
This feature is __beta__ in v1.11 and enabled by default.
Enable this feature using the `CustomResourceSubresources` feature gate on
You can disable this feature using the `CustomResourceSubresources` feature gate on
the [kube-apiserver](/docs/admin/kube-apiserver):
```
--feature-gates=CustomResourceSubresources=true
--feature-gates=CustomResourceSubresources=false
```
When the `CustomResourceSubresources` feature gate is enabled, only the `properties` construct
is allowed in the root schema for custom resource validation.
The status and scale subresources can be optionally enabled by
defining them in the CustomResourceDefinition.
@@ -357,6 +370,7 @@ When the status subresource is enabled, the `/status` subresource for the custom
- `PUT` requests to the `/status` subresource only validate the status stanza of the custom resource.
- `PUT`/`POST`/`PATCH` requests to the custom resource ignore changes to the status stanza.
- Any changes to the spec stanza increments the value at `.metadata.generation`.
- `properties`, `required` and `description` are the only constructs allowed in the root of the CRD OpenAPI validation schema.
#### Scale subresource
@@ -398,7 +412,10 @@ metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
@@ -489,7 +506,10 @@ metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
@@ -546,6 +566,8 @@ crontabs/my-new-cron-object 3s
{{% capture whatsnext %}}
* Learn how to [Migrate a ThirdPartyResource to CustomResourceDefinition](/docs/tasks/access-kubernetes-api/migrate-third-party-resource/).
* See [CustomResourceDefinition](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#customresourcedefinition-v1beta1-apiextensions-k8s-io).
* Serve [multiple versions](custom-resource-definitions-versioning) of a
CustomResourceDefinition
{{% /capture %}}
@@ -4,6 +4,7 @@ reviewers:
- enisoc
- deads2k
content_template: templates/task
weight: 50
---
{{% capture overview %}}
@@ -71,7 +72,10 @@ you **on a best-effort basis**.
spec:
scope: Namespaced
group: stable.example.com
version: v1
versions:
- name: v1
served: true
storage: true
names:
kind: CronTab
plural: crontabs
@@ -163,7 +167,7 @@ you **on a best-effort basis**.
{{% capture whatsnext %}}
* Learn more about [custom resources](/docs/concepts/api-extension/custom-resources/).
* Learn more about [using CustomResourceDefinitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
* Learn more about [using CustomResourceDefinitions](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/).
* See [CustomResourceDefinition](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#customresourcedefinition-v1beta1-apiextensions).
{{% /capture %}}
@@ -1,6 +1,7 @@
---
title: Use an HTTP Proxy to Access the Kubernetes API
content_template: templates/task
weight: 40
---
{{% capture overview %}}
@@ -5,6 +5,7 @@ reviewers:
- cheftako
- chenopis
content_template: templates/task
weight: 15
---
{{% capture overview %}}
@@ -206,9 +206,6 @@ The objects that are stored to disk for a cluster's internal representation of t
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.
@@ -217,6 +214,4 @@ You can use `kubectl convert` command to convert config files between different
kubectl convert -f pod.yaml --output-version v1
```
For more options, please refer to the usage of [kubectl convert](/docs/reference/generated/kubectl/kubectl-commands/#convert) command.
{{% /capture %}}
For more options, please refer to the usage of [kubectl convert](/docs/user-guide/kubectl/{{page.version}}/#convert) command.
@@ -6,11 +6,8 @@ min-kubernetes-server-version: v1.9
content_template: templates/task
---
{{< feature-state state="beta" >}}
{{% capture overview %}}
This page describes how to enable CoreDNS instead of kube-dns for service
discovery.
This page describes the CoreDNS upgrade process and how to install kube-dns instead of CoreDNS.
{{% /capture %}}
{{% capture prerequisites %}}
@@ -19,41 +16,47 @@ discovery.
{{% capture steps %}}
## About CoreDNS
[CoreDNS](https://coredns.io) is a flexible, extensible DNS server that can serve as the Kubernetes cluster DNS.
Like Kubernetes, the CoreDNS project is hosted by the [CNCF.](http://www.cncf.io)
You can use CoreDNS instead of kube-dns in your cluster by replacing kube-dns in an existing
deployment, or by using tools like kubeadm that will deploy and upgrade the cluster for you.
## Installing CoreDNS
For manual deployment or replacement of kube-dns, see the documentation at the
[CoreDNS GitHub project.](https://github.com/coredns/deployment/tree/master/kubernetes)
## Installing CoreDNS with kubeadm
In Kubernetes 1.9, [CoreDNS](https://coredns.io) is available as an alpha feature, and
in Kubernetes 1.10 it is available as a beta feature. In either case, you may install
it during cluster creation by setting the `CoreDNS` feature gate to `true` during `kubeadm init`:
In Kubernetes 1.11, CoreDNS has graduated to General Availability (GA)
and is installed by default. To install kube-dns instead, set the `CoreDNS` feature gate
value to `false`:
```
kubeadm init --feature-gates=CoreDNS=true
kubeadm init --feature-gates=CoreDNS=false
```
This installs CoreDNS instead of kube-dns.
## Upgrading an existing cluster with kubeadm
## Using a custom CoreDNS image repository with kubeadm
To use a custom image repository for the CoreDNS image, e.g. one located in your own Docker registry,
you can execute the following command after kubeadm has deployed the CoreDNS manifest:
```shell
kubectl set image -n kube-system deploy/coredns coredns=prefix.example.com/coredns/coredns:1.0.6
```
## Upgrading an Existing Cluster with kubeadm
In Kubernetes 1.10, you can also move to CoreDNS when you use `kubeadm` to upgrade
In Kubernetes version 1.10 and later, you can also move to CoreDNS when you use `kubeadm` to upgrade
a cluster that is using `kube-dns`. In this case, `kubeadm` will generate the CoreDNS configuration
("Corefile") based upon the `kube-dns` ConfigMap, preserving configurations for federation,
stub domains, and upstream name server.
Note that if you are running CoreDNS in your cluster already, prior to upgrade, your existing Corefile will be
**overwritten** by the one created during upgrade. **You should save your existing ConfigMap
if you have customized it.** You may re-apply your customizations after the new ConfigMap is
up and running.
If you are moving from kube-dns to CoreDNS, make sure to set the `CoreDNS` feature gate to `true`
during an upgrade. For example, here is what a `v1.11.0` upgrade would look like:
```
kubeadm upgrade apply v1.11.0 --feature-gates=CoreDNS=true
```
This process will be modified for the GA release of this feature, such that an existing
Corefile will not be overwritten.
In versions prior to 1.11 the Corefile will be **overwritten** by the one created during upgrade.
**You should save your existing ConfigMap if you have customized it.** You may re-apply your
customizations after the new ConfigMap is up and running.
If you are running CoreDNS in Kubernetes version 1.11 and later, during upgrade,
your existing Corefile will be retained.
{{% /capture %}}
@@ -9,6 +9,11 @@ content_template: templates/concept
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.11" state="beta" >}}
In upcoming releases, Cloud Controller Manager will
be the preferred way to integrate Kubernetes with any cloud. This will ensure cloud providers
can develop their features independently from the core Kubernetes release cycles.**
{{< feature-state for_k8s_version="1.8" state="alpha" >}}
Before going into how to build your own cloud controller manager, some background on how it works under the hood is helpful. The cloud controller manager is code from `kube-controller-manager` utilizing Go interfaces to allow implementations from any cloud to be plugged in. Most of the scaffolding and generic controller implementations will be in core, but it will always exec out to the cloud interfaces it is provided, so long as the [cloud provider interface](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/cloud.go#L29-L50) is satisfied.
@@ -7,56 +7,59 @@ content_template: templates/task
---
{{% capture overview %}}
This page provides hints on configuring DNS Pod and guidance on customizing the
DNS resolution process.
This page explains how to configure your DNS Pod and customize the
DNS resolution process. In Kubernetes version 1.11 and later, CoreDNS is at GA
and is installed by default with kubeadm. See [Configuring CoreDNS](#config-coredns)
and [Using CoreDNS for Service Discovery](/docs/tasks/administer-cluster/coredns/).
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* Kubernetes version 1.6 and above.
* The cluster must be configured to use the `kube-dns` addon.
* Kubernetes version 1.6 or later. To work with CoreDNS, version 1.9 or later.
* The appropriate add-on: kube-dns or CoreDNS. To install with kubeadm,
see [the kubeadm reference documentation](/docs/reference/setup-tools/kubeadm/kubeadm-alpha/#cmd-phase-addon).
{{% /capture %}}
{{% capture steps %}}
## Introduction
Starting from Kubernetes v1.3, DNS is a built-in service launched automatically
DNS is a built-in Kubernetes service launched automatically
using the addon manager
[cluster add-on](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/README.md).
The running Kubernetes DNS pod holds 3 containers:
The running DNS Pod holds 3 containers:
- "`kubedns`": The `kubedns` process watches the Kubernetes master for changes
- "`kubedns`": watches the Kubernetes master for changes
in Services and Endpoints, and maintains in-memory lookup structures to serve
DNS requests.
- "`dnsmasq`": The `dnsmasq` container adds DNS caching to improve performance.
- "`sidecar`": The `sidecar` container provides a single health check endpoint
while performing dual healthchecks (for `dnsmasq` and `kubedns`).
- "`dnsmasq`": adds DNS caching to improve performance.
- "`sidecar`": provides a single health check endpoint
to perform healthchecks for `dnsmasq` and `kubedns`.
The DNS pod is exposed as a Kubernetes Service with a static IP. Once assigned
the kubelet passes DNS configured using the `--cluster-dns=<dns-service-ip>`
flag to each container.
The DNS Pod is exposed as a Kubernetes Service with a static IP.
The kubelet passes DNS to each container with the `--cluster-dns=<dns-service-ip>`
flag.
DNS names also need domains. The local domain is configurable in the kubelet
using the flag `--cluster-domain=<default-local-domain>`.
DNS names also need domains. You configure the local domain in the kubelet
with the flag `--cluster-domain=<default-local-domain>`.
The Kubernetes cluster DNS server is based off the
The Kubernetes cluster DNS server is based on the
[SkyDNS](https://github.com/skynetservices/skydns) library. It supports forward
lookups (A records), service lookups (SRV records) and reverse IP address
lookups (A records), service lookups (SRV records), and reverse IP address
lookups (PTR records).
## Inheriting DNS from the node
When running a pod, kubelet will prepend the cluster DNS server and search
paths to the node's own DNS settings. If the node is able to resolve DNS names
specific to the larger environment, pods should be able to, also.
See [Known issues](#known-issues) below for a caveat.
When running a Pod, kubelet prepends the cluster DNS server and searches
paths to the node's DNS settings. If the node is able to resolve DNS names
specific to the larger environment, Pods should also be able to resolve.
But see [Known issues](#known-issues).
If you don't want this, or if you want a different DNS config for pods, you can
use the kubelet's `--resolv-conf` flag. Setting it to "" means that pods will
not inherit DNS. Setting it to a valid file path means that kubelet will use
this file instead of `/etc/resolv.conf` for DNS inheritance.
use the kubelet's `--resolv-conf` flag. Set this flag to "" to prevent Pods from
inheriting DNS. Set it to a valid file path to specify a file other than
`/etc/resolv.conf` for DNS inheritance.
## Configure stub-domain and upstream DNS servers
@@ -64,7 +67,7 @@ Cluster administrators can specify custom stub domains and upstream nameservers
by providing a ConfigMap for kube-dns (`kube-system:kube-dns`).
For example, the following ConfigMap sets up a DNS configuration with a single stub domain and two
upstream nameservers.
upstream nameservers:
```yaml
apiVersion: v1
@@ -79,11 +82,11 @@ data:
["8.8.8.8", "8.8.4.4"]
```
As specified, DNS requests with the “.acme.local” suffix
DNS requests with the “.acme.local” suffix
are forwarded to a DNS listening at 1.2.3.4. Google Public DNS
serves the upstream queries.
The table below describes how queries with certain domain names would map to
The table below describes how queries with certain domain names map to
their destination DNS servers:
| Domain name | Server answering the query |
@@ -99,9 +102,9 @@ details about the configuration option format.
{{% capture discussion %}}
### Impacts on Pods
### Effects on Pods
Custom upstream nameservers and stub domains won't impact Pods that have their
Custom upstream nameservers and stub domains do not affect Pods with a
`dnsPolicy` set to "`Default`" or "`None`".
If a Pod's `dnsPolicy` is set to "`ClusterFirst`", its name resolution is
@@ -113,23 +116,23 @@ cluster domain suffix, such as "www.kubernetes.io", is forwarded to the upstream
nameserver inherited from the node.
**With custom configurations**: If stub domains and upstream DNS servers are
configured (as in the [previous example](#configuring-stub-domain-and-upstream-dns-servers)),
DNS queries will be routed according to the following flow:
configured,
DNS queries are routed according to the following flow:
1. The query is first sent to the DNS caching layer in kube-dns.
1. From the caching layer, the suffix of the request is examined and then
forwarded to the appropriate DNS, based on the following cases:
* *Names with the cluster suffix* (e.g.".cluster.local"):
* *Names with the cluster suffix*, for example ".cluster.local":
The request is sent to kube-dns.
* *Names with the stub domain suffix* (e.g. ".acme.local"):
The request is sent to the configured custom DNS resolver (e.g. listening at 1.2.3.4).
* *Names with the stub domain suffix*, for example ".acme.local":
The request is sent to the configured custom DNS resolver, listening for example at 1.2.3.4.
* *Names without a matching suffix* (e.g."widget.com"):
The request is forwarded to the upstream DNS
(e.g. Google public DNS servers at 8.8.8.8 and 8.8.4.4).
* *Names without a matching suffix*, for example "widget.com":
The request is forwarded to the upstream DNS,
for example Google public DNS servers at 8.8.8.8 and 8.8.4.4.
![DNS lookup flow](/docs/tasks/administer-cluster/dns-custom-nameservers/dns.png)
@@ -139,17 +142,17 @@ Options for the kube-dns `kube-system:kube-dns` ConfigMap:
| Field | Format | Description |
| ----- | ------ | ----------- |
| `stubDomains` (optional) | A JSON map using a DNS suffix key (e.g. “acme.local”) and a value consisting of a JSON array of DNS IPs. | The target nameserver may itself be a Kubernetes service. For instance, you can run your own copy of dnsmasq to export custom DNS names into the ClusterDNS namespace. |
| `upstreamNameservers` (optional) | A JSON array of DNS IPs. | Note: If specified, then the values specified replace the nameservers taken by default from the nodes `/etc/resolv.conf`. Limits: a maximum of three upstream nameservers can be specified. |
| `stubDomains` (optional) | A JSON map using a DNS suffix key such as “acme.local”, and a value consisting of a JSON array of DNS IPs. | The target nameserver can itself be a Kubernetes Service. For instance, you can run your own copy of dnsmasq to export custom DNS names into the ClusterDNS namespace. |
| `upstreamNameservers` (optional) | A JSON array of DNS IPs. | If specified, the values replace the nameservers taken by default from the nodes `/etc/resolv.conf`. Limits: a maximum of three upstream nameservers can be specified. |
### Examples
#### Example: Stub domain
In this example, the user has a Consul DNS service discovery system that they wish to
In this example, the user has a Consul DNS service discovery system they want to
integrate with kube-dns. The consul domain server is located at 10.150.0.1, and
all consul names have the suffix .consul.local. To configure Kubernetes, the
cluster administrator simply creates a ConfigMap object as shown below.
all consul names have the suffix `.consul.local`. To configure Kubernetes, the
cluster administrator creates the following ConfigMap:
```yaml
apiVersion: v1
@@ -162,7 +165,7 @@ data:
{"consul.local": ["10.150.0.1"]}
```
Note that the cluster administrator did not wish to override the nodes
Note that the cluster administrator does not want to override the nodes
upstream nameservers, so they did not specify the optional
`upstreamNameservers` field.
@@ -170,8 +173,8 @@ upstream nameservers, so they did not specify the optional
In this example the cluster administrator wants to explicitly force all
non-cluster DNS lookups to go through their own nameserver at 172.16.0.1.
Again, this is easy to accomplish; they just need to create a ConfigMap with the
`upstreamNameservers` field specifying the desired nameserver.
In this case, they create a ConfigMap with the
`upstreamNameservers` field specifying the desired nameserver:
```yaml
apiVersion: v1
@@ -184,9 +187,97 @@ data:
["172.16.0.1"]
```
## What's next
- [Debugging DNS Resolution](/docs/tasks/administer-cluster/dns-debugging-resolution/).
{{% /capture %}}
## Configuring CoreDNS {config-coredns}
You can configure [CoreDNS](https://coredns.io/) as a service discovery.
CoreDNS is available as an option in Kubernetes starting with version 1.9.
It is currently a [GA feature](https://github.com/kubernetes/community/blob/master/keps/sig-network/0010-20180314-coredns-GA-proposal.md) and is on course to be [the default](https://github.com/kubernetes/community/blob/master/keps/sig-network/0012-20180518-coredns-default-proposal.md), replacing kube-dns.
## CoreDNS ConfigMap options
CoreDNS chains plugins and can be configured by maintaining a Corefile with the ConfigMap. CoreDNS supports all the functionalities and more that is provided by kube-dns.
A ConfigMap created for kube-dns to support `StubDomains`and `upstreamnameserver` translates to the `proxy` plugin in CoreDNS.
Similarly, the `Federation` plugin translates to the `federation` plugin in CoreDNS.
### Example
This example ConfigMap for kube0dns specifies federations, stubdomains and upstreamnameservers:
```yaml
apiVersion: v1
data:
federations: |
{"foo" : "foo.feddomain.com"}
stubDomains: |
{"abc.com" : ["1.2.3.4"], "my.cluster.local" : ["2.3.4.5"]}
upstreamNameservers: |
["8.8.8.8", "8.8.4.4"]
kind: ConfigMap
```
The equivalent configuration in CoreDNS creates a Corefile:
* For federations:
```yaml
federation cluster.local {
foo foo.feddomain.com
}
```
* For stubDomains:
```yaml
abc.com:53 {
errors
cache 30
proxy . 1.2.3.4
}
my.cluster.local:53 {
errors
cache 30
proxy . 2.3.4.5
}
```
The complete Corefile with the default plugins:
```yaml
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
upstream 8.8.8.8 8.8.4.4
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
federation cluster.local {
foo foo.feddomain.com
}
prometheus :9153
proxy . 8.8.8.8 8.8.4.4
cache 30
}
abc.com:53 {
errors
cache 30
proxy . 1.2.3.4
}
my.cluster.local:53 {
errors
cache 30
proxy . 2.3.4.5
}
```
In Kubernetes version 1.10 and later, kubeadm supports automatic translation of the CoreDNS ConfigMap from the kube-dns ConfigMap.
## Migration to CoreDNS
A number of tools support the installation of CoreDNS instead of kube-dns.
To migrate from kube-dns to CoreDNS, [a detailed blog](https://coredns.io/2018/05/21/migration-from-kube-dns-to-coredns/) is available to help users adapt CoreDNS in place of kube-dns.
## What's next
- [Debugging DNS Resolution](/docs/tasks/administer-cluster/dns-debugging-resolution/).
@@ -83,7 +83,6 @@ The output shows that the Node has a capacity of 4 dongles:
```
"capacity": {
"alpha.kubernetes.io/nvidia-gpu": "0",
"cpu": "2",
"memory": "2049008Ki",
"example.com/dongle": "4",
@@ -99,7 +98,6 @@ Once again, the output shows the dongle resource:
```yaml
Capacity:
alpha.kubernetes.io/nvidia-gpu: 0
cpu: 2
memory: 2049008Ki
example.com/dongle: 4
@@ -205,6 +203,3 @@ kubectl describe node <your-node-name> | grep dongle
{{% /capture %}}
@@ -11,7 +11,7 @@ content_template: templates/concept
In addition to Kubernetes core components like api-server, scheduler, controller-manager running on a master machine
there are a number of add-ons which, for various reasons, must run on a regular cluster node (rather than the Kubernetes master).
Some of these add-ons are critical to a fully functional cluster, such as Heapster, DNS, and UI.
Some of these add-ons are critical to a fully functional cluster, such as metrics-server, DNS, and UI.
A cluster may stop working properly if a critical add-on is evicted (either manually or as a side effect of another operation like upgrade)
and becomes pending (for example when the cluster is highly utilized and either there are other pending pods that schedule into the space
vacated by the evicted critical add-on pod or the amount of resources available on the node changed for some other reason).
@@ -0,0 +1,279 @@
---
reviewers:
- sig-cluster-lifecycle
title: Upgrading kubeadm clusters from v1.10 to v1.11
content_template: templates/task
---
{{% capture overview %}}
This page explains how to upgrade a Kubernetes cluster created with `kubeadm` from version 1.10.x to version 1.11.x, and from version 1.11.x to 1.11.y, where `y > x`.
{{% /capture %}}
{{% capture prerequisites %}}
- You need to have a `kubeadm` Kubernetes cluster running version 1.10.0 or later. Swap must be disabled. The cluster should use a static control plane and etcd pods.
- Make sure you read the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md) carefully.
- Make sure to back up any important components, such as app-level state stored in a database. `kubeadm upgrade` does not touch your workloads, only components internal to Kubernetes, but backups are always a best practice.
### Additional information
- All containers are restarted after upgrade, because the container spec hash value is changed.
- You can upgrade only froom one minor version to the next minor version. That is, you cannot skip versions when you upgrade. For example, you can upgrade only from 1.10 to 1.11, not from 1.9 to 1.11.
- The default DNS provider in version 1.11 is [CoreDNS](https://coredns.io/) rather than [kube-dns](https://github.com/kubernetes/dns).
To keep `kube-dns`, pass `--feature-flags=CoreDNS=false` to `kubeadm upgrade apply`.
{{% /capture %}}
{{% capture steps %}}
## Upgrade the control plane
1. On your master node, run the following (as root:
export VERSION=$(curl -sSL https://dl.k8s.io/release/stable.txt) # or manually specify a released Kubernetes version
export ARCH=amd64 # or: arm, arm64, ppc64le, s390x
curl -sSL https://dl.k8s.io/release/${VERSION}/bin/linux/${ARCH}/kubeadm > /usr/bin/kubeadm
chmod a+rx /usr/bin/kubeadm
Note that upgrading the `kubeadm` package on your system prior to upgrading the control plane causes a failed upgrade. Even though `kubeadm` ships in the Kubernetes repositories, it's important to install it manually. The kubeadm team is working on fixing this limitation.
1. Verify that the download works and has the expected version:
```shell
kubeadm version
```
1. On the master node, run:
```shell
kubeadm upgrade plan
```
You should see output similar to this:
<!-- TODO: copy-paste actual output once new version is stable -->
```shell
[preflight] Running pre-flight checks.
[upgrade] Making sure the cluster is healthy:
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
I0618 20:32:32.950358 15307 feature_gate.go:230] feature gates: &{map[]}
[upgrade] Fetching available versions to upgrade to
[upgrade/versions] Cluster version: v1.10.4
[upgrade/versions] kubeadm version: v1.11.0-beta.2.78+e0b33dbc2bde88
Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.10.4 v1.11.0
Upgrade to the latest version in the v1.10 series:
COMPONENT CURRENT AVAILABLE
API Server v1.10.4 v1.11.0
Controller Manager v1.10.4 v1.11.0
Scheduler v1.10.4 v1.11.0
Kube Proxy v1.10.4 v1.11.0
CoreDNS 1.1.3
Kube DNS 1.14.8
Etcd 3.1.12 3.2.18
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.11.0
Note: Before you can perform this upgrade, you have to update kubeadm to v1.11.0.
_____________________________________________________________________
```
This command checks that your cluster can be upgraded, and fetches the versions you can upgrade to.
1. Choose a version to upgrade to, and run the appropriate command. For example:
```shell
kubeadm upgrade apply v1.11.0
```
If you currently use `kube-dns` and wish to continue doing so, add `--feature-flags=CoreDNS=false`.
You should see output similar to this:
<!-- TODO: output from stable -->
```shell
[preflight] Running pre-flight checks.
[upgrade] Making sure the cluster is healthy:
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
I0614 20:56:08.320369 30918 feature_gate.go:230] feature gates: &{map[]}
[upgrade/apply] Respecting the --cri-socket flag that is set with higher priority than the config file.
[upgrade/version] You have chosen to change the cluster version to "v1.11.0-beta.2.78+e0b33dbc2bde88"
[upgrade/versions] Cluster version: v1.10.4
[upgrade/versions] kubeadm version: v1.11.0-beta.2.78+e0b33dbc2bde88
[upgrade/confirm] Are you sure you want to proceed with the upgrade? [y/N]: y
[upgrade/prepull] Will prepull images for components [kube-apiserver kube-controller-manager kube-scheduler etcd]
[upgrade/apply] Upgrading your Static Pod-hosted control plane to version "v1.11.0-beta.2.78+e0b33dbc2bde88"...
Static pod: kube-apiserver-ip-172-31-85-18 hash: 7a329408b21bc0c44d7b3b78ff8187bf
Static pod: kube-controller-manager-ip-172-31-85-18 hash: 24fd3157627c7567b687968967c6a5e8
Static pod: kube-scheduler-ip-172-31-85-18 hash: 5179266fb24d4c1834814c4f69486371
Static pod: etcd-ip-172-31-85-18 hash: 9dfc197f444be11fcc70ab1467b030b8
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests089436939/etcd.yaml"
[certificates] Using the existing etcd/ca certificate and key.
[certificates] Using the existing etcd/server certificate and key.
[certificates] Using the existing etcd/peer certificate and key.
[certificates] Using the existing etcd/healthcheck-client certificate and key.
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/etcd.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2018-06-14-20-56-11/etcd.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
Static pod: etcd-ip-172-31-85-18 hash: 9dfc197f444be11fcc70ab1467b030b8
< snip >
[apiclient] Found 1 Pods for label selector component=etcd
[upgrade/staticpods] Component "etcd" upgraded successfully!
[upgrade/etcd] Waiting for etcd to become available
[util/etcd] Waiting 0s for initial delay
[util/etcd] Attempting to see if all cluster endpoints are available 1/10
[upgrade/staticpods] Writing new Static Pod manifests to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests089436939"
[controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests089436939/kube-apiserver.yaml"
[controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests089436939/kube-controller-manager.yaml"
[controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests089436939/kube-scheduler.yaml"
[certificates] Using the existing etcd/ca certificate and key.
[certificates] Using the existing apiserver-etcd-client certificate and key.
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-apiserver.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2018-06-14-20-56-11/kube-apiserver.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
Static pod: kube-apiserver-ip-172-31-85-18 hash: 7a329408b21bc0c44d7b3b78ff8187bf
< snip >
[apiclient] Found 1 Pods for label selector component=kube-apiserver
[upgrade/staticpods] Component "kube-apiserver" upgraded successfully!
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-controller-manager.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2018-06-14-20-56-11/kube-controller-manager.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
Static pod: kube-controller-manager-ip-172-31-85-18 hash: 24fd3157627c7567b687968967c6a5e8
Static pod: kube-controller-manager-ip-172-31-85-18 hash: 63992ff14733dcb9dcfa6ac0a3b8031a
[apiclient] Found 1 Pods for label selector component=kube-controller-manager
[upgrade/staticpods] Component "kube-controller-manager" upgraded successfully!
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-scheduler.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2018-06-14-20-56-11/kube-scheduler.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
Static pod: kube-scheduler-ip-172-31-85-18 hash: 5179266fb24d4c1834814c4f69486371
Static pod: kube-scheduler-ip-172-31-85-18 hash: 831e4b9425f758e572392976311e56d9
[apiclient] Found 1 Pods for label selector component=kube-scheduler
[upgrade/staticpods] Component "kube-scheduler" upgraded successfully!
[uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.11" in namespace kube-system with the configuration for the kubelets in the cluster
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.11" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "ip-172-31-85-18" as an annotation
[bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.11.0-beta.2.78+e0b33dbc2bde88". Enjoy!
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
```
1. Manually upgrade your Software Defined Network (SDN).
Your Container Network Interface (CNI) provider may have its own upgrade instructions to follow.
Check the [addons](/docs/concepts/cluster-administration/addons/) page to
find your CNI provider and see whther additional upgrade steps are required.
## Upgrade master and node packages
1. Prepare each host for maintenance, marking it unschedulable and evicting the workload:
```shell
kubectl drain $HOST --ignore-daemonsets
```
On the master host, you must add `--ignore-daemonsets`:
```shell
kubectl drain ip-172-31-85-18
node "ip-172-31-85-18" cordoned
error: unable to drain node "ip-172-31-85-18", aborting command...
There are pending nodes to be drained:
ip-172-31-85-18
error: DaemonSet-managed pods (use --ignore-daemonsets to ignore): calico-node-5798d, kube-proxy-thjp9
```
```
kubectl drain ip-172-31-85-18 --ignore-daemonsets
node "ip-172-31-85-18" already cordoned
WARNING: Ignoring DaemonSet-managed pods: calico-node-5798d, kube-proxy-thjp9
node "ip-172-31-85-18" drained
```
1. Upgrade the Kubernetes package version on each `$HOST` node by running the Linux package manager for your distribution:
{{< tabs name="k8s_install" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
apt-get update
apt-get upgrade -y kubelet kubeadm
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
yum upgrade -y kubelet kubedam
{{% /tab %}}
{{< /tabs >}}
## Upgrade kubelet on each node
1. On each node except the master node, upgrade the kubelet config:
```shell
sudo kubeadm upgrade node config --kubelet-version $(kubelet --version | cut -d ' ' -f 2)
```
1. Restart the kubectl process:
```shell
sudo systemctl restart kubelet
```
1. Verify that the new version of the `kubelet` is running on the host:
```shell
systemctl status kubelet
```
1. Bring the host back online by marking it schedulable:
```shell
kubectl uncordon $HOST
```
1. After the kubelet is upgraded on all hosts, verify that all nodes are available again by running the following command from anywhere -- for example, from outside the cluster:
```shell
kubectl get nodes
```
The `STATUS` column should show `Ready` for all your hosts, and the version number should be updated.
{{% /capture %}}
## Recovering from a failure state
If `kubeadm upgrade` fails and does not roll back, for example because of an unexpected shutdown during execution,
you can run `kubeadm upgrade` again. This command is idempotent and eventually makes sure that the actual state is the desired state you declare.
To recover from a bad state, you can also run `kubeadm upgrade --force` without changing the version that your cluster is running.
## How it works
`kubeadm upgrade apply` does the following:
- Checks that your cluster is in an upgradeable state:
- The API server is reachable,
- All nodes are in the `Ready` state
- The control plane is healthy
- Enforces the version skew policies.
- Makes sure the control plane images are available or available to pull to the machine.
- Upgrades the control plane components or rollbacks if any of them fails to come up.
- Applies the new `kube-dns` and `kube-proxy` manifests and enforces that all necessary RBAC rules are created.
- Creates new certificate and key files of the API server and backs up old files if they're about to expire in 180 days.
@@ -1,145 +0,0 @@
---
reviewers:
- msau42
- jsafrane
title: Persistent Volume Claim Protection
content_template: templates/task
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.9" state="alpha" >}}
As of Kubernetes 1.9, persistent volume claims (PVCs) that are in active use by a pod can be protected from pre-mature removal.
{{% /capture %}}
{{% capture prerequisites %}}
- A v1.9 or higher Kubernetes must be installed.
- As PVC Protection is a Kubernetes v1.9 alpha feature it must be enabled:
1. [Admission controller](/docs/admin/admission-controllers/) must be started with the [PVC Protection plugin](/docs/admin/admission-controllers/#persistent-volume-claim-protection-alpha).
2. All Kubernetes components must be started with the `PVCProtection` alpha features enabled.
{{% /capture %}}
{{% capture steps %}}
## PVC Protection Verification
The example below uses a GCE PD `StorageClass`, however, similar steps can be performed for any volume type.
Create a `StorageClass` for convenient storage provisioning:
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
```
There are two scenarios: a PVC deleted by a user is either in active use or not in active use by a pod.
### Scenario 1: The PVC is not in active use by a pod
- Create a PVC:
```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: slzc
spec:
accessModes:
- ReadWriteOnce
storageClassName: slow
resources:
requests:
storage: 3.7Gi
```
- Check that the PVC has the finalizer `kubernetes.io/pvc-protection` set:
```shell
$ kubectl describe pvc slzc
Name: slzc
Namespace: default
StorageClass: slow
Status: Bound
Volume: pvc-bee8c30a-d6a3-11e7-9af0-42010a800002
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/gce-pd
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 4Gi
Access Modes: RWO
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ProvisioningSucceeded 2m persistentvolume-controller Successfully provisioned volume pvc-bee8c30a-d6a3-11e7-9af0-42010a800002 using kubernetes.io/gce-pd
```
- Delete the PVC and check that the PVC (not in active use by a pod) was removed successfully.
### Scenario 2: The PVC is in active use by a pod
- Again, create the same PVC.
- Create a pod that uses the PVC:
```yaml
kind: Pod
apiVersion: v1
metadata:
name: app1
spec:
containers:
- name: test-pod
image: k8s.gcr.io/busybox:1.24
command:
- "/bin/sh"
args:
- "-c"
- "date > /mnt/app1.txt; sleep 60 && exit 0 || exit 1"
volumeMounts:
- name: path-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: path-pvc
persistentVolumeClaim:
claimName: slzc
```
- Wait until the pod status is `Running`, i.e. the PVC becomes in active use.
- Delete the PVC that is now in active use by a pod and verify that the PVC is not removed but its status is `Terminating`:
```shell
Name: slzc
Namespace: default
StorageClass: slow
Status: Terminating (since Fri, 01 Dec 2017 14:47:55 +0000)
Volume: pvc-803a1f4d-d6a6-11e7-9af0-42010a800002
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/gce-pd
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 4Gi
Access Modes: RWO
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ProvisioningSucceeded 52s persistentvolume-controller Successfully provisioned volume pvc-803a1f4d-d6a6-11e7-9af0-42010a800002 using kubernetes.io/gce-pd
```
- Wait until the pod status is `Terminated` (either delete the pod or wait until it finishes). Afterwards, check that the PVC is removed.
{{% /capture %}}
{{% capture discussion %}}
{{% /capture %}}
@@ -7,31 +7,28 @@ content_template: templates/task
---
{{% capture overview %}}
{{< feature-state state="alpha" >}}
As of Kubernetes 1.8, the new
{{< feature-state for_k8s_version="v1.11" state="beta" >}}
[Dynamic Kubelet Configuration](https://github.com/kubernetes/features/issues/281)
feature is available in alpha. This allows you to change the configuration of
Kubelets in a live Kubernetes cluster via first-class Kubernetes concepts.
Specifically, this feature allows you to configure individual Nodes' Kubelets
via ConfigMaps.
allows you to change the configuration of each Kubelet in a live Kubernetes
cluster by deploying a ConfigMap and configuring each Node to use it.
{{< warning >}}
**Warning:** All Kubelet configuration parameters may be changed dynamically,
but not all parameters are safe to change dynamically. This feature is intended
for system experts who have a strong understanding of how configuration changes
will affect behavior. No documentation currently exists which plainly lists
"safe to change" fields, but we plan to add it before this feature graduates
from alpha.
**Warning:** All Kubelet configuration parameters can be changed dynamically,
but this is unsafe for some parameters. Before deciding to change a parameter
dynamically, you need a strong understanding of how that change will affect your
cluster's behavior. Always carefully test configuration changes on a small set
of nodes before rolling them out cluster-wide. Advice on configuring specific
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 >}}
{{% /capture %}}
{{% capture prerequisites %}}
- A live Kubernetes cluster with both Master and Node at v1.8 or higher must be
running, with the `DynamicKubeletConfig` feature gate enabled and the Kubelet's
`--dynamic-config-dir` flag set to a writable directory on the Node.
This flag must be set to enable Dynamic Kubelet Configuration.
- The kubectl command-line tool must be also v1.8 or higher, and must be
configured to communicate with the cluster.
- Kubernetes v1.11 or higher on both the Master and the Nodes
- kubectl v1.11 or higher, configured to communicate with the cluster
- The Kubelet's `--dynamic-config-dir` flag must be set to a writable
directory on the Node.
{{% /capture %}}
{{% capture steps %}}
@@ -50,20 +47,19 @@ Kubelet's configuration.
Each Kubelet watches a configuration reference on its respective Node object.
When this reference changes, the Kubelet downloads the new configuration,
updates a local reference to refer to the file, and exits.
For the feature to work correctly, you must be running a process manager
(like systemd) which will restart the Kubelet when it exits. When the Kubelet is
restarted, it will begin using the new configuration.
For the feature to work correctly, you must be running an OS-level service
manager (such as systemd), which will restart the Kubelet if it exits. When the
Kubelet is restarted, it will begin using the new configuration.
The new configuration completely overrides configuration provided by `--config`,
and is overridden by command-line flags. Unspecified values in the new configuration
will receive default values appropriate to the configuration version
(e.g. `kubelet.config.k8s.io/v1beta1`), unless overridden by flags.
The status of the Node's Kubelet configuration is reported via the `KubeletConfigOK`
condition in the Node status. Once you have updated a Node to use the new
ConfigMap, you can observe this condition to confirm that the Node is using the
intended configuration. A table describing the possible conditions can be found
at the end of this article.
The status of the Node's Kubelet configuration is reported via
`Node.Spec.Status.Config`. Once you have updated a Node to use the new
ConfigMap, you can observe this status to confirm that the Node is using the
intended configuration.
This document describes editing Nodes using `kubectl edit`.
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
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
to which Nodes. If you currently use the Node authorizer, your Kubelets will not
be automatically granted permission to download their respective ConfigMaps.
### Automatic RBAC rules for Node Authorizer
The temporary workaround used in this document is to manually create the RBAC
Roles and RoleBindings for each ConfigMap. The Node Authorizer will be extended
before the Dynamic Kubelet Configuration feature graduates from alpha, so doing
this in production should never be necessary.
Previously, you were required to manually create RBAC rules
to allow Nodes to access their assigned ConfigMaps. The Node Authorizer now
automatically configures these rules.
### Generating a file that contains the current configuration
@@ -92,54 +91,63 @@ 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
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)),
and you will simply edit a copy of this file (which, as a best practice, should
live in version control) while creating the first Kubelet ConfigMap. Today,
however, the Kubelet is still bootstrapped with command-line flags. Fortunately,
there is a dirty trick you can use to generate a config file containing a Node's
current configuration. The trick involves accessing the Kubelet server's `configz`
endpoint via the kubectl proxy. This endpoint, in its current implementation, is
intended to be used only as a debugging aid, which is part of why this is a
dirty trick. The endpoint may be improved in the future, but until then
it should not be relied on for production scenarios.
This trick also requires the `jq` command to be installed on your machine,
for unpacking and editing the JSON response from the endpoint.
Currently, the Kubelet is bootstrapped with **a combination of this file and command-line flags**
that can override the configuration in the file.
As a workaround, you can generate a config file containing a Node's current
configuration by accessing the Kubelet server's `configz` endpoint via the
kubectl proxy. This endpoint, in its current implementation, is intended to be
used only as a debugging aid. Do not rely on the behavior of this endpoint for
production scenarios. The examples below use the `jq` command to streamline
working with JSON. To follow the tasks as written, you need to have `jq`
installed, but you can adapt the tasks if you prefer to extract the
`kubeletconfig` subobject manually.
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.
2. Start the kubectl proxy in the background with `kubectl proxy --port=8001 &`
3. Run the following command to download and unpack the configuration from the
configz endpoint:
1. Choose a Node to reconfigure. In this example, the name of this Node is
referred to as `NODE_NAME`.
2. Start the kubectl proxy in the background using the following command:
```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**, note that common zsh configurations add backslashes
to escape the opening and closing curly braces around the variable name in the URL.
For example: `${NODE_NAME}` will be rewritten as `$\{NODE_NAME\}` during the paste.
You must remove the backslashes before running the command, or the command will fail.
```
$ export 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}
```
```bash
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}
```
Note that we have to manually add the `kind` and `apiVersion` to the downloaded
object, as these are not reported by the configz endpoint. This is one of the
limitations of the endpoint.
{{< note >}}
You need to manually add the `kind` and `apiVersion` to the downloaded
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
`kubelet_configz_${NODE_NAME}` file from the previous step. A QPS parameter,
`eventRecordQPS` for example, is a good candidate.
Using a text editor, change one of the parameters in the
file generated by the previous procedure. For example, you
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
following command:
```
$ kubectl -n kube-system create configmap my-node-config --from-file=kubelet=kubelet_configz_${NODE_NAME} --append-hash -o yaml
```bash
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
data:
kubelet: |
@@ -154,304 +162,204 @@ metadata:
uid: 946d785e-998a-11e7-a8dd-42010a800006
```
Note that the configuration data must appear under the ConfigMap's
`kubelet` key.
We create the ConfigMap in the `kube-system` namespace, which is appropriate
because this ConfigMap configures a Kubernetes system component - the Kubelet.
The ConfigMap is created in the `kube-system` namespace because this
ConfigMap configures a Kubelet, which is Kubernetes system component.
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
automatically, yet deterministically, generate new names for new ConfigMaps.
to the name. This is convenient for an edit-then-push workflow, because it
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
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
#### Set the Node to use the new configuration
Edit the Node's reference to point to the new ConfigMap with the
following command:
```
```bash
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:
configMapRef:
configMap:
name: CONFIG_MAP_NAME
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
`KubeletConfigOK` condition in `status.conditions`. You should see the message
`Using current (UID: CONFIG_MAP_UID)` when the Kubelet starts using the new
configuration.
Retrieve the Node using the `kubectl get node ${NODE_NAME} -o yaml` command and inspect
`Node.Status.Config`. The config sources corresponding to the `active`,
`assigned`, and `lastKnownGood` configurations are reported in the status.
For convenience, you can use the following command (using `jq`) to filter down
to the `KubeletConfigOK` condition:
- The `active` configuration is the version the Kubelet is currently running with.
- 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"))'
[
{
"lastHeartbeatTime": "2017-09-20T18:08:29Z",
"lastTransitionTime": "2017-09-20T18:08:17Z",
"message": "using current: /api/v1/namespaces/kube-system/configmaps/my-node-config-gkt4c2m4b2",
"reason": "passing all checks",
"status": "True",
"type": "KubeletConfigOK"
The following is an example response:
```json
{
"active": {
"configMap": {
"kubeletConfigKey": "kubelet",
"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.
We will refer to the new name as NEW_CONFIG_MAP_NAME and the new uid
as NEW_CONFIG_MAP_UID.
If an error occurs, the Kubelet reports it in the `Node.Status.Config.Error`
structure. Possible errors are listed in
[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
read it. First, create a Role for your new ConfigMap with the
following commands:
Follow the workflow above to make more changes and push them again. Each time
you push a ConfigMap with new contents, the --append-hash kubectl option creates
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.
```
$ 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}
```
#### Reset the Node to use its local default configuration
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.
```
$ kubectl -n kube-system create rolebinding ${NEW_CONFIG_MAP_NAME}-reader --role=${NEW_CONFIG_MAP_NAME}-reader --user=system:node:${NODE_NAME}
```
#### Observe that the Node is using its local default configuration
Once the Node Authorizer is updated to do this automatically, you will
be able to skip this step.
### Configure the Node to use the new configuration
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.
After removing this subfield, `Node.Status.Config` eventually becomes
empty, since all config sources have been reset to `nil`, which indicates that
the local default config is `assigned`, `active`, and `lastKnownGood`, and no
error is reported.
{{% /capture %}}
{{% capture discussion %}}
## 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`:
```
kubectl patch node ${NODE_NAME} -p "{\"spec\":{\"configSource\":{\"configMapRef\":{\"name\":\"${CONFIG_MAP_NAME}\",\"namespace\":\"kube-system\",\"uid\":\"${CONFIG_MAP_UID}\"}}}}"
You can change a Node's configSource using several different mechanisms.
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
might encounter in a cluster that has Dynamic Kubelet Config enabled. If you
observe a condition with `status=False`, you should check the Kubelet log for
more error details by searching for the message or reason text.
When a new config is assigned to the Node, the Kubelet downloads and unpacks the
config payload as a set of files on the local disk. The Kubelet also records metadata
that locally tracks the assigned and last-known-good config sources, so that the
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 align="left">
<tr>
<th>Possible Messages</th>
<th>Possible Reasons</th>
<th>Status</th>
<th>Error Message</th>
<th>Possible Causes</th>
</tr>
<tr>
<td><p>using current: local</p></td>
<td><p>when the config source is nil, the Kubelet uses its local config</p></td>
<td><p>True</p></td>
<td><p>failed to load config, see Kubelet log for details</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>
</tr>
<tr>
<td><p>using current: /api/v1/namespaces/${CURRENT_CONFIG_MAP_NAMESPACE}/configmaps/${CURRENT_CONFIG_MAP_NAME}</p></td>
<td><p>passing all checks</p></td>
<td><p>True</p></td>
<td><p>failed to validate config, see Kubelet log for details</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>
</tr>
<tr>
<td><p>using last-known-good: local</p></td>
<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>
<td><p>invalid NodeConfigSource, exactly one subfield must be non-nil, but all were nil</p></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>
</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>
<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>
<td><p>failed to sync: failed to download config, see Kubelet log for details</p></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>
</tr>
<tr>
<td>
<p>
The reasons in the next column could potentially appear for any of
the above messages.
</p>
<p>
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>
<td><p>failed to sync: internal failure, see Kubelet log for details</p></td>
<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>
</tr>
<tr>
<td><p>internal failure, see Kubelet log for details</p></td>
<td><p>The Kubelet encountered some internal problem while manipulating config, outside of the configuration sync loop.</p></td>
</tr>
</table>
{{% /capture %}}
@@ -9,7 +9,7 @@ content_template: templates/concept
{{% capture overview %}}
{{< feature-state state="alpha" >}}
{{< feature-state state="beta" >}}
Kubernetes v1.6 introduced a new binary called `cloud-controller-manager`. `cloud-controller-manager` is a daemon that embeds cloud-specific control loops. These cloud-specific control loops were originally in the `kube-controller-manager`. Since cloud providers develop and release at a different pace compared to the Kubernetes project, abstracting the provider-specific code to the `cloud-controller-manager` binary allows cloud vendors to evolve independently from the core Kubernetes code.
@@ -37,7 +37,8 @@ Successfully running cloud-controller-manager requires some changes to your clus
* `kube-apiserver` and `kube-controller-manager` MUST NOT specify the `--cloud-provider` flag. This ensures that it does not run any cloud specific loops that would be run by cloud controller manager. In the future, this flag will be deprecated and removed.
* `kubelet` must run with `--cloud-provider=external`. This is to ensure that the kubelet is aware that it must be initialized by the cloud controller manager before it is scheduled any work.
* `kube-apiserver` SHOULD NOT run the `PersistentVolumeLabel` admission controller since the cloud controller manager takes over labeling persistent volumes. To prevent the PersistentVolumeLabel admission plugin from running in `kube-apiserver`, include the `PersistentVolumeLabel` as a listed value in the `--disable-admission-plugins` flag.
* `kube-apiserver` SHOULD NOT run the `PersistentVolumeLabel` admission controller
since the cloud controller manager takes over labeling persistent volumes.
* For the `cloud-controller-manager` to label persistent volumes, initializers will need to be enabled and an InitializerConifguration needs to be added to the system. Follow [these instructions](/docs/admin/extensible-admission-controllers.md#enable-initializers-alpha-feature) to enable initializers. Use the following YAML to create the InitializerConfiguration:
{{< code file="persistent-volume-label-initializer-config.yaml" >}}
@@ -53,7 +54,7 @@ As of v1.8, cloud controller manager can implement:
* node controller - responsible for updating kubernetes nodes using cloud APIs and deleting kubernetes nodes that were deleted on your cloud.
* service controller - responsible for loadbalancers on your cloud against services of type LoadBalancer.
* route controller - responsible for setting up network routes on your cloud
* [PersistentVolumeLabel Admission Controller](/docs/admin/admission-controllers#persistentvolumelabel) - responsible for labeling persistent volumes on your cloud - ensure that the persistent volume label admission plugin is not enabled on your kube-apiserver.
* persistent valume labels controller - responsible for setting the zone and region labels on PersistentVolumes created in GCP and AWS clouds.
* any other features you would like to implement if you are running an out-of-tree provider.
@@ -7,15 +7,16 @@ content_template: templates/task
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
Persistent volume claims (PVCs) that are in active use by a pod and persistent volumes (PVs) that are bound to PVCs can be protected from pre-mature removal.
Persistent volume claims (PVCs) that are in active use by a pod and persistent volumes (PVs) that are bound to PVCs can be protected from premature removal.
{{% /capture %}}
{{% capture prerequisites %}}
- The Storage Object in Use Protection feature is enabled in a version of Kubernetes in which it is supported.
The Storage Object in Use Protection feature is enabled in one of the below Kubernetes versions:
- {% assign for_k8s_version = "1.10" %} {% include feature-state-beta.md %}
- {% assign for_k8s_version = "1.11" %} {% include feature-state-stable.md %}
{{% /capture %}}
@@ -312,5 +313,3 @@ No resources found.
{{% /capture %}}
@@ -1,13 +1,15 @@
---
title: Using Sysctls in a Kubernetes Cluster
title: Using sysctls in a Kubernetes Cluster
reviewers:
- sttts
content_template: templates/task
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.11" state="beta" >}}
This document describes how sysctls are used within a Kubernetes cluster.
This document describes how to configure and use kernel parameters within a
Kubernetes cluster using the sysctl interface.
{{% /capture %}}
@@ -74,7 +76,7 @@ application tuning. _Unsafe_ sysctls are enabled on a node-by-node basis with a
flag of the kubelet, e.g.:
```shell
$ kubelet --experimental-allowed-unsafe-sysctls \
$ kubelet --allowed-unsafe-sysctls \
'kernel.msg*,net.ipv4.route.min_pmtu' ...
```
@@ -89,10 +91,11 @@ Only _namespaced_ sysctls can be enabled this way.
## Setting Sysctls for a Pod
A number of sysctls are _namespaced_ in today's Linux kernels. This means that
they can be set independently for each pod on a node. Being namespaced is a
requirement for sysctls to be accessible in a pod context within Kubernetes.
they can be set independently for each pod on a node. Only namespaced sysctls
are configurable via the pod securityContext within Kubernetes.
The following sysctls are known to be _namespaced_:
The following sysctls are known to be namespaced. This list could change
in future versions of the Linux kernel.
- `kernel.shm*`,
- `kernel.msg*`,
@@ -100,25 +103,37 @@ The following sysctls are known to be _namespaced_:
- `fs.mqueue.*`,
- `net.*`.
Sysctls which are not namespaced are called _node-level_ and must be set
manually by the cluster admin, either by means of the underlying Linux
distribution of the nodes (e.g. via `/etc/sysctls.conf`) or using a DaemonSet
with privileged containers.
Sysctls with no namespace are called _node-level_ sysctls. If you need to set
them, you must manually configure them on each node's operating system, or by
using a DaemonSet with privileged containers.
The sysctl feature is an alpha API. Therefore, sysctls are set using annotations
on pods. They apply to all containers in the same pod.
Use the pod securityContext to configure namespaced sysctls. The securityContext
applies to all containers in the same pod.
Here is an example, with different annotations for _safe_ and _unsafe_ sysctls:
This example uses the pod securityContext to set a safe sysctl
`kernel.shm_rmid_forced` and two unsafe sysctls `net.ipv4.route.min_pmtu` and
`kernel.msgmax` There is no distinction between _safe_ and _unsafe_ sysctls in
the specification.
{{< warning >}}
Only modify sysctl parameters after you understand their effects, to avoid
destabilizing your operating system.
{{< /warning >}}
```yaml
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
annotations:
security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1
security.alpha.kubernetes.io/unsafe-sysctls: net.ipv4.route.min_pmtu=1000,kernel.msgmax=1 2 3
spec:
securityContext:
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.ipv4.route.min_pmtu
value: "552"
- name: kernel.msgmax
value: "65536"
...
```
{{% /capture %}}
@@ -143,27 +158,52 @@ is recommended to use
[taints on nodes](/docs/concepts/configuration/taint-and-toleration/)
to schedule those pods onto the right nodes.
## PodSecurityPolicy Annotations
## PodSecurityPolicy
The use of sysctl in pods can be controlled via annotation on the PodSecurityPolicy.
You can further control which sysctls can be set in pods by specifying lists of
sysctls or sysctl patterns in the `forbiddenSysctls` and/or
`allowedUnsafeSysctls` fields of the PodSecurityPolicy. A sysctl pattern ends
with a `*` character, such as `kernel.*`. A `*` character on its own matches
all sysctls.
Sysctl annotation represents a whitelist of allowed safe and unsafe sysctls
in a pod spec. It's a comma-separated list of plain sysctl names or sysctl patterns
(which end in `*`). The string `*` matches all sysctls.
By default, all safe sysctls are allowed.
Here is an example, it authorizes binding user creating pod with corresponding sysctls.
Both `forbiddenSysctls` and `allowedUnsafeSysctls` are lists of plain sysctl names
or sysctl patterns (which end with `*`). The string `*` matches all sysctls.
The `forbiddenSysctls` field excludes specific sysctls. You can forbid a
combination of safe and unsafe sysctls in the list. To forbid setting any
sysctls, use `*` on its own.
If you specify any unsafe sysctl in the `allowedUnsafeSysctls` field and it is
not present in the `forbiddenSysctls` field, that sysctl can be used in Pods
using this PodSecurityPolicy. To allow all unsafe sysctls in the
PodSecurityPolicy to be set, use `*` on its own.
Do not configure these two fields such that there is overlap, meaning that a
given sysctl is both allowed and forbidden.
{{< warning >}}
**Warning**: If you whitelist unsafe sysctls via the `allowedUnsafeSysctls` field
in a PodSecurityPolicy, any pod using such a sysctl will fail to start
if the sysctl is not whitelisted via the `--allowed-unsafe-sysctls` kubelet
flag as well on that node.
{{< /warning >}}
This example allows unsafe sysctls prefixed with `kernel.msg` to be set and
disallows setting of the `kernel.shm_rmid_forced` sysctl.
```yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: sysctl-psp
annotations:
security.alpha.kubernetes.io/sysctls: 'net.ipv4.route.*,kernel.msg*'
spec:
allowedUnsafeSysctls:
- kernel.msg*
forbiddenSysctls:
- kernel.shm_rmid_forced
...
```
{{% /capture %}}
@@ -20,28 +20,32 @@ but is not allowed to use more CPU than its limit.
Each node in your cluster must have at least 1 cpu.
A few of the steps on this page require that the
[Heapster](https://github.com/kubernetes/heapster) service is running
in your cluster. But if you don't have Heapster running, you can do most
of the steps, and it won't be a problem if you skip the Heapster steps.
A few of the steps on this page require you to run the
[metrics-server](https://github.com/kubernetes-incubator/metrics-server)
service in your cluster. If you don't have metrics-server
running, you can skip those steps.
If you are running minikube, run the following command to enable heapster:
If you are running minikube, run the following command to enable
metrics-server:
```shell
minikube addons enable heapster
minikube addons enable metrics-server
```
To see whether the Heapster service is running, enter this command:
To see whether metrics-server (or another provider of the resource metrics
API, `metrics.k8s.io`) is running, enter this command:
```shell
kubectl get services --namespace=kube-system
kubectl get apiservices
```
If the heapster service is running, it shows in the output:
If the resource metrics API is available, the output will include a
reference to `metrics.k8s.io`.
```shell
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-system heapster 10.11.240.9 <none> 80/TCP 6d
NAME
v1beta1.metrics.k8s.io
```
{{% /capture %}}
@@ -101,26 +105,18 @@ resources:
cpu: 500m
```
Start a proxy so that you can call the heapster service:
Use `kubectl top` to fetch the metrics for the pod:
```shell
kubectl proxy
```
In another command window, get the CPU usage rate from the heapster service:
```
curl http://localhost:8001/api/v1/namespaces/kube-system/services/heapster/proxy/api/v1/model/namespaces/cpu-example/pods/cpu-demo/metrics/cpu/usage_rate
kubectl top pod memory-demo
```
The output shows that the Pod is using 974 millicpu, which is just a bit less than
the limit of 1 cpu specified in the Pod's configuration file.
```json
{
"timestamp": "2017-06-22T18:48:00Z",
"value": 974
}
```
NAME CPU(cores) MEMORY(bytes)
memory-demo 794m <something>
```
Recall that by setting `-cpu "2"`, you configured the Container to attempt to use 2 cpus.
@@ -19,28 +19,33 @@ but is not allowed to use more memory than its limit.
Each node in your cluster must have at least 300 MiB of memory.
A few of the steps on this page require that the
[Heapster](https://github.com/kubernetes/heapster) service is running
in your cluster. But if you don't have Heapster running, you can do most
of the steps, and it won't be a problem if you skip the Heapster steps.
A few of the steps on this page require you to run the
[metrics-server](https://github.com/kubernetes-incubator/metrics-server)
service in your cluster. If you don't have metrics-server
+running, you can skip those steps.
If you are running minikube, run the following command to enable heapster:
If you are running minikube, run the following command to enable
metrics-server:
```shell
minikube addons enable heapster
minikube addons enable metrics-server
```
To see whether the Heapster service is running, enter this command:
To see whether metrics-server (or another provider of the resource metrics
API, `metrics.k8s.io`) is running, enter this command:
```shell
kubectl get services --namespace=kube-system
kubectl get apiservices
```
If the Heapster service is running, it shows in the output:
If the resource metrics API is available, the output will include a
reference to `metrics.k8s.io`.
```shell
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-system heapster 10.11.240.9 <none> 80/TCP 6d
NAME
v1beta1.metrics.k8s.io
```
{{% /capture %}}
@@ -103,29 +108,20 @@ resources:
...
```
Start a proxy so that you can call the Heapster service:
Use `kubectl top` to fetch the metrics for the pod:
```shell
kubectl proxy
```
In another command window, get the memory usage from the Heapster service:
```
curl http://localhost:8001/api/v1/namespaces/kube-system/services/heapster/proxy/api/v1/model/namespaces/mem-example/pods/memory-demo/metrics/memory/usage
kubectl top pod memory-demo
```
The output shows that the Pod is using about 162,900,000 bytes of memory, which
is about 150 MiB. This is greater than the Pod's 100 MiB request, but within the
Pod's 200 MiB limit.
```json
{
"timestamp": "2017-06-20T18:54:00Z",
"value": 162856960
}
```
NAME CPU(cores) MEMORY(bytes)
memory-demo <something> 162856960
```
Delete your Pod:
@@ -0,0 +1,326 @@
---
reviewers:
- Random-Liu
- feiskyer
- mrunalp
title: Debugging Kubernetes nodes with crictl
content_template: templates/task
---
{{< toc >}}
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.11" state="stable" >}}
`crictl` is a command-line interface for CRI-compatible container runtimes.
You can use it to inspect and debug container runtimes and applications on a
Kubernetes node. `crictl` and its source are hosted in the
[cri-tools](https://github.com/kubernetes-incubator/cri-tools) repository.
{{% /capture %}}
{{% capture prerequisites %}}
`crictl` requires a Linux operating system with a CRI runtime.
{{% /capture %}}
{{% capture steps %}}
## Installing crictl
You can download a compressed archive `crictl` from the cri-tools [release
page](https://github.com/kubernetes-incubator/cri-tools/releases), for several
different architectures. Download the version that corresponds to your version
of Kubernetes. Extract it and move it to a location on your system path, such as
`/usr/local/bin/`.
## General usage
The `crictl` command has several subcommands and runtime flags. Use
`crictl help` or `crictl <subcommand> help` for more details.
`crictl` connects to `unix:///var/run/dockershim.sock` by default. For other
runtimes, you can set the endpoint in multiple different ways:
- By setting flags `--runtime-endpoint` and `--image-endpoint`
- By setting environment variables `CONTAINER_RUNTIME_ENDPOINT` and `IMAGE_SERVICE_ENDPOINT`
- By setting the endpoint in the config file `--config=/etc/crictl.yaml`
You can also specify timeout values when connecting to the server and enable or
disable debugging, by specifying `timeout` or `debug` values in the configuration
file or using the `--timeout` and `--debug` command-line flags.
To view or edit the current configuration, view or edit the contents of
`/etc/crictl.yaml`.
```sh
$ cat /etc/crictl.yaml
runtime-endpoint: unix:///var/run/dockershim.sock
image-endpoint: unix:///var/run/dockershim.sock
timeout: 10
debug: true
```
## Example crictl commands
The following examples show some `crictl` commands and and example output.
{{< warning >}}
If you use `crictl` to create pod sandboxes or containers on a running
Kubernetes cluster, the Kubelet will eventually delete them. `crictl` is not a
general purpose workflow tool, but a tool that is useful for debugging.
{{< /warning >}}
### List pods
List all pods:
```bash
crictl pods
```
```none
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
926f1b5a1d33a About a minute ago Ready sh-84d7dcf559-4r2gq default 0
4dccb216c4adb About a minute ago Ready nginx-65899c769f-wv2gp default 0
a86316e96fa89 17 hours ago Ready kube-proxy-gblk4 kube-system 0
919630b8f81f1 17 hours ago Ready nvidia-device-plugin-zgbbv kube-system 0
```
List pods by name:
```bash
crictl pods --name nginx-65899c769f-wv2gp
```
```none
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
4dccb216c4adb 2 minutes ago Ready nginx-65899c769f-wv2gp default 0
```
List pods by label:
```bash
crictl pods --label run=nginx
```
```none
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
4dccb216c4adb 2 minutes ago Ready nginx-65899c769f-wv2gp default 0
```
### List images
List all images:
```bash
crictl images
```
```none
IMAGE TAG IMAGE ID SIZE
busybox latest 8c811b4aec35f 1.15MB
k8s-gcrio.azureedge.net/hyperkube-amd64 v1.10.3 e179bbfe5d238 665MB
k8s-gcrio.azureedge.net/pause-amd64 3.1 da86e6ba6ca19 742kB
nginx latest cd5239a0906a6 109MB
```
List images by repository:
```bash
crictl images nginx
```
```none
IMAGE TAG IMAGE ID SIZE
nginx latest cd5239a0906a6 109MB
```
Only list image IDs:
```bash
crictl images -q
```
```none
sha256:8c811b4aec35f259572d0f79207bc0678df4c736eeec50bc9fec37ed936a472a
sha256:e179bbfe5d238de6069f3b03fccbecc3fb4f2019af741bfff1233c4d7b2970c5
sha256:da86e6ba6ca197bf6bc5e9d900febd906b133eaa4750e6bed647b0fbe50ed43e
sha256:cd5239a0906a6ccf0562354852fae04bc5b52d72a2aff9a871ddb6bd57553569
```
### List containers
List all containers:
```bash
crictl ps -a
```
```none
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT
1f73f2d81bf98 busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 7 minutes ago Running sh 1
9c5951df22c78 busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 8 minutes ago Exited sh 0
87d3992f84f74 nginx@sha256:d0a8828cccb73397acb0073bf34f4d7d8aa315263f1e7806bf8c55d8ac139d5f 8 minutes ago Running nginx 0
1941fb4da154f k8s-gcrio.azureedge.net/hyperkube-amd64@sha256:00d814b1f7763f4ab5be80c58e98140dfc69df107f253d7fdd714b30a714260a 18 hours ago Running kube-proxy 0
```
List running containers:
```bash
crictl ps
```
```none
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT
1f73f2d81bf98 busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 6 minutes ago Running sh 1
87d3992f84f74 nginx@sha256:d0a8828cccb73397acb0073bf34f4d7d8aa315263f1e7806bf8c55d8ac139d5f 7 minutes ago Running nginx 0
1941fb4da154f k8s-gcrio.azureedge.net/hyperkube-amd64@sha256:00d814b1f7763f4ab5be80c58e98140dfc69df107f253d7fdd714b30a714260a 17 hours ago Running kube-proxy 0
```
### Execute a command in a running container
```bash
crictl exec -i -t 1f73f2d81bf98 ls
```
```none
bin dev etc home proc root sys tmp usr var
```
### Get a coontainer's logs
Get all container logs:
```bash
crictl logs 87d3992f84f74
```
```none
10.240.0.96 - - [06/Jun/2018:02:45:49 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.96 - - [06/Jun/2018:02:45:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.96 - - [06/Jun/2018:02:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
```
Get only the latest `N` lines of logs:
```bash
crictl logs --tail=1 87d3992f84f74
```
```none
10.240.0.96 - - [06/Jun/2018:02:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
```
### Run a pod sandbox
Using `crictl` to run a pod sandbox is useful for debugging container runtimes.
On a running Kubernetes cluster, the sandbox will eventually be stopped and
deleted by the Kubelet.
1. Create a JSON file like the following:
```json
{
"metadata": {
"name": "nginx-sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb"
},
"logDirectory": "/tmp",
"linux": {
}
}
```
2. Use the `crictl runp` command to apply the JSON and run the sandbox.
```bash
crictl runp pod-config.json
```
The ID of the sandbox is returned.
### Create a container
Using `crictl` to create a container is useful for debugging container runtimes.
On a running Kubernetes cluster, the sandbox will eventually be stopped and
deleted by the Kubelet.
1. Pull a busybox image
```bash
crictl pull busybox
Image is up to date for busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47
```
2. Create configs for the pod and the container:
**Pod config**:
```yaml
{
"metadata": {
"name": "nginx-sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb"
},
"log_directory": "/tmp",
"linux": {
}
}
```
**Container config**:
```yaml
{
"metadata": {
"name": "busybox"
},
"image":{
"image": "busybox"
},
"command": [
"top"
],
"log_path":"busybox/0.log",
"linux": {
}
}
```
3. Create the container, passing the ID of the previously-created pod, the
container config file, and the pod config file. The ID of the container is
returned.
```bash
crictl create f84dd361f8dc51518ed291fbadd6db537b0496536c1d2d6c05ff943ce8c9a54f container-config.json pod-config.json
```
4. List all containers and verify that the newly-created container has its
state set to `Created`.
```bash
crictl ps -a
```
```none
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT
3e025dd50a72d busybox 32 seconds ago Created busybox 0
```
### Start a container
To start a container, pass its ID to `crictl start`:
```bash
crictl start 3e025dd50a72d956c4f14881fbb5b1080c9275674e95fb67f965f6478a957d60
```
```none
3e025dd50a72d956c4f14881fbb5b1080c9275674e95fb67f965f6478a957d60
$ crictl ps
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT
3e025dd50a72d busybox About a minute ago Running busybox 0
```
{{% /capture %}}
{{% capture discussion %}}
See [kubernetes-incubator/cri-tools](https://github.com/kubernetes-incubator/cri-tools)
for more information.
{{% /capture %}}
@@ -363,6 +363,8 @@ status:
systemUUID: ABE5F6B4-D44B-108B-C46A-24CCE16C8B6E
```
{{% /capture %}}
{{% capture whatsnext %}}
Learn about additional debugging tools, including:
@@ -372,5 +374,6 @@ Learn about additional debugging tools, including:
* [Getting into containers via `exec`](/docs/tasks/debug-application-cluster/get-shell-running-container/)
* [Connecting to containers via proxies](/docs/tasks/access-kubernetes-api/http-proxy-access-api/)
* [Connecting to containers via port forwarding](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)
* [Inspect Kubernetes node with crictl](/docs/tasks/debug-application-cluster/crictl/)
{{% /capture %}}
@@ -7,7 +7,14 @@ title: Tools for Monitoring Compute, Storage, and Network Resources
{{% capture overview %}}
Understanding how an application behaves when deployed is crucial to scaling the application and providing a reliable service. In a Kubernetes cluster, application performance can be examined at many different levels: containers, [pods](/docs/user-guide/pods), [services](/docs/user-guide/services), and whole clusters. As part of Kubernetes we want to provide users with detailed resource usage information about their running applications at all these levels. This will give users deep insights into how their applications are performing and where possible application bottlenecks may be found. In comes [Heapster](https://github.com/kubernetes/heapster), a project meant to provide a base monitoring platform on Kubernetes.
To scale and application and provide a reliable service, you need to
understand how an application behaves when it is deployed. You can examine
application performance in a Kubernetes cluster by examining the containers,
[pods](/docs/user-guide/pods), [services](/docs/user-guide/services), and
the characteristics of the overall cluster. Kubernetes provides detailed
information about an application's resource usage at each of these levels.
This information allows you to evaluate your application's performance and
where bottlenecks can be removed to improve overall performance.
{{% /capture %}}
@@ -15,11 +22,31 @@ Understanding how an application behaves when deployed is crucial to scaling the
{{% capture body %}}
Heapster is a cluster-wide aggregator of monitoring and event data. It currently supports Kubernetes natively and works on all Kubernetes setups. Heapster runs as a pod in the cluster, similar to how any Kubernetes application would run. The Heapster pod discovers all nodes in the cluster and queries usage information from the nodes' [Kubelet](/docs/admin/kubelet/)s, the on-machine Kubernetes agent. The Kubelet itself fetches the data from [cAdvisor](https://github.com/google/cadvisor). Heapster groups the information by pod along with the relevant labels. This data is then pushed to a configurable backend for storage and visualization. Currently supported backends include [InfluxDB](http://influxdb.com/) (with [Grafana](http://grafana.org/) for visualization), [Google Cloud Monitoring](https://cloud.google.com/monitoring/) and many others described in more details [here](https://git.k8s.io/heapster/docs/sink-configuration.md). The overall architecture of the service can be seen below:
In Kubernetes, application monitoring does not depend on a single monitoring
solution. On new clusters, you can use two separate pipelines to collect
monitoring statistics by default:
![overall monitoring architecture](/images/docs/monitoring-architecture.png)
- The **resource metrics pipeline** provides a limited set of metrics related
to cluster components such as the HorizontalPodAutoscaler controller, as well
as the `kubectl top` utility. These metrics are collected by
[metrics-server](https://github.com/kubernetes-incubator/metrics-server)
and are exposed via the `metrics.k8s.io` API. `metrics-server` discovers
all nodes on the cluster and queries each node's [Kubelet](/docs/admin/kubelet)
for CPU and memory usage. The Kubelet fetches the data from
[cAdvisor](https://github.com/google/cadvisor). `metrics-server` is a
lightweight short-term in-memory store.
- A **full monitoring pipeline**, such as Prometheus, gives you access to richer
metrics. In addition, Kubernetes can respond to these metrics by automatically
scaling or adapting the cluster based on its current state, using mechanisms
such as the Horizontal Pod Autoscaler. The monitoring pipeline fetches
metrics from the Kubelet, and then exposes them to Kubernetes via an adapter
by implementing either the `custom.metrics.k8s.io` or
`external.metrics.k8s.io` API. See
[Full metrics pipeline](#full-metrics-pipelines) for more information about
some popular pipelines that implement these APIs and enable these
capabilities.
Let's look at some of the other components in more detail.
### cAdvisor
@@ -33,38 +60,36 @@ On most Kubernetes clusters, cAdvisor exposes a simple UI for on-machine contain
The Kubelet acts as a bridge between the Kubernetes master and the nodes. It manages the pods and containers running on a machine. Kubelet translates each pod into its constituent containers and fetches individual container usage statistics from cAdvisor. It then exposes the aggregated pod resource usage statistics via a REST API.
## Storage Backends
## Full Metrics Pipelines
### InfluxDB and Grafana
Many full metrics solutions exist for Kubernetes. Prometheus and Google Cloud
Monitoring are two of the most popular.
A Grafana setup with InfluxDB is a very popular combination for monitoring in the open source world. InfluxDB exposes an easy to use API to write and fetch time series data. Heapster is setup to use this storage backend by default on most Kubernetes clusters. A detailed setup guide can be found [here](https://github.com/GoogleCloudPlatform/heapster/blob/master/docs/influxdb.md). InfluxDB and Grafana run in Pods. The pod exposes itself as a Kubernetes service which is how Heapster discovers it.
### Prometheus
The Grafana container serves Grafana's UI which provides an easy to configure dashboard interface. The default dashboard for Kubernetes contains an example dashboard that monitors resource usage of the cluster and the pods inside of it. This dashboard can easily be customized and expanded. Take a look at the storage schema for InfluxDB [here](https://github.com/GoogleCloudPlatform/heapster/blob/master/docs/storage-schema.md#metrics).
Here is a video showing how to monitor a Kubernetes cluster using heapster, InfluxDB and Grafana:
[![How to monitor a Kubernetes cluster using heapster, InfluxDB and Grafana](http://img.youtube.com/vi/SZgqjMrxo3g/0.jpg)](http://www.youtube.com/watch?v=SZgqjMrxo3g)
Here is a snapshot of the default Kubernetes Grafana dashboard that shows the CPU and Memory usage of the entire cluster, individual pods and containers:
![snapshot of the default Kubernetes Grafana dashboard](/images/docs/influx.png)
[Prometheus](https://prometheus.io) natively monitors Prometheus.
The [Prometheus Operator](https://coreos.com/operators/prometheus/docs/latest/)
simplifies Prometheus setup on Kubernetes, and allows you to serve the
custom metrics API using the
[Prometheus adapter](https://github.com/directxman12/k8s-prometheus-adapter).
Prometheus provides a robust query language and a built-in dashboard for
querying and visualizing your data. Prometheus is also a supported
data source for [Grafana](https://prometheus.io/docs/visualization/grafana/).
### Google Cloud Monitoring
Google Cloud Monitoring is a hosted monitoring service that allows you to visualize and alert on important metrics in your application. Heapster can be setup to automatically push all collected metrics to Google Cloud Monitoring. These metrics are then available in the [Cloud Monitoring Console](https://app.google.stackdriver.com/). This storage backend is the easiest to setup and maintain. The monitoring console allows you to easily create and customize dashboards using the exported data.
Google Cloud Monitoring is a hosted monitoring service you can use to
visualize and alert on important metrics in your application. can collect
metrics from Kubernetes, and you can access them
using the [Cloud Monitoring Console](https://app.google.stackdriver.com/).
You can create and customize dashboards to visualize the data gathered
from your Kubernetes cluster.
Here is a video showing how to setup and run a Google Cloud Monitoring backed Heapster:
This video shows how to configure and run a Google Cloud Monitoring backed Heapster:
[![how to setup and run a Google Cloud Monitoring backed Heapster](http://img.youtube.com/vi/xSMNR2fcoLs/0.jpg)](http://www.youtube.com/watch?v=xSMNR2fcoLs)
Here is a snapshot of the Google Cloud Monitoring dashboard showing cluster-wide resource usage.
![Google Cloud Monitoring dashboard](/images/docs/gcm.png)
{{< figure src="/images/docs/gcm.png" alt="Google Cloud Monitoring dashboard example" title="Google Cloud Monitoring dashboard example" caption="This dashboard shows cluster-wide resource usage." >}}
{{% /capture %}}
{{% capture whatsnext %}}
Now that you've learned a bit about Heapster, feel free to try it out on your own clusters! The [Heapster repository](https://github.com/kubernetes/heapster) is available on GitHub. It contains detailed instructions to setup Heapster and its storage backends. Heapster runs by default on most Kubernetes clusters, so you may already have it! Feedback is always welcome. Please let us know if you run into any issues via the troubleshooting [channels](/docs/troubleshooting/).
{{% /capture %}}
@@ -152,70 +152,3 @@ spec:
This will ensure that the pod will be scheduled to a node that has the GPU type
you specified.
## v1.6 and v1.7
To enable GPU support in 1.6 and 1.7, a special **alpha** feature gate
`Accelerators` has to be set to true across the system:
`--feature-gates="Accelerators=true"`. It also requires using the Docker
Engine as the container runtime.
Further, the Kubernetes nodes have to be pre-installed with NVIDIA drivers.
Kubelet will not detect NVIDIA GPUs otherwise.
When you start Kubernetes components after all the above conditions are true,
Kubernetes will expose `alpha.kubernetes.io/nvidia-gpu` as a schedulable
resource.
You can consume these GPUs from your containers by requesting
`alpha.kubernetes.io/nvidia-gpu` just like you request `cpu` or `memory`.
However, there are some limitations in how you specify the resource requirements
when using GPUs:
- GPUs are only supposed to be specified in the `limits` section, which means:
* You can specify GPU `limits` without specifying `requests` because
Kubernetes will use the limit as the request value by default.
* You can specify GPU in both `limits` and `requests` but these two values
must be equal.
* You cannot specify GPU `requests` without specifying `limits`.
- Containers (and pods) do not share GPUs. There's no overcommitting of GPUs.
- Each container can request one or more GPUs. It is not possible to request a
fraction of a GPU.
When using `alpha.kubernetes.io/nvidia-gpu` as the resource, you also have to
mount host directories containing NVIDIA libraries (libcuda.so, libnvidia.so
etc.) to the container.
Here's an example:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
# https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
alpha.kubernetes.io/nvidia-gpu: 1 # requesting 1 GPU
volumeMounts:
- name: "nvidia-libraries"
mountPath: "/usr/local/nvidia/lib64"
volumes:
- name: "nvidia-libraries"
hostPath:
path: "/usr/lib/nvidia-375"
```
The `Accelerators` feature gate and `alpha.kubernetes.io/nvidia-gpu` resource
works on 1.8 and 1.9 as well. It will be deprecated in 1.10 and removed in
1.11.
## Future
- Support for hardware accelerators in Kubernetes is still in alpha.
- Better APIs will be introduced to provision and consume accelerators in a scalable manner.
- Kubernetes will automatically ensure that applications consuming GPUs get the best possible performance.
{{% /capture %}}
@@ -25,10 +25,10 @@ This document walks you through an example of enabling Horizontal Pod Autoscaler
{{% capture prerequisites %}}
This example requires a running Kubernetes cluster and kubectl, version 1.2 or later.
[Heapster](https://github.com/kubernetes/heapster) monitoring needs to be deployed in the cluster
as Horizontal Pod Autoscaler uses it to collect metrics
(if you followed [getting started on GCE guide](/docs/getting-started-guides/gce),
heapster monitoring will be turned-on by default).
[metrics-server](https://github.com/kubernetes/heapster) monitoring needs to be deployed in the cluster
to provide metrics via the resource metrics API, as Horizontal Pod Autoscaler uses this API to collect metrics
(if you followed [getting started on GCE guide](/docs/getting-started-guides/gce.md),
metrics-server monitoring will be turned-on by default).
To specify multiple resource metrics for a Horizontal Pod Autoscaler, you must have a Kubernetes cluster
and kubectl at version 1.6 or later. Furthermore, in order to make use of custom metrics, your cluster
@@ -212,7 +212,7 @@ Notice that the `targetCPUUtilizationPercentage` field has been replaced with an
The CPU utilization metric is a *resource metric*, since it is represented as a percentage of a resource
specified on pod containers. Notice that you can specify other resource metrics besides CPU. By default,
the only other supported resource metric is memory. These resources do not change names from cluster
to cluster, and should always be available, as long as Heapster is deployed.
to cluster, and should always be available, as long as the `metrics.k8s.io` API is available.
You can also specify resource metrics in terms of direct values, instead of as percentages of the
requested value. To do so, use the `targetAverageValue` field instead of the `targetAverageUtilization`
@@ -60,19 +60,16 @@ or the custom metrics API (for all other metrics).
* For object metrics, a single metric is fetched (which describes the object
in question), and compared to the target value, to produce a ratio as above.
The HorizontalPodAutoscaler controller can fetch metrics in two different ways: direct Heapster
access, and REST client access.
The HorizontalPodAutoscaler normally fetches metrics a series of aggregated APIs (`metrics.k8s.io`,\
`custom.metrics.k8s.io`, and `external.metrics.k8s.io`). It can also fetch metrics directly
from Heapster. Fetching metrics from Heapster is deprecated as of Kubernetes 1.11.
When using direct Heapster access, the HorizontalPodAutoscaler queries Heapster directly
through the API server's service proxy subresource. Heapster needs to be deployed on the
cluster and running in the kube-system namespace.
See [Support for custom metrics](#support-for-custom-metrics) for more details on REST client access.
The autoscaler accesses corresponding replication controller, deployment or replica set by scale sub-resource.
Scale is an interface that allows you to dynamically set the number of replicas and examine each of their current states.
More details on scale sub-resource can be found [here](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#scale-subresource).
See [Support for metrics APIs](#support-for-metrics-apis) for more details.
The autoscaler accesses corresponding scalable controllers (such as replication controllers, deployments, and replica sets)
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. More details on scale sub-resource can be found
[here](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#scale-subresource).
## API Object
@@ -158,30 +155,27 @@ Kubernetes 1.6 adds support for making use of custom metrics in the Horizontal P
You can add custom metrics for the Horizontal Pod Autoscaler to use in the `autoscaling/v2beta1` API.
Kubernetes then queries the new custom metrics API to fetch the values of the appropriate custom metrics.
### Requirements
See [Support for metrics APIs](#support-for-metrics-APIs) for the requirements.
To use custom metrics with your Horizontal Pod Autoscaler, you must set the necessary configurations when deploying your cluster:
## Support for metrics APIs
* [Enable the API aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/) if you have not already done so.
By default, the HorizontalPodAutoscaler controller retrieves metrics from a series of APIs. In order for it to access these
APIs, cluster administrators must ensure that:
* Register your resource metrics API, your
custom metrics API and, optionally, external metrics API with the API aggregation layer. All of these API servers must be running *on* your cluster.
* The [API aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/) is enabled.
* *Resource Metrics API*: You can use Heapster's implementation of the resource metrics API, by running Heapster with its `--api-server` flag set to true.
* The corresponding APIs are registered:
* *Custom Metrics API*: This must be provided by a separate component. To get started with boilerplate code, see the [kubernetes-incubator/custom-metrics-apiserver](https://github.com/kubernetes-incubator/custom-metrics-apiserver) and the [k8s.io/metrics](https://github.com/kubernetes/metrics) repositories.
* For resource metrics, this is the `metrics.k8s.io` API, generally provided by [metrics-server](https://github.com/kubernetes-incubator/metrics-server).
It can be launched as a cluster addon.
* *External Metrics API*: Starting from Kubernetes 1.10 you can use this API if you need to autoscale on metrics not related to any Kubernetes object. Similarly to *Custom Metrics API* this must be provided by a separate component.
* For custom metrics, this is the `custom.metrics.k8s.io` API. It's provided by "adapter" API servers provided by metrics solution vendors.
Check with your metrics pipeline, or the [list of known solutions](https://github.com/kubernetes/metrics/blob/master/IMPLEMENTATIONS.md#custom-metrics-api).
If you would like to write your own, check out the [boilerplate](https://github.com/kubernetes-incubator/custom-metrics-apiserver) to get started.
* Set the appropriate flags for kube-controller-manager:
* For external metrics, this is the `external.metrics.k8s.io` API. It may be provided by the custom metrics adapters provided above.
* `--horizontal-pod-autoscaler-use-rest-clients` should be true.
* `--kubeconfig <path-to-kubeconfig>` OR `--master <ip-address-of-apiserver>`
Note that either the `--master` or `--kubeconfig` flag can be used; `--master` will override `--kubeconfig` if both are specified. These flags specify the location of the API aggregation layer, allowing the controller manager to communicate to the API server.
In Kubernetes 1.7, the standard aggregation layer that Kubernetes provides runs in-process with the kube-apiserver, so the target IP address can be found with `kubectl get pods --selector k8s-app=kube-apiserver --namespace kube-system -o jsonpath='{.items[0].status.podIP}'`.
* The `--horizontal-pod-autoscaler-use-rest-clients` is `true` or unset. Setting this to false switches to Heapster-based autoscaling, which is deprecated.
{{% /capture %}}