mirror of https://github.com/k3s-io/k3s
Change EnvVarSource.FieldPath -> FieldRef and add example
parent
b0129089da
commit
e949a623ff
|
@ -0,0 +1,33 @@
|
|||
# Downward API example
|
||||
|
||||
Following this example, you will create a pod with a containers that consumes the pod's name and
|
||||
namespace using the downward API.
|
||||
|
||||
## Step Zero: Prerequisites
|
||||
|
||||
This example assumes you have a Kubernetes cluster installed and running, and that you have
|
||||
installed the ```kubectl``` command line tool somewhere in your path. Please see the [getting
|
||||
started](../../docs/getting-started-guides) for installation instructions for your platform.
|
||||
|
||||
## Step One: Create the pod
|
||||
|
||||
Containers consume the downward API using environment variables. The downward API allows
|
||||
containers to be injected with the name and namespace of the pod the container is in.
|
||||
|
||||
Use the `examples/secrets/secret-pod.yaml` file to create a Pod with a container that consumes the
|
||||
downward API.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f examples/downward-api/dapi-pod.yaml
|
||||
```
|
||||
|
||||
### Examine the logs
|
||||
|
||||
This pod runs the `env` command in a container that consumes the downward API. You can grep
|
||||
through the pod logs to see that the pod was injected with the correct values:
|
||||
|
||||
```shell
|
||||
$ kubectl log dapi-test-pod | grep POD_
|
||||
2015-04-30T20:22:18.568024817Z POD_NAME=dapi-test-pod
|
||||
2015-04-30T20:22:18.568087688Z POD_NAMESPACE=default
|
||||
```
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: v1beta3
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "env" ]
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
restartPolicy: Never
|
|
@ -196,12 +196,12 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
|||
ev.Value = c.RandString()
|
||||
} else {
|
||||
ev.ValueFrom = &api.EnvVarSource{}
|
||||
ev.ValueFrom.FieldPath = &api.ObjectFieldSelector{}
|
||||
ev.ValueFrom.FieldRef = &api.ObjectFieldSelector{}
|
||||
|
||||
versions := []string{"v1beta1", "v1beta2", "v1beta3"}
|
||||
|
||||
ev.ValueFrom.FieldPath.APIVersion = versions[c.Rand.Intn(len(versions))]
|
||||
ev.ValueFrom.FieldPath.FieldPath = c.RandString()
|
||||
ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))]
|
||||
ev.ValueFrom.FieldRef.FieldPath = c.RandString()
|
||||
}
|
||||
},
|
||||
func(e *api.Event, c fuzz.Continue) {
|
||||
|
|
|
@ -518,7 +518,7 @@ type EnvVar struct {
|
|||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
type EnvVarSource struct {
|
||||
// Required: Selects a field of the pod; only name and namespace are supported.
|
||||
FieldPath *ObjectFieldSelector `json:"fieldPath"`
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef"`
|
||||
}
|
||||
|
||||
// ObjectFieldSelector selects an APIVersioned field of an object.
|
||||
|
|
|
@ -330,7 +330,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
Env: []current.EnvVar{
|
||||
{
|
||||
ValueFrom: ¤t.EnvVarSource{
|
||||
FieldPath: ¤t.ObjectFieldSelector{},
|
||||
FieldRef: ¤t.ObjectFieldSelector{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -344,7 +344,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
pod2 := obj2.(*current.Pod)
|
||||
s2 := pod2.Spec
|
||||
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion
|
||||
if apiVersion != "v1" {
|
||||
t.Errorf("Expected default APIVersion v1, got: %v", apiVersion)
|
||||
}
|
||||
|
|
|
@ -529,7 +529,7 @@ type EnvVar struct {
|
|||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
type EnvVarSource struct {
|
||||
// Required: Selects a field of the pod; only name and namespace are supported.
|
||||
FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
}
|
||||
|
||||
// ObjectFieldSelector selects an APIVersioned field of an object.
|
||||
|
|
|
@ -322,7 +322,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
Env: []current.EnvVar{
|
||||
{
|
||||
ValueFrom: ¤t.EnvVarSource{
|
||||
FieldPath: ¤t.ObjectFieldSelector{},
|
||||
FieldRef: ¤t.ObjectFieldSelector{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -335,7 +335,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
sList2 := obj2.(*current.ContainerManifestList)
|
||||
s2 := sList2.Items[0]
|
||||
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion
|
||||
if apiVersion != "v1beta1" {
|
||||
t.Errorf("Expected default APIVersion v1beta1, got: %v", apiVersion)
|
||||
}
|
||||
|
|
|
@ -414,7 +414,7 @@ type EnvVar struct {
|
|||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
type EnvVarSource struct {
|
||||
// Required: Selects a field of the pod; only name and namespace are supported.
|
||||
FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
}
|
||||
|
||||
// ObjectFieldSelector selects an APIVersioned field of an object.
|
||||
|
|
|
@ -321,7 +321,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
Env: []current.EnvVar{
|
||||
{
|
||||
ValueFrom: ¤t.EnvVarSource{
|
||||
FieldPath: ¤t.ObjectFieldSelector{},
|
||||
FieldRef: ¤t.ObjectFieldSelector{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -334,7 +334,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
sList2 := obj2.(*current.ContainerManifestList)
|
||||
s2 := sList2.Items[0]
|
||||
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion
|
||||
if apiVersion != "v1beta2" {
|
||||
t.Errorf("Expected default APIVersion v1beta2, got: %v", apiVersion)
|
||||
}
|
||||
|
|
|
@ -391,7 +391,7 @@ type EnvVar struct {
|
|||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
type EnvVarSource struct {
|
||||
// Required: Selects a field of the pod; only name and namespace are supported.
|
||||
FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
}
|
||||
|
||||
// ObjectFieldSelector selects an APIVersioned field of an object.
|
||||
|
|
|
@ -632,14 +632,14 @@ func convert_api_EnvVar_To_v1beta3_EnvVar(in *newer.EnvVar, out *EnvVar, s conve
|
|||
}
|
||||
|
||||
func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *newer.EnvVarSource, s conversion.Scope) error {
|
||||
if err := s.Convert(&in.FieldPath, &out.FieldPath, 0); err != nil {
|
||||
if err := s.Convert(&in.FieldRef, &out.FieldRef, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *newer.EnvVarSource, out *EnvVarSource, s conversion.Scope) error {
|
||||
if err := s.Convert(&in.FieldPath, &out.FieldPath, 0); err != nil {
|
||||
if err := s.Convert(&in.FieldRef, &out.FieldRef, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -330,7 +330,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
Env: []current.EnvVar{
|
||||
{
|
||||
ValueFrom: ¤t.EnvVarSource{
|
||||
FieldPath: ¤t.ObjectFieldSelector{},
|
||||
FieldRef: ¤t.ObjectFieldSelector{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -344,7 +344,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
|
|||
pod2 := obj2.(*current.Pod)
|
||||
s2 := pod2.Spec
|
||||
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion
|
||||
apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion
|
||||
if apiVersion != "v1beta3" {
|
||||
t.Errorf("Expected default APIVersion v1beta3, got: %v", apiVersion)
|
||||
}
|
||||
|
|
|
@ -529,7 +529,7 @@ type EnvVar struct {
|
|||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
type EnvVarSource struct {
|
||||
// Required: Selects a field of the pod; only name and namespace are supported.
|
||||
FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"`
|
||||
}
|
||||
|
||||
// ObjectFieldSelector selects an APIVersioned field of an object.
|
||||
|
|
|
@ -591,9 +591,9 @@ func validateEnvVarValueFrom(ev api.EnvVar) errs.ValidationErrorList {
|
|||
numSources := 0
|
||||
|
||||
switch {
|
||||
case ev.ValueFrom.FieldPath != nil:
|
||||
case ev.ValueFrom.FieldRef != nil:
|
||||
numSources++
|
||||
allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldPath).Prefix("fieldPath")...)
|
||||
allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldRef).Prefix("fieldRef")...)
|
||||
}
|
||||
|
||||
if ev.Value != "" && numSources != 0 {
|
||||
|
|
|
@ -636,7 +636,7 @@ func TestValidateEnv(t *testing.T) {
|
|||
{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
|
@ -668,7 +668,7 @@ func TestValidateEnv(t *testing.T) {
|
|||
Name: "abc",
|
||||
Value: "foo",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
|
@ -681,50 +681,50 @@ func TestValidateEnv(t *testing.T) {
|
|||
envs: []api.EnvVar{{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: "[0].valueFrom.fieldPath.fieldPath: required value",
|
||||
expectedError: "[0].valueFrom.fieldRef.fieldPath: required value",
|
||||
},
|
||||
{
|
||||
name: "missing APIVersion on ObjectFieldSelector",
|
||||
envs: []api.EnvVar{{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: "[0].valueFrom.fieldPath.apiVersion: required value",
|
||||
expectedError: "[0].valueFrom.fieldRef.apiVersion: required value",
|
||||
},
|
||||
{
|
||||
name: "invalid fieldPath",
|
||||
envs: []api.EnvVar{{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
FieldPath: "metadata.whoops",
|
||||
APIVersion: "v1beta3",
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: "[0].valueFrom.fieldPath.fieldPath: invalid value 'metadata.whoops': error converting fieldPath",
|
||||
expectedError: "[0].valueFrom.fieldRef.fieldPath: invalid value 'metadata.whoops': error converting fieldPath",
|
||||
},
|
||||
{
|
||||
name: "unsupported fieldPath",
|
||||
envs: []api.EnvVar{{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
FieldPath: "status.phase",
|
||||
APIVersion: "v1beta3",
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: "[0].valueFrom.fieldPath.fieldPath: unsupported value 'status.phase'",
|
||||
expectedError: "[0].valueFrom.fieldRef.fieldPath: unsupported value 'status.phase'",
|
||||
},
|
||||
}
|
||||
for _, tc := range errorCases {
|
||||
|
|
|
@ -795,8 +795,8 @@ func (kl *Kubelet) runtimeEnvVarValue(envVar api.EnvVar, pod *api.Pod) (string,
|
|||
return runtimeVal, nil
|
||||
}
|
||||
|
||||
if envVar.ValueFrom != nil && envVar.ValueFrom.FieldPath != nil {
|
||||
return kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldPath, pod)
|
||||
if envVar.ValueFrom != nil && envVar.ValueFrom.FieldRef != nil {
|
||||
return kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod)
|
||||
}
|
||||
|
||||
return runtimeVal, nil
|
||||
|
|
|
@ -2181,7 +2181,7 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
|
@ -2190,7 +2190,7 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||
{
|
||||
Name: "POD_NAMESPACE",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.namespace",
|
||||
},
|
||||
|
|
|
@ -66,7 +66,7 @@ var _ = Describe("Downward API", func() {
|
|||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
|
@ -75,7 +75,7 @@ var _ = Describe("Downward API", func() {
|
|||
{
|
||||
Name: "POD_NAMESPACE",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.namespace",
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue