Merge pull request #19675 from apcera/kubelet-report-runtime-version

Update container runtime to properly report the engine and version
pull/6/head
Alex Mohr 2016-01-21 10:31:19 -08:00
commit c52122cab5
8 changed files with 67 additions and 25 deletions

View File

@ -43,6 +43,7 @@ type FakeRuntime struct {
StartedContainers []string
KilledContainers []string
VersionInfo string
APIVersionInfo string
RuntimeType string
Err error
InspectErr error
@ -154,6 +155,14 @@ func (f *FakeRuntime) Version() (Version, error) {
return &FakeVersion{Version: f.VersionInfo}, f.Err
}
func (f *FakeRuntime) APIVersion() (Version, error) {
f.Lock()
defer f.Unlock()
f.CalledFunctions = append(f.CalledFunctions, "APIVersion")
return &FakeVersion{Version: f.APIVersionInfo}, f.Err
}
func (f *FakeRuntime) GetPods(all bool) ([]*Pod, error) {
f.Lock()
defer f.Unlock()

View File

@ -55,6 +55,9 @@ type Runtime interface {
// Version returns the version information of the container runtime.
Version() (Version, error)
// APIVersion returns the API version information of the container
// runtime. This may be different from the runtime engine's version.
APIVersion() (Version, error)
// GetPods returns a list containers group by pods. The boolean parameter
// specifies whether the runtime returns all containers including those already
// exited and dead containers (used for garbage collection).

View File

@ -47,6 +47,11 @@ func (r *Mock) Version() (Version, error) {
return args.Get(0).(Version), args.Error(1)
}
func (r *Mock) APIVersion() (Version, error) {
args := r.Called()
return args.Get(0).(Version), args.Error(1)
}
func (r *Mock) GetPods(all bool) ([]*Pod, error) {
args := r.Called(all)
return args.Get(0).([]*Pod), args.Error(1)

View File

@ -160,7 +160,16 @@ func TestVersion(t *testing.T) {
if err != nil {
t.Errorf("got error while getting docker server version - %s", err)
}
expectedVersion, _ := docker.NewAPIVersion("1.15")
expectedVersion, _ := docker.NewAPIVersion("1.1.3")
if e, a := expectedVersion.String(), version.String(); e != a {
t.Errorf("invalid docker server version. expected: %v, got: %v", e, a)
}
version, err = manager.APIVersion()
if err != nil {
t.Errorf("got error while getting docker server version - %s", err)
}
expectedVersion, _ = docker.NewAPIVersion("1.15")
if e, a := expectedVersion.String(), version.String(); e != a {
t.Errorf("invalid docker server version. expected: %v, got: %v", e, a)
}

View File

@ -980,11 +980,26 @@ func (dm *DockerManager) Version() (kubecontainer.Version, error) {
return nil, fmt.Errorf("docker: failed to get docker version: %v", err)
}
engineVersion := env.Get("Version")
version, err := docker.NewAPIVersion(engineVersion)
if err != nil {
glog.Errorf("docker: failed to parse docker server version %q: %v", engineVersion, err)
return nil, fmt.Errorf("docker: failed to parse docker server version %q: %v", engineVersion, err)
}
return dockerVersion(version), nil
}
func (dm *DockerManager) APIVersion() (kubecontainer.Version, error) {
env, err := dm.client.Version()
if err != nil {
return nil, fmt.Errorf("docker: failed to get docker version: %v", err)
}
apiVersion := env.Get("ApiVersion")
version, err := docker.NewAPIVersion(apiVersion)
if err != nil {
glog.Errorf("docker: failed to parse docker server version %q: %v", apiVersion, err)
return nil, fmt.Errorf("docker: failed to parse docker server version %q: %v", apiVersion, err)
glog.Errorf("docker: failed to parse docker api version %q: %v", apiVersion, err)
return nil, fmt.Errorf("docker: failed to parse docker api version %q: %v", apiVersion, err)
}
return dockerVersion(version), nil
}
@ -993,7 +1008,7 @@ func (dm *DockerManager) Version() (kubecontainer.Version, error) {
var dockerAPIVersionWithExec = "1.15"
func (dm *DockerManager) nativeExecSupportExists() (bool, error) {
version, err := dm.Version()
version, err := dm.APIVersion()
if err != nil {
return false, err
}

View File

@ -2455,14 +2455,6 @@ func (kl *Kubelet) LatestLoopEntryTime() time.Time {
return val.(time.Time)
}
// Returns the container runtime version for this Kubelet.
func (kl *Kubelet) GetContainerRuntimeVersion() (kubecontainer.Version, error) {
if kl.containerRuntime == nil {
return nil, fmt.Errorf("no container runtime")
}
return kl.containerRuntime.Version()
}
func (kl *Kubelet) validatePodPhase(podStatus *api.PodStatus) error {
switch podStatus.Phase {
case api.PodRunning, api.PodSucceeded, api.PodFailed:
@ -2785,8 +2777,13 @@ func (kl *Kubelet) setNodeStatusVersionInfo(node *api.Node) {
} else {
node.Status.NodeInfo.KernelVersion = verinfo.KernelVersion
node.Status.NodeInfo.OSImage = verinfo.ContainerOsVersion
// TODO: Determine the runtime is docker or rocket
node.Status.NodeInfo.ContainerRuntimeVersion = "docker://" + verinfo.DockerVersion
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()
@ -2976,7 +2973,7 @@ func (kl *Kubelet) setNodeStatus(node *api.Node) error {
func (kl *Kubelet) isContainerRuntimeVersionCompatible() error {
switch kl.GetRuntime().Type() {
case "docker":
version, err := kl.GetContainerRuntimeVersion()
version, err := kl.GetRuntime().APIVersion()
if err != nil {
return nil
}

View File

@ -2521,6 +2521,9 @@ func updateDiskSpacePolicy(kubelet *Kubelet, mockCadvisor *cadvisor.Mock, rootCa
func TestUpdateNewNodeStatus(t *testing.T) {
testKubelet := newTestKubelet(t)
kubelet := testKubelet.kubelet
fakeRuntime := testKubelet.fakeRuntime
fakeRuntime.RuntimeType = "docker"
fakeRuntime.VersionInfo = "1.5.0"
kubeClient := testKubelet.fakeKubeClient
kubeClient.ReactionChain = testclient.NewSimpleFake(&api.NodeList{Items: []api.Node{
{ObjectMeta: api.ObjectMeta{Name: testKubeletHostname}},
@ -2538,7 +2541,6 @@ func TestUpdateNewNodeStatus(t *testing.T) {
versionInfo := &cadvisorapi.VersionInfo{
KernelVersion: "3.16.0-0.bpo.4-amd64",
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
DockerVersion: "1.5.0",
}
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
@ -2662,7 +2664,6 @@ func TestUpdateNewNodeOutOfDiskStatusWithTransitionFrequency(t *testing.T) {
versionInfo := &cadvisorapi.VersionInfo{
KernelVersion: "3.16.0-0.bpo.4-amd64",
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
DockerVersion: "1.5.0",
}
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
@ -2724,7 +2725,8 @@ func testDockerRuntimeVersion(t *testing.T) {
kubelet := testKubelet.kubelet
fakeRuntime := testKubelet.fakeRuntime
fakeRuntime.RuntimeType = "docker"
fakeRuntime.VersionInfo = "1.18"
fakeRuntime.VersionInfo = "1.5.0"
fakeRuntime.APIVersionInfo = "1.18"
kubeClient := testKubelet.fakeKubeClient
kubeClient.ReactionChain = testclient.NewSimpleFake(&api.NodeList{Items: []api.Node{
{ObjectMeta: api.ObjectMeta{Name: testKubeletHostname}},
@ -2741,7 +2743,6 @@ func testDockerRuntimeVersion(t *testing.T) {
versionInfo := &cadvisorapi.VersionInfo{
KernelVersion: "3.16.0-0.bpo.4-amd64",
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
DockerVersion: "1.5.0",
}
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
@ -2866,6 +2867,9 @@ func testDockerRuntimeVersion(t *testing.T) {
func TestUpdateExistingNodeStatus(t *testing.T) {
testKubelet := newTestKubelet(t)
kubelet := testKubelet.kubelet
fakeRuntime := testKubelet.fakeRuntime
fakeRuntime.RuntimeType = "docker"
fakeRuntime.VersionInfo = "1.5.0"
kubeClient := testKubelet.fakeKubeClient
kubeClient.ReactionChain = testclient.NewSimpleFake(&api.NodeList{Items: []api.Node{
{
@ -2916,7 +2920,6 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
versionInfo := &cadvisorapi.VersionInfo{
KernelVersion: "3.16.0-0.bpo.4-amd64",
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
DockerVersion: "1.5.0",
}
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
@ -3179,10 +3182,8 @@ func TestUpdateNodeStatusWithoutContainerRuntime(t *testing.T) {
kubelet := testKubelet.kubelet
kubeClient := testKubelet.fakeKubeClient
fakeRuntime := testKubelet.fakeRuntime
// This causes returning an error from GetContainerRuntimeVersion() which
// simulates that container runtime is down.
fakeRuntime.VersionInfo = ""
fakeRuntime.RuntimeType = "docker"
fakeRuntime.VersionInfo = "1.5.0"
kubeClient.ReactionChain = testclient.NewSimpleFake(&api.NodeList{Items: []api.Node{
{ObjectMeta: api.ObjectMeta{Name: testKubeletHostname}},
}}).ReactionChain
@ -3199,7 +3200,6 @@ func TestUpdateNodeStatusWithoutContainerRuntime(t *testing.T) {
versionInfo := &cadvisorapi.VersionInfo{
KernelVersion: "3.16.0-0.bpo.4-amd64",
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
DockerVersion: "1.5.0",
}
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)

View File

@ -971,6 +971,10 @@ func (r *Runtime) Version() (kubecontainer.Version, error) {
return r.binVersion, nil
}
func (r *Runtime) APIVersion() (kubecontainer.Version, error) {
return r.binVersion, nil
}
// SyncPod syncs the running pod to match the specified desired pod.
func (r *Runtime) SyncPod(pod *api.Pod, podStatus api.PodStatus, internalPodStatus *kubecontainer.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error {
// TODO: (random-liu) Stop using running pod in SyncPod()