diff --git a/pkg/kubelet/BUILD b/pkg/kubelet/BUILD index f284d6918f2..c6f168426a9 100644 --- a/pkg/kubelet/BUILD +++ b/pkg/kubelet/BUILD @@ -103,7 +103,6 @@ go_library( "//pkg/util/node:go_default_library", "//pkg/util/oom:go_default_library", "//pkg/util/removeall:go_default_library", - "//pkg/version:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/csi:go_default_library", "//pkg/volume/util:go_default_library", diff --git a/pkg/kubelet/kubelet_node_status.go b/pkg/kubelet/kubelet_node_status.go index 02efe8f3679..0f7f5df45c4 100644 --- a/pkg/kubelet/kubelet_node_status.go +++ b/pkg/kubelet/kubelet_node_status.go @@ -40,7 +40,6 @@ import ( "k8s.io/kubernetes/pkg/kubelet/util" "k8s.io/kubernetes/pkg/scheduler/algorithm" nodeutil "k8s.io/kubernetes/pkg/util/node" - "k8s.io/kubernetes/pkg/version" volutil "k8s.io/kubernetes/pkg/volume/util" ) @@ -445,28 +444,6 @@ func (kl *Kubelet) recordEvent(eventType, event, message string) { kl.recorder.Eventf(kl.nodeRef, eventType, event, message) } -// Set versioninfo for the node. -func (kl *Kubelet) setNodeStatusVersionInfo(node *v1.Node) { - verinfo, err := kl.cadvisor.VersionInfo() - if err != nil { - glog.Errorf("Error getting version info: %v", err) - return - } - - node.Status.NodeInfo.KernelVersion = verinfo.KernelVersion - node.Status.NodeInfo.OSImage = verinfo.ContainerOsVersion - - runtimeVersion := "Unknown" - if runtimeVer, err := kl.containerRuntime.Version(); err == nil { - runtimeVersion = runtimeVer.String() - } - node.Status.NodeInfo.ContainerRuntimeVersion = fmt.Sprintf("%s://%s", kl.containerRuntime.Type(), runtimeVersion) - - node.Status.NodeInfo.KubeletVersion = version.Get().String() - // TODO: kube-proxy might be different version from kubelet in the future - node.Status.NodeInfo.KubeProxyVersion = version.Get().String() -} - // Set daemonEndpoints for the node. func (kl *Kubelet) setNodeStatusDaemonEndpoints(node *v1.Node) { node.Status.DaemonEndpoints = *kl.daemonEndpoints @@ -571,7 +548,7 @@ func (kl *Kubelet) defaultNodeStatusFuncs() []func(*v1.Node) error { nodestatus.NodeAddress(kl.nodeIP, kl.nodeIPValidator, kl.hostname, kl.externalCloudProvider, kl.cloud, nodeAddressesFunc), nodestatus.MachineInfo(string(kl.nodeName), kl.maxPods, kl.podsPerCore, kl.GetCachedMachineInfo, kl.containerManager.GetCapacity, kl.containerManager.GetDevicePluginResourceCapacity, kl.containerManager.GetNodeAllocatableReservation, kl.recordEvent), - withoutError(kl.setNodeStatusVersionInfo), + nodestatus.VersionInfo(kl.cadvisor.VersionInfo, kl.containerRuntime.Type, kl.containerRuntime.Version), withoutError(kl.setNodeStatusDaemonEndpoints), withoutError(kl.setNodeStatusImages), withoutError(kl.setNodeStatusGoRuntime), diff --git a/pkg/kubelet/nodestatus/BUILD b/pkg/kubelet/nodestatus/BUILD index 2c358e0ce2a..00b50925cba 100644 --- a/pkg/kubelet/nodestatus/BUILD +++ b/pkg/kubelet/nodestatus/BUILD @@ -12,7 +12,9 @@ go_library( "//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/cadvisor:go_default_library", "//pkg/kubelet/cm:go_default_library", + "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/events:go_default_library", + "//pkg/version:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -44,7 +46,10 @@ go_test( deps = [ "//pkg/cloudprovider/providers/fake:go_default_library", "//pkg/kubelet/cm:go_default_library", + "//pkg/kubelet/container:go_default_library", + "//pkg/kubelet/container/testing:go_default_library", "//pkg/kubelet/events:go_default_library", + "//pkg/version:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", diff --git a/pkg/kubelet/nodestatus/setters.go b/pkg/kubelet/nodestatus/setters.go index 9d238fec636..66f161a2902 100644 --- a/pkg/kubelet/nodestatus/setters.go +++ b/pkg/kubelet/nodestatus/setters.go @@ -36,7 +36,9 @@ import ( kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cm" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/events" + "k8s.io/kubernetes/pkg/version" "github.com/golang/glog" ) @@ -292,6 +294,35 @@ func MachineInfo(nodeName string, } } +// VersionInfo returns a Setter that updates version-related information on the node. +func VersionInfo(versionInfoFunc func() (*cadvisorapiv1.VersionInfo, error), // typically Kubelet.cadvisor.VersionInfo + runtimeTypeFunc func() string, // typically Kubelet.containerRuntime.Type + runtimeVersionFunc func() (kubecontainer.Version, error), // typically Kubelet.containerRuntime.Version +) Setter { + return func(node *v1.Node) error { + verinfo, err := versionInfoFunc() + if err != nil { + // TODO(mtaufen): consider removing this log line, since returned error will be logged + glog.Errorf("Error getting version info: %v", err) + return fmt.Errorf("error getting version info: %v", err) + } + + node.Status.NodeInfo.KernelVersion = verinfo.KernelVersion + node.Status.NodeInfo.OSImage = verinfo.ContainerOsVersion + + runtimeVersion := "Unknown" + if runtimeVer, err := runtimeVersionFunc(); err == nil { + runtimeVersion = runtimeVer.String() + } + node.Status.NodeInfo.ContainerRuntimeVersion = fmt.Sprintf("%s://%s", runtimeTypeFunc(), runtimeVersion) + + node.Status.NodeInfo.KubeletVersion = version.Get().String() + // TODO: kube-proxy might be different version from kubelet in the future + node.Status.NodeInfo.KubeProxyVersion = version.Get().String() + return nil + } +} + // ReadyCondition returns a Setter that updates the v1.NodeReady condition on the node. func ReadyCondition( nowFunc func() time.Time, // typically Kubelet.clock.Now diff --git a/pkg/kubelet/nodestatus/setters_test.go b/pkg/kubelet/nodestatus/setters_test.go index 0a396b6a867..8042f89adae 100644 --- a/pkg/kubelet/nodestatus/setters_test.go +++ b/pkg/kubelet/nodestatus/setters_test.go @@ -32,7 +32,10 @@ import ( "k8s.io/apimachinery/pkg/util/diff" fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake" "k8s.io/kubernetes/pkg/kubelet/cm" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubecontainertest "k8s.io/kubernetes/pkg/kubelet/container/testing" "k8s.io/kubernetes/pkg/kubelet/events" + "k8s.io/kubernetes/pkg/version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -618,6 +621,89 @@ func TestMachineInfo(t *testing.T) { } +func TestVersionInfo(t *testing.T) { + cases := []struct { + desc string + node *v1.Node + versionInfo *cadvisorapiv1.VersionInfo + versionInfoError error + runtimeType string + runtimeVersion kubecontainer.Version + runtimeVersionError error + expectNode *v1.Node + expectError error + }{ + { + desc: "versions set in node info", + node: &v1.Node{}, + versionInfo: &cadvisorapiv1.VersionInfo{ + KernelVersion: "KernelVersion", + ContainerOsVersion: "ContainerOSVersion", + }, + runtimeType: "RuntimeType", + runtimeVersion: &kubecontainertest.FakeVersion{ + Version: "RuntimeVersion", + }, + expectNode: &v1.Node{ + Status: v1.NodeStatus{ + NodeInfo: v1.NodeSystemInfo{ + KernelVersion: "KernelVersion", + OSImage: "ContainerOSVersion", + ContainerRuntimeVersion: "RuntimeType://RuntimeVersion", + KubeletVersion: version.Get().String(), + KubeProxyVersion: version.Get().String(), + }, + }, + }, + }, + { + desc: "error getting version info", + node: &v1.Node{}, + versionInfoError: fmt.Errorf("foo"), + expectNode: &v1.Node{}, + expectError: fmt.Errorf("error getting version info: foo"), + }, + { + desc: "error getting runtime version results in Unknown runtime", + node: &v1.Node{}, + versionInfo: &cadvisorapiv1.VersionInfo{}, + runtimeType: "RuntimeType", + runtimeVersionError: fmt.Errorf("foo"), + expectNode: &v1.Node{ + Status: v1.NodeStatus{ + NodeInfo: v1.NodeSystemInfo{ + ContainerRuntimeVersion: "RuntimeType://Unknown", + KubeletVersion: version.Get().String(), + KubeProxyVersion: version.Get().String(), + }, + }, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + versionInfoFunc := func() (*cadvisorapiv1.VersionInfo, error) { + return tc.versionInfo, tc.versionInfoError + } + runtimeTypeFunc := func() string { + return tc.runtimeType + } + runtimeVersionFunc := func() (kubecontainer.Version, error) { + return tc.runtimeVersion, tc.runtimeVersionError + } + // construct setter + setter := VersionInfo(versionInfoFunc, runtimeTypeFunc, runtimeVersionFunc) + // call setter on node + err := setter(tc.node) + require.Equal(t, tc.expectError, err) + // check expected node + assert.True(t, apiequality.Semantic.DeepEqual(tc.expectNode, tc.node), + "Diff: %s", diff.ObjectDiff(tc.expectNode, tc.node)) + }) + } +} + func TestReadyCondition(t *testing.T) { now := time.Now() before := now.Add(-time.Second)