mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
kubeadm: Extended KubeletVersionCheck
KubeletVersionCheck now able to detect if kubelet version is higher than control plane. As this might lead to malfunctional cluster setups, kubeadm will give warning. Fixes: kubernetes/kubeadm#496
This commit is contained in:
parent
e9f7970caa
commit
de272d0617
@ -498,7 +498,9 @@ func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// KubeletVersionCheck validates installed kubelet version
|
// KubeletVersionCheck validates installed kubelet version
|
||||||
type KubeletVersionCheck struct{}
|
type KubeletVersionCheck struct {
|
||||||
|
KubernetesVersion string
|
||||||
|
}
|
||||||
|
|
||||||
// Check validates kubelet version. It should be not less than minimal supported version
|
// Check validates kubelet version. It should be not less than minimal supported version
|
||||||
func (kubever KubeletVersionCheck) Check() (warnings, errors []error) {
|
func (kubever KubeletVersionCheck) Check() (warnings, errors []error) {
|
||||||
@ -509,7 +511,17 @@ func (kubever KubeletVersionCheck) Check() (warnings, errors []error) {
|
|||||||
if kubeletVersion.LessThan(kubeadmconstants.MinimumKubeletVersion) {
|
if kubeletVersion.LessThan(kubeadmconstants.MinimumKubeletVersion) {
|
||||||
return nil, []error{fmt.Errorf("Kubelet version %q is lower than kubadm can support. Please upgrade kubelet", kubeletVersion)}
|
return nil, []error{fmt.Errorf("Kubelet version %q is lower than kubadm can support. Please upgrade kubelet", kubeletVersion)}
|
||||||
}
|
}
|
||||||
return nil, []error{}
|
|
||||||
|
if kubever.KubernetesVersion != "" {
|
||||||
|
k8sVersion, err := versionutil.ParseSemantic(kubever.KubernetesVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, []error{fmt.Errorf("couldn't parse kubernetes version %q: %v", kubever.KubernetesVersion, err)}
|
||||||
|
}
|
||||||
|
if kubeletVersion.Major() > k8sVersion.Major() || kubeletVersion.Minor() > k8sVersion.Minor() {
|
||||||
|
return nil, []error{fmt.Errorf("the kubelet version is higher than the control plane version. This is not a supported version skew and may lead to a malfunctional cluster. Kubelet version: %q Control plane version: %q", kubeletVersion, k8sVersion)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwapCheck warns if swap is enabled
|
// SwapCheck warns if swap is enabled
|
||||||
@ -688,7 +700,7 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
|
|||||||
SystemVerificationCheck{},
|
SystemVerificationCheck{},
|
||||||
IsPrivilegedUserCheck{},
|
IsPrivilegedUserCheck{},
|
||||||
HostnameCheck{nodeName: cfg.NodeName},
|
HostnameCheck{nodeName: cfg.NodeName},
|
||||||
KubeletVersionCheck{},
|
KubeletVersionCheck{KubernetesVersion: cfg.KubernetesVersion},
|
||||||
ServiceCheck{Service: "kubelet", CheckIfActive: false},
|
ServiceCheck{Service: "kubelet", CheckIfActive: false},
|
||||||
ServiceCheck{Service: "docker", CheckIfActive: true},
|
ServiceCheck{Service: "docker", CheckIfActive: true},
|
||||||
FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}},
|
FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}},
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -556,3 +557,59 @@ func restoreEnv(e map[string]string) {
|
|||||||
os.Setenv(k, v)
|
os.Setenv(k, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestKubeletVersionCheck(t *testing.T) {
|
||||||
|
type T struct {
|
||||||
|
kubeletVersion string
|
||||||
|
k8sVersion string
|
||||||
|
expectErrors bool
|
||||||
|
expectWarnings bool
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []T{
|
||||||
|
{"v1.10.2", "", false, false}, // check minimally supported version when there is no information about control plane
|
||||||
|
{"v1.7.3", "v1.7.8", true, false}, // too old kubelet (older than kubeadmconstants.MinimumKubeletVersion), should fail.
|
||||||
|
{"v1.9.0", "v1.9.5", false, false}, // kubelet within same major.minor as control plane
|
||||||
|
{"v1.9.5", "v1.9.1", false, false}, // kubelet is newer, but still within same major.minor as control plane
|
||||||
|
{"v1.9.0", "v1.10.1", false, false}, // kubelet is lower than control plane, but newer than minimally supported
|
||||||
|
{"v1.10.0-alpha.1", "v1.9.1", true, false}, // kubelet is newer (development build) than control plane, should fail.
|
||||||
|
{"v1.10.0", "v1.9.5", true, false}, // kubelet is newer (release) than control plane, should fail.
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "test-kubelet-version-check")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to create directory for testing GetKubeletVersion: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
// We don't want to call real kubelet or something else in $PATH
|
||||||
|
oldPATH := os.Getenv("PATH")
|
||||||
|
defer os.Setenv("PATH", oldPATH)
|
||||||
|
|
||||||
|
os.Setenv("PATH", dir)
|
||||||
|
|
||||||
|
kubeletFn := filepath.Join(dir, "kubelet")
|
||||||
|
for _, tc := range cases {
|
||||||
|
|
||||||
|
content := []byte(fmt.Sprintf("#!/bin/sh\necho 'Kubernetes %s'", tc.kubeletVersion))
|
||||||
|
if err := ioutil.WriteFile(kubeletFn, content, 0755); err != nil {
|
||||||
|
t.Errorf("Error creating test stub file %s: %v", kubeletFn, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
check := KubeletVersionCheck{KubernetesVersion: tc.k8sVersion}
|
||||||
|
warnings, errors := check.Check()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case warnings != nil && !tc.expectWarnings:
|
||||||
|
t.Errorf("KubeletVersionCheck: unexpected warnings for kubelet version %q and kubernetes version %q. Warnings: %v", tc.kubeletVersion, tc.k8sVersion, warnings)
|
||||||
|
case warnings == nil && tc.expectWarnings:
|
||||||
|
t.Errorf("KubeletVersionCheck: expected warnings for kubelet version %q and kubernetes version %q but got nothing", tc.kubeletVersion, tc.k8sVersion)
|
||||||
|
case errors != nil && !tc.expectErrors:
|
||||||
|
t.Errorf("KubeletVersionCheck: unexpected errors for kubelet version %q and kubernetes version %q. errors: %v", tc.kubeletVersion, tc.k8sVersion, errors)
|
||||||
|
case errors == nil && tc.expectErrors:
|
||||||
|
t.Errorf("KubeletVersionCheck: expected errors for kubelet version %q and kubernetes version %q but got nothing", tc.kubeletVersion, tc.k8sVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user