Release 1.8 (#5659)

* GC now supports non-core resources

* Add two examples about how to analysis audits of kube-apiserver (#4264)

* Deprecate system:nodes binding

* [1.8] StatefulSet `initialized` annotation is now ignored.

* inits the kubeadm upgrade docs

addresses kubernetes/kubernetes.github.io/issues/4689

* adds kubeadm upgrade cmd to ToC

addresses kubernetes/kubernetes.github.io/issues/4689

* add workload placement docs

* ScaleIO - document udpate for 1.8

* Add documentation on storageClass.mountOptions and PV.mountOptions (#5254)

* Add documentation on storageClass.mountOptions and PV.mountOptions

* convert notes into callouts

* Add docs for CustomResource validation

add info about supported fields

* advanced audit beta features (#5300)

* Update job workload doc with backoff failure policy (#5319)

Add to the Jobs documentation how to use the new backoffLimit field that
limit the number of Pod failure before considering the Job as failed.

* Documented additional AWS Service annotations (#4864)

* Add device plugin doc under concepts/cluster-administration. (#5261)

* Add device plugin doc under concepts/cluster-administration.

* Update device-plugins.md

* Update device-plugins.md

Add meta description. Fix typo. Change bare metal deployment to manual deployment.

* Update device-plugins.md

Fix typo again.

* Update page.version. (#5341)

* Add documentation on storageClass.reclaimPolicy (#5171)

* [Advanced audit] use new herf for audit-api (#5349)

This tag contains all the changes in v1beta1 version. Update it now.

* Added documentation around creating the InitializerConfiguration for the persistent volume label controller in the cloud-controller-manager (#5255)

* Documentation for kubectl plugins (#5294)

* Documentation for kubectl plugins

* Update kubectl-plugins.md

* Update kubectl-plugins.md

* Updated CPU manager docs to match implementation. (#5332)

* Noted limitation of alpha static cpumanager.

* Updated CPU manager docs to match implementation.

- Removed references to CPU pressure node condition and evictions.
- Added note about new --cpu-manager-reconcile-period flag.
- Added note about node allocatable requirements for static policy.
- Noted limitation of alpha static cpumanager.

* Move cpu-manager task link to rsc mgmt section.

* init containers annotation removed in  1.8 (#5390)

* Add documentation for TaintNodesByCondition (#5352)

* Add documentation for TaintNodesByCondition

* Update nodes.md

* Update taint-and-toleration.md

* Update daemonset.md

* Update nodes.md

* Update taint-and-toleration.md

* Update daemonset.md

* Fix deployments (#5421)

* Document extended resources and OIR deprecation. (#5399)

* Document extended resources and OIR deprecation.

* Updated extended resources doc per reviews.

* reverts extra spacing in _data/tasks.yml

* addresses `kubeadm upgrade` review comments

Feedback from @chenopis, @luxas, and @steveperry-53 addressed with this commit

* HugePages documentation (#5419)

* Update cpu-management-policies.md (#5407)

Fixed the bad link.
Modified "cpu" to "CPU".
Added more 'yaml' as supplement.

* Update RBAC docs for v1 (#5445)

* Add user docs for pod priority and preemption (#5328)

* Add user docs for pod priority and preemption

* Update pod-priority-preemption.md

* More updates

* Update docs/admin/kubeadm.md for 1.8 (#5440)

- Made a couple of minor wording changes (not strictly 1.8 related).
 - Did some reformatting (not strictly 1.8 related).
 - Updated references to the default token TTL (was infinite, now 24 hours).
 - Documented the new `--discovery-token-ca-cert-hash` and `--discovery-token-unsafe-skip-ca-verification` flags for `kubeadm join`.
 - Added references to the new `--discovery-token-ca-cert-hash` flag in all the default examples.
 - Added a new _Security model_ section that describes the security tradeoffs of the various discovery modes.
 - Documented the new `--groups` flag for `kubeadm token create`.
 - Added a note of caution under _Automating kubeadm_ that references the _Security model_ section.
 - Updated the component version table to drop 1.6 and add 1.8.
 - Update `_data/reference.yml` to try to get the sidebar fixed up and more consistent with `kubefed`.

* Update StatefulSet Basics for 1.8 release (#5398)

* addresses `kubeadm upgrade` review comments

2nd iteration review comments by @luxas

* adds kubelet upgrade section to kubeadm upgrade

* Fix a bulleted list on docs/admin/kubeadm.md. (#5458)

I updated this doc yesterday and I was absolutely sure I fixed this, but I just saw that this commit got lost somehow.

This was introduced recently in https://github.com/kubernetes/kubernetes.github.io/pull/5440.

* Clarify the API to check for device plugins

* Moving Flexvolume to separate out-of-tree section

* addresses `kubeadm upgrade` review comments

CC: @luxas

* fixes kubeadm upgrade index

* Update Stackdriver Logging documentation (#5495)

* Re-update WordPress and MySQL PV doc to use apps/v1beta2 APIs (#5526)

* Update statefulset concepts doc to use apps/v1beta2 APIs (#5420)

* add document on kubectl's behavior regarding initializers (#5505)

* Update docs/admin/kubeadm.md to cover self-hosting in 1.8. (#5497)

This is a new beta feature in 1.8.

* Update kubectl patch doc to use apps/v1beta2 APIs (#5422)

* [1.8] Update "Run Applications" tasks to apps/v1beta2. (#5525)

* Update replicated stateful application task for 1.8.

* Update single instance stateful app task for 1.8.

* Update stateless app task for 1.8.

* Update kubectl patch task for 1.8.

* fix the link of persistent storage (#5515)

* update the admission-controllers.md index.md what-is-kubernetes.md link

* fix the link of persistent storage

* Add quota support for local ephemeral storage (#5493)

* Add quota support for local ephemeral storage

update the doc to this alpha feature

* Update resource-quotas.md

* Updated Deployments concepts doc (#5491)

* Updated Deployments concepts doc

* Addressed comments

* Addressed more comments

* Modify allocatable storage to ephemeral-storage (#5490)

Update the doc to use ephemeral-storage instead of storage

* Revamped concepts doc for ReplicaSet (#5463)

* Revamped concepts doc for ReplicaSet

* Minor changes to call out specific versions for selector defaulting and
immutability

* Addressed doc review comments

* Remove petset documentations (#5395)

* Update docs to use batch/v1beta1 cronjobs (#5475)

* add federation job doc (#5485)

* add federation job doc

* Update job.md

Edits for clarity and consistency

* Update job.md

Fixed a typo

* update DaemonSet concept for 1.8 release (#5397)

* update DaemonSet concept for 1.8 release

* Update daemonset.md

Fix typo. than -> then

* Update bootstrap tokens doc for 1.8. (#5479)

* Update bootstrap tokens doc for 1.8.

This has some changes I missed when I was updating the main kubeadm documention:
 - Bootstrap tokens are now beta, not alpha (https://github.com/kubernetes/features/issues/130)
 - The apiserver flag to enable the authenticator changedin 1.8 (https://github.com/kubernetes/kubernetes/pull/51198)
 - Added `auth-extra-groups` documentaion (https://github.com/kubernetes/kubernetes/pull/50933)
 - Updated the _Token Management with `kubeadm`_ section to link to the main kubeadm docs, since it was just duplicated information.

* Update bootstrap-tokens.md

* Updated the Cassandra tutorial to use apps/v1beta2 (#5548)

* add docs for AllowPrivilegeEscalation (#5448)

Signed-off-by: Jess Frazelle <acidburn@microsoft.com>

* Add local ephemeral storage alpha feature in managing compute resource (#5522)

* Add local ephemeral storage alpha feature in managing compute resource

Since 1.8, we add the local ephemeral storage alpha feature as one
resource type to manage. Add this feature into the doc.

* Update manage-compute-resources-container.md

* Update manage-compute-resources-container.md

* Update manage-compute-resources-container.md

* Update manage-compute-resources-container.md

* Update manage-compute-resources-container.md

* Update manage-compute-resources-container.md

* Added documentation for Metrics Server (#5560)

* authorization: improve authorization debugging docs (#5549)

* Document mount propagation (#5544)

* Update /docs/setup/independent/create-cluster-kubeadm.md for 1.8. (#5524)

This introduction needed a couple of small tweaks to cover the `--discovery-token-ca-cert-hash` flag added in https://github.com/kubernetes/kubernetes/pull/49520 and some version bumps.

* Add task doc for alpha dynamic kubelet configuration (#5523)

* Fix input/output of selfsubjectaccess review (#5593)

* Add docs for implementing resize (#5528)

* Add docs for implementing resize

* Update admission-controllers.md

* Added link to PVC section

* minor typo fixes

* Update NetworkPolicy concept guide with egress and CIDR changes (#5529)

* update zookeeper tutorial for 1.8 release

* add doc for hostpath type (#5503)

* Federated Hpa feature doc (#5487)

* Federated Hpa feature doc

* Federated Hpa feature doc review fixes

* Update hpa.md

* Update hpa.md

* update cloud controller manager docs for v1.8

* Update cronjob with defaults information (#5556)

* Kubernetes 1.8 reference docs (#5632)

* Kubernetes 1.8 reference docs

* Kubectl reference docs for 1.8

* Update side bar with 1.8 kubectl and api ref docs links

* remove petset.md

* update on state of HostAlias in 1.8 with hostNetwork Pod support (#5644)

* Fix cron job deletion section (#5655)

* update imported docs (#5656)

* Add documentation for certificate rotation. (#5639)

* Link to using kubeadm page

* fix the command output

fix the command output

* fix typo in api/resources reference: "Worloads"

* Add documentation for certificate rotation.

* Create TOC entry for cloud controller manager. (#5662)

* Updates for new versions of API types

* Followup 5655: fix link to garbage collection (#5666)

* Temporarily redirect resources-reference to api-reference. (#5668)

* Update config for 1.8 release. (#5661)

* Update config for 1.8 release.

* Address reviewer comments.

* Switch references in HPA docs from alpha to beta (#5671)

The HPA docs still referenced the alpha version.  This switches them to
talk about v2beta1, which is the appropriate version for Kubernetes 1.8

* Deprecate openstack heat (#5670)

* Fix typo in pod preset conflict example

Move container port definition to the correct line.

* Highlight openstack-heat provider deprecation

The openstack-heat provider for kube-up is being deprecated and will be
removed in a future release.

* Temporarily fix broken links by redirecting. (#5672)

* Fix broken links. (#5675)

* Fix render of code block (#5674)

* Fix broken links. (#5677)

* Add a small note about auto-bootstrapped CSR ClusterRoles (#5660)

* Update kubeadm install doc for v1.8 (#5676)

* add draft workloads api content for 1.8 (#5650)

* add draft workloads api content for 1.8

* edits per review, add tables, for 1.8 workloads api doc

* fix typo

* Minor fixes to kubeadm 1.8 upgrade guide. (#5678)

- The kubelet upgrade instructions should be done on every host, not
  just worker nodes.
- We should just upgrade all packages, instead of calling out kubelet
  specifically. This will also upgrade kubectl, kubeadm, and
  kubernetes-cni, if installed.
- Draining nodes should also ignore daemonsets, and master errors can be
  ignored.
- Make sure that the new kubeadm download is chmoded correctly.
- Add a step to run `kubeadm version` to verify after downloading.
- Manually approve new kubelet CSRs if rotation is enabled (known issue).

* Release 1.8 (#5680)

* Fix versions for 1.8 API ref docs

* Updates for 1.8 kubectl reference docs

* Kubeadm /docs/admin/kubeadm.md cleanup, editing. (#5681)

* Update docs/admin/kubeadm.md (mostly 1.8 related).

This is Fabrizio's work, which I'm committing along with my edits (in a commit on top of this).

* A few of my own edits to clarify and clean up some Markdown.
This commit is contained in:
Steve Perry
2017-09-28 21:46:51 -07:00
committed by GitHub
parent 88d3ed821d
commit 799eaf4229
1553 changed files with 318572 additions and 3286 deletions
+24 -1
View File
@@ -66,7 +66,27 @@ The node condition is represented as a JSON object. For example, the following r
If the Status of the Ready condition is "Unknown" or "False" for longer than the `pod-eviction-timeout`, an argument is passed to the [kube-controller-manager](/docs/admin/kube-controller-manager) and all of the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on it. The decision to delete the pods cannot be communicated to the kubelet until it re-establishes communication with the apiserver. In the meantime, the pods which are scheduled for deletion may continue to run on the partitioned node.
In versions of Kubernetes prior to 1.5, the node controller would [force delete](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods) these unreachable pods from the apiserver. However, in 1.5 and higher, the node controller does not force delete pods until it is confirmed that they have stopped running in the cluster. One can see these pods which may be running on an unreachable node as being in the "Terminating" or "Unknown" states. In cases where Kubernetes cannot deduce from the underlying infrastructure if a node has permanently left a cluster, the cluster administrator may need to delete the node object by hand. Deleting the node object from Kubernetes causes all the Pod objects running on it to be deleted from the apiserver, freeing up their names.
In versions of Kubernetes prior to 1.5, the node controller would [force delete](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods)
these unreachable pods from the apiserver. However, in 1.5 and higher, the node controller does not force delete pods until it is
confirmed that they have stopped running in the cluster. One can see these pods which may be running on an unreachable node as being in
the "Terminating" or "Unknown" states. In cases where Kubernetes cannot deduce from the underlying infrastructure if a node has
permanently left a cluster, the cluster administrator may need to delete the node object by hand. Deleting the node object from
Kubernetes causes all the Pod objects running on it to be deleted from the apiserver, freeing up their names.
Version 1.8 introduces an alpha feature that automatically creates
[taints](/docs/concepts/configuration/taint-and-toleration) that represent conditions.
To enable this behavior, pass an additional feature gate flag `--feature-gates=...,TaintNodesByCondition=true`
to the API server, controller manager, and scheduler.
When `TaintNodesByCondition` is enabled, the scheduler ignores conditions when considering a Node; instead
it looks at the Node's taints and a Pod's tolerations.
Now users can choose between the old scheduling model and a new, more flexible scheduling model.
A Pod that does not have any tolerations gets scheduled according to the old model. But a Pod that
tolerates the taints of a particular Node can be scheduled on that Node.
Note that because of small delay, usually less than one second, between time when condition is observed and a taint
is created, it's possible that enabling this feature will slightly increase number of Pods that are successfully
scheduled but rejected by the kubelet.
### Capacity
@@ -175,6 +195,9 @@ NodeController is responsible for adding taints corresponding to node problems l
node unreachable or not ready. See [this documentation](/docs/concepts/configuration/taint-and-toleration)
for details about `NoExecute` taints and the alpha feature.
Starting in version 1.8, the node controller can be made responsible for creating taints that represent
Node conditions. This is an alpha feature of version 1.8.
### Self-Registration of Nodes
When the kubelet flag `--register-node` is true (the default), the kubelet will attempt to
@@ -0,0 +1,114 @@
---
approvers:
title: Device Plugins
description: Use the Kubernetes device plugin framework to implement plugins for GPUs, NICs, FPGAs, InfiniBand, and similar resources that require vendor-specific setup.
---
{% include feature-state-alpha.md %}
{% capture overview %}
Starting in version 1.8, Kubernetes provides a [device plugin framework](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/device-plugin.md)
for vendors to advertise their resources to the kubelet without changing Kubernetes core code.
Instead of writing custom Kubernetes code, vendors can implement a device plugin that can
be deployed manually or as a DaemonSet. The targeted devices include GPUs,
High-performance NICs, FPGAs, InfiniBand, and other similar computing resources
that may require vendor specific initialization and setup.
{% endcapture %}
{% capture body %}
## Device plugin registration
The device plugins feature is gated by the `DevicePlugins` feature gate and is disabled by default.
When the device plugins feature is enabled, the kubelet exports a `Registration` gRPC service:
```gRPC
service Registration {
rpc Register(RegisterRequest) returns (Empty) {}
}
```
A device plugin can register itself with the kubelet through this gRPC service.
During the registration, the device plugin needs to send:
* The name of its Unix socket.
* The Device Plugin API version against which it was built.
* The `ResourceName` it wants to advertise. Here `ResourceName` needs to follow the
[extended resource naming scheme](https://github.com/kubernetes/kubernetes/pull/48922)
as `vendor-domain/resource`.
For example, an Nvidia GPU is advertised as `nvidia.com/gpu`.
Following a successful registration, the device plugin sends the kubelet the
list of devices it manages, and the kubelet is then in charge of advertising those
resources to the API server as part of the kubelet node status update.
For example, after a device plugin registers `vendor-domain/foo` with the kubelet
and reports two healthy devices on a node, the node status is updated
to advertise 2 `vendor-domain/foo`.
Then, developers can request devices in a
[Container](/docs/api-reference/{{page.version}}/#container-v1-core)
specification by using the same process that is used for
[opaque integer resources](/docs/tasks/configure-pod-container/opaque-integer-resource/).
In version 1.8, extended resources are spported only as integer resources and must have
`limit` equal to `request` in the Container specification.
## Device plugin implementation
The general workflow of a device plugin includes the following steps:
* Initialization. During this phase, the device plugin performs vendor specific
initialization and setup to make sure the devices are in a ready state.
* The plugin starts a gRPC service, with a Unix socket under host path
`/var/lib/kubelet/device-plugins/`, that implements the following interfaces:
```gRPC
service DevicePlugin {
// ListAndWatch returns a stream of List of Devices
// Whenever a Device state change or a Device disapears, ListAndWatch
// returns the new list
rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
// Allocate is called during container creation so that the Device
// Plugin can run device specific operations and instruct Kubelet
// of the steps to make the Device available in the container
rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
}
```
* The plugin registers itself with the kubelet through the Unix socket at host
path `/var/lib/kubelet/device-plugins/kubelet.sock`.
* After successfully registering itself, the device plugin runs in serving mode, during which it keeps
monitoring device health and reports back to the kubelet upon any device state changes.
It is also responsible for serving `Allocate` gRPC requests. During `Allocate`, the device plugin may
do device-specific preparation; for example, GPU cleanup or QRNG initialization.
If the operations succeed, the device plugin returns an `AllocateResponse` that contains container
runtime configurations for accessing the allocated devices. The kubelet passes this information
to the container runtime.
A device plugin is expected to detect kubelet restarts and re-register itself with the new
kubelet instance. In version 1.8, a new kubelet instance cleans up all the existing Unix sockets
under `/var/lib/kubelet/device-plugins` when it starts. A device plugin can monitor the deletion
of its Unix socket and re-register itself upon such an event.
## Device plugin deployment
A device plugin can be deployed manually or as a DaemonSet. Being deployed as a DaemonSet has
the benefit that Kubernetes can restart the device plugin if it fails.
Otherwise, an extra mechanism is needed to recover from device plugin failures.
The canonical directory `/var/lib/kubelet/device-plugins` requires privileged access,
so a device plugin must run in a privileged security context.
If a device plugin is running as a DaemonSet, `/var/lib/kubelet/device-plugins`
must be mounted as a
[Volume](/docs/api-reference/{{page.version}}/#volume-v1-core)
in the plugin's
[PodSpec](/docs/api-reference/{{paage.version}}/#podspec-v1-core).
## Examples
For an example device plugin implementation, see
[nvidia GPU device plugin for COS base OS](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/nvidia_gpu).
{% endcapture %}
{% include templates/concept.md %}
@@ -91,7 +91,9 @@ The following guides explain some of the resources in detail:
* [DaemonSets](/docs/tasks/administer-federation/daemonset/)
* [Deployment](/docs/tasks/administer-federation/deployment/)
* [Events](/docs/tasks/administer-federation/events/)
* [Hpa](/docs/tasks/administer-federation/hpa/)
* [Ingress](/docs/tasks/administer-federation/ingress/)
* [Jobs](/docs/tasks/administer-federation/job/)
* [Namespaces](/docs/tasks/administer-federation/namespaces/)
* [ReplicaSets](/docs/tasks/administer-federation/replicaset/)
* [Secrets](/docs/tasks/administer-federation/secret/)
@@ -303,7 +303,67 @@ LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-0
You can see that the Container was terminated because of `reason:OOM Killed`,
where `OOM` stands for Out Of Memory.
## Opaque integer resources (Alpha feature)
## Local ephemeral storage (alpha feature)
Kubernetes version 1.8 introduces a new resource, _ephemeral-storage_ for managing local ephemeral storage. In each Kubernetes node, kubelet's root directory (/var/lib/kubelet by default) and log directory (/var/log) are stored on the root partition of the node. This partition is also shared and consumed by pods via EmptyDir volumes, container logs, image layers and container writable layers.
This partition is “ephemeral” and applications cannot expect any performance SLAs (Disk IOPS for example) from this partition. Local ephemeral storage management only applies for the root partition; the optional partition for image layer and writable layer is out of scope.
**Note:** If an optional runntime partition is used, root parition will not hold any image layer or writable layers.
{: .note}
### Requests and limits setting for local ephemeral storage
Each Container of a Pod can specify one or more of the following:
* `spec.containers[].resources.limits.ephemeral-storage`
* `spec.containers[].resources.requests.ephemeral-storage`
Limits and requests for `ephemeral-storage` are measured in bytes. You can express storage as
a plain integer or as a fixed-point integer using one of these suffixes:
E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi,
Mi, Ki. For example, the following represent roughly the same value:
```shell
128974848, 129e6, 129M, 123Mi
```
For example, the following Pod has two Containers. Each Container has a request of 2GiB of local ephemeral storage. Each Container has a limit of 4GiB of local ephemeral storage. Therefore, the Pod has a request of 4GiB of local ephemeral storage, and a limit of 8GiB of storage.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
- name: wp
image: wordpress
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
```
### How Pods with ephemeral-storage requests are scheduled
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. (For more information, see ["Node Allocatable"](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node.
### How Pods with ephemeral-storage limits run
For container-level isolation, if a Container's writable layer and logs usage exceeds its storage limit, the pod will be evicted. For pod-level isolation, if the sum of the local ephemeral storage usage from all containers and also the pod's EmptyDir volumes exceeds the limit, the pod will be evicted.
## Opaque integer resources (alpha feature)
{% include feature-state-deprecated.md %}
Kubernetes version 1.5 introduces Opaque integer resources. Opaque
integer resources allow cluster operators to advertise new node-level
@@ -313,9 +373,12 @@ Users can consume these resources in Pod specs just like CPU and memory.
The scheduler takes care of the resource accounting so that no more than the
available amount is simultaneously allocated to Pods.
**Note:** Opaque integer resources are Alpha in Kubernetes version 1.5.
Only resource accounting is implemented; node-level isolation is still
under active development.
**Note:** Opaque Integer Resources will be removed in version 1.9.
[Extended Resources](#extended-resources) are a replacement for Opaque Integer
Resources. Users can use any domain name prefix outside of the `kubernetes.io/`
domain instead of the previous `pod.alpha.kubernetes.io/opaque-int-resource-`
prefix.
{: .note}
Opaque integer resources are resources that begin with the prefix
`pod.alpha.kubernetes.io/opaque-int-resource-`. The API server
@@ -339,22 +402,9 @@ first pod that requests the resource to be scheduled on that node.
**Example:**
Here is an HTTP request that advertises five "foo" resources on node `k8s-node-1` whose master is `k8s-master`.
```http
PATCH /api/v1/nodes/k8s-node-1/status HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Host: k8s-master:8080
[
{
"op": "add",
"path": "/status/capacity/pod.alpha.kubernetes.io~1opaque-int-resource-foo",
"value": "5"
}
]
```
Here is an example showing how to use `curl` to form an HTTP request that
advertises five "foo" resources on node `k8s-node-1` whose master is
`k8s-master`.
```shell
curl --header "Content-Type: application/json-patch+json" \
@@ -395,6 +445,92 @@ spec:
pod.alpha.kubernetes.io/opaque-int-resource-foo: 1
```
## Extended Resources
Kubernetes version 1.8 introduces Extended Resources. Extended Resources are
fully-qualified resource names outside the `kubernetes.io` domain. Extended
Resources allow cluster operators to advertise new node-level resources that
would be otherwise unknown to the system. Extended Resource quantities must be
integers and cannot be overcommitted.
Users can consume Extended Resources in Pod specs just like CPU and memory.
The scheduler takes care of the resource accounting so that no more than the
available amount is simultaneously allocated to Pods.
The API server restricts quantities of Extended Resources to whole numbers.
Examples of _valid_ quantities are `3`, `3000m` and `3Ki`. Examples of
_invalid_ quantities are `0.5` and `1500m`.
**Note:** Extended Resources replace [Opaque Integer
Resources](#opaque-integer-resources-alpha-feature). Users can use any domain
name prefix outside of the `kubernetes.io/` domain instead of the previous
`pod.alpha.kubernetes.io/opaque-int-resource-` prefix.
{: .note}
There are two steps required to use Extended Resources. First, the
cluster operator must advertise a per-node Extended Resource on one or more
nodes. Second, users must request the Extended Resource in Pods.
To advertise a new Extended Resource, the cluster operator should
submit a `PATCH` HTTP request to the API server to specify the available
quantity in the `status.capacity` for a node in the cluster. After this
operation, the node's `status.capacity` will include a new resource. The
`status.allocatable` field is updated automatically with the new resource
asynchronously by the kubelet. Note that because the scheduler uses the
node `status.allocatable` value when evaluating Pod fitness, there may
be a short delay between patching the node capacity with a new resource and the
first pod that requests the resource to be scheduled on that node.
**Example:**
Here is an example showing how to use `curl` to form an HTTP request that
advertises five "example.com/foo" resources on node `k8s-node-1` whose master
is `k8s-master`.
```shell
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
http://k8s-master:8080/api/v1/nodes/k8s-node-1/status
```
**Note**: In the preceding request, `~1` is the encoding for the character `/`
in the patch path. The operation path value in JSON-Patch is interpreted as a
JSON-Pointer. For more details, see
[IETF RFC 6901, section 3](https://tools.ietf.org/html/rfc6901#section-3).
{: .note}
To consume an Extended Resource in a Pod, include the resource name as a key
in the `spec.containers[].resources.requests` map.
**Note:** Extended resources cannot be overcommitted, so request and limit
must be equal if both are present in a container spec.
{: .note}
The Pod is scheduled only if all of the resource requests are
satisfied, including cpu, memory and any Extended Resources. The Pod will
remain in the `PENDING` state as long as the resource request cannot be met by
any node.
**Example:**
The Pod below requests 2 cpus and 1 "example.com/foo" (an extended resource.)
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
```
## Planned Improvements
Kubernetes version 1.5 only allows resource quantities to be specified on a
@@ -0,0 +1,239 @@
---
approvers:
- davidopp
- wojtek-t
title: Pod Priority and Preemption
---
{% capture overview %}
{% include feature-state-alpha.md %}
[Pods](/docs/user-guide/pods) in Kubernetes 1.8 and later can have priority. Priority
indicates the importance of a Pod relative to other Pods. When a Pod cannot be scheduled,
the scheduler tries to preempt (evict) lower priority Pods to make scheduling of the
pending Pod possible. In a future Kubernetes release, priority will also affect
out-of-resource eviction ordering on the Node.
**Note:** Preemption does not respect PodDisruptionBudget; see
[the limitations section](#poddisruptionbudget-is-not-supported) for more details.
{: .note}
{% endcapture %}
{% capture body %}
## How to use priority and preemption
To use priority and preemption in Kubernetes 1.8, follow these steps:
1. Enable the feature.
1. Add one or more PriorityClasses.
1. Create Pods with `PriorityClassName` set to one of the added PriorityClasses.
Of course you do not need to create the Pods directly; normally you would add
`PriorityClassName` to the Pod template of a collection object like a Deployment.
The following sections provide more information about these steps.
## Enabling priority and preemption
Pod priority and preemption is disabled by default in Kubernetes 1.8.
To enable the feature, set this command-line flag for the API server
and the scheduler:
```
--feature-gates=PodPriority=true
```
Also set this flag for API server:
```
--runtime-config=scheduling.k8s.io/v1alpha1=true
```
After the feature is enabled, you can create [PriorityClasses](#priorityclass)
and create Pods with [`PriorityClassName`](#pod-priority) set.
If you try the feature and then decide to disable it, you must remove the PodPriority
command-line flag or set it to false, and then restart the API server and
scheduler. After the feature is disabled, the existing Pods keep their priority
fields, but preemption is disabled, and priority fields are ignored, and you
cannot set PriorityClassName in new Pods.
## PriorityClass
A PriorityClass is a non-namespaced object that defines a mapping from a priority
class name to the integer value of the priority. The name is specified in the `name`
field of the PriorityClass object's metadata. The value is specified in the required
`value` field. The higher the value, the higher the priority.
A PriorityClass object can have any 32-bit integer value smaller than or equal to
1 billion. Larger numbers are reserved for critical system Pods that should not
normally be preempted or evicted. A cluster admin should create one PriorityClass
object for each such mapping that they want.
PriorityClass also has two optional fields: `globalDefault` and `description`.
The `globalDefault` field indicates that the value of this PriorityClass should
be used for Pods without a `PriorityClassName`. Only one PriorityClass with
`globalDefault` set to true can exist in the system. If there is no PriorityClass
with `globalDefault` set, the priority of Pods with no `PriorityClassName` is zero.
The `description` field is an arbitrary string. It is meant to tell users of
the cluster when they should use this PriorityClass.
**Note 1**: If you upgrade your existing cluster and enable this feature, the priority
of your existing Pods will be considered to be zero.
{: .note}
**Note 2**: Addition of a PriorityClass with `globalDefault` set to true does not
change the priorities of existing Pods. The value of such a PriorityClass is used only
for Pods created after the PriorityClass is added.
{: .note}
**Note 3**: If you delete a PriorityClass, existing Pods that use the name of the
deleted priority class remain unchanged, but you are not able to create more Pods
that use the name of the deleted PriorityClass.
{: .note}
### Example PriorityClass
```yaml
apiVersion: v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."
```
## Pod priority
After you have one or more PriorityClasses, you can create Pods that specify one
of those PriorityClass names in their specifications. The priority admission
controller uses the `priorityClassName` field and populates the integer value
of the priority. If the priority class is not found, the Pod is rejected.
The following YAML is an example of a Pod configuration that uses the PriorityClass
created in the preceding example. The priority admission controller checks the
specification and resolves the priority of the Pod to 1000000.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
```
## Preemption
When Pods are created, they go to a queue and wait to be scheduled. The scheduler
picks a Pod from the queue and tries to schedule it on a Node. If no Node is found
that satisfies all the specified requirements of the Pod, preemption logic is triggered
for the pending Pod. Let's call the pending pod P. Preemption logic tries to find a Node
where removal of one or more Pods with lower priority than P would enable P to be scheduled
on that Node. If such a Node is found, one or more lower priority Pods get
deleted from the Node. After the Pods are gone, P can be scheduled on the Node.
### Limitations of preemption (alpha version)
#### Starvation of preempting Pod
When Pods are preempted, the victims get their
[graceful termination period](https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods).
They have that much time to finish their work and exit. If they don't, they are
killed. This graceful termination period creates a time gap between the point
that the scheduler preempts Pods and the time when the pending Pod (P) can be
scheduled on the Node (N). In the meantime, the scheduler keeps scheduling other
pending Pods. As victims exit or get terminated, the scheduler tries to schedule
Pods in the pending queue, and one or more of them may be considered and
scheduled to N before the scheduler considers scheduling P on N. In such a case,
it is likely that when all the victims exit, Pod P won't fit on Node N anymore.
So, scheduler will have to preempt other Pods on Node N or another Node so that
P can be scheduled. This scenario might be repeated again for the second and
subsequent rounds of preemption, and P might not get scheduled for a while.
This scenario can cause problems in various clusters, but is particularly
problematic in clusters with a high Pod creation rate.
We will address this problem in the beta version of Pod preemption. The solution
we plan to implement is
[provided here](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/pod-preemption.md#preemption-mechanics).
#### PodDisruptionBudget is not supported
A [Pod Disruption Budget (PDB)](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/)
allows application owners to limit the number Pods of a replicated application that
are down simultaneously from voluntary disruptions. However, the alpha version of
preemption does not respect PDB when choosing preemption victims.
We plan to add PDB support in beta, but even in beta, respecting PDB will be best
effort. The Scheduler will try to find victims whose PDB won't be violated by preemption,
but if no such victims are found, preemption will still happen, and lower priority Pods
will be removed despite their PDBs being violated.
#### Inter-Pod affinity on lower-priority Pods
In version 1.8, a Node is considered for preemption only when
the answer to this question is yes: "If all the Pods with lower priority than
the pending Pod are removed from the Node, can the pending pod be scheduled on
the Node?"
**Note:** Preemption does not necessarily remove all lower-priority Pods. If the
pending pod can be scheduled by removing fewer than all lower-priority Pods, then
only a portion of the lower-priority Pods are removed. Even so, the answer to the
preceding question must be yes. If the answer is no, the Node is not considered
for preemption.
{: .note}
If a pending Pod has inter-pod affinity to one or more of the lower-priority Pods
on the Node, the inter-Pod affinity rule cannot be satisfied in the absence of those
lower-priority Pods. In this case, the scheduler does not preempt any Pods on the
Node. Instead, it looks for another Node. The scheduler might find a suitable Node
or it might not. There is no guarantee that the pending Pod can be scheduled.
We might address this issue in future versions, but we don't have a clear plan yet.
We will not consider it a blocker for Beta or GA. Part
of the reason is that finding the set of lower-priority Pods that satisfy all
inter-Pod affinity rules is computationally expensive, and adds substantial
complexity to the preemption logic. Besides, even if preemption keeps the lower-priority
Pods to satisfy inter-Pod affinity, the lower priority Pods might be preempted
later by other Pods, which removes the benefits of having the complex logic of
respecting inter-Pod affinity.
Our recommended solution for this problem is to create inter-Pod affinity only towards
equal or higher priority pods.
#### Cross node preemption
Suppose a Node N is being considered for preemption so that a pending Pod P
can be scheduled on N. P might become feasible on N only if a Pod on another
Node is preempted. Here's an example:
* Pod P is being considered for Node N.
* Pod Q is running on another Node in the same zone as Node N.
* Pod P has anit-affinity with Pod Q.
* There are no other cases of anti-affinity between Pod P and other Pods in the zone.
* In order to schedule Pod P on Node N, Pod Q should be preempted, but scheduler
does not perform cross-node preemption. So, Pod P will be deemed unschedulable
on Node N.
If Pod Q were removed from its Node, the anti-affinity violation would be gone,
and Pod P could possibly be scheduled on Node N.
We may consider adding cross Node preemption in future versions if we find an
algorithm with reasonable performance. We cannot promise anything at this point,
and cross Node preemption will not be considered a blocker for Beta or GA.
{% endcapture %}
{% include templates/concept.md %}
@@ -188,7 +188,7 @@ running on the node as follows
The above behavior is a beta feature. In addition, Kubernetes 1.6 has alpha
support for representing node problems. In other words, the node controller
automatically taints a node when certain condition is true. The builtin taints
automatically taints a node when certain condition is true. The built-in taints
currently include:
* `node.alpha.kubernetes.io/notReady`: Node is not ready. This corresponds to
@@ -249,9 +249,20 @@ admission controller](https://git.k8s.io/kubernetes/plugin/pkg/admission/default
* `node.alpha.kubernetes.io/unreachable`
* `node.alpha.kubernetes.io/notReady`
* `node.kubernetes.io/memoryPressure`
* `node.kubernetes.io/diskPressure`
* `node.kubernetes.io/outOfDisk` (*only for critical pods*)
This ensures that DaemonSet pods are never evicted due to these problems,
which matches the behavior when this feature is disabled.
## Taint Nodes by Condition
Version 1.8 introduces an alpha feature that causes the node controller to create taints corresponding to
Node conditions. When this feature is enabled, the scheduler does not check conditions; instead the scheduler checks taints. This assures that conditions don't affect what's scheduled onto the Node. The user can choose to ignore some of the Node's problems (represented as conditions) by adding appropriate Pod tolerations.
To make sure that turning on this feature doesn't break DaemonSets, starting in version 1.8, the DaemonSet controller automatically adds the following `NoSchedule` tolerations to all daemons:
* `node.kubernetes.io/memory-pressure`
* `node.kubernetes.io/disk-pressure`
* `node.kubernetes.io/out-of-disk` (*only for critical pods*)
The above settings ensure backward compatibility, but we understand they may not fit all user's needs, which is why
cluster admin may choose to add arbitrary tolerations to DaemonSets.
-18
View File
@@ -1,18 +0,0 @@
apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
+33 -17
View File
@@ -21,22 +21,24 @@ actions that a pod can perform and what it has the ability to access. The
run with in order to be accepted into the system. They allow an
administrator to control the following:
| Control Aspect | Field Name |
| ------------------------------------------------------------- | --------------------------------- |
| Running of privileged containers | `privileged` |
| Default set of capabilities that will be added to a container | `defaultAddCapabilities` |
| Capabilities that will be dropped from a container | `requiredDropCapabilities` |
| Capabilities a container can request to be added | `allowedCapabilities` |
| Controlling the usage of volume types | [`volumes`](#controlling-volumes) |
| The use of host networking | [`hostNetwork`](#host-network) |
| The use of host ports | `hostPorts` |
| The use of host's PID namespace | `hostPID` |
| The use of host's IPC namespace | `hostIPC` |
| The SELinux context of the container | [`seLinux`](#selinux) |
| The user ID | [`runAsUser`](#runasuser) |
| Configuring allowable supplemental groups | [`supplementalGroups`](#supplementalgroups) |
| Allocating an FSGroup that owns the pod's volumes | [`fsGroup`](#fsgroup) |
| Requiring the use of a read only root file system | `readOnlyRootFilesystem` |
| Control Aspect | Field Name |
| ---------------------------------------------------------------------- | ------------------------------------------- |
| Running of privileged containers | `privileged` |
| Default set of capabilities that will be added to a container | `defaultAddCapabilities` |
| Capabilities that will be dropped from a container | `requiredDropCapabilities` |
| Capabilities a container can request to be added | `allowedCapabilities` |
| Controlling the usage of volume types | [`volumes`](#controlling-volumes) |
| The use of host networking | [`hostNetwork`](#host-network) |
| The use of host ports | `hostPorts` |
| The use of host's PID namespace | `hostPID` |
| The use of host's IPC namespace | `hostIPC` |
| The SELinux context of the container | [`seLinux`](#selinux) |
| The user ID | [`runAsUser`](#runasuser) |
| Configuring allowable supplemental groups | [`supplementalGroups`](#supplementalgroups) |
| Allocating an FSGroup that owns the pod's volumes | [`fsGroup`](#fsgroup) |
| Requiring the use of a read only root file system | `readOnlyRootFilesystem` |
| Running of a container that allow privilege escalation from its parent | [`allowPrivilegeEscalation`](#allowPrivilegeEscalation) |
| Control whether a process can gain more privileges than its parent process | [`defaultAllowPrivilegeEscalation`](#defaultAllowPrivilegeEscalation) |
_Pod Security Policies_ are comprised of settings and strategies that
control the security features a pod has access to. These settings fall
@@ -124,7 +126,21 @@ configMap, downwardAPI, emptyDir, persistentVolumeClaim, secret, and projected.
### Host Network
- *HostPorts*, default `empty`. List of `HostPortRange`, defined by `min`(inclusive) and `max`(inclusive), which define the allowed host ports.
### AllowPrivilegeEscalation
Gates whether or not a user is allowed to set the security context of a container
to `allowPrivilegeEscalation=true`. This field defaults to `false`.
### DefaultAllowPrivilegeEscalation
Sets the default for the security context `AllowPrivilegeEscalation` of a container.
This bool directly controls whether the `no_new_privs` flag gets set on the
container process. It defaults to `nil`. The default behavior of `nil`
allows privilege escalation so as to not break setuid binaries. Setting it to `false`
ensures that no child process of a container can gain more privileges than
its parent.
## Admission
_Admission control_ with `PodSecurityPolicy` allows for control over the
+7
View File
@@ -84,6 +84,13 @@ define a quota as follows:
* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi`
* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi`
In release 1.8, quota support for local ephemeral storage is added as alpha feature
| Resource Name | Description |
| ------------------------------- |----------------------------------------------------------- |
| `requests.ephemeral-storage` | Across all pods in the namespace, the sum of local ephemeral storage requests cannot exceed this value. |
| `limits.ephemeral-storage` | Across all pods in the namespace, the sum of local ephemeral storage limits cannot exceed this value. |
## Object Count Quota
The number of objects of a given type can be restricted. The following types
@@ -80,7 +80,11 @@ With the additional entries specified at the bottom.
## Limitations
As of 1.7, Pods with hostNetwork enabled will not be able to use this feature. This is because kubelet only manages the hosts file for non-hostNetwork Pods. There are ongoing discussions to change this.
HostAlias is only supported in 1.7+.
HostAlias support in 1.7 is limited to non-hostNetwork Pods because kubelet only manages the hosts file for non-hostNetwork Pods.
In 1.8, HostAlias is supported for all Pods regardless of network configuration.
## Why Does Kubelet Manage the Hosts File?
@@ -21,7 +21,7 @@ Network policies are implemented by the network plugin, so you must be using a n
By default, pods are non-isolated; they accept traffic from any source.
Pods become isolated by having a NetworkPolicy that selects them. Once there is any NetworkPolicy in a Namespace selecting a particular pod, that pod will reject any connections that are not allowed by any NetworkPolicy. (Other pods in the Namespace that are not selected by any NetworkPolicy will continue to accept all traffic.)
Pods become isolated by having a NetworkPolicy that selects them. Once there is any NetworkPolicy in a namespace selecting a particular pod, that pod will reject any connections that are not allowed by any NetworkPolicy. (Other pods in the namespace that are not selected by any NetworkPolicy will continue to accept all traffic.)
## The `NetworkPolicy` Resource
@@ -39,6 +39,9 @@ spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
@@ -54,6 +57,13 @@ spec:
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
```
*POSTing this to the API server will have no effect unless your chosen networking solution supports network policy.*
@@ -64,7 +74,11 @@ __spec__: `NetworkPolicy` [spec](https://git.k8s.io/community/contributors/devel
__podSelector__: Each `NetworkPolicy` includes a `podSelector` which selects the grouping of pods to which the policy applies. Since `NetworkPolicy` currently only supports defining `ingress` rules, this `podSelector` essentially defines the "destination pods" for the policy. The example policy selects pods with the label "role=db". An empty `podSelector` selects all pods in the namespace.
__ingress__: Each `NetworkPolicy` includes a list of whitelist `ingress` rules. Each rule allows traffic which matches both the `from` and `ports` sections. The example policy contains a single rule, which matches traffic on a single port, from either of two sources, the first specified via a `namespaceSelector` and the second specified via a `podSelector`.
__policyTypes__: Each `NetworkPolicy` includes a `policyTypes` list which may include either `Ingress`, `Egress`, or both. The `policyTypes` field indicates whether or not the given policy applies to ingress traffic to selected pod, egress traffic from selected pods, or both. If no `policyTypes` are specified on a NetworkPolicy then by default `Ingress` will always be set and `Egress` will be set if the NetworkPolicy has any egress rules.
__ingress__: Each `NetworkPolicy` may include a list of whitelist `ingress` rules. Each rule allows traffic which matches both the `from` and `ports` sections. The example policy contains a single rule, which matches traffic on a single port, from either of two sources, the first specified via a `namespaceSelector` and the second specified via a `podSelector`.
__egress__: Each `NetworkPolicy` may include a list of whitelist `egress` rules. Each rule allows traffic which matches both the `to` and `ports` sections. The example policy contains a single rule, which matches traffic on a single port to any destination in `10.0.0.0/24`.
__ipBlock__: `ipBlock` describes a particular CIDR that is allowed to
the pods matched by a NetworkPolicySpec's podSelector. The `except` entry
@@ -73,15 +87,21 @@ values will be rejected if they are outside the CIDR range.
So, the example NetworkPolicy:
1. isolates "role=db" pods in the "default" namespace (if they weren't already isolated)
1. isolates "role=db" pods in the "default" namespace for both ingress and egress traffic (if they weren't already isolated)
2. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from any pod in the "default" namespace with the label "role=frontend"
3. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from any pod in a namespace with the label "project=myproject"
3. allows connections from any pod in the "default" namespace with the label "role=db" to CIDR 10.0.0.0/24 on TCP port 5978
See the [NetworkPolicy getting started guide](/docs/getting-started-guides/network-policy/walkthrough) for further examples.
## Default policies
You can create a "default" isolation policy for a Namespace by creating a NetworkPolicy that selects all pods but does not allow any traffic:
By default, if no policies exist in a namespace, then all ingress and egress traffic is allowed to and from pods in that namespace. The following examples let you change the default behavior
in that namespace.
### Default deny all ingress traffic
You can create a "default" isolation policy for a namespace by creating a NetworkPolicy that selects all pods but does not allow any ingress traffic to those pods.
```yaml
apiVersion: networking.k8s.io/v1
@@ -90,11 +110,15 @@ metadata:
name: default-deny
spec:
podSelector:
policyTypes:
- Ingress
```
This ensures that even pods that aren't selected by any other NetworkPolicy will still be isolated.
This ensures that even pods that aren't selected by any other NetworkPolicy will still be isolated. This policy does not change the default egress isolation behavior.
Alternatively, if you want to allow all traffic for all pods in a Namespace (even if policies are added that cause some pods to be treated as "isolated"), you can create a policy that explicitly allows all traffic:
### Default allow all ingress traffic
If you want to allow all traffic to all pods in a namespace (even if policies are added that cause some pods to be treated as "isolated"), you can create a policy that explicitly allows all traffic in that namespace.
```yaml
apiVersion: networking.k8s.io/v1
@@ -107,6 +131,57 @@ spec:
- {}
```
### Default deny all egress traffic.
You can create a "default" egress isolation policy for a namespace by creating a NetworkPolicy that selects all pods but does not allow any egress traffic from those pods.
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector:
policyTypes:
- Egress
```
This ensures that even pods that aren't selected by any other NetworkPolicy will not be allowed egress traffic. This policy does not
change the default ingress isolation behavior.
### Default allow all egress traffic
If you want to allow all traffic from all pods in a namespace (even if policies are added that cause some pods to be treated as "isolated"), you can create a policy that explicitly allows all egress traffic in that namespace.
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector:
egress:
- {}
```
### Default deny all ingress and all egress traffic
You can create a "default" policy for a namespace which prevents all ingress AND egress traffic by creating the following NetworkPolicy in that namespace.
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector:
policyTypes:
- Ingress
- Egress
```
This ensures that even pods that aren't selected by any other NetworkPolicy will not be allowed ingress or egress traffic.
## What's next?
- See the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/)
+29 -32
View File
@@ -470,9 +470,9 @@ metadata:
{% capture azure %}
```yaml
[...]
metadata:
metadata:
name: my-service
annotations:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
[...]
```
@@ -516,40 +516,37 @@ ELB at the other end of its connection) when forwarding requests.
TCP and SSL will select layer 4 proxying: the ELB will forward traffic without
modifying the headers.
```yaml
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: (comma-separated-port-names)
```
The third annotation indicates which port(s) should accept SSL traffic on the ELB. If a certificate is set on the
Service, the default is to configure all ports on the ELB to use SSL. This is not typically desired for HTTP servers.
A complete HTTP Service supporting SSL might look like:
In a mixed-use environment where some ports are secured and others are left unencrypted,
the following annotations may be used:
```yaml
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
spec:
type: LoadBalancer
ports:
- port: 80
name: http
targetPort: 8080
- port: 443
name: https
targetPort: 8080
selector:
app: MyApp
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443,8443"
```
In the above example, if the service contained three ports, `80`, `443`, and
`8443`, then `443` and `8443` would use the SSL certificate, but `80` would just
be proxied HTTP.
#### PROXY protocol support on AWS
To enable [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
support for clusters running on AWS, you can use the following service
annotation:
```yaml
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
```
Since version 1.3.0 the use of this annotation applies to all ports proxied by the ELB
and cannot be configured otherwise.
### External IPs
If there are external IPs that route to one or more cluster nodes, Kubernetes services can be exposed on those
+100 -67
View File
@@ -107,7 +107,40 @@ However, the particular path specified in the custom recycler pod template in th
#### Deleting
For volume plugins that support the Delete reclaim policy, deletion removes both the `PersistentVolume` object from Kubernetes, as well as deleting the associated storage asset in the external infrastructure, such as an AWS EBS, GCE PD, Azure Disk, or Cinder volume. Volumes that were dynamically provisioned are always deleted. If that is not desired, currently, the only option is to edit or patch the PV after it is created. See [Change the Reclaim Policy of a PersistentVolume](https://kubernetes.io/docs/tasks/administer-cluster/change-pv-reclaim-policy/).
For volume plugins that support the Delete reclaim policy, deletion removes both the `PersistentVolume` object from Kubernetes, as well as deleting the associated storage asset in the external infrastructure, such as an AWS EBS, GCE PD, Azure Disk, or Cinder volume. Volumes that were dynamically provisioned inherit the [reclaim policy of their `StorageClass`](#reclaim-policy-1), which defaults to Delete. The administrator should configure the `StorageClass` according to users' expectations, otherwise the PV must be edited or patched after it is created. See [Change the Reclaim Policy of a PersistentVolume](https://kubernetes.io/docs/tasks/administer-cluster/change-pv-reclaim-policy/).
### Expanding Persistent Volumes Claims
With Kubernetes 1.8, we have added Alpha support for expanding persistent volumes. The current Alpha support was designed to only support volume types
that don't need file system resizing (Currently only glusterfs).
Administrator can allow expanding persistent volume claims by setting `ExpandPersistentVolumes` feature gate to true. Administrator
should also enable [`PersistentVolumeClaimResize` admission plugin](/docs/admin/admission-controllers/#persistentvolumeclaimresize)
to perform additional validations of volumes that can be resized.
Once `PersistentVolumeClaimResize` admission plug-in has been turned on, resizing will only be allowed for storage classes
whose `allowVolumeExpansion` field is set to true.
``` yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
```
Once both feature gate and aforementioned admission plug-in are turned on, an user can request larger volume for their `PersistentVolumeClaim`
by simply editing the claim and requesting bigger size. This in turn will trigger expansion of volume that is backing underlying `PersistentVolume`.
Under no circustances a new `PersistentVolume` gets created to satisfy the claim. Kubernetes will attempt to resize existing volume to satisfy the claim.
## Types of Persistent Volumes
@@ -139,20 +172,23 @@ For volume plugins that support the Delete reclaim policy, deletion removes both
Each PV contains a spec and status, which is the specification and status of the volume.
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
nfs:
path: /tmp
server: 172.17.0.2
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
```
### Capacity
@@ -225,47 +261,14 @@ Current reclaim policies are:
Currently, only NFS and HostPath support recycling. AWS EBS, GCE PD, Azure Disk, and Cinder volumes support deletion.
### Phase
A volume will be in one of the following phases:
* Available -- a free resource that is not yet bound to a claim
* Bound -- the volume is bound to a claim
* Released -- the claim has been deleted, but the resource is not yet reclaimed by the cluster
* Failed -- the volume has failed its automatic reclamation
The CLI will show the name of the PVC bound to the PV.
### Mount Options
A Kubernetes administrator can specify additional mount options for when a Persistent Volume is being mounted on a node.
A Kubernetes administrator can specify additional mount options for when a Persistent Volume is mounted on a node.
You can specify a mount option by using the annotation `volume.beta.kubernetes.io/mount-options` on
your Persistent Volume.
**Note:** Not all Persistent volume types support mount options.
{: .note}
For example:
```yaml
apiVersion: "v1"
kind: "PersistentVolume"
metadata:
name: gce-disk-1
annotations:
volume.beta.kubernetes.io/mount-options: "discard"
spec:
capacity:
storage: "10Gi"
accessModes:
- "ReadWriteOnce"
gcePersistentDisk:
fsType: "ext4"
pdName: "gce-disk-1"
```
A mount option is a string which will be cumulatively joined and used while mounting volume to the disk.
Note that not all Persistent volume types support mount options. In Kubernetes version 1.6, the following
volume types support mount options.
The following volume types support mount options:
* GCEPersistentDisk
* AWSElasticBlockStore
@@ -281,6 +284,22 @@ volume types support mount options.
* Quobyte Volumes
* VMware Photon
Mount options are not validated, so mount will simply fail if one is invalid.
In the past, the annotation `volume.beta.kubernetes.io/mount-options` was used instead
of the `mountOptions` attribute. This annotation is still working, however
it will become fully deprecated in a future Kubernetes release.
### Phase
A volume will be in one of the following phases:
* Available -- a free resource that is not yet bound to a claim
* Bound -- the volume is bound to a claim
* Released -- the claim has been deleted, but the resource is not yet reclaimed by the cluster
* Failed -- the volume has failed its automatic reclamation
The CLI will show the name of the PVC bound to the PV.
## PersistentVolumeClaims
@@ -355,8 +374,10 @@ to Kubernetes cluster by addon manager during installation.
When a PVC specifies a `selector` in addition to requesting a `StorageClass`,
the requirements are ANDed together: only a PV of the requested class and with
the requested labels may be bound to the PVC. Note that currently, a PVC with a
non-empty `selector` can't have a PV dynamically provisioned for it.
the requested labels may be bound to the PVC.
**Note:** Currently, a PVC with a non-empty `selector` can't have a PV dynamically provisioned for it.
{: .note}
In the past, the annotation `volume.beta.kubernetes.io/storage-class` was used instead
of `storageClassName` attribute. This annotation is still working, however
@@ -390,9 +411,9 @@ spec:
## StorageClasses
Each `StorageClass` contains the fields `provisioner` and `parameters`, which
are used when a `PersistentVolume` belonging to the class needs to be
dynamically provisioned.
Each `StorageClass` contains the fields `provisioner`, `parameters`, and
`reclaimPolicy`, which are used when a `PersistentVolume` belonging to the
class needs to be dynamically provisioned.
The name of a `StorageClass` object is significant, and is how users can
request a particular class. Administrators set the name and other parameters
@@ -412,6 +433,9 @@ metadata:
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
mountOptions:
- debug
```
### Provisioner
@@ -455,13 +479,22 @@ There are also cases when 3rd party storage vendors provide their own external
provisioner.
### Reclaim Policy
Persistent Volumes that are dynamically created by a storage class will have a reclaim
policy of `delete`. If that is not desired, the only current option is to edit the
PV after it is created.
Persistent Volumes that are dynamically created by a storage class will have the
reclaim policy specified in the `reclaimPolicy` field of the class, which can be
either `Delete` or `Retain`. If no `reclaimPolicy` is specified when a
`StorageClass` object is created, it will default to `Delete`.
Persistent Volumes that are created manually and managed via a storage class will have
whatever reclaim policy they were assigned at creation.
### Mount Options
Persistent Volumes that are dynamically created by a storage class will have the
mount options specified in the `mountOptions` field of the class.
If the volume plugin does not support mount options but mount options are
specified, provisioning will fail. Mount options are not validated on neither
the class nor PV, so mount of the PV will simply fail if one is invalid.
### Parameters
Storage classes have parameters that describe volumes belonging to the storage
class. Different parameters may be accepted depending on the `provisioner`. For
@@ -795,8 +828,8 @@ provisioner: kubernetes.io/scaleio
parameters:
gateway: https://192.168.99.200:443/api
system: scaleio
protectionDomain: default
storagePool: default
protectionDomain: pd0
storagePool: sp1
storageMode: ThinProvisionned
secretRef: sio-secret
readOnly: false
@@ -806,12 +839,12 @@ parameters:
* `provisioner`: attribute is set to `kubernetes.io/scaleio`
* `gateway`: address to a ScaleIO API gateway (required)
* `system`: the name of the ScaleIO system (required)
* `protectionDomain`: the name of the ScaleIO protection domain
* `storagePool`: the name of the volume storage pool
* `protectionDomain`: the name of the ScaleIO protection domain (required)
* `storagePool`: the name of the volume storage pool (required)
* `storageMode`: the storage provision mode: `ThinProvisionned` (default) or `ThickProvisionned`
* `secretRef`: reference to a configured Secret object (required, see detail below)
* `readOnly`: specifies the access mode to the mounted volume
* `fsType`: the file system to use for the volume
* `secretRef`: reference to a configured Secret object (required)
* `readOnly`: specifies the access mode to the mounted volume (default false)
* `fsType`: the file system to use for the volume (default ext4)
The ScaleIO Kubernetes volume plugin requires a configured Secret object.
The secret must be created with type `kubernetes.io/scaleio` and use the same namespace value as that of the PVC where it is referenced
+85 -10
View File
@@ -141,7 +141,7 @@ spec:
### hostPath
A `hostPath` volume mounts a file or directory from the host node's filesystem
into your pod. This is not something that most Pods will need, but it offers a
into your pod. This is not something that most Pods will need, but it offers a
powerful escape hatch for some applications.
For example, some uses for a `hostPath` are:
@@ -149,6 +149,24 @@ For example, some uses for a `hostPath` are:
* running a container that needs access to Docker internals; use a `hostPath`
of `/var/lib/docker`
* running cAdvisor in a container; use a `hostPath` of `/dev/cgroups`
* allowing a pod to specify whether a given hostPath should exist prior to the
pod running, whether it should be created, and what it should exist as
In addition to the required `path` property, user can optionally specify a `type` for a `hostPath` volume.
The supported values for field `type` are:
| Value | Behavior |
|:------|:---------|
| | Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the hostPath volume. |
| `DirectoryOrCreate` | If nothing exists at the given path, an empty directory will be created there as needed with permission set to 0755, having the same group and ownership with Kubelet. |
| `Directory` | A directory must exist at the given path |
| `FileOrCreate` | If nothing exists at the given path, an empty file will be created there as needed with permission set to 0644, having the same group and ownership with Kubelet. |
| `File` | A file must exist at the given path |
| `Socket` | A UNIX socket must exist at the given path |
| `CharDevice` | A character device must exist at the given path |
| `BlockDevice` | A block device must exist at the given path |
Watch out when using this type of volume, because:
@@ -156,7 +174,7 @@ Watch out when using this type of volume, because:
behave differently on different nodes due to different files on the nodes
* when Kubernetes adds resource-aware scheduling, as is planned, it will not be
able to account for resources used by a `hostPath`
* the directories created on the underlying hosts are only writable by root. You
* the files or directories created on the underlying hosts are only writable by root. You
either need to run your process as root in a
[privileged container](/docs/user-guide/security-context) or modify the file
permissions on the host to be able to write to a `hostPath` volume
@@ -180,6 +198,8 @@ spec:
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory
```
### gcePersistentDisk
@@ -549,14 +569,6 @@ with ConfigMap naming.
volume source. However, as illustrated above, you can explicitly set the `mode`
for each individual projection.
### FlexVolume
A `FlexVolume` enables users to mount vendor volumes into a pod. It expects vendor
drivers are installed in the volume plugin path on each kubelet node. This is
an alpha feature and may change in future.
More details are in [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/flexvolume/README.md).
### AzureFileVolume
A `AzureFileVolume` is used to mount a Microsoft Azure File Volume (SMB 2.1 and 3.0)
@@ -699,6 +711,8 @@ spec:
scaleIO:
gateway: https://localhost:443/api
system: scaleio
protectionDomain: sd0
storagePool: sp1
volumeName: vol-0
secretRef:
name: sio-secret
@@ -847,6 +861,67 @@ request a certain amount of space using a [resource](/docs/user-guide/compute-re
specification, and to select the type of media to use, for clusters that have
several media types.
## Out-of-Tree Volume Plugins
In addition to the previously listed volume types, storage vendors may create
custom plugins without adding it to the Kubernetes repository. This can be
achieved by using the `FlexVolume` plugin.
`FlexVolume` enables users to mount vendor volumes into a pod. The vendor plugin
is implemented using a driver, an executable supporting a list of volume commands
defined by the `FlexVolume` API. Drivers must be installed in a pre-defined
volume plugin path on each node. This is an alpha feature and may change in future.
More details can be found [here](https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md).
## Mount propagation
**Note:** Mount propagation is an alpha feature in Kubernetes 1.8 and may be
redesigned or even removed in future releases.
{: .note}
Mount propagation allows for sharing volumes mounted by a Container to
other Containers in the same Pod, or even to other Pods on the same node.
If the MountPropagation feature is disabled, volume mounts in pods are not propagated.
That is, Containers run with `private` mount propagation as described in the
[Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).
To enable this feature, specify `MountPropagation=true` in the
`--feature-gates` command line option. When enabled, the `volumeMounts` field
of a Container has a new `mountPropagation` subfield. Its values are:
* `HostToContainer` - This volume mount will receive all subsequent mounts
that are mounted to this volume or any of its subdirectories. This is
the default mode when the MountPropagation feature is enabled.
In other words, if the host mounts anything inside the volume mount, the
Container will see it mounted there.
Similarly, if any pod with `Bidirectional` mount propagation to the same
volume mounts anything there, the Container with `HostToContainer` mount
propagation will see it.
This mode is equal to `rslave` mount propagation as described in the
[Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)
* `Bidirectional` - This volume mount behaves the same the `HostToContainer` mount.
In addition, all volume mounts created by the Container will be propagated
back to the host and to all Containers of all Pods that use the same volume.
A typical use case for this mode is a Pod with a Flex volume driver or
a Pod that needs to mount something on the host using a HostPath volume.
This mode is equal to `rshared` mount propagation as described in the
[Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)
**Caution:** `Bidirectional` mount propagation can be dangerous. It can damage
the host operating system and therefore it is allowed only in privileged
Containers. Familiarity with Linux kernel behavior is strongly recommended.
In addition, any volume mounts created by Containers in Pods must be destroyed
(unmounted) by the Containers on termination.
{: .caution}
{% endcapture %}
{% capture whatsnext %}
@@ -22,8 +22,10 @@ on a given schedule, written in [Cron](https://en.wikipedia.org/wiki/Cron) forma
**Note:** The question mark (`?`) in the schedule has the same meaning as an asterisk `*`,
that is, it stands for any of available value for a given field.
**Note:** ScheduledJob resource was introduced in Kubernetes version 1.4, but starting
from version 1.5 its current name is CronJob.
**Note:** CronJob resource in `batch/v2alpha1` API group has been deprecated starting
from cluster version 1.8. You should switch to using `batch/v1beta1`, instead, which is
enabled by default in the API server. Further in this document, we will be using
`batch/v1beta1` in all the examples.
A typical use case is:
@@ -32,8 +34,8 @@ A typical use case is:
### Prerequisites
You need a working Kubernetes cluster at version >= 1.4 (for ScheduledJob), >= 1.5 (for CronJob),
with batch/v2alpha1 API turned on by passing `--runtime-config=batch/v2alpha1=true` while bringing up
You need a working Kubernetes cluster at version >= 1.8 (for CronJob). For previous versions of cluster (< 1.8)
you need to explicitly enable `batch/v2alpha1` API by passing `--runtime-config=batch/v2alpha1=true` to
the API server (see [Turn on or off an API version for your cluster](/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster)
for more).
@@ -111,25 +113,8 @@ $ kubectl delete cronjob hello
cronjob "hello" deleted
```
This stops new jobs from being created. However, running jobs won't be stopped, and no jobs or their pods will
be deleted. To clean up those jobs and pods, you need to list all jobs created by the cron job, and delete them all:
```shell
$ kubectl get jobs
NAME DESIRED SUCCESSFUL AGE
hello-1201907962 1 1 11m
hello-1202039034 1 1 8m
...
$ kubectl delete jobs hello-1201907962 hello-1202039034 ...
job "hello-1201907962" deleted
job "hello-1202039034" deleted
...
```
Once the jobs are deleted, the pods created by them are deleted as well. Note that all jobs created by cron
job "hello" will be prefixed "hello-". You can delete them at once with `kubectl delete jobs --all`, if you want to
delete all jobs in the current namespace (not just the ones created by "hello").
This stops new jobs from being created and removes all the jobs and pods created by this cronjob.
You can read more about it in [garbage collection section](/docs/concepts/workloads/controllers/garbage-collection/).
## Cron Job Limitations
@@ -187,6 +172,7 @@ apply to already started executions. Defaults to false.
### Jobs History Limits
The `.spec.successfulJobsHistoryLimit` and `.spec.failedJobsHistoryLimit` fields are optional. These fields specify how many completed and failed jobs should be kept.
By default, there are no limits, and all successful and failed jobs are kept. However, jobs can pile up quickly when running a cron job, and setting these fields is recommended. Setting a limit to `0` corresponds to keeping none of the corresponding kind of jobs after they finish.
The `.spec.successfulJobsHistoryLimit` and `.spec.failedJobsHistoryLimit` fields are optional.
These fields specify how many completed and failed jobs should be kept. By default, they are
set to 3 and 1 respectively. Setting a limit to `0` corresponds to keeping none of the corresponding
kind of jobs after they finish.
@@ -1,4 +1,4 @@
apiVersion: batch/v2alpha1
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
@@ -1,6 +1,10 @@
---
approvers:
- enisoc
- erictune
- foxish
- janetkuo
- kow3ns
title: Daemon Sets
---
@@ -9,9 +13,9 @@ title: Daemon Sets
## What is a DaemonSet?
A _DaemonSet_ ensures that all (or some) nodes run a copy of a pod. As nodes are added to the
cluster, pods are added to them. As nodes are removed from the cluster, those pods are garbage
collected. Deleting a DaemonSet will clean up the pods it created.
A _DaemonSet_ ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the
cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage
collected. Deleting a DaemonSet will clean up the Pods it created.
Some typical uses of a DaemonSet are:
@@ -47,20 +51,26 @@ A DaemonSet also needs a [`.spec`](https://git.k8s.io/community/contributors/dev
### Pod Template
The `.spec.template` is the only required field of the `.spec`.
The `.spec.template` is one of the required fields in `.spec`.
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an `apiVersion` or `kind`.
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [Pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an `apiVersion` or `kind`.
In addition to required fields for a pod, a pod template in a DaemonSet has to specify appropriate
In addition to required fields for a Pod, a Pod template in a DaemonSet has to specify appropriate
labels (see [pod selector](#pod-selector)).
A pod template in a DaemonSet must have a [`RestartPolicy`](/docs/user-guide/pod-states)
A Pod Template in a DaemonSet must have a [`RestartPolicy`](/docs/user-guide/pod-states)
equal to `Always`, or be unspecified, which defaults to `Always`.
### Pod Selector
The `.spec.selector` field is a pod selector. It works the same as the `.spec.selector` of
a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) or other new resources.
a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/).
As of Kubernetes 1.8, you must specify a pod selector that matches the labels of the
`.spec.template`. The pod selector will no longer be defaulted when left empty. Selector
defaulting was not compatible with `kubectl apply`. Also, once a DaemonSet is created,
its `spec.selector` can not be mutated. Mutating the pod selector can lead to the
unintentional orphaning of Pods, and it was found to be confusing to users.
The `spec.selector` is an object consisting of two fields:
@@ -73,53 +83,58 @@ When the two are specified the result is ANDed.
If the `.spec.selector` is specified, it must match the `.spec.template.metadata.labels`. If not
specified, they are defaulted to be equal. Config with these not matching will be rejected by the API.
Also you should not normally create any pods whose labels match this selector, either directly, via
another DaemonSet, or via other controller such as ReplicationController. Otherwise, the DaemonSet
controller will think that those pods were created by it. Kubernetes will not stop you from doing
this. One case where you might want to do this is manually create a pod with a different value on
Also you should not normally create any Pods whose labels match this selector, either directly, via
another DaemonSet, or via other controller such as ReplicaSet. Otherwise, the DaemonSet
controller will think that those Pods were created by it. Kubernetes will not stop you from doing
this. One case where you might want to do this is manually create a Pod with a different value on
a node for testing.
If you attempt to create a DaemonSet such that
### Running Pods on Only Some Nodes
If you specify a `.spec.template.spec.nodeSelector`, then the DaemonSet controller will
create pods on nodes which match that [node
create Pods on nodes which match that [node
selector](/docs/concepts/configuration/assign-pod-node/). Likewise if you specify a `.spec.template.spec.affinity`,
then DaemonSet controller will create pods on nodes which match that [node affinity](/docs/concepts/configuration/assign-pod-node/).
If you do not specify either, then the DaemonSet controller will create pods on all nodes.
then DaemonSet controller will create Pods on nodes which match that [node affinity](/docs/concepts/configuration/assign-pod-node/).
If you do not specify either, then the DaemonSet controller will create Pods on all nodes.
## How Daemon Pods are Scheduled
Normally, the machine that a pod runs on is selected by the Kubernetes scheduler. However, pods
created by the Daemon controller have the machine already selected (`.spec.nodeName` is specified
when the pod is created, so it is ignored by the scheduler). Therefore:
Normally, the machine that a Pod runs on is selected by the Kubernetes scheduler. However, Pods
created by the DaemonSet controller have the machine already selected (`.spec.nodeName` is specified
when the Pod is created, so it is ignored by the scheduler). Therefore:
- The [`unschedulable`](/docs/admin/node/#manual-node-administration) field of a node is not respected
by the DaemonSet controller.
- DaemonSet controller can make pods even when the scheduler has not been started, which can help cluster
- The DaemonSet controller can make Pods even when the scheduler has not been started, which can help cluster
bootstrap.
Daemon pods do respect [taints and tolerations](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),
Daemon Pods do respect [taints and tolerations](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),
but they are created with `NoExecute` tolerations for the following taints with no `tolerationSeconds`:
- `node.alpha.kubernetes.io/notReady`
- `node.alpha.kubernetes.io/unreachable`
- `node.alpha.kubernetes.io/memoryPressure`
- `node.alpha.kubernetes.io/diskPressure`
When the support to critical pods is enabled and the pods in a DaemonSet are
labelled as critical, the Daemon pods are created with an additional
`NoExecute` toleration for the `node.alpha.kubernetes.io/outOfDisk` taint with
no `tolerationSeconds`.
This ensures that when the `TaintBasedEvictions` alpha feature is enabled,
they will not be evicted when there are node problems such as a network partition. (When the
`TaintBasedEvictions` feature is not enabled, they are also not evicted in these scenarios, but
due to hard-coded behavior of the NodeController rather than due to tolerations).
They also tolerate following `NoSchedule` taints:
- `node.kubernetes.io/memory-pressure`
- `node.kubernetes.io/disk-pressure`
When the support to critical pods is enabled and the pods in a DaemonSet are
labelled as critical, the Daemon pods are created with an additional
`NoSchedule` toleration for the `node.kubernetes.io/out-of-disk` taint.
Note that all above `NoSchedule` taints above are created only in version 1.8 or later if the alpha feature `TaintNodesByCondition` is enabled.
## Communicating with Daemon Pods
Some possible patterns for communicating with pods in a DaemonSet are:
Some possible patterns for communicating with Pods in a DaemonSet are:
- **Push**: Pods in the DaemonSet are configured to send updates to another service, such
as a stats database. They do not have clients.
@@ -127,24 +142,24 @@ Some possible patterns for communicating with pods in a DaemonSet are:
- **DNS**: Create a [headless service](/docs/concepts/services-networking/service/#headless-services) with the same pod selector,
and then discover DaemonSets using the `endpoints` resource or retrieve multiple A records from
DNS.
- **Service**: Create a service with the same pod selector, and use the service to reach a
- **Service**: Create a service with the same Pod selector, and use the service to reach a
daemon on a random node. (No way to reach specific node.)
## Updating a DaemonSet
If node labels are changed, the DaemonSet will promptly add pods to newly matching nodes and delete
pods from newly not-matching nodes.
If node labels are changed, the DaemonSet will promptly add Pods to newly matching nodes and delete
Pods from newly not-matching nodes.
You can modify the pods that a DaemonSet creates. However, pods do not allow all
You can modify the Pods that a DaemonSet creates. However, Pods do not allow all
fields to be updated. Also, the DaemonSet controller will use the original template the next
time a node (even with the same name) is created.
You can delete a DaemonSet. If you specify `--cascade=false` with `kubectl`, then the pods
You can delete a DaemonSet. If you specify `--cascade=false` with `kubectl`, then the Pods
will be left on the nodes. You can then create a new DaemonSet with a different template.
the new DaemonSet with the different template will recognize all the existing pods as having
matching labels. It will not modify or delete them despite a mismatch in the pod template.
You will need to force new pod creation by deleting the pod or deleting the node.
The new DaemonSet with the different template will recognize all the existing Pods as having
matching labels. It will not modify or delete them despite a mismatch in the Pod template.
You will need to force new Pod creation by deleting the Pod or deleting the node.
In Kubernetes version 1.6 and later, you can [perform a rolling update](/docs/tasks/manage-daemon/update-daemon-set/) on a DaemonSet.
@@ -159,35 +174,35 @@ It is certainly possible to run daemon processes by directly starting them on a
running such processes via a DaemonSet:
- Ability to monitor and manage logs for daemons in the same way as applications.
- Same config language and tools (e.g. pod templates, `kubectl`) for daemons and applications.
- Same config language and tools (e.g. Pod templates, `kubectl`) for daemons and applications.
- Future versions of Kubernetes will likely support integration between DaemonSet-created
pods and node upgrade workflows.
Pods and node upgrade workflows.
- Running daemons in containers with resource limits increases isolation between daemons from app
containers. However, this can also be accomplished by running the daemons in a container but not in a pod
containers. However, this can also be accomplished by running the daemons in a container but not in a Pod
(e.g. start directly via Docker).
### Bare Pods
It is possible to create pods directly which specify a particular node to run on. However,
a DaemonSet replaces pods that are deleted or terminated for any reason, such as in the case of
It is possible to create Pods directly which specify a particular node to run on. However,
a DaemonSet replaces Pods that are deleted or terminated for any reason, such as in the case of
node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, you should
use a DaemonSet rather than creating individual pods.
use a DaemonSet rather than creating individual Pods.
### Static Pods
It is possible to create pods by writing a file to a certain directory watched by Kubelet. These
It is possible to create Pods by writing a file to a certain directory watched by Kubelet. These
are called [static pods](/docs/concepts/cluster-administration/static-pod/).
Unlike DaemonSet, static pods cannot be managed with kubectl
or other Kubernetes API clients. Static pods do not depend on the apiserver, making them useful
in cluster bootstrapping cases. Also, static pods may be deprecated in the future.
Unlike DaemonSet, static Pods cannot be managed with kubectl
or other Kubernetes API clients. Static Pods do not depend on the apiserver, making them useful
in cluster bootstrapping cases. Also, static Pods may be deprecated in the future.
### Replication Controller
### Deployments
DaemonSet are similar to [Replication Controllers](/docs/user-guide/replication-controller) in that
they both create pods, and those pods have processes which are not expected to terminate (e.g. web servers,
DaemonSets are similar to [Deployments](/docs/concepts/workloads/controllers/deployment.md) in that
they both create Pods, and those Pods have processes which are not expected to terminate (e.g. web servers,
storage servers).
Use a replication controller for stateless services, like frontends, where scaling up and down the
Use a Deployment for stateless services, like frontends, where scaling up and down the
number of replicas and rolling out updates are more important than controlling exactly which host
the pod runs on. Use a Daemon Controller when it is important that a copy of a pod always run on
all or certain hosts, and when it needs to start before other pods.
the Pod runs on. Use a DaemonSet when it is important that a copy of a Pod always run on
all or certain hosts, and when it needs to start before other Pods.
@@ -1,4 +1,4 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1beta2
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
@@ -6,6 +6,9 @@ metadata:
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
@@ -33,4 +36,4 @@ spec:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
path: /var/lib/docker/containers
@@ -288,6 +288,9 @@ It is generally discouraged to make label selector updates and it is suggested t
In any case, if you need to perform a label selector update, exercise great caution and make sure you have grasped
all of the implications.
**Note:** In API version `apps/v1beta2`, a Deployment's label selector is immutable after it gets created.
{: .note}
* Selector additions require the pod template labels in the Deployment spec to be updated with the new label too,
otherwise a validation error is returned. This change is a non-overlapping one, meaning that the new selector does
not select ReplicaSets and Pods created with the old selector, resulting in orphaning all old ReplicaSets and
@@ -850,9 +853,9 @@ allowed, which is the default if not specified.
`.spec.selector` is an optional field that specifies a [label selector](/docs/concepts/overview/working-with-objects/labels/)
for the Pods targeted by this deployment.
If specified, `.spec.selector` must match `.spec.template.metadata.labels`, or it will be rejected by
the API. If `.spec.selector` is unspecified, `.spec.selector.matchLabels` defaults to
`.spec.template.metadata.labels`.
`.spec.selector` must match `.spec.template.metadata.labels`, or it will be rejected by the API.
In API version `apps/v1beta2`, `.spec.selector` and `.metadata.labels` no longer default to `.spec.template.metadata.labels` if not set. So they must be set explicitly. Also note that `.spec.selector` is immutable after creation of the Deployment in `apps/v1beta2`.
A Deployment may terminate Pods whose labels match the selector if their template is different
from `.spec.template` or if the total number of such Pods exceeds `.spec.replicas`. It brings up new
@@ -926,20 +929,7 @@ a Pod is considered ready, see [Container Probes](/docs/concepts/workloads/pods/
### Rollback To
`.spec.rollbackTo` is an optional field with the configuration the Deployment
should roll back to. Setting this field triggers a rollback, and this field will
be cleared by the server after a rollback is done.
Because this field will be cleared by the server, it should not be used
declaratively. For example, you should not perform `kubectl apply` with a
manifest with `.spec.rollbackTo` field set.
#### Revision
`.spec.rollbackTo.revision` is an optional field specifying the revision to roll
back to. Setting to 0 means rolling back to the last revision in history;
otherwise, means rolling back to the specified revision. This defaults to 0 when
[`spec.rollbackTo`](#rollback-to) is set.
Field `.spec.rollbackTo` has been deprecated in API versions `extensions/v1beta1` and `apps/v1beta1`, and is no longer supported in API version `apps/v1beta2`. Instead, `kubectl rollout undo` as introduced in [Rolling Back to a Previous Revision](#rolling-back-to-a-previous-revision) should be used.
### Revision History Limit
@@ -1,20 +1,14 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1beta2 # for versions before 1.6.0 use extensions/v1beta1
kind: ReplicaSet
metadata:
name: frontend
# these labels can be applied automatically
# from the labels in the pod template if not set
# labels:
# app: guestbook
# tier: frontend
labels:
app: guestbook
tier: frontend
spec:
# this replicas value is default
# modify it according to your case
replicas: 3
# selector can be applied automatically
# from the labels in the pod template if not set,
# but we are specifying the selector here to
# demonstrate its usage.
selector:
matchLabels:
tier: frontend
@@ -155,11 +155,8 @@ is not used, only the ReplicaSets will be deleted, and the Pods will be orphaned
See [kubeadm/#149](https://github.com/kubernetes/kubeadm/issues/149#issuecomment-284766613) for more information.
## Known issues
* As of 1.7, garbage collection does not yet support
[custom resources](/docs/concepts/api-extension/custom-resources/),
such as those added through CustomResourceDefinition or aggregated API servers.
[Other known issues](https://github.com/kubernetes/kubernetes/issues/26120)
Tracked at [#26120](https://github.com/kubernetes/kubernetes/issues/26120)
{% endcapture %}
@@ -12,4 +12,5 @@ spec:
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
@@ -196,6 +196,12 @@ sometimes be started twice.
If you do specify `.spec.parallelism` and `.spec.completions` both greater than 1, then there may be
multiple pods running at once. Therefore, your pods must also be tolerant of concurrency.
### Pod Backoff failure policy
There are situations where you want to fail a Job after some amount of retries due to a logical error in configuration etc.
To do so set `.spec.template.spec.backoffLimit` to specify the number of retries before considering a Job as failed.
The back-off limit is set by default to 6. Failed Pods associated with the Job are recreated by the Job controller with an exponential back-off delay (10s, 20s, 40s ...) capped at six minutes, The back-off limit is reset if no new failed Pods appear before the Job's next status check.
## Job Termination and Cleanup
When a Job completes, no more Pods are created, but the Pods are not deleted either. Since they are terminated,
@@ -230,6 +236,7 @@ spec:
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 5
```
Note that both the Job Spec and the Pod Template Spec within the Job have a field with the same name.
@@ -1,9 +1,14 @@
apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
apiVersion: apps/v1beta2 # for versions before 1.7.0 use apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
@@ -1,441 +0,0 @@
---
approvers:
- bprashanth
- enisoc
- erictune
- foxish
- janetkuo
- kow3ns
- smarterclayton
title: PetSets
---
__Warning:__ Starting in Kubernetes version 1.5, PetSet has been renamed to [StatefulSet](/docs/concepts/abstractions/controllers/statefulsets). To use (or continue to use) PetSet in Kubernetes 1.5, you _must_ [migrate](/docs/tasks/manage-stateful-set/upgrade-pet-set-to-stateful-set/) your existing PetSets to StatefulSets. For information on working with StatefulSet, see the tutorial on [how to run replicated stateful applications](/docs/tasks/run-application/run-replicated-stateful-application/).
__This document has been deprecated__, but can still apply if you're using
Kubernetes version 1.4 or earlier.
* TOC
{:toc}
__Terminology__
Throughout this doc you will see a few terms that are sometimes used interchangeably elsewhere, that might cause confusion. This section attempts to clarify them.
* Node: A single virtual or physical machine in a Kubernetes cluster.
* Cluster: A group of nodes in a single failure domain, unless mentioned otherwise.
* Persistent Volume Claim (PVC): A request for storage, typically a [persistent volume](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/).
* Host name: The hostname attached to the UTS namespace of the pod, i.e. the output of `hostname` in the pod.
* DNS/Domain name: A *cluster local* domain name resolvable using standard methods (e.g.: [gethostbyname](http://linux.die.net/man/3/gethostbyname)).
* Ordinality: the property of being "ordinal", or occupying a position in a sequence.
* Pet: a single member of a PetSet; more generally, a stateful application.
* Peer: a process running a server, capable of communicating with other such processes.
__Prerequisites__
This doc assumes familiarity with the following Kubernetes concepts:
* [Pods](/docs/user-guide/pods/single-container/)
* [Cluster DNS](/docs/concepts/services-networking/dns-pod-service/)
* [Headless Services](/docs/concepts/services-networking/service/#headless-services)
* [Persistent Volumes](/docs/concepts/storage/persistent-volumes/)
* [Persistent Volume Provisioning](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/README.md)
You need a working Kubernetes cluster at version >= 1.3, with a healthy DNS [cluster addon](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/README.md) at version >= 15. You cannot use PetSet on a hosted Kubernetes provider that has disabled `alpha` resources.
## What is a PetSet?
In Kubernetes, most pod management abstractions group them into disposable units of work that compose a micro service. Replication controllers for example, are designed with a weak guarantee - that there should be N replicas of a particular pod template. The pods are treated as stateless units, if one of them is unhealthy or superseded by a newer version, the system just disposes it.
```
foo.default.svc.cluster.local
|service|
/ \
| pod-asdf | | pod-zxcv |
```
A PetSet, in contrast, is a group of stateful pods that require a stronger notion of identity. The document refers to these as "clustered applications".
```
*.foo.default.svc.cluster.local
| mysql-0 | <-> | mysql-1 |
[pv 0] [pv 1]
```
The co-ordinated deployment of clustered applications is notoriously hard. They require stronger notions of identity and membership, which they use in opaque internal protocols, and are especially prone to race conditions and deadlock. Traditionally administrators have deployed these applications by leveraging nodes as stable, long-lived entities with persistent storage and static ips.
The goal of PetSet is to decouple this dependency by assigning identities to individual instances of an application that are not anchored to the underlying physical infrastructure. For the rest of this document we will refer to these entities as "Pets". Our use of this term is predated by the "Pets vs Cattle" analogy.
__Relationship between Pets and Pods__: PetSet requires there be {0..N-1} Pets. Each Pet has a deterministic name - PetSetName-Ordinal, and a unique identity. Each Pet has at most one pod, and each PetSet has at most one Pet with a given identity.
## When to use PetSet?
A PetSet ensures that a specified number of "pets" with unique identities are running at any given time. The identity of a Pet is comprised of:
* a stable hostname, available in DNS
* an ordinal index
* stable storage: linked to the ordinal & hostname
These properties are useful in deploying stateful applications. However most stateful applications are also clustered, meaning they form groups with strict membership requirements that rely on stored state. PetSet also helps with the 2 most common problems encountered managing such clustered applications:
* discovery of peers for quorum
* startup/teardown ordering
Only use PetSet if your application requires some or all of these properties. Managing pods as stateless replicas is vastly easier.
Example workloads for PetSet:
* Databases like MySQL or PostgreSQL that require a single instance attached to an NFS persistent volume at any time
* Clustered software like Zookeeper, Etcd, or Elasticsearch that require stable membership.
## Alpha limitations
Before you start deploying applications as PetSets, there are a few limitations you should understand.
* PetSet is an *alpha* resource, not available in any Kubernetes release prior to 1.3.
* As with all alpha/beta resources, it can be disabled through the `--runtime-config` option passed to the apiserver, and in fact most likely will be disabled on hosted offerings of Kubernetes.
* The only updatable field on a PetSet is `replicas`.
* The storage for a given pet must either be provisioned by a [persistent volume provisioner](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin. Note that persistent volume provisioning is also currently in alpha.
* Deleting and/or scaling a PetSet down will *not* delete the volumes associated with the PetSet. This is done to ensure safety first, your data is more valuable than an auto purge of all related PetSet resources. **Deleting the Persistent Volume Claims will result in a deletion of the associated volumes**.
* All PetSets currently require a "governing service", or a Service responsible for the network identity of the pets. The user is responsible for this Service.
* Updating an existing PetSet is currently a manual process, meaning you either need to deploy a new PetSet with the new image version, or orphan Pets one by one, update their image, and join them back to the cluster.
## Example PetSet
We'll create a basic PetSet to demonstrate how Pets are assigned unique and "sticky" identities.
{% include code.html language="yaml" file="petset.yaml" ghlink="/docs/concepts/workloads/controllers/petset.yaml" %}
Saving this config into `petset.yaml` and submitting it to a Kubernetes cluster should create the defined PetSet and Pets it manages:
```shell
$ kubectl create -f petset.yaml
service "nginx" created
petset "web" created
```
## Pet Identity
The identity of a Pet sticks to it, regardless of which node it's (re) scheduled on. We can examine the identity of the pets we just created.
### Ordinal index
you should see 2 pods with predictable names formatted thus: `$(petset name)-$(ordinal index assigned by petset controller)`
```shell
$ kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 10m
web-1 1/1 Running 0 10m
```
### Stable storage
2 persistent volumes, one per pod. This is auto created by the PetSet based on the `volumeClaimTemplate` field
```shell
$ kubectl get pv
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE
pvc-90234946-3717-11e6-a46e-42010af00002 1Gi RWO Bound default/www-web-0 11m
pvc-902733c2-3717-11e6-a46e-42010af00002 1Gi RWO Bound default/www-web-1 11m
```
### Network identity
The network identity has 2 parts. First, we created a headless Service that controls the domain within which we create Pets. The domain managed by this Service takes the form: `$(service name).$(namespace).svc.cluster.local`, where "cluster.local" is the [cluster domain](/docs/concepts/services-networking/dns-pod-service/). As each pet is created, it gets a matching DNS subdomain, taking the form: `$(petname).$(governing service domain)`, where the governing service is defined by the `serviceName` field on the PetSet.
Here are some examples of choices for Cluster Domain, Service name, PetSet name, and how that affects the DNS names for the Pets and the hostnames in the Pet's pods:
Cluster Domain | Service (ns/name) | PetSet (ns/name) | PetSet Domain | Pet DNS | Pet Hostname |
-------------- | ----------------- | ----------------- | -------------- | ------- | ------------ |
cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
Note that Cluster Domain will be set to `cluster.local` unless [otherwise configured](https://github.com/kubernetes/kubernetes/blob/master/examples/cluster-dns/README.md).
Let's verify our assertion with a simple test.
```shell
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx None <none> 80/TCP 12m
...
```
First, the PetSet provides a stable hostname:
```shell
$ for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1
```
And the hostname is linked to the in-cluster DNS address:
```shell
$ kubectl run -i --tty --image busybox dns-test --restart=Never /bin/sh
dns-test # nslookup web-0.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.180.3.5
dns-test # nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.180.0.9
```
The containers are running nginx webservers, which by default will look for an index.html file in `/usr/share/nginx/html/index.html`. That directory is backed by a `PersistentVolume` created by the PetSet. So let's write our hostname there:
```shell
$ for i in 0 1; do
kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html';
done
```
And verify each webserver serves its own hostname:
```shell
$ for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
web-0
web-1
```
Now delete all pods in the petset:
```shell
$ kubectl delete po -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
```
Wait for them to come back up, and try to retrieve the previously written hostname through the DNS name of the peer. They match, because the storage, DNS name, and hostname stick to the Pet no matter where it gets scheduled:
```shell
$ kubectl exec -it web-1 -- curl web-0.nginx
web-0
$ kubectl exec -it web-0 -- curl web-1.nginx
web-1
```
## Peer discovery
A pet can piece together its own identity:
1. Use the [downward api](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) to find its pod name
2. Run `hostname` to find its DNS name
3. Run `mount` or `df` to find its volumes (usually this is unnecessary)
It's not necessary to "discover" the governing Service of a PetSet, since it's known at creation time you can simply pass it down through an [environment variable](/docs/user-guide/environment-guide).
Usually pets also need to find their peers. In the previous nginx example, we just used `kubectl` to get the names of existing pods, and as humans, we could tell which ones belonged to a given PetSet. Another way to find peers is by contacting the API server, just like `kubectl`, but that has several disadvantages (you end up implementing a Kubernetes specific init system that runs as pid 1 in your application container).
PetSet gives you a way to discover your peers using DNS records. To illustrate this we can use the previous example (note: one usually doesn't `apt-get` in a container).
```shell
$ kubectl exec -it web-0 /bin/sh
web-0 # apt-get update && apt-get install -y dnsutils
...
web-0 # nslookup -type=srv nginx.default
Server: 10.0.0.10
Address: 10.0.0.10#53
nginx.default.svc.cluster.local service = 10 50 0 web-1.ub.default.svc.cluster.local.
nginx.default.svc.cluster.local service = 10 50 0 web-0.ub.default.svc.cluster.local.
```
## Updating a PetSet
You cannot update any field of the PetSet except `spec.replicas` and the `containers` in the podTemplate. Updating `spec.replicas` will scale the PetSet, updating `containers` will not have any effect till a Pet is deleted, at which time it is recreated with the modified podTemplate.
## Scaling a PetSet
You can scale a PetSet by updating the "replicas" field. Note however that the controller will only:
1. Create one pet at a time, in order from {0..N-1}, and wait till each one is in [Running and Ready](/docs/user-guide/pod-states) before creating the next
2. Delete one pet at a time, in reverse order from {N-1..0}, and wait till each one is completely shutdown (past its [terminationGracePeriodSeconds](/docs/concepts/workloads/pods/pod/#termination-of-pods) before deleting the next
```shell
$ kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 30s
web-1 1/1 Running 0 36s
$ kubectl patch petset web -p '{"spec":{"replicas":3}}'
petset "web" patched
$ kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 40s
web-1 1/1 Running 0 46s
web-2 1/1 Running 0 8s
```
You can also use the `kubectl scale` command:
```shell
$ kubectl get petset
NAME DESIRED CURRENT AGE
web 3 3 24m
$ kubectl scale petset web --replicas=5
petset "web" scaled
$ kubectl get po --watch-only
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 10m
web-1 1/1 Running 0 27m
web-2 1/1 Running 0 10m
web-3 1/1 Running 0 3m
web-4 0/1 ContainerCreating 0 48s
$ kubectl get petset web
NAME DESIRED CURRENT AGE
web 5 5 30m
```
Note however, that scaling up to N and back down to M *will not* delete the volumes of the M-N pets, as described in the section on [deletion](#deleting-a-petset), i.e. scaling back up to M creates new pets that use the same volumes. To see this in action, scale the PetSet back down to 3:
```shell
$ kubectl get po --watch-only
web-4 1/1 Terminating 0 4m
web-4 1/1 Terminating 0 4m
web-3 1/1 Terminating 0 6m
web-3 1/1 Terminating 0 6m
```
Note that we still have 5 pvcs:
```shell
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-42ca5cef-8113-11e6-82f6-42010af00002 1Gi RWO 32m
www-web-1 Bound pvc-42de30af-8113-11e6-82f6-42010af00002 1Gi RWO 32m
www-web-2 Bound pvc-ba416413-8115-11e6-82f6-42010af00002 1Gi RWO 14m
www-web-3 Bound pvc-ba45f19c-8115-11e6-82f6-42010af00002 1Gi RWO 14m
www-web-4 Bound pvc-ba47674a-8115-11e6-82f6-42010af00002 1Gi RWO 14m
```
This allows you to upgrade the image of a petset and have it come back up with the same data, as described in the next section.
## Image upgrades
PetSet currently *does not* support automated image upgrade as noted in the section on [limitations](#alpha-limitations), however you can update the `image` field of any container in the podTemplate and delete Pets one by one, the PetSet controller will recreate it with the new image.
Edit the image on the PetSet to `gcr.io/google_containers/nginx-slim:0.7` and delete 1 Pet:
```shell{% raw %}
$ for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
gcr.io/google_containers/nginx-slim:0.8
gcr.io/google_containers/nginx-slim:0.8
gcr.io/google_containers/nginx-slim:0.8
$ kubectl delete po web-0
pod "web-0" deleted
$ for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
gcr.io/google_containers/nginx-slim:0.7
gcr.io/google_containers/nginx-slim:0.8
gcr.io/google_containers/nginx-slim:0.8
{% endraw %}```
Delete the remaining 2:
```shell
$ kubectl delete po web-1 web-2
pod "web-1" deleted
pod "web-2" deleted
```
Wait till the PetSet is stable and check the images:
```shell{% raw %}
$ for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
gcr.io/google_containers/nginx-slim:0.7
gcr.io/google_containers/nginx-slim:0.7
gcr.io/google_containers/nginx-slim:0.7
{% endraw %}```
## Deleting a PetSet
Deleting a PetSet through kubectl will scale it down to 0, thereby deleting all the Pets. If you wish to delete just the PetSet and not the Pets, use `--cascade=false`:
```shell
$ kubectl delete -f petset.yaml --cascade=false
petset "web" deleted
$ kubectl get po -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 21h
web-1 1/1 Running 0 21h
$ kubectl delete po -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
```
Deleting the pods will *not* delete the volumes. Until we finalize the recycle policy for these volumes they will have to get cleaned up by an admin. This is to ensure that you have the chance to copy data off the volume before deleting it. Simply deleting the PVC after the pods have left the [terminating state](/docs/concepts/workloads/pods/pod/#termination-of-pods) should trigger deletion of the backing Persistent Volumes.
**Note: you will lose all your data once the PVC is deleted, do this with caution.**
```shell
$ kubectl get po -l app=nginx
$ kubectl get pvc -l app=nginx
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-62d271cd-3822-11e6-b1b7-42010af00002 0 21h
www-web-1 Bound pvc-62d6750e-3822-11e6-b1b7-42010af00002 0 21h
$ kubectl delete pvc -l app=nginx
$ kubectl get pv
```
If you simply want to clean everything:
```shell{% raw %}
$ grace=$(kubectl get po web-0 --template '{{.spec.terminationGracePeriodSeconds}}')
$ kubectl delete petset,po -l app=nginx
$ sleep $grace
$ kubectl delete pvc -l app=nginx
{% endraw %}
```
## Troubleshooting
You might have noticed an `annotations` field in all the PetSets shown above.
```yaml
annotations:
pod.alpha.kubernetes.io/initialized: "true"
```
This field is a debugging hook. It pauses any scale up/down operations on the entire PetSet. If you'd like to pause a petset after each pet, set it to `false` in the template, wait for each pet to come up, verify it has initialized correctly, and then set it to `true` using `kubectl edit` on the pet (setting it to `false` on *any pet* is enough to pause the PetSet). If you don't need it, create the PetSet with it set to `true` as shown. This is surprisingly useful in debugging bootstrapping race conditions.
## Future Work
There are a LOT of planned improvements since PetSet is still in alpha.
* Data gravity and local storage
* Richer notification events
* Public network identities
* WAN cluster deployments (multi-AZ/region/cloud provider)
* Image and node upgrades
This list goes on, if you have examples, ideas or thoughts, please contribute.
## Alternatives
Deploying one RC of size 1/Service per pod is a popular alternative, as is simply deploying a DaemonSet that utilizes the identity of a Node.
## Next steps
* Learn about [StatefulSet](/docs/concepts/abstractions/controllers/statefulsets/),
the replacement for PetSet introduced in Kubernetes version 1.5.
* [Migrate your existing PetSets to StatefulSets](/docs/tasks/manage-stateful-set/upgrade-pet-set-to-stateful-set/)
when upgrading to Kubernetes version 1.5 or higher.
@@ -1,51 +0,0 @@
# A headless service to create DNS records
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
# *.nginx.default.svc.cluster.local
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1alpha1
kind: PetSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
annotations:
pod.alpha.kubernetes.io/initialized: "true"
spec:
terminationGracePeriodSeconds: 0
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
annotations:
volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
+127 -12
View File
@@ -17,7 +17,6 @@ whereas a Replication Controller only supports equality-based selector requireme
{% endcapture %}
{% capture body %}
## How to use a ReplicaSet
@@ -52,20 +51,21 @@ use a Deployment instead, and define your application in the spec section.
{% include code.html language="yaml" file="frontend.yaml" ghlink="/docs/concepts/workloads/controllers/frontend.yaml" %}
Saving this config into `frontend.yaml` and submitting it to a Kubernetes cluster should
Saving this manifest into `frontend.yaml` and submitting it to a Kubernetes cluster should
create the defined ReplicaSet and the pods that it manages.
```shell
$ kubectl create -f frontend.yaml
replicaset "frontend" created
$ kubectl describe rs/frontend
Name: frontend
Namespace: default
Selector: tier=frontend,tier in (frontend)
Labels: app=guestbook,tier=frontend
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Name: frontend
Namespace: default
Selector: tier=frontend,tier in (frontend)
Labels: app=guestbook
tier=frontend
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=guestbook
tier=frontend
@@ -93,7 +93,98 @@ frontend-dnjpy 1/1 Running 0 1m
frontend-qhloh 1/1 Running 0 1m
```
## ReplicaSet as an Horizontal Pod Autoscaler target
## Writing a ReplicaSet Spec
As with all other Kubernetes API objects, a ReplicaSet needs the `apiVersion`, `kind`, and `metadata` fields. For
general information about working with manifests, see [here](/docs/user-guide/simple-yaml/),
[here](/docs/user-guide/configuring-containers/), and [here](/docs/concepts/tools/kubectl/object-management-overview/).
A ReplicaSet also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status).
### Pod Template
The `.spec.template` is the only required field of the `.spec`. The `.spec.template` is a
[pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a
[pod](/docs/concepts/workloads/pods/pod/), except that it is nested and does not have an `apiVersion` or `kind`.
In addition to required fields of a pod, a pod template in a ReplicaSet must specify appropriate
labels and an appropriate restart policy.
For labels, make sure to not overlap with other controllers. For more information, see [pod selector](#pod-selector).
For [restart policy](/docs/concepts/workloads/pods/pod-lifecycle/), the only allowed value for `.spec.template.spec.restartPolicy` is `Always`, which is the default.
For local container restarts, ReplicaSet delegates to an agent on the node,
for example the [Kubelet](/docs/admin/kubelet/) or Docker.
### Pod Selector
The `.spec.selector` field is a [label selector](/docs/user-guide/labels/#label-selectors). A ReplicaSet
manages all the pods with labels that match the selector. It does not distinguish
between pods that it created or deleted and pods that another person or process created or
deleted. This allows the ReplicaSet to be replaced without affecting the running pods.
The `.spec.template.metadata.labels` must match the `.spec.selector`, or it will
be rejected by the API.
In Kubernetes 1.8 the API version `apps/v1beta2` on the ReplicaSet kind is the current version and is enabled by default. The API version `extensions/v1beta1` is deprecated. In API version `apps/v1beta2`, `.spec.selector` and `.metadata.labels` no longer default to `.spec.template.metadata.labels` if not set. So they must be set explicitly. Also note that `.spec.selector` is immutable after creation starting in API version `apps/v1beta2`.
Also you should not normally create any pods whose labels match this selector, either directly, with
another ReplicaSet, or with another controller such as a Deployment. If you do so, the ReplicaSet thinks that it
created the other pods. Kubernetes does not stop you from doing this.
If you do end up with multiple controllers that have overlapping selectors, you
will have to manage the deletion yourself.
### Labels on a ReplicaSet
The ReplicaSet can itself have labels (`.metadata.labels`). Typically, you
would set these the same as the `.spec.template.metadata.labels`. However, they are allowed to be
different, and the `.metadata.labels` do not affect the behavior of the ReplicaSet.
### Replicas
You can specify how many pods should run concurrently by setting `.spec.replicas`. The number running at any time may be higher
or lower, such as if the replicas were just increased or decreased, or if a pod is gracefully
shut down, and a replacement starts early.
If you do not specify `.spec.replicas`, then it defaults to 1.
## Working with ReplicaSets
### Deleting a ReplicaSet and its Pods
To delete a ReplicaSet and all its pods, use [`kubectl
delete`](/docs/user-guide/kubectl/{{page.version}}/#delete). Kubectl will scale the ReplicaSet to zero and wait
for it to delete each pod before deleting the ReplicaSet itself. If this kubectl command is interrupted, it can
be restarted.
When using the REST API or go client library, you need to do the steps explicitly (scale replicas to
0, wait for pod deletions, then delete the ReplicaSet).
### Deleting just a ReplicaSet
You can delete a ReplicaSet without affecting any of its pods, using [`kubectl delete`](/docs/user-guide/kubectl/{{page.version}}/#delete) with the `--cascade=false` option.
When using the REST API or go client library, simply delete the ReplicaSet object.
Once the original is deleted, you can create a new ReplicaSet to replace it. As long
as the old and new `.spec.selector` are the same, then the new one will adopt the old pods.
However, it will not make any effort to make existing pods match a new, different pod template.
To update pods to a new spec in a controlled way, use a [rolling update](#rolling-updates).
### Isolating pods from a ReplicaSet
Pods may be removed from a ReplicaSet's target set by changing their labels. This technique may be used to remove pods
from service for debugging, data recovery, etc. Pods that are removed in this way will be replaced automatically (
assuming that the number of replicas is not also changed).
### Scaling a ReplicaSet
A ReplicaSet can be easily scaled up or down by simply updating the `.spec.replicas` field. The ReplicaSet controller
ensures that that a desired number of pods with a matching label selector are available and operational.
### ReplicaSet as an Horizontal Pod Autoscaler Target
A ReplicaSet can also be a target for
[Horizontal Pod Autoscalers (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/). That is,
@@ -102,8 +193,7 @@ the ReplicaSet we created in the previous example.
{% include code.html language="yaml" file="hpa-rs.yaml" ghlink="/docs/concepts/workloads/controllers/hpa-rs.yaml" %}
Saving this config into `hpa-rs.yaml` and submitting it to a Kubernetes cluster should
Saving this manifest into `hpa-rs.yaml` and submitting it to a Kubernetes cluster should
create the defined HPA that autoscales the target ReplicaSet depending on the CPU usage
of the replicated pods.
@@ -118,6 +208,31 @@ Alternatively, you can use the `kubectl autoscale` command to accomplish the sam
kubectl autoscale rs frontend
```
## Alternatives to ReplicaSet
### Deployment (Recommended)
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying ReplicaSets and their Pods
in a similar fashion as `kubectl rolling-update`. Deployments are recommended if you want this rolling update functionality,
because unlike `kubectl rolling-update`, they are declarative, server-side, and have additional features. For more information on running a stateless
application using a Deployment, please read [Run a Stateless Application Using a Deployment](/docs/tasks/run-application/run-stateless-application-deployment/).
### Bare Pods
Unlike the case where a user directly created pods, a ReplicaSet replaces pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicaSet even if your application requires only a single pod. Think of it similarly to a process supervisor, only it supervises multiple pods across multiple nodes instead of individual processes on a single node. A ReplicaSet delegates local container restarts to some agent on the node (for example, Kubelet or Docker).
### Job
Use a [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) instead of a ReplicaSet for pods that are expected to terminate on their own
(that is, batch jobs).
### DaemonSet
Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicaSet for pods that provide a
machine-level function, such as machine monitoring or machine logging. These pods have a lifetime that is tied
to a machine lifetime: the pod needs to be running on the machine before other pods start, and are
safe to terminate when the machine is otherwise ready to be rebooted/shutdown.
{% endcapture %}
{% include templates/concept.md %}
@@ -10,10 +10,8 @@ title: StatefulSets
---
{% capture overview %}
**StatefulSets are a beta feature in 1.7. This feature replaces the
PetSets feature from 1.4. Users of PetSets are referred to the 1.5
[Upgrade Guide](/docs/tasks/run-application/upgrade-pet-set-to-stateful-set/)
for further information on how to upgrade existing PetSets to StatefulSets.**
**StatefulSet is the workload API object used to manage stateful applications.
StatefulSets are beta in 1.8.**
{% include templates/glossary/snippet.md term="statefulset" length="long" %}
{% endcapture %}
@@ -51,8 +49,7 @@ The example below demonstrates the components of a StatefulSet.
* A Headless Service, named nginx, is used to control the network domain.
* The StatefulSet, named web, has a Spec that indicates that 3 replicas of the nginx container will be launched in unique Pods.
* The volumeClaimTemplates will provide stable storage using [PersistentVolumes](/docs/concepts/storage/volumes/) provisioned by a
PersistentVolume Provisioner.
* The volumeClaimTemplates will provide stable storage using [PersistentVolumes](/docs/concepts/storage/volumes/) provisioned by a PersistentVolume Provisioner.
```yaml
apiVersion: v1
@@ -69,17 +66,20 @@ spec:
selector:
app: nginx
---
apiVersion: apps/v1beta1
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
@@ -102,6 +102,9 @@ spec:
storage: 1Gi
```
## Pod Selector
You must set the `spec.selector` field of a StatefulSet to match the labels of its `.spec.template.metadata.labels`. Prior to Kubernetes 1.8, the `spec.selector` field was defaulted when omitted. In 1.8 and later versions, failing to specify a matching Pod Selector will result in a validation error during StatefulSet creation.
## Pod Identity
StatefulSet Pods have a unique identity that is comprised of an ordinal, a
stable network identity, and stable storage. The identity sticks to the Pod,
@@ -14,7 +14,8 @@ scripts not present in an app image.
This feature has exited beta in 1.6. Init Containers can be specified in the PodSpec
alongside the app `containers` array. The beta annotation value will still be respected
and overrides the PodSpec field value.
and overrides the PodSpec field value, however, they are deprecated in 1.6 and 1.7.
In 1.8, the annotations are no longer supported and must be converted to the PodSpec field.
{% capture body %}
## Understanding Init Containers
@@ -123,7 +124,7 @@ spec:
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
```
There is a new syntax in Kubernetes 1.6, although the old annotation syntax still works. We have moved the declaration of init containers to `spec`:
There is a new syntax in Kubernetes 1.6, although the old annotation syntax still works for 1.6 and 1.7. The new syntax must be used for 1.8 or greater. We have moved the declaration of init containers to `spec`:
```yaml
apiVersion: v1
@@ -146,7 +147,7 @@ spec:
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
```
1.5 syntax still works on 1.6, but we recommend using 1.6 syntax. In Kubernetes 1.6, Init Containers were made a field in the API. The beta annotation is still respected but will be deprecated in future releases.
1.5 syntax still works on 1.6, but we recommend using 1.6 syntax. In Kubernetes 1.6, Init Containers were made a field in the API. The beta annotation is still respected in 1.6 and 1.7, but is not supported in 1.8 or greater.
Yaml file below outlines the `mydb` and `myservice` services:
@@ -311,6 +312,10 @@ into alpha and beta annotations so that Kubelets version 1.3.0 or greater can ex
Init Containers, and so that a version 1.6 apiserver can safely be rolled back to version
1.5.x without losing Init Container functionality for existing created pods.
In Apiserver and Kubelet versions 1.8.0 or greater, support for the alpha and beta annotations
is removed, requiring a conversion from the deprecated annotations to the
`spec.initContainers` field.
{% endcapture %}
+1 -1
View File
@@ -150,7 +150,7 @@ Pod is exposed as a primitive in order to facilitate:
* clean composition of Kubelet-level functionality with cluster-level functionality &mdash; Kubelet is effectively the "pod controller"
* high-availability applications, which will expect pods to be replaced in advance of their termination and certainly in advance of deletion, such as in the case of planned evictions, image prefetching, or live pod migration [#3949](http://issue.k8s.io/3949)
There is new first-class support for stateful pods with the [StatefulSet](/docs/concepts/abstractions/controllers/statefulsets/) controller (currently in beta). The feature was alpha in 1.4 and was called [PetSet](/docs/concepts/workloads/controllers/petset/). For prior versions of Kubernetes, best practice for having stateful pods is to create a replication controller with `replicas` equal to `1` and a corresponding service, see [this MySQL deployment example](/docs/tutorials/stateful-application/run-stateful-application/).
There is new first-class support for stateful pods with the [StatefulSet](/docs/concepts/workloads/controllers/statefulset.md) controller (currently in beta). The feature was alpha in 1.4 and was called PetSet. For prior versions of Kubernetes, best practice for having stateful pods is to create a replication controller with `replicas` equal to `1` and a corresponding service, see [this MySQL deployment example](/docs/tutorials/stateful-application/run-stateful-application/).
## Termination of Pods