kubeadm preflight - enforce maximum supported Kubernetes version

pull/6/head
fabriziopandini 2017-08-21 22:05:13 +02:00
parent 35f6b12e79
commit 9730b82fcf
3 changed files with 104 additions and 2 deletions

View File

@ -17,6 +17,8 @@ go_library(
"//pkg/api/validation:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//pkg/util/initsystem:go_default_library",
"//pkg/util/version:go_default_library",
"//pkg/version:go_default_library",
"//plugin/cmd/kube-scheduler/app/options:go_default_library",
"//test/e2e_node/system:go_default_library",
"//vendor/github.com/PuerkitoBio/purell:go_default_library",

View File

@ -28,6 +28,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"crypto/tls"
@ -46,6 +47,8 @@ import (
"k8s.io/kubernetes/pkg/api/validation"
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"k8s.io/kubernetes/pkg/util/initsystem"
versionutil "k8s.io/kubernetes/pkg/util/version"
kubeadmversion "k8s.io/kubernetes/pkg/version"
schoptions "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options"
"k8s.io/kubernetes/test/e2e_node/system"
)
@ -394,6 +397,40 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
return warns, nil
}
type KubernetesVersionCheck struct {
KubeadmVersion string
KubernetesVersion string
}
func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
// Skip this check for "super-custom builds", where apimachinery/the overall codebase version is not set.
if strings.HasPrefix(kubever.KubeadmVersion, "v0.0.0") {
return nil, nil
}
kadmVersion, err := versionutil.ParseSemantic(kubever.KubeadmVersion)
if err != nil {
return nil, []error{fmt.Errorf("couldn't parse kubeadm version %q: %v", kubever.KubeadmVersion, err)}
}
k8sVersion, err := versionutil.ParseSemantic(kubever.KubernetesVersion)
if err != nil {
return nil, []error{fmt.Errorf("couldn't parse kubernetes version %q: %v", kubever.KubernetesVersion, err)}
}
// Checks if k8sVersion greater or equal than the first unsupported versions by current version of kubeadm,
// that is major.minor+1 (all patch and pre-releases versions included)
// NB. in semver patches number is a numeric, while prerelease is a string where numeric identifiers always have lower precedence than non-numeric identifiers.
// thus setting the value to x.y.0-0 we are defining the very first patch - prereleases within x.y minor release.
firstUnsupportedVersion := versionutil.MustParseSemantic(fmt.Sprintf("%d.%d.%s", kadmVersion.Major(), kadmVersion.Minor()+1, "0-0"))
if k8sVersion.AtLeast(firstUnsupportedVersion) {
return []error{fmt.Errorf("kubernetes version is greater than kubeadm version. Please consider to upgrade kubeadm. kubernetes version: %s. Kubeadm version: %d.%d.x", k8sVersion, kadmVersion.Components()[0], kadmVersion.Components()[1])}, nil
}
return nil, nil
}
type etcdVersionResponse struct {
Etcdserver string `json:"etcdserver"`
Etcdcluster string `json:"etcdcluster"`
@ -534,6 +571,7 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
}
checks := []Checker{
KubernetesVersionCheck{KubernetesVersion: cfg.KubernetesVersion, KubeadmVersion: kubeadmversion.Get().GitVersion},
SystemVerificationCheck{},
IsRootCheck{},
HostnameCheck{nodeName: cfg.NodeName},

View File

@ -26,7 +26,6 @@ import (
"os"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
)
@ -180,7 +179,7 @@ func TestRunInitMasterChecks(t *testing.T) {
}{
{
cfg: &kubeadmapi.MasterConfiguration{
API: kubeadm.API{AdvertiseAddress: "foo"},
API: kubeadmapi.API{AdvertiseAddress: "foo"},
},
expected: false,
},
@ -347,3 +346,66 @@ func TestConfigCertAndKey(t *testing.T) {
)
}
}
func TestKubernetesVersionCheck(t *testing.T) {
var tests = []struct {
check KubernetesVersionCheck
expectWarnings bool
}{
{
check: KubernetesVersionCheck{
KubeadmVersion: "v1.6.6", //Same version
KubernetesVersion: "v1.6.6",
},
expectWarnings: false,
},
{
check: KubernetesVersionCheck{
KubeadmVersion: "v1.6.6", //KubernetesVersion version older than KubeadmVersion
KubernetesVersion: "v1.5.5",
},
expectWarnings: false,
},
{
check: KubernetesVersionCheck{
KubeadmVersion: "v1.6.6", //KubernetesVersion newer than KubeadmVersion, within the same minor release (new patch)
KubernetesVersion: "v1.6.7",
},
expectWarnings: false,
},
{
check: KubernetesVersionCheck{
KubeadmVersion: "v1.6.6", //KubernetesVersion newer than KubeadmVersion, in a different minor/in pre-release
KubernetesVersion: "v1.7.0-alpha.0",
},
expectWarnings: true,
},
{
check: KubernetesVersionCheck{
KubeadmVersion: "v1.6.6", //KubernetesVersion newer than KubeadmVersion, in a different minor/stable
KubernetesVersion: "v1.7.0",
},
expectWarnings: true,
},
{
check: KubernetesVersionCheck{
KubeadmVersion: "v0.0.0", //"super-custom" builds - Skip this check
KubernetesVersion: "v1.7.0",
},
expectWarnings: false,
},
}
for _, rt := range tests {
warning, _ := rt.check.Check()
if (warning != nil) != rt.expectWarnings {
t.Errorf(
"failed KubernetesVersionCheck:\n\texpected: %t\n\t actual: %t (KubeadmVersion:%s, KubernetesVersion: %s)",
rt.expectWarnings,
(warning != nil),
rt.check.KubeadmVersion,
rt.check.KubernetesVersion,
)
}
}
}