From 01f378542694a7ca17bbd1fabea64b87b5f38132 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Wed, 12 Aug 2015 14:14:49 -0400 Subject: [PATCH] Add status.podIP as a valid downward API target Getting the public IP a container is supposed to use is O(hard), and usually involves ugly gyrations in python or with interfaces. Using the downward API means that the IP Kube is announcing to other endpoints is also visible inside the container for pods to identify themselves. --- docs/user-guide/downward-api.md | 5 +++++ docs/user-guide/downward-api/README.md | 5 +++-- docs/user-guide/downward-api/dapi-pod.yaml | 4 ++++ pkg/api/v1/conversion.go | 1 + pkg/api/validation/validation.go | 2 +- pkg/api/validation/validation_test.go | 2 +- pkg/kubelet/kubelet.go | 5 ++++- pkg/kubelet/kubelet_test.go | 11 +++++++++++ 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/user-guide/downward-api.md b/docs/user-guide/downward-api.md index 36bc3769ed2..c3fbf9f1fcd 100644 --- a/docs/user-guide/downward-api.md +++ b/docs/user-guide/downward-api.md @@ -51,6 +51,7 @@ The following information is available to a `Pod` through the downward API: * The pod's name * The pod's namespace +* The pod's IP More information will be exposed through this same API over time. @@ -101,6 +102,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP restartPolicy: Never ``` diff --git a/docs/user-guide/downward-api/README.md b/docs/user-guide/downward-api/README.md index c93bbce2011..36d40fe2824 100644 --- a/docs/user-guide/downward-api/README.md +++ b/docs/user-guide/downward-api/README.md @@ -61,8 +61,9 @@ through the pod logs to see that the pod was injected with the correct values: ```console $ kubectl logs 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 +2015-04-30T20:22:18.568024817Z MY_POD_NAME=dapi-test-pod +2015-04-30T20:22:18.568087688Z MY_POD_NAMESPACE=default +2015-04-30T20:22:18.568092435Z MY_POD_IP=10.0.1.6 ``` diff --git a/docs/user-guide/downward-api/dapi-pod.yaml b/docs/user-guide/downward-api/dapi-pod.yaml index e02ce6e78fd..7d688aa0e99 100644 --- a/docs/user-guide/downward-api/dapi-pod.yaml +++ b/docs/user-guide/downward-api/dapi-pod.yaml @@ -16,4 +16,8 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP restartPolicy: Never diff --git a/pkg/api/v1/conversion.go b/pkg/api/v1/conversion.go index a61a6252607..5cf1c615b85 100644 --- a/pkg/api/v1/conversion.go +++ b/pkg/api/v1/conversion.go @@ -44,6 +44,7 @@ func addConversionFuncs() { case "metadata.name", "metadata.namespace", "status.phase", + "status.podIP", "spec.nodeName": return label, value, nil // This is for backwards compatibility with old v1 clients which send spec.host diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index c1d6fa28e3f..9d42e5b1427 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -680,7 +680,7 @@ func validateEnvVarValueFrom(ev api.EnvVar) errs.ValidationErrorList { return allErrs } -var validFieldPathExpressions = util.NewStringSet("metadata.name", "metadata.namespace") +var validFieldPathExpressions = util.NewStringSet("metadata.name", "metadata.namespace", "status.podIP") func validateObjectFieldSelector(fs *api.ObjectFieldSelector) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 14eab7e276b..b20de4cd9d2 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -667,7 +667,7 @@ func TestValidateEnv(t *testing.T) { }, }, }}, - expectedError: "[0].valueFrom.fieldRef.fieldPath: unsupported value 'status.phase', Details: supported values: metadata.name, metadata.namespace", + expectedError: "[0].valueFrom.fieldRef.fieldPath: unsupported value 'status.phase', Details: supported values: metadata.name, metadata.namespace, status.podIP", }, } for _, tc := range errorCases { diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 2b4c3404dae..3fd7c83f45d 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -1051,7 +1051,10 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *api.ObjectFieldSelector, pod if err != nil { return "", err } - + switch internalFieldPath { + case "status.podIP": + return pod.Status.PodIP, nil + } return fieldpath.ExtractFieldPathAsString(pod, internalFieldPath) } diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 5af88797d7e..cea439c03b5 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -1187,6 +1187,15 @@ func TestMakeEnvironmentVariables(t *testing.T) { }, }, }, + { + Name: "POD_IP", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: testapi.Version(), + FieldPath: "status.podIP", + }, + }, + }, }, }, masterServiceNs: "nothing", @@ -1194,6 +1203,7 @@ func TestMakeEnvironmentVariables(t *testing.T) { expectedEnvs: []kubecontainer.EnvVar{ {Name: "POD_NAME", Value: "dapi-test-pod-name"}, {Name: "POD_NAMESPACE", Value: "downward-api"}, + {Name: "POD_IP", Value: "1.2.3.4"}, }, }, { @@ -1345,6 +1355,7 @@ func TestMakeEnvironmentVariables(t *testing.T) { Name: "dapi-test-pod-name", }, } + testPod.Status.PodIP = "1.2.3.4" result, err := kl.makeEnvironmentVariables(testPod, tc.container) if err != nil {