From 91c027d6cccce36a6b1116313142f45884f8a7b0 Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Wed, 8 Mar 2017 03:08:09 -0500 Subject: [PATCH 1/7] support hostIP in downward API --- pkg/api/v1/conversion.go | 1 + pkg/api/validation/validation.go | 2 +- pkg/api/validation/validation_test.go | 24 ++++++++++++++++--- pkg/fieldpath/fieldpath.go | 5 ---- pkg/kubelet/kubelet_pods.go | 2 ++ test/e2e/common/downward_api.go | 8 +++++++ .../user-guide/downward-api/dapi-pod.yaml | 4 ++++ 7 files changed, 37 insertions(+), 9 deletions(-) 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/validation/validation.go b/pkg/api/validation/validation.go index 1ca11e43043..29201afa900 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 f131cc16cd7..7b9361397cf 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/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 3aa8509f039..175a34e7061 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -617,6 +617,8 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod return pod.Spec.NodeName, nil case "spec.serviceAccountName": return pod.Spec.ServiceAccountName, nil + case "status.hostIP": + return pod.Status.HostIP, nil case "status.podIP": return podIP, nil } diff --git a/test/e2e/common/downward_api.go b/test/e2e/common/downward_api.go index 549bdb40f4a..19cd2e1eee6 100644 --- a/test/e2e/common/downward_api.go +++ b/test/e2e/common/downward_api.go @@ -73,11 +73,19 @@ var _ = framework.KubeDescribe("Downward API", func() { FieldPath: "status.podIP", }, }, + 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 From 824d0b11cb3866a9ab611f035b2dbc5560a3b2d3 Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Mon, 13 Mar 2017 20:13:32 -0400 Subject: [PATCH 2/7] e2e tests for status.hostIP in downward api --- pkg/kubelet/kubelet_pods_test.go | 13 +++++++++++++ test/e2e/common/downward_api.go | 2 ++ 2 files changed, 15 insertions(+) diff --git a/pkg/kubelet/kubelet_pods_test.go b/pkg/kubelet/kubelet_pods_test.go index 0132b385322..56962fdee1f 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: "5.6.7.8"}, }, }, { @@ -1142,6 +1152,9 @@ func TestMakeEnvironmentVariables(t *testing.T) { ServiceAccountName: "special", NodeName: "node-name", }, + Status: v1.PodStatus{ + HostIP: "5.6.7.8", + }, } podIP := "1.2.3.4" diff --git a/test/e2e/common/downward_api.go b/test/e2e/common/downward_api.go index 19cd2e1eee6..226a6446710 100644 --- a/test/e2e/common/downward_api.go +++ b/test/e2e/common/downward_api.go @@ -73,6 +73,8 @@ var _ = framework.KubeDescribe("Downward API", func() { FieldPath: "status.podIP", }, }, + }, + { Name: "HOST_IP", ValueFrom: &v1.EnvVarSource{ FieldRef: &v1.ObjectFieldSelector{ From c001deed43e8b6304066b4c8ea08f3b8f2cde23a Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Sat, 18 Mar 2017 22:38:38 -0400 Subject: [PATCH 3/7] fetch hostIP at runtime since status manager didn't update it yet --- pkg/kubelet/container/helpers.go | 7 +++++-- .../container/testing/fake_runtime_helper.go | 8 ++++++- pkg/kubelet/dockertools/docker_manager.go | 21 ++++++++++++------- pkg/kubelet/kubelet_pods.go | 12 +++++------ pkg/kubelet/kubelet_pods_test.go | 10 ++++----- .../kuberuntime/kuberuntime_container.go | 8 +++---- .../kuberuntime/kuberuntime_manager.go | 10 +++++++-- .../kuberuntime/kuberuntime_manager_test.go | 2 +- pkg/kubelet/rkt/rkt.go | 20 +++++++++++------- pkg/kubelet/rkt/rkt_test.go | 2 +- test/e2e/common/downward_api.go | 2 +- 11 files changed, 64 insertions(+), 38 deletions(-) diff --git a/pkg/kubelet/container/helpers.go b/pkg/kubelet/container/helpers.go index 4c5344be990..c36678378d3 100644 --- a/pkg/kubelet/container/helpers.go +++ b/pkg/kubelet/container/helpers.go @@ -21,6 +21,7 @@ import ( "fmt" "hash/adler32" "hash/fnv" + "net" "strings" "time" @@ -46,9 +47,9 @@ 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) + GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP, hostIP string) (contOpts *RunContainerOptions, useClusterFirstPolicy bool, err error) GetClusterDNS(pod *v1.Pod) (dnsServers []string, dnsSearches []string, useClusterFirstPolicy bool, err error) // GetPodCgroupParent returns the the CgroupName identifer, and its literal cgroupfs form on the host // of a pod. @@ -59,6 +60,8 @@ type RuntimeHelper interface { // supplemental groups for the Pod. These extra supplemental groups come // from annotations on persistent volumes that the pod depends on. GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 + + GetHostIP() (net.IP, error) } // ShouldContainerBeRestarted checks whether a container needs to be restarted. diff --git a/pkg/kubelet/container/testing/fake_runtime_helper.go b/pkg/kubelet/container/testing/fake_runtime_helper.go index 76bbd0a4bc3..dd788e198a1 100644 --- a/pkg/kubelet/container/testing/fake_runtime_helper.go +++ b/pkg/kubelet/container/testing/fake_runtime_helper.go @@ -17,6 +17,8 @@ limitations under the License. package testing import ( + "net" + kubetypes "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/api/v1" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" @@ -32,7 +34,7 @@ type FakeRuntimeHelper struct { Err error } -func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, bool, error) { +func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP, hostIP string) (*kubecontainer.RunContainerOptions, bool, error) { var opts kubecontainer.RunContainerOptions if len(container.TerminationMessagePath) != 0 { opts.PodContainerDir = f.PodContainerDir @@ -60,3 +62,7 @@ func (f *FakeRuntimeHelper) GetPodDir(podUID kubetypes.UID) string { func (f *FakeRuntimeHelper) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 { return nil } + +func (f *FakeRuntimeHelper) GetHostIP() (net.IP, error) { + return []byte{}, nil +} diff --git a/pkg/kubelet/dockertools/docker_manager.go b/pkg/kubelet/dockertools/docker_manager.go index d89e14c12bc..0a3e24b68e0 100644 --- a/pkg/kubelet/dockertools/docker_manager.go +++ b/pkg/kubelet/dockertools/docker_manager.go @@ -1743,7 +1743,7 @@ func (dm *DockerManager) applyOOMScoreAdj(pod *v1.Pod, container *v1.Container, // Run a single container from a pod. Returns the docker container ID // If do not need to pass labels, just pass nil. -func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP, imageRef string, restartCount int) (kubecontainer.ContainerID, error) { +func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP, hostIP, imageRef string, restartCount int) (kubecontainer.ContainerID, error) { start := time.Now() defer func() { metrics.ContainerManagerLatency.WithLabelValues("runContainerInPod").Observe(metrics.SinceInMicroseconds(start)) @@ -1756,7 +1756,7 @@ func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, glog.V(5).Infof("Generating ref for container %s: %#v", container.Name, ref) } - opts, useClusterFirstPolicy, err := dm.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) + opts, useClusterFirstPolicy, err := dm.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP, hostIP) if err != nil { return kubecontainer.ContainerID{}, fmt.Errorf("GenerateRunContainerOptions: %v", err) } @@ -1993,7 +1993,8 @@ func (dm *DockerManager) createPodInfraContainer(pod *v1.Pod) (kubecontainer.Doc } // Currently we don't care about restart count of infra container, just set it to 0. - id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", imageRef, 0) + // We also don't care about podIP and hostIP since their only passed in during runtime because of downward API + id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", "", imageRef, 0) if err != nil { return "", kubecontainer.ErrRunContainer, err.Error() } @@ -2269,6 +2270,12 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon podIP = podStatus.IP } + rawHostIP, err := dm.runtimeHelper.GetHostIP() + hostIP := rawHostIP.String() + if err != nil { + glog.Errorf("Failed to get Host IP for pod: %s; %v", format.Pod(pod), err) + } + // If we should create infra container then we do it first. podInfraContainerID := containerChanges.InfraContainerId if containerChanges.StartInfraContainer && (len(containerChanges.ContainersToStart) > 0) { @@ -2369,7 +2376,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon } glog.V(4).Infof("Creating init container %+v in pod %v", container, format.Pod(pod)) - if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP); err != nil { + if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP, hostIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) return @@ -2407,7 +2414,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon } glog.V(4).Infof("Creating container %+v in pod %v", container, format.Pod(pod)) - if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP); err != nil { + if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP, hostIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) continue @@ -2418,7 +2425,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon // tryContainerStart attempts to pull and start the container, returning an error and a reason string if the start // was not successful. -func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP string) (err error, reason string) { +func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP, hostIP string) (err error, reason string) { imageRef, msg, err := dm.imagePuller.EnsureImageExists(pod, container, pullSecrets) if err != nil { return err, msg @@ -2445,7 +2452,7 @@ func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, netMode = namespaceMode } - _, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, imageRef, restartCount) + _, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, hostIP, imageRef, restartCount) if err != nil { // TODO(bburns) : Perhaps blacklist a container after N failures? return kubecontainer.ErrRunContainer, err.Error() diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 175a34e7061..f12165c946e 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -275,7 +275,7 @@ func (kl *Kubelet) GetPodCgroupParent(pod *v1.Pod) string { // GenerateRunContainerOptions generates the RunContainerOptions, which can be used by // the container runtime to set parameters for launching a container. -func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, bool, error) { +func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP, hostIP string) (*kubecontainer.RunContainerOptions, bool, error) { var err error useClusterFirstPolicy := false cgroupParent := kl.GetPodCgroupParent(pod) @@ -299,7 +299,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai if err != nil { return nil, false, err } - opts.Envs, err = kl.makeEnvironmentVariables(pod, container, podIP) + opts.Envs, err = kl.makeEnvironmentVariables(pod, container, podIP, hostIP) if err != nil { return nil, false, err } @@ -386,7 +386,7 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string) (map[string]string, error) { } // Make the environment variables for a pod in the given namespace. -func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP string) ([]kubecontainer.EnvVar, error) { +func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP, hostIP string) ([]kubecontainer.EnvVar, error) { var result []kubecontainer.EnvVar // Note: These are added to the docker Config, but are not included in the checksum computed // by dockertools.BuildDockerName(...). That way, we can still determine whether an @@ -506,7 +506,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container // Step 1b: resolve alternate env var sources switch { case envVar.ValueFrom.FieldRef != nil: - runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP) + runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP, hostIP) if err != nil { return result, err } @@ -607,7 +607,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container // podFieldSelectorRuntimeValue returns the runtime value of the given // selector for a pod. -func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP string) (string, error) { +func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP, hostIP string) (string, error) { internalFieldPath, _, err := api.Scheme.ConvertFieldLabel(fs.APIVersion, "Pod", fs.FieldPath, "") if err != nil { return "", err @@ -618,7 +618,7 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod case "spec.serviceAccountName": return pod.Spec.ServiceAccountName, nil case "status.hostIP": - return pod.Status.HostIP, nil + return hostIP, nil case "status.podIP": return podIP, nil } diff --git a/pkg/kubelet/kubelet_pods_test.go b/pkg/kubelet/kubelet_pods_test.go index 56962fdee1f..b1e8af5730d 100644 --- a/pkg/kubelet/kubelet_pods_test.go +++ b/pkg/kubelet/kubelet_pods_test.go @@ -187,7 +187,7 @@ func TestGenerateRunContainerOptions_DNSConfigurationParams(t *testing.T) { options := make([]*kubecontainer.RunContainerOptions, 4) for i, pod := range pods { var err error - options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "") + options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "", "") if err != nil { t.Fatalf("failed to generate container options: %v", err) } @@ -220,7 +220,7 @@ func TestGenerateRunContainerOptions_DNSConfigurationParams(t *testing.T) { kubelet.resolverConfig = "/etc/resolv.conf" for i, pod := range pods { var err error - options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "") + options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "", "") if err != nil { t.Fatalf("failed to generate container options: %v", err) } @@ -1152,13 +1152,11 @@ func TestMakeEnvironmentVariables(t *testing.T) { ServiceAccountName: "special", NodeName: "node-name", }, - Status: v1.PodStatus{ - HostIP: "5.6.7.8", - }, } podIP := "1.2.3.4" + hostIP := "5.6.7.8" - result, err := kl.makeEnvironmentVariables(testPod, tc.container, podIP) + result, err := kl.makeEnvironmentVariables(testPod, tc.container, podIP, hostIP) select { case e := <-fakeRecorder.Events: assert.Equal(t, tc.expectedEvent, e) diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 5c519354e58..4c20baf116b 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -51,7 +51,7 @@ import ( // * create the container // * start the container // * run the post start lifecycle hooks (if applicable) -func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string) (string, error) { +func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP, hostIP string) (string, error) { // Step 1: pull the image. imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets) if err != nil { @@ -72,7 +72,7 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb restartCount = containerStatus.RestartCount + 1 } - containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef) + containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP, hostIP, imageRef) if err != nil { m.recorder.Eventf(ref, v1.EventTypeWarning, events.FailedToCreateContainer, "Failed to create container with error: %v", err) return "Generate Container Config Failed", err @@ -131,8 +131,8 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb } // generateContainerConfig generates container config for kubelet runtime v1. -func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string) (*runtimeapi.ContainerConfig, error) { - opts, _, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) +func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, hostIP, imageRef string) (*runtimeapi.ContainerConfig, error) { + opts, _, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP, hostIP) if err != nil { return nil, err } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index a09909e8c04..18c8b7a147a 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -604,6 +604,12 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStat podIP = podStatus.IP } + rawHostIP, err := m.runtimeHelper.GetHostIP() + hostIP := rawHostIP.String() + if err != nil { + glog.Errorf("Failed to get Host IP for pod: %s; %v", format.Pod(pod), err) + } + // Step 4: Create a sandbox for the pod if necessary. podSandboxID := podContainerChanges.SandboxID if podContainerChanges.CreateSandbox && len(podContainerChanges.ContainersToStart) > 0 { @@ -680,7 +686,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStat } glog.V(4).Infof("Creating init container %+v in pod %v", container, format.Pod(pod)) - if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP); err != nil { + if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, hostIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("init container start failed: %v: %s", err, msg)) return @@ -714,7 +720,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStat } glog.V(4).Infof("Creating container %+v in pod %v", container, format.Pod(pod)) - if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP); err != nil { + if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, hostIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) continue diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index 1b29e2422ea..8bf91ae385b 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -146,7 +146,7 @@ func makeFakeContainer(t *testing.T, m *kubeGenericRuntimeManager, template cont sandboxConfig, err := m.generatePodSandboxConfig(template.pod, template.sandboxAttempt) assert.NoError(t, err, "generatePodSandboxConfig for container template %+v", template) - containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image) + containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", "", template.container.Image) assert.NoError(t, err, "generateContainerConfig for container template %+v", template) podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata) diff --git a/pkg/kubelet/rkt/rkt.go b/pkg/kubelet/rkt/rkt.go index 7decec4c5bc..fb3ab16054e 100644 --- a/pkg/kubelet/rkt/rkt.go +++ b/pkg/kubelet/rkt/rkt.go @@ -607,7 +607,7 @@ func setApp(imgManifest *appcschema.ImageManifest, c *v1.Container, } // makePodManifest transforms a kubelet pod spec to the rkt pod manifest. -func (r *Runtime) makePodManifest(pod *v1.Pod, podIP string, pullSecrets []v1.Secret) (*appcschema.PodManifest, error) { +func (r *Runtime) makePodManifest(pod *v1.Pod, podIP, hostIP string, pullSecrets []v1.Secret) (*appcschema.PodManifest, error) { manifest := appcschema.BlankPodManifest() ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout) @@ -654,7 +654,7 @@ func (r *Runtime) makePodManifest(pod *v1.Pod, podIP string, pullSecrets []v1.Se } for _, c := range pod.Spec.Containers { - err := r.newAppcRuntimeApp(pod, podIP, c, requiresPrivileged, pullSecrets, manifest) + err := r.newAppcRuntimeApp(pod, podIP, hostIP, c, requiresPrivileged, pullSecrets, manifest) if err != nil { return nil, err } @@ -776,7 +776,7 @@ func (r *Runtime) makeContainerLogMount(opts *kubecontainer.RunContainerOptions, return &mnt, nil } -func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP string, c v1.Container, requiresPrivileged bool, pullSecrets []v1.Secret, manifest *appcschema.PodManifest) error { +func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP, hostIP string, c v1.Container, requiresPrivileged bool, pullSecrets []v1.Secret, manifest *appcschema.PodManifest) error { var annotations appctypes.Annotations = []appctypes.Annotation{ { Name: *appctypes.MustACIdentifier(k8sRktContainerHashAnno), @@ -810,7 +810,7 @@ func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP string, c v1.Container, r } // TODO: determine how this should be handled for rkt - opts, _, err := r.runtimeHelper.GenerateRunContainerOptions(pod, &c, podIP) + opts, _, err := r.runtimeHelper.GenerateRunContainerOptions(pod, &c, podIP, hostIP) if err != nil { return err } @@ -1135,9 +1135,9 @@ func constructSyslogIdentifier(generateName string, podName string) string { // // On success, it will return a string that represents name of the unit file // and the runtime pod. -func (r *Runtime) preparePod(pod *v1.Pod, podIP string, pullSecrets []v1.Secret, netnsName string) (string, *kubecontainer.Pod, error) { +func (r *Runtime) preparePod(pod *v1.Pod, podIP, hostIP string, pullSecrets []v1.Secret, netnsName string) (string, *kubecontainer.Pod, error) { // Generate the appc pod manifest from the k8s pod spec. - manifest, err := r.makePodManifest(pod, podIP, pullSecrets) + manifest, err := r.makePodManifest(pod, podIP, hostIP, pullSecrets) if err != nil { return "", nil, err } @@ -1349,7 +1349,13 @@ func (r *Runtime) RunPod(pod *v1.Pod, pullSecrets []v1.Secret) error { return err } - name, runtimePod, prepareErr := r.preparePod(pod, podIP, pullSecrets, netnsName) + rawHostIP, err := r.runtimeHelper.GetHostIP() + hostIP := rawHostIP.String() + if err != nil { + glog.Errorf("Failed to get Host IP for pod: %s; %v", format.Pod(pod), err) + } + + name, runtimePod, prepareErr := r.preparePod(pod, podIP, hostIP, pullSecrets, netnsName) // Set container references and generate events. // If preparedPod fails, then send out 'failed' events for each container. diff --git a/pkg/kubelet/rkt/rkt_test.go b/pkg/kubelet/rkt/rkt_test.go index d38a48c3e95..c5118f9cf0b 100644 --- a/pkg/kubelet/rkt/rkt_test.go +++ b/pkg/kubelet/rkt/rkt_test.go @@ -1902,7 +1902,7 @@ func TestMakePodManifestAnnotations(t *testing.T) { for i, testCase := range testCases { hint := fmt.Sprintf("case #%d", i) - result, err := r.makePodManifest(testCase.in, "", []v1.Secret{}) + result, err := r.makePodManifest(testCase.in, "", "", []v1.Secret{}) assert.Equal(t, testCase.outerr, err, hint) if err == nil { sort.Sort(annotationsByName(result.Annotations)) diff --git a/test/e2e/common/downward_api.go b/test/e2e/common/downward_api.go index 226a6446710..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{ { From f05d584a4aa5a2071755c7bc97b2c3048f1557cb Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Mon, 13 Mar 2017 22:23:02 -0400 Subject: [PATCH 4/7] Regenerate code for api change --- api/openapi-spec/swagger.json | 2 +- api/swagger-spec/apps_v1beta1.json | 2 +- api/swagger-spec/batch_v1.json | 2 +- api/swagger-spec/extensions_v1beta1.json | 2 +- api/swagger-spec/settings.k8s.io_v1alpha1.json | 2 +- api/swagger-spec/v1.json | 2 +- docs/api-reference/apps/v1beta1/definitions.html | 4 ++-- docs/api-reference/batch/v1/definitions.html | 4 ++-- docs/api-reference/extensions/v1beta1/definitions.html | 4 ++-- docs/api-reference/settings.k8s.io/v1alpha1/definitions.html | 4 ++-- docs/api-reference/v1/definitions.html | 4 ++-- federation/apis/openapi-spec/swagger.json | 2 +- pkg/api/types.go | 2 +- pkg/api/v1/generated.proto | 2 +- pkg/api/v1/types.go | 2 +- pkg/api/v1/types_swagger_doc_generated.go | 2 +- pkg/generated/openapi/zz_generated.openapi.go | 2 +- staging/src/k8s.io/client-go/pkg/api/types.go | 2 +- staging/src/k8s.io/client-go/pkg/api/v1/conversion.go | 1 + staging/src/k8s.io/client-go/pkg/api/v1/generated.proto | 2 +- staging/src/k8s.io/client-go/pkg/api/v1/types.go | 2 +- .../client-go/pkg/api/v1/types_swagger_doc_generated.go | 2 +- 22 files changed, 27 insertions(+), 26 deletions(-) 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/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/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/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/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 8ef514a5cf5..703e310617d 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/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", From 4f6c1b5ad5d190a978a4932a4f7926ffe043f272 Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Tue, 28 Mar 2017 12:07:17 -0400 Subject: [PATCH 5/7] call GetHostIP from makeEnvironment --- api/swagger-spec/batch_v2alpha1.json | 2 +- pkg/kubelet/container/helpers.go | 5 +--- .../container/testing/fake_runtime_helper.go | 8 +----- pkg/kubelet/dockertools/docker_manager.go | 21 +++++---------- pkg/kubelet/kubelet_pods.go | 17 +++++++----- pkg/kubelet/kubelet_pods_test.go | 9 +++---- pkg/kubelet/kubelet_test.go | 27 ++++++++++++++++++- .../kuberuntime/kuberuntime_container.go | 8 +++--- .../kuberuntime/kuberuntime_manager.go | 10 ++----- .../kuberuntime/kuberuntime_manager_test.go | 2 +- pkg/kubelet/rkt/rkt.go | 20 +++++--------- pkg/kubelet/rkt/rkt_test.go | 2 +- 12 files changed, 66 insertions(+), 65 deletions(-) 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/pkg/kubelet/container/helpers.go b/pkg/kubelet/container/helpers.go index c36678378d3..3dfecdecbdc 100644 --- a/pkg/kubelet/container/helpers.go +++ b/pkg/kubelet/container/helpers.go @@ -21,7 +21,6 @@ import ( "fmt" "hash/adler32" "hash/fnv" - "net" "strings" "time" @@ -49,7 +48,7 @@ type HandlerRunner interface { // RuntimeHelper wraps kubelet to make container runtime // able to get necessary informations like the RunContainerOptions, DNS settings, Host IP. type RuntimeHelper interface { - GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP, hostIP string) (contOpts *RunContainerOptions, useClusterFirstPolicy bool, err error) + 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) // GetPodCgroupParent returns the the CgroupName identifer, and its literal cgroupfs form on the host // of a pod. @@ -60,8 +59,6 @@ type RuntimeHelper interface { // supplemental groups for the Pod. These extra supplemental groups come // from annotations on persistent volumes that the pod depends on. GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 - - GetHostIP() (net.IP, error) } // ShouldContainerBeRestarted checks whether a container needs to be restarted. diff --git a/pkg/kubelet/container/testing/fake_runtime_helper.go b/pkg/kubelet/container/testing/fake_runtime_helper.go index dd788e198a1..76bbd0a4bc3 100644 --- a/pkg/kubelet/container/testing/fake_runtime_helper.go +++ b/pkg/kubelet/container/testing/fake_runtime_helper.go @@ -17,8 +17,6 @@ limitations under the License. package testing import ( - "net" - kubetypes "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/api/v1" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" @@ -34,7 +32,7 @@ type FakeRuntimeHelper struct { Err error } -func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP, hostIP string) (*kubecontainer.RunContainerOptions, bool, error) { +func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, bool, error) { var opts kubecontainer.RunContainerOptions if len(container.TerminationMessagePath) != 0 { opts.PodContainerDir = f.PodContainerDir @@ -62,7 +60,3 @@ func (f *FakeRuntimeHelper) GetPodDir(podUID kubetypes.UID) string { func (f *FakeRuntimeHelper) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 { return nil } - -func (f *FakeRuntimeHelper) GetHostIP() (net.IP, error) { - return []byte{}, nil -} diff --git a/pkg/kubelet/dockertools/docker_manager.go b/pkg/kubelet/dockertools/docker_manager.go index 0a3e24b68e0..d89e14c12bc 100644 --- a/pkg/kubelet/dockertools/docker_manager.go +++ b/pkg/kubelet/dockertools/docker_manager.go @@ -1743,7 +1743,7 @@ func (dm *DockerManager) applyOOMScoreAdj(pod *v1.Pod, container *v1.Container, // Run a single container from a pod. Returns the docker container ID // If do not need to pass labels, just pass nil. -func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP, hostIP, imageRef string, restartCount int) (kubecontainer.ContainerID, error) { +func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP, imageRef string, restartCount int) (kubecontainer.ContainerID, error) { start := time.Now() defer func() { metrics.ContainerManagerLatency.WithLabelValues("runContainerInPod").Observe(metrics.SinceInMicroseconds(start)) @@ -1756,7 +1756,7 @@ func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, glog.V(5).Infof("Generating ref for container %s: %#v", container.Name, ref) } - opts, useClusterFirstPolicy, err := dm.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP, hostIP) + opts, useClusterFirstPolicy, err := dm.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) if err != nil { return kubecontainer.ContainerID{}, fmt.Errorf("GenerateRunContainerOptions: %v", err) } @@ -1993,8 +1993,7 @@ func (dm *DockerManager) createPodInfraContainer(pod *v1.Pod) (kubecontainer.Doc } // Currently we don't care about restart count of infra container, just set it to 0. - // We also don't care about podIP and hostIP since their only passed in during runtime because of downward API - id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", "", imageRef, 0) + id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", imageRef, 0) if err != nil { return "", kubecontainer.ErrRunContainer, err.Error() } @@ -2270,12 +2269,6 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon podIP = podStatus.IP } - rawHostIP, err := dm.runtimeHelper.GetHostIP() - hostIP := rawHostIP.String() - if err != nil { - glog.Errorf("Failed to get Host IP for pod: %s; %v", format.Pod(pod), err) - } - // If we should create infra container then we do it first. podInfraContainerID := containerChanges.InfraContainerId if containerChanges.StartInfraContainer && (len(containerChanges.ContainersToStart) > 0) { @@ -2376,7 +2369,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon } glog.V(4).Infof("Creating init container %+v in pod %v", container, format.Pod(pod)) - if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP, hostIP); err != nil { + if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) return @@ -2414,7 +2407,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon } glog.V(4).Infof("Creating container %+v in pod %v", container, format.Pod(pod)) - if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP, hostIP); err != nil { + if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) continue @@ -2425,7 +2418,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon // tryContainerStart attempts to pull and start the container, returning an error and a reason string if the start // was not successful. -func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP, hostIP string) (err error, reason string) { +func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP string) (err error, reason string) { imageRef, msg, err := dm.imagePuller.EnsureImageExists(pod, container, pullSecrets) if err != nil { return err, msg @@ -2452,7 +2445,7 @@ func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, netMode = namespaceMode } - _, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, hostIP, imageRef, restartCount) + _, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, imageRef, restartCount) if err != nil { // TODO(bburns) : Perhaps blacklist a container after N failures? return kubecontainer.ErrRunContainer, err.Error() diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index f12165c946e..d05644f1e95 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -275,7 +275,7 @@ func (kl *Kubelet) GetPodCgroupParent(pod *v1.Pod) string { // GenerateRunContainerOptions generates the RunContainerOptions, which can be used by // the container runtime to set parameters for launching a container. -func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP, hostIP string) (*kubecontainer.RunContainerOptions, bool, error) { +func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, bool, error) { var err error useClusterFirstPolicy := false cgroupParent := kl.GetPodCgroupParent(pod) @@ -299,7 +299,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai if err != nil { return nil, false, err } - opts.Envs, err = kl.makeEnvironmentVariables(pod, container, podIP, hostIP) + opts.Envs, err = kl.makeEnvironmentVariables(pod, container, podIP) if err != nil { return nil, false, err } @@ -386,7 +386,7 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string) (map[string]string, error) { } // Make the environment variables for a pod in the given namespace. -func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP, hostIP string) ([]kubecontainer.EnvVar, error) { +func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP string) ([]kubecontainer.EnvVar, error) { var result []kubecontainer.EnvVar // Note: These are added to the docker Config, but are not included in the checksum computed // by dockertools.BuildDockerName(...). That way, we can still determine whether an @@ -506,7 +506,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container // Step 1b: resolve alternate env var sources switch { case envVar.ValueFrom.FieldRef != nil: - runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP, hostIP) + runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP) if err != nil { return result, err } @@ -607,7 +607,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container // podFieldSelectorRuntimeValue returns the runtime value of the given // selector for a pod. -func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP, hostIP string) (string, error) { +func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP string) (string, error) { internalFieldPath, _, err := api.Scheme.ConvertFieldLabel(fs.APIVersion, "Pod", fs.FieldPath, "") if err != nil { return "", err @@ -618,7 +618,12 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod case "spec.serviceAccountName": return pod.Spec.ServiceAccountName, nil case "status.hostIP": - return hostIP, nil + hostIP, err := kl.GetHostIP() + 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 b1e8af5730d..85ebd38f991 100644 --- a/pkg/kubelet/kubelet_pods_test.go +++ b/pkg/kubelet/kubelet_pods_test.go @@ -187,7 +187,7 @@ func TestGenerateRunContainerOptions_DNSConfigurationParams(t *testing.T) { options := make([]*kubecontainer.RunContainerOptions, 4) for i, pod := range pods { var err error - options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "", "") + options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "") if err != nil { t.Fatalf("failed to generate container options: %v", err) } @@ -220,7 +220,7 @@ func TestGenerateRunContainerOptions_DNSConfigurationParams(t *testing.T) { kubelet.resolverConfig = "/etc/resolv.conf" for i, pod := range pods { var err error - options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "", "") + options[i], _, err = kubelet.GenerateRunContainerOptions(pod, &v1.Container{}, "") if err != nil { t.Fatalf("failed to generate container options: %v", err) } @@ -521,7 +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: "5.6.7.8"}, + {Name: "HOST_IP", Value: testKubeletHostIP}, }, }, { @@ -1154,9 +1154,8 @@ func TestMakeEnvironmentVariables(t *testing.T) { }, } podIP := "1.2.3.4" - hostIP := "5.6.7.8" - result, err := kl.makeEnvironmentVariables(testPod, tc.container, podIP, hostIP) + result, err := kl.makeEnvironmentVariables(testPod, tc.container, podIP) select { case e := <-fakeRecorder.Events: assert.Equal(t, tc.expectedEvent, e) 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/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 4c20baf116b..5c519354e58 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -51,7 +51,7 @@ import ( // * create the container // * start the container // * run the post start lifecycle hooks (if applicable) -func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP, hostIP string) (string, error) { +func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string) (string, error) { // Step 1: pull the image. imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets) if err != nil { @@ -72,7 +72,7 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb restartCount = containerStatus.RestartCount + 1 } - containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP, hostIP, imageRef) + containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef) if err != nil { m.recorder.Eventf(ref, v1.EventTypeWarning, events.FailedToCreateContainer, "Failed to create container with error: %v", err) return "Generate Container Config Failed", err @@ -131,8 +131,8 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb } // generateContainerConfig generates container config for kubelet runtime v1. -func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, hostIP, imageRef string) (*runtimeapi.ContainerConfig, error) { - opts, _, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP, hostIP) +func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string) (*runtimeapi.ContainerConfig, error) { + opts, _, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) if err != nil { return nil, err } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index 18c8b7a147a..a09909e8c04 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -604,12 +604,6 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStat podIP = podStatus.IP } - rawHostIP, err := m.runtimeHelper.GetHostIP() - hostIP := rawHostIP.String() - if err != nil { - glog.Errorf("Failed to get Host IP for pod: %s; %v", format.Pod(pod), err) - } - // Step 4: Create a sandbox for the pod if necessary. podSandboxID := podContainerChanges.SandboxID if podContainerChanges.CreateSandbox && len(podContainerChanges.ContainersToStart) > 0 { @@ -686,7 +680,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStat } glog.V(4).Infof("Creating init container %+v in pod %v", container, format.Pod(pod)) - if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, hostIP); err != nil { + if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("init container start failed: %v: %s", err, msg)) return @@ -720,7 +714,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStat } glog.V(4).Infof("Creating container %+v in pod %v", container, format.Pod(pod)) - if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, hostIP); err != nil { + if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP); err != nil { startContainerResult.Fail(err, msg) utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) continue diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index 8bf91ae385b..1b29e2422ea 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -146,7 +146,7 @@ func makeFakeContainer(t *testing.T, m *kubeGenericRuntimeManager, template cont sandboxConfig, err := m.generatePodSandboxConfig(template.pod, template.sandboxAttempt) assert.NoError(t, err, "generatePodSandboxConfig for container template %+v", template) - containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", "", template.container.Image) + containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image) assert.NoError(t, err, "generateContainerConfig for container template %+v", template) podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata) diff --git a/pkg/kubelet/rkt/rkt.go b/pkg/kubelet/rkt/rkt.go index fb3ab16054e..7decec4c5bc 100644 --- a/pkg/kubelet/rkt/rkt.go +++ b/pkg/kubelet/rkt/rkt.go @@ -607,7 +607,7 @@ func setApp(imgManifest *appcschema.ImageManifest, c *v1.Container, } // makePodManifest transforms a kubelet pod spec to the rkt pod manifest. -func (r *Runtime) makePodManifest(pod *v1.Pod, podIP, hostIP string, pullSecrets []v1.Secret) (*appcschema.PodManifest, error) { +func (r *Runtime) makePodManifest(pod *v1.Pod, podIP string, pullSecrets []v1.Secret) (*appcschema.PodManifest, error) { manifest := appcschema.BlankPodManifest() ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout) @@ -654,7 +654,7 @@ func (r *Runtime) makePodManifest(pod *v1.Pod, podIP, hostIP string, pullSecrets } for _, c := range pod.Spec.Containers { - err := r.newAppcRuntimeApp(pod, podIP, hostIP, c, requiresPrivileged, pullSecrets, manifest) + err := r.newAppcRuntimeApp(pod, podIP, c, requiresPrivileged, pullSecrets, manifest) if err != nil { return nil, err } @@ -776,7 +776,7 @@ func (r *Runtime) makeContainerLogMount(opts *kubecontainer.RunContainerOptions, return &mnt, nil } -func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP, hostIP string, c v1.Container, requiresPrivileged bool, pullSecrets []v1.Secret, manifest *appcschema.PodManifest) error { +func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP string, c v1.Container, requiresPrivileged bool, pullSecrets []v1.Secret, manifest *appcschema.PodManifest) error { var annotations appctypes.Annotations = []appctypes.Annotation{ { Name: *appctypes.MustACIdentifier(k8sRktContainerHashAnno), @@ -810,7 +810,7 @@ func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP, hostIP string, c v1.Cont } // TODO: determine how this should be handled for rkt - opts, _, err := r.runtimeHelper.GenerateRunContainerOptions(pod, &c, podIP, hostIP) + opts, _, err := r.runtimeHelper.GenerateRunContainerOptions(pod, &c, podIP) if err != nil { return err } @@ -1135,9 +1135,9 @@ func constructSyslogIdentifier(generateName string, podName string) string { // // On success, it will return a string that represents name of the unit file // and the runtime pod. -func (r *Runtime) preparePod(pod *v1.Pod, podIP, hostIP string, pullSecrets []v1.Secret, netnsName string) (string, *kubecontainer.Pod, error) { +func (r *Runtime) preparePod(pod *v1.Pod, podIP string, pullSecrets []v1.Secret, netnsName string) (string, *kubecontainer.Pod, error) { // Generate the appc pod manifest from the k8s pod spec. - manifest, err := r.makePodManifest(pod, podIP, hostIP, pullSecrets) + manifest, err := r.makePodManifest(pod, podIP, pullSecrets) if err != nil { return "", nil, err } @@ -1349,13 +1349,7 @@ func (r *Runtime) RunPod(pod *v1.Pod, pullSecrets []v1.Secret) error { return err } - rawHostIP, err := r.runtimeHelper.GetHostIP() - hostIP := rawHostIP.String() - if err != nil { - glog.Errorf("Failed to get Host IP for pod: %s; %v", format.Pod(pod), err) - } - - name, runtimePod, prepareErr := r.preparePod(pod, podIP, hostIP, pullSecrets, netnsName) + name, runtimePod, prepareErr := r.preparePod(pod, podIP, pullSecrets, netnsName) // Set container references and generate events. // If preparedPod fails, then send out 'failed' events for each container. diff --git a/pkg/kubelet/rkt/rkt_test.go b/pkg/kubelet/rkt/rkt_test.go index c5118f9cf0b..d38a48c3e95 100644 --- a/pkg/kubelet/rkt/rkt_test.go +++ b/pkg/kubelet/rkt/rkt_test.go @@ -1902,7 +1902,7 @@ func TestMakePodManifestAnnotations(t *testing.T) { for i, testCase := range testCases { hint := fmt.Sprintf("case #%d", i) - result, err := r.makePodManifest(testCase.in, "", "", []v1.Secret{}) + result, err := r.makePodManifest(testCase.in, "", []v1.Secret{}) assert.Equal(t, testCase.outerr, err, hint) if err == nil { sort.Sort(annotationsByName(result.Annotations)) From 82903d28ff1e9a3bd09372cdbcb145b180c91fb8 Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Tue, 28 Mar 2017 16:14:16 -0400 Subject: [PATCH 6/7] update api ref docs --- docs/api-reference/batch/v2alpha1/definitions.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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:
From a62653456ba6022abf43e3c81d0d3d5795c43ea8 Mon Sep 17 00:00:00 2001 From: andrewsykim Date: Thu, 30 Mar 2017 21:57:08 -0400 Subject: [PATCH 7/7] use kl.getHostIPAnyWay() to get host ip even if node is not registered --- pkg/kubelet/kubelet_pods.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index d05644f1e95..8b91cd8cba7 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -618,11 +618,10 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod case "spec.serviceAccountName": return pod.Spec.ServiceAccountName, nil case "status.hostIP": - hostIP, err := kl.GetHostIP() + hostIP, err := kl.getHostIPAnyWay() if err != nil { return "", err } - return hostIP.String(), nil case "status.podIP": return podIP, nil