diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 9f7bd2cecc1..b241c1247e6 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -38347,7 +38347,7 @@ "$ref": "#/definitions/io.k8s.kubernetes.pkg.api.v1.ConfigMapKeySelector" }, "fieldRef": { - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.", + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.", "$ref": "#/definitions/io.k8s.kubernetes.pkg.api.v1.ObjectFieldSelector" }, "resourceFieldRef": { diff --git a/api/swagger-spec/apps_v1beta1.json b/api/swagger-spec/apps_v1beta1.json index d46666e3218..e86108a228f 100644 --- a/api/swagger-spec/apps_v1beta1.json +++ b/api/swagger-spec/apps_v1beta1.json @@ -3768,7 +3768,7 @@ "properties": { "fieldRef": { "$ref": "v1.ObjectFieldSelector", - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP." + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP." }, "resourceFieldRef": { "$ref": "v1.ResourceFieldSelector", diff --git a/api/swagger-spec/batch_v1.json b/api/swagger-spec/batch_v1.json index 8e1ff0a8cd1..625def7db10 100644 --- a/api/swagger-spec/batch_v1.json +++ b/api/swagger-spec/batch_v1.json @@ -2551,7 +2551,7 @@ "properties": { "fieldRef": { "$ref": "v1.ObjectFieldSelector", - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP." + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP." }, "resourceFieldRef": { "$ref": "v1.ResourceFieldSelector", diff --git a/api/swagger-spec/batch_v2alpha1.json b/api/swagger-spec/batch_v2alpha1.json index 0d5238e2459..7cbb81e9e60 100644 --- a/api/swagger-spec/batch_v2alpha1.json +++ b/api/swagger-spec/batch_v2alpha1.json @@ -3584,7 +3584,7 @@ "properties": { "fieldRef": { "$ref": "v1.ObjectFieldSelector", - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP." + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP." }, "resourceFieldRef": { "$ref": "v1.ResourceFieldSelector", diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index 96890ff6db8..1f3c6e4ec77 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -8015,7 +8015,7 @@ "properties": { "fieldRef": { "$ref": "v1.ObjectFieldSelector", - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP." + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP." }, "resourceFieldRef": { "$ref": "v1.ResourceFieldSelector", diff --git a/api/swagger-spec/settings.k8s.io_v1alpha1.json b/api/swagger-spec/settings.k8s.io_v1alpha1.json index 1379b0dcd08..85a69c234f4 100644 --- a/api/swagger-spec/settings.k8s.io_v1alpha1.json +++ b/api/swagger-spec/settings.k8s.io_v1alpha1.json @@ -1125,7 +1125,7 @@ "properties": { "fieldRef": { "$ref": "v1.ObjectFieldSelector", - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP." + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP." }, "resourceFieldRef": { "$ref": "v1.ResourceFieldSelector", diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json index f3c49d9eab0..09a27a28905 100644 --- a/api/swagger-spec/v1.json +++ b/api/swagger-spec/v1.json @@ -19380,7 +19380,7 @@ "properties": { "fieldRef": { "$ref": "v1.ObjectFieldSelector", - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP." + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP." }, "resourceFieldRef": { "$ref": "v1.ResourceFieldSelector", diff --git a/docs/api-reference/apps/v1beta1/definitions.html b/docs/api-reference/apps/v1beta1/definitions.html index 7cf1b45087e..180666d390d 100755 --- a/docs/api-reference/apps/v1beta1/definitions.html +++ b/docs/api-reference/apps/v1beta1/definitions.html @@ -2498,7 +2498,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

fieldRef

-

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.

+

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

false

v1.ObjectFieldSelector

@@ -6270,7 +6270,7 @@ Examples:
diff --git a/docs/api-reference/batch/v1/definitions.html b/docs/api-reference/batch/v1/definitions.html index daed0784e1c..b75cbadd67f 100755 --- a/docs/api-reference/batch/v1/definitions.html +++ b/docs/api-reference/batch/v1/definitions.html @@ -3741,7 +3741,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

fieldRef

-

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.

+

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

false

v1.ObjectFieldSelector

@@ -5512,7 +5512,7 @@ Examples:
diff --git a/docs/api-reference/batch/v2alpha1/definitions.html b/docs/api-reference/batch/v2alpha1/definitions.html index 88940f4157e..0b7a97a2220 100755 --- a/docs/api-reference/batch/v2alpha1/definitions.html +++ b/docs/api-reference/batch/v2alpha1/definitions.html @@ -3568,7 +3568,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

fieldRef

-

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.

+

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

false

v1.ObjectFieldSelector

@@ -5608,7 +5608,7 @@ Examples:
diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index c8aeb6e9e44..7bd24ba27a8 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -3090,7 +3090,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

fieldRef

-

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.

+

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

false

v1.ObjectFieldSelector

@@ -7917,7 +7917,7 @@ Both these may change in the future. Incoming requests are matched against the h diff --git a/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html b/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html index 8dab404723a..377cb6a14fc 100755 --- a/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html +++ b/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html @@ -2783,7 +2783,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

fieldRef

-

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.

+

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

false

v1.ObjectFieldSelector

@@ -3806,7 +3806,7 @@ Examples:
diff --git a/docs/api-reference/v1/definitions.html b/docs/api-reference/v1/definitions.html index fa47a1190c6..9b9918e2047 100755 --- a/docs/api-reference/v1/definitions.html +++ b/docs/api-reference/v1/definitions.html @@ -3554,7 +3554,7 @@ The resulting set of endpoints can be viewed as:

fieldRef

-

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.

+

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

false

v1.ObjectFieldSelector

@@ -9857,7 +9857,7 @@ Examples:
diff --git a/federation/apis/openapi-spec/swagger.json b/federation/apis/openapi-spec/swagger.json index 6e1b25d48cc..596c6b42839 100644 --- a/federation/apis/openapi-spec/swagger.json +++ b/federation/apis/openapi-spec/swagger.json @@ -9851,7 +9851,7 @@ "$ref": "#/definitions/io.k8s.kubernetes.pkg.api.v1.ConfigMapKeySelector" }, "fieldRef": { - "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.", + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.", "$ref": "#/definitions/io.k8s.kubernetes.pkg.api.v1.ObjectFieldSelector" }, "resourceFieldRef": { diff --git a/pkg/api/types.go b/pkg/api/types.go index 38f40ed1ec5..ec11913d772 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -1250,7 +1250,7 @@ type EnvVar struct { // Only one of its fields may be set. type EnvVarSource struct { // Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, - // spec.nodeName, spec.serviceAccountName, status.podIP. + // spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. // +optional FieldRef *ObjectFieldSelector // Selects a resource of the container: only resources limits and requests diff --git a/pkg/api/v1/conversion.go b/pkg/api/v1/conversion.go index 6784efcae40..b6cf8d4c93b 100644 --- a/pkg/api/v1/conversion.go +++ b/pkg/api/v1/conversion.go @@ -190,6 +190,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error { "spec.restartPolicy", "spec.serviceAccountName", "status.phase", + "status.hostIP", "status.podIP": return label, value, nil // This is for backwards compatibility with old v1 clients which send spec.host diff --git a/pkg/api/v1/generated.proto b/pkg/api/v1/generated.proto index fcc0944df25..43206480c07 100644 --- a/pkg/api/v1/generated.proto +++ b/pkg/api/v1/generated.proto @@ -899,7 +899,7 @@ message EnvVar { // EnvVarSource represents a source for the value of an EnvVar. message EnvVarSource { // Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, - // spec.nodeName, spec.serviceAccountName, status.podIP. + // spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. // +optional optional ObjectFieldSelector fieldRef = 1; diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index ec756de2781..d80da3ffc20 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -1349,7 +1349,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, - // spec.nodeName, spec.serviceAccountName, status.podIP. + // spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. // +optional FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"` // Selects a resource of the container: only resources limits and requests diff --git a/pkg/api/v1/types_swagger_doc_generated.go b/pkg/api/v1/types_swagger_doc_generated.go index f64ecc247f4..3b850c707aa 100644 --- a/pkg/api/v1/types_swagger_doc_generated.go +++ b/pkg/api/v1/types_swagger_doc_generated.go @@ -481,7 +481,7 @@ func (EnvVar) SwaggerDoc() map[string]string { var map_EnvVarSource = map[string]string{ "": "EnvVarSource represents a source for the value of an EnvVar.", - "fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.", + "fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.", "resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.", "configMapKeyRef": "Selects a key of a ConfigMap.", "secretKeyRef": "Selects a key of a secret in the pod's namespace", diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 56143796bf7..1d17daffac7 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -1416,7 +1416,7 @@ func ValidateEnv(vars []api.EnvVar, fldPath *field.Path) field.ErrorList { return allErrs } -var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "spec.nodeName", "spec.serviceAccountName", "status.podIP") +var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP") var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "requests.cpu", "requests.memory") func validateEnvVarValueFrom(ev api.EnvVar, fldPath *field.Path) field.ErrorList { diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 7ce6a6241c7..415c7de6547 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -2153,6 +2153,24 @@ func TestValidateEnv(t *testing.T) { }, }, }, + { + Name: "abc", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: api.Registry.GroupOrDie(api.GroupName).GroupVersion.String(), + FieldPath: "status.hostIP", + }, + }, + }, + { + Name: "abc", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: api.Registry.GroupOrDie(api.GroupName).GroupVersion.String(), + FieldPath: "status.podIP", + }, + }, + }, { Name: "secret_value", ValueFrom: &api.EnvVarSource{ @@ -2328,7 +2346,7 @@ func TestValidateEnv(t *testing.T) { }, }, }}, - expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.podIP`, + expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP`, }, { name: "invalid fieldPath annotations", @@ -2341,7 +2359,7 @@ func TestValidateEnv(t *testing.T) { }, }, }}, - expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.podIP`, + expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP`, }, { name: "unsupported fieldPath", @@ -2354,7 +2372,7 @@ func TestValidateEnv(t *testing.T) { }, }, }}, - expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.podIP`, + expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP`, }, } for _, tc := range errorCases { diff --git a/pkg/fieldpath/fieldpath.go b/pkg/fieldpath/fieldpath.go index ff707e05dce..9ddfa4ca705 100644 --- a/pkg/fieldpath/fieldpath.go +++ b/pkg/fieldpath/fieldpath.go @@ -41,11 +41,6 @@ func FormatMap(m map[string]string) (fmtStr string) { // ExtractFieldPathAsString extracts the field from the given object // and returns it as a string. The object must be a pointer to an // API type. -// -// Currently, this API is limited to supporting the fieldpaths: -// -// 1. metadata.name - The name of an API object -// 2. metadata.namespace - The namespace of an API object func ExtractFieldPathAsString(obj interface{}, fieldPath string) (string, error) { accessor, err := meta.Accessor(obj) if err != nil { diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index c309049cd33..a3351d65526 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -3355,7 +3355,7 @@ func GetOpenAPIDefinitions(ref openapi.ReferenceCallback) map[string]openapi.Ope Properties: map[string]spec.Schema{ "fieldRef": { SchemaProps: spec.SchemaProps{ - Description: "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.", + Description: "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.", Ref: ref("k8s.io/kubernetes/pkg/api/v1.ObjectFieldSelector"), }, }, diff --git a/pkg/kubelet/container/helpers.go b/pkg/kubelet/container/helpers.go index 4c5344be990..3dfecdecbdc 100644 --- a/pkg/kubelet/container/helpers.go +++ b/pkg/kubelet/container/helpers.go @@ -46,7 +46,7 @@ type HandlerRunner interface { } // RuntimeHelper wraps kubelet to make container runtime -// able to get necessary informations like the RunContainerOptions, DNS settings. +// able to get necessary informations like the RunContainerOptions, DNS settings, Host IP. type RuntimeHelper interface { GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, useClusterFirstPolicy bool, err error) GetClusterDNS(pod *v1.Pod) (dnsServers []string, dnsSearches []string, useClusterFirstPolicy bool, err error) diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 0fb29ccda27..6cc135ad51f 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -638,6 +638,12 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod return pod.Spec.NodeName, nil case "spec.serviceAccountName": return pod.Spec.ServiceAccountName, nil + case "status.hostIP": + hostIP, err := kl.getHostIPAnyWay() + if err != nil { + return "", err + } + return hostIP.String(), nil case "status.podIP": return podIP, nil } diff --git a/pkg/kubelet/kubelet_pods_test.go b/pkg/kubelet/kubelet_pods_test.go index 0132b385322..85ebd38f991 100644 --- a/pkg/kubelet/kubelet_pods_test.go +++ b/pkg/kubelet/kubelet_pods_test.go @@ -502,6 +502,15 @@ func TestMakeEnvironmentVariables(t *testing.T) { }, }, }, + { + Name: "HOST_IP", + ValueFrom: &v1.EnvVarSource{ + FieldRef: &v1.ObjectFieldSelector{ + APIVersion: api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String(), + FieldPath: "status.hostIP", + }, + }, + }, }, }, masterServiceNs: "nothing", @@ -512,6 +521,7 @@ func TestMakeEnvironmentVariables(t *testing.T) { {Name: "POD_NODE_NAME", Value: "node-name"}, {Name: "POD_SERVICE_ACCOUNT_NAME", Value: "special"}, {Name: "POD_IP", Value: "1.2.3.4"}, + {Name: "HOST_IP", Value: testKubeletHostIP}, }, }, { diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 6dfb43e8c74..721565e4063 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -79,6 +79,7 @@ func init() { const ( testKubeletHostname = "127.0.0.1" + testKubeletHostIP = "127.0.0.1" testReservationCPU = "200m" testReservationMemory = "100M" @@ -166,7 +167,31 @@ func newTestKubeletWithImageList( kubelet.masterServiceNamespace = metav1.NamespaceDefault kubelet.serviceLister = testServiceLister{} kubelet.nodeLister = testNodeLister{} - kubelet.nodeInfo = testNodeInfo{} + kubelet.nodeInfo = testNodeInfo{ + nodes: []*v1.Node{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: string(kubelet.nodeName), + }, + Status: v1.NodeStatus{ + Conditions: []v1.NodeCondition{ + { + Type: v1.NodeReady, + Status: v1.ConditionTrue, + Reason: "Ready", + Message: "Node ready", + }, + }, + Addresses: []v1.NodeAddress{ + { + Type: v1.NodeInternalIP, + Address: testKubeletHostIP, + }, + }, + }, + }, + }, + } kubelet.recorder = fakeRecorder if err := kubelet.setupDataDirs(); err != nil { t.Fatalf("can't initialize kubelet data dirs: %v", err) diff --git a/staging/src/k8s.io/client-go/pkg/api/types.go b/staging/src/k8s.io/client-go/pkg/api/types.go index 38f40ed1ec5..ec11913d772 100644 --- a/staging/src/k8s.io/client-go/pkg/api/types.go +++ b/staging/src/k8s.io/client-go/pkg/api/types.go @@ -1250,7 +1250,7 @@ type EnvVar struct { // Only one of its fields may be set. type EnvVarSource struct { // Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, - // spec.nodeName, spec.serviceAccountName, status.podIP. + // spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. // +optional FieldRef *ObjectFieldSelector // Selects a resource of the container: only resources limits and requests diff --git a/staging/src/k8s.io/client-go/pkg/api/v1/conversion.go b/staging/src/k8s.io/client-go/pkg/api/v1/conversion.go index 041517819e1..06db046e8c2 100644 --- a/staging/src/k8s.io/client-go/pkg/api/v1/conversion.go +++ b/staging/src/k8s.io/client-go/pkg/api/v1/conversion.go @@ -190,6 +190,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error { "spec.restartPolicy", "spec.serviceAccountName", "status.phase", + "status.hostIP", "status.podIP": return label, value, nil // This is for backwards compatibility with old v1 clients which send spec.host diff --git a/staging/src/k8s.io/client-go/pkg/api/v1/generated.proto b/staging/src/k8s.io/client-go/pkg/api/v1/generated.proto index fcc0944df25..43206480c07 100644 --- a/staging/src/k8s.io/client-go/pkg/api/v1/generated.proto +++ b/staging/src/k8s.io/client-go/pkg/api/v1/generated.proto @@ -899,7 +899,7 @@ message EnvVar { // EnvVarSource represents a source for the value of an EnvVar. message EnvVarSource { // Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, - // spec.nodeName, spec.serviceAccountName, status.podIP. + // spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. // +optional optional ObjectFieldSelector fieldRef = 1; diff --git a/staging/src/k8s.io/client-go/pkg/api/v1/types.go b/staging/src/k8s.io/client-go/pkg/api/v1/types.go index ec756de2781..d80da3ffc20 100644 --- a/staging/src/k8s.io/client-go/pkg/api/v1/types.go +++ b/staging/src/k8s.io/client-go/pkg/api/v1/types.go @@ -1349,7 +1349,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, - // spec.nodeName, spec.serviceAccountName, status.podIP. + // spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. // +optional FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"` // Selects a resource of the container: only resources limits and requests diff --git a/staging/src/k8s.io/client-go/pkg/api/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/client-go/pkg/api/v1/types_swagger_doc_generated.go index f64ecc247f4..3b850c707aa 100644 --- a/staging/src/k8s.io/client-go/pkg/api/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/client-go/pkg/api/v1/types_swagger_doc_generated.go @@ -481,7 +481,7 @@ func (EnvVar) SwaggerDoc() map[string]string { var map_EnvVarSource = map[string]string{ "": "EnvVarSource represents a source for the value of an EnvVar.", - "fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.", + "fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.", "resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.", "configMapKeyRef": "Selects a key of a ConfigMap.", "secretKeyRef": "Selects a key of a secret in the pod's namespace", diff --git a/test/e2e/common/downward_api.go b/test/e2e/common/downward_api.go index 549bdb40f4a..a81570d2113 100644 --- a/test/e2e/common/downward_api.go +++ b/test/e2e/common/downward_api.go @@ -62,7 +62,7 @@ var _ = framework.KubeDescribe("Downward API", func() { testDownwardAPI(f, podName, env, expectations) }) - It("should provide pod IP as an env var [Conformance]", func() { + It("should provide pod and host IP as an env var [Conformance]", func() { podName := "downward-api-" + string(uuid.NewUUID()) env := []v1.EnvVar{ { @@ -74,10 +74,20 @@ var _ = framework.KubeDescribe("Downward API", func() { }, }, }, + { + Name: "HOST_IP", + ValueFrom: &v1.EnvVarSource{ + FieldRef: &v1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "status.hostIP", + }, + }, + }, } expectations := []string{ "POD_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)", + "HOST_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)", } testDownwardAPI(f, podName, env, expectations) diff --git a/test/fixtures/doc-yaml/user-guide/downward-api/dapi-pod.yaml b/test/fixtures/doc-yaml/user-guide/downward-api/dapi-pod.yaml index 7d688aa0e99..a4796fc24c0 100644 --- a/test/fixtures/doc-yaml/user-guide/downward-api/dapi-pod.yaml +++ b/test/fixtures/doc-yaml/user-guide/downward-api/dapi-pod.yaml @@ -20,4 +20,8 @@ spec: valueFrom: fieldRef: fieldPath: status.podIP + - name: MY_HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP restartPolicy: Never