Merge remote-tracking branch 'upstream/master' into release-1.5

This commit is contained in:
Devin Donnelly
2016-11-29 17:08:38 -08:00
100 changed files with 2353 additions and 2091 deletions
+3 -2
View File
@@ -129,7 +129,7 @@ To use it,
* Write an application atop of the client-go clients. Note that client-go defines its own API objects, so if needed, please import API definitions from client-go rather than from the main repository, e.g., `import "k8s.io/client-go/1.4/pkg/api/v1"` is correct.
The Go client can use the same [kubeconfig file](/docs/user-guide/kubeconfig-file)
as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://github.com/kubernetes/client-go/examples/out-of-cluster.go):
as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://github.com/kubernetes/client-go/blob/master/examples/out-of-cluster/main.go):
```golang
import (
@@ -183,7 +183,8 @@ From within a pod the recommended ways to connect to API are:
in any container of the pod can access it. See this [example of using kubectl proxy
in a pod](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/kubectl-container/).
- use the Go client library, and create a client using the `client.NewInCluster()` factory.
This handles locating and authenticating to the apiserver. [example](https://github.com/kubernetes/client-go/examples/in-cluster.go)
This handles locating and authenticating to the apiserver. See this [example of using Go client
library in a pod](https://github.com/kubernetes/client-go/blob/master/examples/in-cluster/main.go).
In each case, the credentials of the pod are used to communicate securely with the apiserver.
+1 -1
View File
@@ -12,7 +12,7 @@ assignees:
In addition to the imperative-style commands, such as `kubectl run` and `kubectl expose`, described [elsewhere](/docs/user-guide/quick-start), Kubernetes supports declarative configuration. Oftentimes, configuration files are preferable to imperative commands, since they can be checked into version control and changes to the files can be code reviewed, which is especially important for more complex configurations, producing a more robust, reliable and archival system.
In the declarative style, all configuration is stored in YAML or JSON configuration files using Kubernetes's API resource schemas as the configuration schemas. `kubectl` can create, update, delete, and get API resources. The `apiVersion` (currently 'v1'?), resource `kind`, and resource `name` are used by `kubectl` to construct the appropriate API path to invoke for the specified operation.
In the declarative style, all configuration is stored in YAML or JSON configuration files using Kubernetes's API resource schemas as the configuration schemas. `kubectl` can create, update, delete, and get API resources. The `apiVersion` (currently `v1`?), resource `kind`, and resource `name` are used by `kubectl` to construct the appropriate API path to invoke for the specified operation.
## Launching a container using a configuration file
@@ -9,16 +9,22 @@ assignees:
* TOC
{:toc}
## What is a _Scheduled Job_?
## What is a _Cron Job_?
A _Scheduled Job_ manages time based [Jobs](/docs/user-guide/jobs/), namely:
A _Cron Job_ manages time based [Jobs](/docs/user-guide/jobs/), namely:
* Once at a specified point in time
* Repeatedly at a specified point in time
One ScheduledJob object is like one line of a _crontab_ (cron table) file. It runs a job periodically
One CronJob object is like one line of a _crontab_ (cron table) file. It runs a job periodically
on a given schedule, written in [Cron](https://en.wikipedia.org/wiki/Cron) format.
**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.
A typical use case is:
* Schedule a job execution at a given point in time.
@@ -26,41 +32,41 @@ A typical use case is:
### Prerequisites
You need a working Kubernetes cluster at version >= 1.4, with batch/v2alpha1 API turned on by passing
`--runtime-config=batch/v2alpha1` while bringing up 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). You cannot use Scheduled Jobs on a hosted Kubernetes provider that has disabled alpha resources.
You need a working Kubernetes cluster at version >= 1.4 (for ScheduledJob), >= 1.5 (for CronJobs),
with batch/v2alpha1 API turned on by passing `--runtime-config=batch/v2alpha1` while bringing up
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). You cannot use Cron Jobs on a hosted Kubernetes provider that has disabled alpha resources.
## Creating a Scheduled Job
## Creating a Cron Job
Here is an example Scheduled Job. Every minute, it runs a simple job to print current time and then say
Here is an example Cron Job. Every minute, it runs a simple job to print current time and then say
hello.
{% include code.html language="yaml" file="sj.yaml" ghlink="/docs/user-guide/sj.yaml" %}
{% include code.html language="yaml" file="cronjob.yaml" ghlink="/docs/user-guide/cronjob.yaml" %}
Run the example scheduled job by downloading the example file and then running this command:
Run the example cron job by downloading the example file and then running this command:
```shell
$ kubectl create -f ./sj.yaml
scheduledjob "hello" created
$ kubectl create -f ./cronjob.yaml
cronjob "hello" created
```
Alternatively, use `kubectl run` to create a scheduled job without writing full config:
Alternatively, use `kubectl run` to create a cron job without writing full config:
```shell
$ kubectl run hello --schedule="0/1 * * * ?" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
scheduledjob "hello" created
$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
cronjob "hello" created
```
After creating the scheduled job, get its status using this command:
After creating the cron job, get its status using this command:
```shell
$ kubectl get scheduledjob hello
$ kubectl get cronjob hello
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
hello 0/1 * * * ? False 0 <none>
hello */1 * * * * False 0 <none>
```
As you can see above, there's no active job yet, and no job has been scheduled, either.
As you can see above, there's no active job yet, and no job has been scheduled, either.
Watch for the job to be created in around one minute:
@@ -70,16 +76,16 @@ NAME DESIRED SUCCESSFUL AGE
hello-4111706356 1 1 2s
```
Now you've seen one running job scheduled by "hello". We can stop watching it and get the scheduled job again:
Now you've seen one running job scheduled by "hello". We can stop watching it and get the cron job again:
```shell
$ kubectl get scheduledjob hello
$ kubectl get cronjob hello
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
hello 0/1 * * * ? False 0 Mon, 29 Aug 2016 14:34:00 -0700
hello */1 * * * * False 0 Mon, 29 Aug 2016 14:34:00 -0700
```
You should see that "hello" successfully scheduled a job at the time specified in `LAST-SCHEDULE`. There are
currently 0 active jobs, meaning that the job that's scheduled is completed or failed.
currently 0 active jobs, meaning that the job that's scheduled is completed or failed.
Now, find the pods created by the job last scheduled and view the standard output of one of the pods. Note that
your job name and pod name would be different.
@@ -96,17 +102,17 @@ Mon Aug 29 21:34:09 UTC 2016
Hello from the Kubernetes cluster
```
## Deleting a Scheduled Job
## Deleting a Cron Job
Once you don't need a scheduled job anymore, simply delete it with `kubectl`:
Once you don't need a cron job anymore, simply delete it with `kubectl`:
```shell
$ kubectl delete scheduledjob hello
scheduledjob "hello" deleted
$ 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 scheduled job, and delete them all:
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
@@ -121,34 +127,34 @@ job "hello-1202039034" deleted
...
```
Once the jobs are deleted, the pods created by them are deleted as well. Note that all jobs created by scheduled
job "hello" will be prefixed "hello-". You can delete them at once with `kubectl delete jobs --all`, if you want to
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".)
## Scheduled Job Limitations
## Cron Job Limitations
A scheduled job creates a job object _about_ once per execution time of its schedule. We say "about" because there
A cron job creates a job object _about_ once per execution time of its schedule. We say "about" because there
are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare,
but do not completely prevent them. Therefore, jobs should be _idempotent_.
The job is responsible for retrying pods, parallelism among pods it creates, and determining the success or failure
of the set of pods. A scheduled job does not examine pods at all.
of the set of pods. A cron job does not examine pods at all.
## Writing a Scheduled Job Spec
## Writing a Cron Job Spec
As with all other Kubernetes configs, a scheduled job needs `apiVersion`, `kind`, and `metadata` fields. For general
information about working with config files, see [deploying applications](/docs/user-guide/deploying-applications),
As with all other Kubernetes configs, a cron job needs `apiVersion`, `kind`, and `metadata` fields. For general
information about working with config files, see [deploying applications](/docs/user-guide/deploying-applications),
[configuring containers](/docs/user-guide/configuring-containers), and
[using kubectl to manage resources](/docs/user-guide/working-with-resources) documents.
A scheduled job also needs a [`.spec` section](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status).
A cron job also needs a [`.spec` section](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status).
**Note:** All modifications to a scheduled job, especially its `.spec`, will be applied only to the next run.
**Note:** All modifications to a cron job, especially its `.spec`, will be applied only to the next run.
### Schedule
### Schedule
The `.spec.schedule` is a required field of the `.spec`. It takes a [Cron](https://en.wikipedia.org/wiki/Cron) format
string, e.g. `0 * * * *` or `@hourly`, as schedule time of its jobs to be created and executed.
string, e.g. `0 * * * *` or `@hourly`, as schedule time of its jobs to be created and executed.
### Job Template
@@ -159,22 +165,22 @@ as a [Job](/docs/user-guide/jobs), except it is nested and does not have an `api
### Starting Deadline Seconds
The `.spec.startingDeadlineSeconds` field is optional. It stands for the deadline (in seconds) for starting the job
if it misses its scheduled time for any reason. Missed jobs executions will be counted as failed ones. If not specified,
there's no deadline.
if it misses its scheduled time for any reason. Missed jobs executions will be counted as failed ones. If not specified,
there's no deadline.
### Concurrency Policy
The `.spec.concurrencyPolicy` field is also optional. It specifies how to treat concurrent executions of a job
created by this scheduled job. Only one of the following concurrent policies may be specified:
created by this cron job. Only one of the following concurrent policies may be specified:
* `Allow` (default): allows concurrently running jobs
* `Forbid`: forbids concurrent runs, skipping next run if previous hasn't finished yet
* `Replace`: cancels currently running job and replaces it with a new one
Note that concurrency policy only applies to the jobs created by the same scheduled job. If there are multiple
scheduled jobs, their respective jobs are always allowed to run concurrently.
Note that concurrency policy only applies to the jobs created by the same cron job. If there are multiple
cron jobs, their respective jobs are always allowed to run concurrently.
### Suspend
The `.spec.suspend` field is also optional. If set to `true`, all subsequent executions will be suspended. It does not
apply to already started executions. Defaults to false.
The `.spec.suspend` field is also optional. If set to `true`, all subsequent executions will be suspended. It does not
apply to already started executions. Defaults to false.
@@ -1,9 +1,9 @@
apiVersion: batch/v2alpha1
kind: ScheduledJob
kind: CronJob
metadata:
name: hello
spec:
schedule: 0/1 * * * ?
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
+62 -12
View File
@@ -64,12 +64,12 @@ healthy backend service endpoint at all times, even in the event of
pod, cluster,
availability zone or regional outages.
Note that in the
case of Google Cloud, the logical L7 load balancer is not a single physical device (which
would present both a single point of failure, and a single global
network routing choke point), but rather a [truly global, highly available
load balancing managed service](https://cloud.google.com/load-balancing/),
globally reachable via a single, static IP address.
Note that in the case of Google Cloud, the logical L7 load balancer is
not a single physical device (which would present both a single point
of failure, and a single global network routing choke point), but
rather a
[truly global, highly available load balancing managed service](https://cloud.google.com/load-balancing/),
globally reachable via a single, static IP address.
Clients inside your federated Kubernetes clusters (i.e. Pods) will be
automatically routed to the cluster-local shard of the Federated Service
@@ -86,13 +86,13 @@ You can create a federated ingress in any of the usual ways, for example using k
``` shell
kubectl --context=federation-cluster create -f myingress.yaml
```
For example ingress YAML configurations, see the [Ingress User Guide](/docs/user-guide/ingress/)
The '--context=federation-cluster' flag tells kubectl to submit the
request to the Federation API endpoint, with the appropriate
credentials. If you have not yet configured such a context, visit the
[federation admin guide](/docs/admin/federation/) or one of the
[administration tutorials](https://github.com/kelseyhightower/kubernetes-cluster-federation)
to find out how to do so. TODO: Update links
to find out how to do so.
As described above, the Federated Ingress will automatically create
and maintain matching Kubernetes ingresses in all of the clusters
@@ -147,17 +147,28 @@ Events:
2m 2m 1 {loadbalancer-controller } Normal CREATE ip: 130.211.5.194
```
Note the address of your Federated Ingress
Note that:
1. the address of your Federated Ingress
corresponds with the address of all of the
underlying Kubernetes ingresses (once these have been allocated - this
may take up to a few minutes).
Note also that we have not yet provisioned any backend Pods to receive
2. we have not yet provisioned any backend Pods to receive
the network traffic directed to this ingress (i.e. 'Service
Endpoints' behind the service backing the Ingress), so the Federated Ingress does not yet consider these to
be healthy shards and will not direct traffic to any of these clusters.
3. the federation control system will
automatically reconfigure the load balancer controllers in all of the
clusters in your federation to make them consistent, and allow
them to share global load balancers. But this reconfiguration can
only complete successfully if there are no pre-existing Ingresses in
those clusters (this is a safety feature to prevent accidental
breakage of existing ingresses). So to ensure that your federated
ingresses function correctly, either start with new, empty clusters, or make
sure that you delete (and recreate if necessary) all pre-existing
Ingresses in the clusters comprising your federation.
## Adding backend services and pods
#Adding backend services and pods
To render the underlying ingress shards healthy, we need to add
backend Pods behind the service upon which the Ingress is based. There are several ways to achieve this, but
@@ -175,6 +186,16 @@ kubectl --context=federation-cluster create -f services/nginx.yaml
kubectl --context=federation-cluster create -f myreplicaset.yaml
```
Note that in order for your federated ingress to work correctly on
Google Cloud, the node ports of all of the underlying cluster-local
services need to be identical. If you're using a federated service
this is easy to do. Simply pick a node port that is not already
being used in any of your clusters, and add that to the spec of your
federated service. If you do not specify a node port for your
federated service, each cluster will choose it's own node port for
its cluster-local shard of the service, and these will probably end
up being different, which is not what you want.
You can verify this by checking in each of the underlying clusters, for example:
``` shell
@@ -258,6 +279,35 @@ Check that:
`service-controller` or `replicaset-controller`,
errors in the output of `kubectl logs federation-controller-manager --namespace federation`).
#### I can create a federated ingress successfully, but request load is not correctly distributed across the underlying clusters
Check that:
1. the services underlying your federated ingress in each cluster have
identical node ports. See [above](#creating_a_federated_ingress) for further explanation.
2. the load balancer controllers in each of your clusters are of the
correct type ("GLBC") and have been correctly reconfigured by the
federation control plane to share a global GCE load balancer (this
should happen automatically). If they of the correct type, and
have been correctly reconfigured, the UID data item in the GLBC
configmap in each cluster will be identical across all clusters.
See
[the GLBC docs](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/BETA_LIMITATIONS.md#changing-the-cluster-uid)
for further details.
If this is not the case, check the logs of your federation
controller manager to determine why this automated reconfiguration
might be failing.
3. no ingresses have been manually created in any of your clusters before the above
reconfiguration of the load balancer controller completed
successfully. Ingresses created before the reconfiguration of
your GLBC will interfere with the behavior of your federated
ingresses created after the reconfiguration (see
[the GLBC docs](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/BETA_LIMITATIONS.md#changing-the-cluster-uid)
for further information. To remedy this,
delete any ingresses created before the cluster joined the
federation (and had it's GLBC reconfigured), and recreate them if
necessary.
#### This troubleshooting guide did not help me solve my problem
Please use one of our [support channels](http://kubernetes.io/docs/troubleshooting/) to seek assistance.
+1 -1
View File
@@ -5,7 +5,7 @@ assignees:
---
Each container in a pod has its own image. Currently, the only type of image supported is a [Docker Image](https://docs.docker.com/userguide/dockerimages/).
Each container in a pod has its own image. Currently, the only type of image supported is a [Docker Image](https://docs.docker.com/engine/tutorials/dockerimages/).
You create your Docker image and push it to a registry before referring to it in a Kubernetes pod.
+12 -12
View File
@@ -53,18 +53,18 @@ Make sure you review the [beta limitations](https://github.com/kubernetes/contri
A minimal Ingress might look like:
```yaml
01. apiVersion: extensions/v1beta1
02. kind: Ingress
03. metadata:
04. name: test-ingress
05. spec:
06. rules:
07. - http:
08. paths:
09. - path: /testpath
10. backend:
11. serviceName: test
12. servicePort: 80
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
```
*POSTing this to the API server will have no effect if you have not configured an [Ingress controller](#ingress-controllers).*
+2 -2
View File
@@ -380,6 +380,6 @@ driver, and then cleans up.
An advantage of this approach is that the overall process gets the completion guarantee of a Job
object, but complete control over what pods are created and how work is assigned to them.
## Scheduled Jobs
## Cron Jobs
Support for creating Jobs at specified times/dates (i.e. cron) is available in Kubernetes [1.4](https://github.com/kubernetes/kubernetes/pull/11980). More information is available in the [scheduled job documents](http://kubernetes.io/docs/user-guide/scheduled-jobs/)
Support for creating Jobs at specified times/dates (i.e. cron) is available in Kubernetes [1.4](https://github.com/kubernetes/kubernetes/pull/11980). More information is available in the [cron job documents](http://kubernetes.io/docs/user-guide/cron-jobs/)
+2 -2
View File
@@ -141,7 +141,7 @@ $ kubectl rolling-update frontend-v1 frontend-v2 --rollback # Abort exist
$ cat pod.json | kubectl replace -f - # Replace a pod based on the JSON passed into stdin
# Force replace, delete and then re-create the resource. Will cause a service outage.
$ kubectl replace --force -f ./pod.json
$ kubectl replace --force -f ./pod.json
# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000
$ kubectl expose rc nginx --port=80 --target-port=8000
@@ -251,7 +251,7 @@ Resource type | Abbreviated alias
`replicasets` |`rs`
`replicationcontrollers` |`rc`
`resourcequotas` |`quota`
`scheduledjob` |
`cronjob` |
`secrets` |
`serviceaccount` |`sa`
`services` |`svc`
+2 -2
View File
@@ -40,7 +40,7 @@ In order for `kubectl run` to satisfy infrastructure as code:
version 1.5 of kuberentes this generator is deprecated, with a plan to be
removed in 1.6. Please use `job/v1` instead.
* Job - use `job/v1`.
* ScheduledJob - use `scheduledjob/v2alpha1`.
* CronJob - use `cronjob/v2alpha1`.
Additionally, if you didn't specify a generator flag, other flags will suggest using
a specific generator. Below table shows which flags force using specific generators,
@@ -52,7 +52,7 @@ depending on your cluster version:
| Replication Controller | `--generator=run/v1` | `--generator=run/v1` | `--generator=run/v1` | `--restart=Always` |
| Deployment | `--restart=Always` | `--restart=Always` | `--restart=Always` | N/A |
| Job | `--restart=OnFailure` | `--restart=OnFailure` | `--restart=OnFailure` OR `--restart=Never` | N/A |
| Scheduled Job | `--schedule=<cron>` | N/A | N/A | N/A |
| Cron Job | `--schedule=<cron>` | N/A | N/A | N/A |
Note that these flags will use a default generator only when you have not specified
any flag. This also means that combining `--generator` with other flags won't
+1 -1
View File
@@ -50,7 +50,7 @@ kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>
# Start the perl container to compute π to 2000 places and print it out.
kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)'
# Start the scheduled job to compute π to 2000 places and print it out every 5 minutes.
# Start the cron job to compute π to 2000 places and print it out every 5 minutes.
kubectl run pi --schedule="0/5 * * * ?" --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)'
```
+1 -1
View File
@@ -173,7 +173,7 @@ on node N if node N has a label with key `failure-domain.beta.kubernetes.io/zone
such that there is at least one node in the cluster with key `failure-domain.beta.kubernetes.io/zone` and
value V that is running a pod that has a label with key "security" and value "S1".) The pod anti-affinity
rule says that the pod cannot schedule onto a node if that node is already running a pod with label
having key "security" and value "S2". (If the `topologyKey` were `failure-domain.beta.kuberntes.io/zone` then
having key "security" and value "S2". (If the `topologyKey` were `failure-domain.beta.kubernetes.io/zone` then
it would mean that the pod cannot schedule onto a node if that node is in the same zone as a pod with
label having key "security" and value "S2".) See the [design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/podaffinity.md).
for many more examples of pod affinity and anti-affinity, both the `requiredDuringSchedulingIgnoredDuringExecution`
@@ -10,4 +10,4 @@ spec:
accessModes:
- ReadWriteOnce
hostPath:
path: "/somepath/data01"
path: "/tmp/data01"
@@ -27,7 +27,7 @@ for ease of development and testing. You'll create a local `HostPath` for this
support local storage on the host at this time. There is no guarantee your pod ends up on the correct node where the `HostPath` resides.
```shell
# This will be nginx's webroot
# This will be nginx's webroot; execute this on the node where your pod will run.
$ mkdir /tmp/data01
$ echo 'I love Kubernetes storage!' > /tmp/data01/index.html
```
@@ -125,4 +125,4 @@ I love Kubernetes storage!
Hopefully this simple guide is enough to get you started with PersistentVolumes. If you have any questions, join the team on [Slack](/docs/troubleshooting/#slack) and ask!
Enjoy!
Enjoy!
@@ -88,7 +88,7 @@ vm-1 # printf "GET / HTTP/1.0\r\n\r\n" | netcat vm-0.ub 80
It's worth exploring what just happened. Init containers run sequentially *before* the application container. In this example we used the init container to copy shared libraries from the rootfs, while preserving user installed packages across container restart.
```yaml
pod.alpha.kubernetes.io/init-containers: '[
pod.beta.kubernetes.io/init-containers: '[
{
"name": "rootfs",
"image": "ubuntu:15.10",
@@ -29,7 +29,7 @@ spec:
app: nginx
annotations:
pod.alpha.kubernetes.io/initialized: "true"
pod.alpha.kubernetes.io/init-containers: '[
pod.beta.kubernetes.io/init-containers: '[
{
"name": "peerfinder",
"image": "gcr.io/google_containers/peer-finder:0.1",
@@ -27,7 +27,7 @@ spec:
app: ub
annotations:
pod.alpha.kubernetes.io/initialized: "true"
pod.alpha.kubernetes.io/init-containers: '[
pod.beta.kubernetes.io/init-containers: '[
{
"name": "rootfs",
"image": "ubuntu:15.10",
+2 -2
View File
@@ -66,8 +66,8 @@ The possible values for RestartPolicy are `Always`, `OnFailure`, or `Never`. If
Three types of controllers are currently available:
- Use a [`Job`](/docs/user-guide/jobs/) for pods which are expected to terminate (e.g. batch computations).
- Use a [`ReplicationController`](/docs/user-guide/replication-controller/) for pods which are not expected to
terminate (e.g. web servers).
- Use a [`ReplicationController`](/docs/user-guide/replication-controller/) or [`Deployment`](/docs/user-guide/deployments/)
for pods which are not expected to terminate (e.g. web servers).
- Use a [`DaemonSet`](/docs/admin/daemons/): Use for pods which need to run 1 per machine because they provide a
machine-specific system service.
If you are unsure whether to use ReplicationController or Daemon, then see [Daemon Set versus
+169
View File
@@ -0,0 +1,169 @@
---
assignees:
- erictune
---
* TOC
{:toc}
In addition to having one or more main containers (or **app containers**), a
pod can also have one or more **init containers** which run before the app
containers. Init containers allow you to reduce and reorganize setup scripts
and "glue code".
## Overview
An init container is exactly like a regular container, except that it always
runs to completion and each init container must complete successfully before
the next one is started. If the init container fails, Kubernetes will restart
the pod until the init container succeeds. If a pod is marked as `RestartNever`,
the pod will fail if the init container fails.
You specify a container as an init container by adding an annotation
The annotation key is `pod.beta.kubernetes.io/init-containers`. The annotation
value is a JSON array of [objects of type `v1.Container`
](http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_container)
Once the feature exits beta, the init containers will be specified on the Pod
Spec alongside the app `containers` array.
The status of the init containers is returned as another annotation -
`pod.beta.kubernetes.io/init-container-statuses` -- as an array of the
container statuses (similar to the `status.containerStatuses` field).
Init containers support all of the same features as normal containers,
including resource limits, volumes, and security settings. The resource
requests and limits for an init container are [handled slightly differently](
#resources). Init containers do not support readiness probes since they will
run to completion before the pod can be ready.
An init container has all of the fields of an app container.
If you specify multiple init containers for a pod, those containers run one at
a time in sequential order. Each must succeed before the next can run. Once all
init containers have run to completion, Kubernetes initializes the pod and runs
the application containers as usual.
## What are Init Containers Good For?
Because init containers have separate images from application containers, they
have some advantages for start-up related code. These include:
* they can contain utilities that are not desirable to include in the app container
image for security reasons,
* they can contain utilities or custom code for setup that is not present in an app
image. (No need to make an image `FROM` another image just to use a tool like
`sed`, `awk`, `python`, `dig`, etc during setup).
* the application image builder and the deployer roles can work independently without
the need to jointly build a single app image.
Because init containers have different filesystem view (Linux namespaces) from
app containers, they can be given access to Secrets that the app containers are
not able to access.
Since init containers run to completion before any app containers start, and
since app containers run in parallel, they provide an easier way to block or
delay the startup of application containers until some precondition is met.
Because init containers run in sequence and there can be multiple init containers,
they can be composed easily.
Here are some ideas for how to use init containers:
- Wait for a service to be created with a shell command like:
`for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1`
- Register this pod with a remote server with a command like:
`curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(POD_NAME)&ip=$(POD_IP)'`
using `POD_NAME` and `POD_IP` from the downward API.
- Wait for some time before starting the app container with a command like `sleep 60`.
- Clone a git repository into a volume
- Place values like a POD_IP into a configuration file, and run a template tool (e.g. jinja)
to generate a configuration file to be consumed by the main app contianer.
```
Complete usage examples can be found in the [PetSets
guide](docs/user-guide/petset/bootstrapping/index.md) and the [Production Pods
guide](/docs/user-guide/production-pods.md#handling-initialization).
## Detailed Behavior
Each pod may have 0..N init containers defined along with the existing
1..M app containers.
On startup of the pod, after the network and volumes are initialized, the init
containers are started in order. Each container must exit successfully before
the next is invoked. If a container fails to start (due to the runtime) or
exits with failure, it is retried according to the pod RestartPolicy, except
when the pod restart policy is RestartPolicyAlways, in which case just the init
containers use RestartPolicyOnFailure.
A pod cannot be ready until all init containers have succeeded. The ports on an
init container are not aggregated under a service. A pod that is being
initialized is in the `Pending` phase but should has a condition `Initializing`
set to `true`.
If the pod is [restarted](#pod-restart-reasons) all init containers must
execute again.
Changes to the init container spec are limited to the container image field.
Altering a init container image field is equivalent to restarting the pod.
Because init containers can be restarted, retried, or reexecuted, init container
code should be idempotent. In particular, code that writes to files on EmptyDirs
should be prepared for the possibility that an output file already exists.
An init container has all of the fields of an app container. The following
fields are prohibited from being used on init containers by validation:
* `readinessProbe` - init containers must exit for pod startup to continue,
are not included in rotation, and so cannot define readiness distinct from
completion.
Init container authors may use `activeDeadlineSeconds` on the pod and
`livenessProbe` on the container to prevent init containers from failing
forever. The active deadline includes init containers.
The name of each app and init container in a pod must be unique - it is a
validation error for any container to share a name.
### Resources
Given the ordering and execution for init containers, the following rules
for resource usage apply:
* The highest of any particular resource request or limit defined on all init
containers is the **effective init request/limit**
* The pod's **effective request/limit** for a resource is the higher of:
* sum of all app containers request/limit for a resource
* effective init request/limit for a resource
* Scheduling is done based on effective requests/limits, which means
init containers can reserve resources for initialization that are not used
during the life of the pod.
* QoS tier of the pod's **effective QoS tier** is the QoS tier for init containers
and app containers alike.
Quota and limits are applied based on the effective pod request and
limit.
Pod level cGroups are based on the effective pod request and limit, the
same as the scheduler.
## Pod Restart Reasons
A Pod may "restart", causing reexecution of init containers, for the following
reasons:
* An init container image is changed by a user updating the Pod Spec.
* App container image changes only restart the app container.
* The pod infrastructure container is restarted
* This is uncommon and would have to be done by someone with root access to nodes.
* All containers in a pod are terminated, requiring a restart (RestartPolicyAlways) AND the record of init container completion has been lost due to garbage collection.
## Support and compatibilty
A cluster with Kubelet and Apiserver version 1.4.0 or greater supports init
containers with the beta annotations. Support varies for other combinations of
Kubelet and Apiserver version; see the [release notes
](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md) for details.
+3 -1
View File
@@ -204,6 +204,8 @@ The status of the init containers is returned as another annotation - `pod.beta.
Init containers support all of the same features as normal containers, including resource limits, volumes, and security settings. The resource requests and limits for an init container are handled slightly different than normal containers since init containers are run one at a time instead of all at once - any limits or quotas will be applied based on the largest init container resource quantity, rather than as the sum of quantities. Init containers do not support readiness probes since they will run to completion before the pod can be ready.
[Complete Init Container Documentation](/docs/user-guide/pods/init-containers.md)
## Lifecycle hooks and termination notice
@@ -218,7 +220,7 @@ The specification of a pre-stop hook is similar to that of probes, but without t
## Termination message
In order to achieve a reasonably high level of availability, especially for actively developed applications, it's important to debug failures quickly. Kubernetes can speed debugging by surfacing causes of fatal errors in a way that can be display using [`kubectl`](/docs/user-guide/kubectl/kubectl) or the [UI](/docs/user-guide/ui), in addition to general [log collection](/docs/user-guide/logging). It is possible to specify a `terminationMessagePath` where a container will write its 'death rattle'?, such as assertion failure messages, stack traces, exceptions, and so on. The default path is `/dev/termination-log`.
In order to achieve a reasonably high level of availability, especially for actively developed applications, it's important to debug failures quickly. Kubernetes can speed debugging by surfacing causes of fatal errors in a way that can be display using [`kubectl`](/docs/user-guide/kubectl/) or the [UI](/docs/user-guide/ui), in addition to general [log collection](/docs/user-guide/logging). It is possible to specify a `terminationMessagePath` where a container will write its 'death rattle'?, such as assertion failure messages, stack traces, exceptions, and so on. The default path is `/dev/termination-log`.
Here is a toy example:
+1 -1
View File
@@ -265,7 +265,7 @@ All listed keys must exist in the corresponding secret. Otherwise, the volume is
**Secret files permissions**
You can also specify the permission mode bits files part of a secret will have.
If you don't specify any, `0644` is used by default. You can sepecify a default
If you don't specify any, `0644` is used by default. You can specify a default
mode for the whole secret volume and override per key if needed.
For example, you can specify a default mode like this:
+2 -2
View File
@@ -31,8 +31,8 @@ you get the raw json or yaml for a pod you have created (e.g. `kubectl get
pods/podname -o yaml`), you can see the `spec.serviceAccount` field has been
[automatically set](/docs/user-guide/working-with-resources/#resources-are-automatically-modified).
You can access the API using a proxy or with a client library, as described in
[Accessing the Cluster](/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod).
With service accounts, you can access the API inside the pod using a proxy or with a client library,
as described in [Accessing the Cluster](/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod).
## Using Multiple Service Accounts.
+2 -2
View File
@@ -182,7 +182,7 @@ In Kubernetes v1.0 the proxy was purely in userspace. In Kubernetes v1.1 an
iptables proxy was added, but was not the default operating mode. Since
Kubernetes v1.2, the iptables proxy is the default.
As of Kubernetes v1.0, `Services` are a "layer 3" (TCP/UDP over IP) construct.
As of Kubernetes v1.0, `Services` are a "layer 4" (TCP/UDP over IP) construct.
In Kubernetes v1.1 the `Ingress` API was added (beta) to represent "layer 7"
(HTTP) services.
@@ -345,7 +345,7 @@ can do a DNS SRV query for `"_http._tcp.my-service.my-ns"` to discover the port
number for `"http"`.
The Kubernetes DNS server is the only way to access services of type
`ExternalName`.
`ExternalName`. More information is available in the [DNS Admin Guide](http://kubernetes.io/docs/admin/dns/).
## Headless services
+2 -2
View File
@@ -115,12 +115,12 @@ make all four clusters available on both hosts by running
# on host2, copy host1's default kubeconfig, and merge it from env
$ scp host1:/path/to/home1/.kube/config /path/to/other/.kube/config
$ export $KUBECONFIG=/path/to/other/.kube/config
$ export KUBECONFIG=/path/to/other/.kube/config
# on host1, copy host2's default kubeconfig and merge it from env
$ scp host2:/path/to/home2/.kube/config /path/to/other/.kube/config
$ export $KUBECONFIG=/path/to/other/.kube/config
$ export KUBECONFIG=/path/to/other/.kube/config
```
Detailed examples and explanation of `kubeconfig` loading/merging rules can be found in [kubeconfig-file](/docs/user-guide/kubeconfig-file).
+1 -1
View File
@@ -22,7 +22,7 @@ Each `ThirdPartyResource` has the following:
* `description` - A free text description of the resource.
* `versions` - A list of the versions of the resource.
The `kind` for a `ThirdPartyResource` takes the form `<kind name>.<domain>`. You are expected to provide a unique kind and domain name in order to avoid conflicts with other `ThirdPartyResource` objects. Kind names will be converted to CamelCase when creating instances of the `ThirdPartyResource`. Hypens in the `kind` are assumed to be word breaks. For instance the kind `camel-case` would be converted to `CamelCase` but `camelcase` would be converted to `Camelcase`.
The `kind` for a `ThirdPartyResource` takes the form `<kind name>.<domain>`. You are expected to provide a unique kind and domain name in order to avoid conflicts with other `ThirdPartyResource` objects. Kind names will be converted to CamelCase when creating instances of the `ThirdPartyResource`. Hyphens in the `kind` are assumed to be word breaks. For instance the kind `camel-case` would be converted to `CamelCase` but `camelcase` would be converted to `Camelcase`.
Other fields on the `ThirdPartyResource` are treated as custom data fields. These fields can hold arbitrary JSON data and have any structure.
+1 -1
View File
@@ -46,7 +46,7 @@ The system adds fields in several ways:
- Some fields are added synchronously with creation of the resource and some are set asynchronously.
- For example: `metadata.uid` is set synchronously. (Read more about [metadata](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#metadata)).
- For example, `status.hostIP` is set only after the pod has been scheduled. This often happens fast, but you may notice pods which do not have this set yet. This is called Late Initialization. (Read mode about [status](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status) and [late initialization](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#late-initialization) ).
- For example, `status.hostIP` is set only after the pod has been scheduled. This often happens fast, but you may notice pods which do not have this set yet. This is called Late Initialization. (Read more about [status](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#spec-and-status) and [late initialization](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#late-initialization)).
- Some fields are set to default values. Some defaults vary by cluster and some are fixed for the API at a certain version. (Read more about [defaulting](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#defaulting)).
- For example, `spec.containers[0].imagePullPolicy` always defaults to `IfNotPresent` in api v1.
- For example, `spec.containers[0].resources.limits.cpu` may be defaulted to `100m` on some clusters, to some other value on others, and not defaulted at all on others.