Skip to content

Commit

Permalink
adding downward api volume plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
sdminonne committed Sep 1, 2015
1 parent cfe2bf1 commit f4dc065
Show file tree
Hide file tree
Showing 25 changed files with 1,919 additions and 40 deletions.
69 changes: 52 additions & 17 deletions api/swagger-spec/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -12517,6 +12517,10 @@
"cinder": {
"$ref": "v1.CinderVolumeSource",
"description": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md"
},
"downwardAPI": {
"$ref": "v1.DownwardAPIVolumeSource",
"description": "DownwardAPI represents downward API about the pod that should populate this volume"
}
}
},
Expand Down Expand Up @@ -12578,6 +12582,54 @@
}
}
},
"v1.DownwardAPIVolumeSource": {
"id": "v1.DownwardAPIVolumeSource",
"description": "DownwardAPIVolumeSource represents a volume containing downward API info",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "v1.DownwardAPIVolumeFile"
},
"description": "Items is a list of downward API volume file"
}
}
},
"v1.DownwardAPIVolumeFile": {
"id": "v1.DownwardAPIVolumeFile",
"description": "DownwardAPIVolumeFile represents information to create the file containing the pod field",
"required": [
"path",
"fieldRef"
],
"properties": {
"path": {
"type": "string",
"description": "Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'"
},
"fieldRef": {
"$ref": "v1.ObjectFieldSelector",
"description": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported."
}
}
},
"v1.ObjectFieldSelector": {
"id": "v1.ObjectFieldSelector",
"description": "ObjectFieldSelector selects an APIVersioned field of an object.",
"required": [
"fieldPath"
],
"properties": {
"apiVersion": {
"type": "string",
"description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\"."
},
"fieldPath": {
"type": "string",
"description": "Path of the field to select in the specified API version."
}
}
},
"v1.Container": {
"id": "v1.Container",
"description": "A single application container that you want to run within a pod.",
Expand Down Expand Up @@ -12735,23 +12787,6 @@
}
}
},
"v1.ObjectFieldSelector": {
"id": "v1.ObjectFieldSelector",
"description": "ObjectFieldSelector selects an APIVersioned field of an object.",
"required": [
"fieldPath"
],
"properties": {
"apiVersion": {
"type": "string",
"description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\"."
},
"fieldPath": {
"type": "string",
"description": "Path of the field to select in the specified API version."
}
}
},
"v1.VolumeMount": {
"id": "v1.VolumeMount",
"description": "VolumeMount describes a mounting of a Volume within a container.",
Expand Down
2 changes: 2 additions & 0 deletions cmd/kubelet/app/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/aws_ebs"
"k8s.io/kubernetes/pkg/volume/cinder"
"k8s.io/kubernetes/pkg/volume/downwardapi"
"k8s.io/kubernetes/pkg/volume/empty_dir"
"k8s.io/kubernetes/pkg/volume/gce_pd"
"k8s.io/kubernetes/pkg/volume/git_repo"
Expand Down Expand Up @@ -60,6 +61,7 @@ func ProbeVolumePlugins() []volume.VolumePlugin {
allPlugins = append(allPlugins, persistent_claim.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...)
allPlugins = append(allPlugins, downwardapi.ProbeVolumePlugins()...)
return allPlugins
}

Expand Down
73 changes: 71 additions & 2 deletions docs/user-guide/downward-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ More information will be exposed through this same API over time.
## Exposing pod information into a container

Containers consume information from the downward API using environment
variables. In the future, containers will also be able to consume the downward
API via a volume plugin.
variables or using a volume plugin.

### Environment variables

Expand Down Expand Up @@ -112,6 +111,76 @@ spec:
[Download example](downward-api/dapi-pod.yaml)
<!-- END MUNGE: EXAMPLE downward-api/dapi-pod.yaml -->
### Downward API volume
Using a similar syntax it's possible to expose pod information to containers using plain text files.
Downward API are dumped to a mounted volume. This is achieved using a `downwardAPI`
volume type and the different items represent the files to be created. `fieldPath` references the field to be exposed.

Downward API volume permits to store more complex data like [`metadata.labels`](labels.md) and [`metadata.annotations`](annotations.md). Currently key/value pair set fields are saved using `key="value"` format:

```
key1="value1"
key2="value2"
```

In future, it will be possible to specify an output format option.

Downward API volumes can expose:

* The pod's name
* The pod's namespace
* The pod's labels
* The pod's annotations

The downward API volume refreshes its data in step with the kubelet refresh loop. When labels will be modifiable on the fly without respawning the pod containers will be able to detect changes through mechanisms such as [inotify](https://en.wikipedia.org/wiki/Inotify).

In future, it will be possible to specify a specific annotation or label.

## Example

This is an example of a pod that consumes its labels and annotations via the downward API volume, labels and annotations are dumped in `/etc/podlabels` and in `/etc/annotations`, respectively:

<!-- BEGIN MUNGE: EXAMPLE downward-api/volume/dapi-volume.yaml -->

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: gcr.io/google_containers/busybox
command: ["sh", "-c", "while true; do if [[ -e /etc/labels ]]; then cat /etc/labels; fi; if [[ -e /etc/annotations ]]; then cat /etc/annotations; fi; sleep 5; done"]
volumeMounts:
- name: podinfo
mountPath: /etc
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
```

[Download example](downward-api/volume/dapi-volume.yaml)
<!-- END MUNGE: EXAMPLE downward-api/volume/dapi-volume.yaml -->

Some more thorough examples:
* [environment variables](environment-guide/)
* [downward API](downward-api/)
Expand Down
105 changes: 105 additions & 0 deletions docs/user-guide/downward-api/volume/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->

<!-- BEGIN STRIP_FOR_RELEASE -->

<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
width="25" height="25">
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
width="25" height="25">
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
width="25" height="25">
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
width="25" height="25">
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
width="25" height="25">

<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>

If you are using a released version of Kubernetes, you should
refer to the docs that go with that version.

<strong>
The latest 1.0.x release of this document can be found
[here](http://releases.k8s.io/release-1.0/docs/user-guide/downward-api/volume/README.md).

Documentation for other releases can be found at
[releases.k8s.io](http://releases.k8s.io).
</strong>
--

<!-- END STRIP_FOR_RELEASE -->

<!-- END MUNGE: UNVERSIONED_WARNING -->

# Downward API volume plugin

Following this example, you will create a pod with a downward API volume.
A downward API volume is a k8s volume plugin with the ability to save some pod information in a plain text file. The pod information can be for example some [metadata](../../../../docs/devel/api-conventions.md#metadata).

Supported metadata fields:

1. `metadata.annotations`
2. `metadata.namespace`
3. `metadata.name`
4. `metadata.labels`

### Step Zero: Prerequisites

This example assumes you have a Kubernetes cluster installed and running, and the ```kubectl``` command line tool somewhere in your path. Please see the [gettingstarted](../../../../docs/getting-started-guides/) for installation instructions for your platform.

### Step One: Create the pod

Use the `docs/user-guide/downward-api/dapi-volume.yaml` file to create a Pod with a  downward API volume which stores pod labels and pod annotations to `/etc/labels` and  `/etc/annotations` respectively.

```shell
$ kubectl create -f docs/user-guide/downward-api/volume/dapi-volume.yaml
```

### Step Two: Examine pod/container output

The pod displays (every 5 seconds) the content of the dump files which can be executed via the usual `kubectl log` command

```shell
$ kubectl logs kubernetes-downwardapi-volume-example
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
kubernetes.io/config.seen="2015-08-24T13:47:23.432459138Z"
kubernetes.io/config.source="api"
```

### Internals

In pod's `/etc` directory one may find the file created by the plugin (system files elided):

```shell
$ kubectl exec kubernetes-downwardapi-volume-example -i -t -- sh
/ # ls -laR /etc
/etc:
total 32
drwxrwxrwt 3 0 0 180 Aug 24 13:03 .
drwxr-xr-x 1 0 0 4096 Aug 24 13:05 ..
drwx------ 2 0 0 80 Aug 24 13:03 ..2015_08_24_13_03_44259413923
lrwxrwxrwx 1 0 0 30 Aug 24 13:03 ..downwardapi -> ..2015_08_24_13_03_44259413923
lrwxrwxrwx 1 0 0 25 Aug 24 13:03 annotations -> ..downwardapi/annotations
lrwxrwxrwx 1 0 0 20 Aug 24 13:03 labels -> ..downwardapi/labels

/etc/..2015_08_24_13_03_44259413923:
total 8
drwx------ 2 0 0 80 Aug 24 13:03 .
drwxrwxrwt 3 0 0 180 Aug 24 13:03 ..
-rw-r--r-- 1 0 0 115 Aug 24 13:03 annotations
-rw-r--r-- 1 0 0 53 Aug 24 13:03 labels
/ #
```

The file `labels` is stored in a temporary directory (`..2015_08_24_13_03_44259413923` in the example above) which is symlinked to by `..downwardapi`. Symlinks for annotations and labels in `/etc` point to files containing the actual metadata through the `..downwardapi` indirection.  This structure allows for dynamic atomic refresh of the metadata: updates are written to a new temporary directory, and the `..downwardapi` symlink is updated atomically using `rename(2)`.




<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/downward-api/volume/README.md?pixel)]()
<!-- END MUNGE: GENERATED_ANALYTICS -->
30 changes: 30 additions & 0 deletions docs/user-guide/downward-api/volume/dapi-volume.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: gcr.io/google_containers/busybox
command: ["sh", "-c", "while true; do if [[ -e /etc/labels ]]; then cat /etc/labels; fi; if [[ -e /etc/annotations ]]; then cat /etc/annotations; fi; sleep 5; done"]
volumeMounts:
- name: podinfo
mountPath: /etc
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
8 changes: 8 additions & 0 deletions docs/user-guide/volumes.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Familiarity with [pods](pods.md) is suggested.
- [gitRepo](#gitrepo)
- [secret](#secret)
- [persistentVolumeClaim](#persistentvolumeclaim)
- [downwardAPI](#downwardapi)
- [Resources](#resources)

<!-- END MUNGE: GENERATED_TOC -->
Expand Down Expand Up @@ -381,6 +382,13 @@ iSCSI volume) without knowing the details of the particular cloud environment.
See the [PersistentVolumes example](persistent-volumes/) for more
details.

### downwardAPI

A `downwardAPI` volume is used to make downward API data available to applications.
It mounts a directory and writes the requested data in plain text files.

See the [`downwardAPI` volume example](downward-api/volume/README.md) for more details.

## Resources

The storage media (Disk, SSD, etc) of an `emptyDir` volume is determined by the
Expand Down
3 changes: 3 additions & 0 deletions examples/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ func TestExampleObjectSchemas(t *testing.T) {
"../docs/user-guide/downward-api": {
"dapi-pod": &api.Pod{},
},
"../docs/user-guide/downward-api/volume/": {
"dapi-volume": &api.Pod{},
},
"../examples/elasticsearch": {
"mytunes-namespace": &api.Namespace{},
"music-rc": &api.ReplicationController{},
Expand Down
Loading

0 comments on commit f4dc065

Please sign in to comment.