"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"
}
}
},
...
...
@@ -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.",
...
...
@@ -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.",
@@ -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
...
...
@@ -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 -->
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.
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)`.
// DownwardAPIVolumeFile represents a single file containing information from the downward API
typeDownwardAPIVolumeFilestruct{
// 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 '..'
Pathstring`json:"path"`
// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
FieldRefObjectFieldSelector`json:"fieldRef"`
}
// ContainerPort represents a network port in a single container
typeContainerPortstruct{
// Optional: If specified, this must be an IANA_SVC_NAME Each named port
// DownwardAPIVolumeFile represents information to create the file containing the pod field
typeDownwardAPIVolumeFilestruct{
// 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 '..'
Pathstring`json:"path"`
// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
FieldRefObjectFieldSelector`json:"fieldRef"`
}
// SecurityContext holds security configuration that will be applied to a container.
typeSecurityContextstruct{
// The linux kernel capabilites that should be added or removed.
"":"DownwardAPIVolumeFile represents information to create the file containing the pod field",
"path":"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":"Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.",
"":"EmptyDirVolumeSource is temporary directory that shares a pod's lifetime.",
"medium":"What type of storage medium should back this directory. The default is \"\" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#emptydir",
...
...
@@ -1373,8 +1392,9 @@ var map_VolumeSource = map[string]string{
"iscsi":"ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/HEAD/examples/iscsi/README.md",
"glusterfs":"Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md",
"persistentVolumeClaim":"PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims",
"rbd":"RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md",
"cinder":"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",
"rbd":"RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md",
"cinder":"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":"DownwardAPI represents downward API about the pod that should populate this volume",
"name not a DNS label":{[]api.Volume{{Name:"a.b.c",VolumeSource:emptyVS}},errors.ValidationErrorTypeInvalid,"[0].name",DNS1123LabelErrorMsg},
"name not unique":{[]api.Volume{{Name:"abc",VolumeSource:emptyVS},{Name:"abc",VolumeSource:emptyVS}},errors.ValidationErrorTypeDuplicate,"[1].name",""},
"dot dot path":{[]api.Volume{{Name:"dotdotpath",VolumeSource:dotDotInPath}},errors.ValidationErrorTypeInvalid,"[0].source.downwardApi.path","must not contain \"..\"."},
"dot dot file name":{[]api.Volume{{Name:"dotdotfilename",VolumeSource:dotDotPathName}},errors.ValidationErrorTypeInvalid,"[0].source.downwardApi.path","must not start with \"..\"."},
"dot dot first level dirent ":{[]api.Volume{{Name:"dotdotdirfilename",VolumeSource:dotDotFirstLevelDirent}},errors.ValidationErrorTypeInvalid,"[0].source.downwardApi.path","must not start with \"..\"."},