Merge pull request #79223 from rosti/kubeadm-component-configs-versioned

kubeadm: component configs versioned
This commit is contained in:
Kubernetes Prow Robot 2019-11-12 15:38:11 -08:00 committed by GitHub
commit eedfb6bc7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 77 additions and 493 deletions

View File

@ -18,8 +18,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm",
deps = [
"//pkg/kubelet/apis/config:go_default_library",
"//pkg/proxy/apis/config:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
@ -27,6 +25,8 @@ go_library(
"//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library",
"//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library",
"//staging/src/k8s.io/cluster-bootstrap/util/secrets:go_default_library",
"//staging/src/k8s.io/kube-proxy/config/v1alpha1:go_default_library",
"//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)

View File

@ -19,8 +19,8 @@ package kubeadm
import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -182,9 +182,9 @@ type ImageMeta struct {
// ComponentConfigs holds known internal ComponentConfig types for other components
type ComponentConfigs struct {
// Kubelet holds the ComponentConfiguration for the kubelet
Kubelet *kubeletconfig.KubeletConfiguration
Kubelet *kubeletconfigv1beta1.KubeletConfiguration
// KubeProxy holds the ComponentConfiguration for the kube-proxy
KubeProxy *kubeproxyconfig.KubeProxyConfiguration
KubeProxy *kubeproxyconfigv1alpha1.KubeProxyConfiguration
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@ -32,10 +32,10 @@ go_test(
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1beta2:go_default_library",
"//pkg/proxy/apis/config:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//staging/src/k8s.io/kube-proxy/config/v1alpha1:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
],

View File

@ -26,9 +26,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
utilpointer "k8s.io/utils/pointer"
)
@ -449,23 +449,23 @@ func TestValidateInitConfiguration(t *testing.T) {
},
},
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
KubeProxy: &kubeproxyconfigv1alpha1.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
IPTables: kubeproxyconfigv1alpha1.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
IPVS: kubeproxyconfigv1alpha1.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Conntrack: kubeproxyconfigv1alpha1.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
@ -495,23 +495,23 @@ func TestValidateInitConfiguration(t *testing.T) {
},
},
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
KubeProxy: &kubeproxyconfigv1alpha1.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
IPTables: kubeproxyconfigv1alpha1.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
IPVS: kubeproxyconfigv1alpha1.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Conntrack: kubeproxyconfigv1alpha1.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},

View File

@ -24,8 +24,8 @@ import (
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
config "k8s.io/kubernetes/pkg/kubelet/apis/config"
apisconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
v1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
v1beta1 "k8s.io/kubelet/config/v1beta1"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
@ -224,12 +224,12 @@ func (in *ComponentConfigs) DeepCopyInto(out *ComponentConfigs) {
*out = *in
if in.Kubelet != nil {
in, out := &in.Kubelet, &out.Kubelet
*out = new(config.KubeletConfiguration)
*out = new(v1beta1.KubeletConfiguration)
(*in).DeepCopyInto(*out)
}
if in.KubeProxy != nil {
in, out := &in.KubeProxy, &out.KubeProxy
*out = new(apisconfig.KubeProxyConfiguration)
*out = new(v1alpha1.KubeProxyConfiguration)
(*in).DeepCopyInto(*out)
}
return

View File

@ -18,12 +18,6 @@ go_library(
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//pkg/kubelet/apis/config:go_default_library",
"//pkg/kubelet/apis/config/v1beta1:go_default_library",
"//pkg/kubelet/apis/config/validation:go_default_library",
"//pkg/proxy/apis/config:go_default_library",
"//pkg/proxy/apis/config/v1alpha1:go_default_library",
"//pkg/proxy/apis/config/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
@ -41,6 +35,21 @@ go_library(
],
)
go_test(
name = "go_default_test",
srcs = ["config_test.go"],
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
@ -54,25 +63,3 @@ filegroup(
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"config_test.go",
"validation_test.go",
],
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//pkg/kubelet/apis/config:go_default_library",
"//pkg/proxy/apis/config:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
],
)

View File

@ -25,10 +25,10 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/version"
clientset "k8s.io/client-go/kubernetes"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
)
// GetFromKubeletConfigMap returns the pointer to the ComponentConfig API object read from the kubelet-config-version
@ -49,7 +49,7 @@ func GetFromKubeletConfigMap(client clientset.Interface, version *version.Versio
}
// Decodes the kubeletConfigData into the internal component config
obj := &kubeletconfig.KubeletConfiguration{}
obj := &kubeletconfigv1beta1.KubeletConfiguration{}
err = unmarshalObject(obj, []byte(kubeletConfigData))
if err != nil {
return nil, err
@ -82,7 +82,7 @@ func GetFromKubeProxyConfigMap(client clientset.Interface, version *version.Vers
}
// Decodes the Config map dat into the internal component config
obj := &kubeproxyconfig.KubeProxyConfiguration{}
obj := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
err = unmarshalObject(obj, []byte(kubeproxyConfigData))
if err != nil {
return nil, err

View File

@ -27,8 +27,6 @@ import (
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
utilpointer "k8s.io/utils/pointer"
)
@ -58,14 +56,16 @@ const (
// DefaultKubeProxyConfiguration assigns default values for the kube-proxy ComponentConfig
func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
externalproxycfg := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{FeatureGates: make(map[string]bool)}
kind := "KubeProxyConfiguration"
// Do a roundtrip to the external version for defaulting
if internalcfg.ComponentConfigs.KubeProxy != nil {
Scheme.Convert(internalcfg.ComponentConfigs.KubeProxy, externalproxycfg, nil)
if internalcfg.ComponentConfigs.KubeProxy == nil {
internalcfg.ComponentConfigs.KubeProxy = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{
FeatureGates: map[string]bool{},
}
}
externalproxycfg := internalcfg.ComponentConfigs.KubeProxy
if externalproxycfg.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" {
externalproxycfg.ClusterCIDR = internalcfg.Networking.PodSubnet
} else if internalcfg.Networking.PodSubnet != "" && externalproxycfg.ClusterCIDR != internalcfg.Networking.PodSubnet {
@ -83,29 +83,20 @@ func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration)
if enabled, present := internalcfg.FeatureGates[features.IPv6DualStack]; present {
externalproxycfg.FeatureGates[features.IPv6DualStack] = enabled
}
// Run the rest of the kube-proxy defaulting code
Scheme.Default(externalproxycfg)
if internalcfg.ComponentConfigs.KubeProxy == nil {
internalcfg.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
}
// TODO: Figure out how to handle errors in defaulting code
// Go back to the internal version
Scheme.Convert(externalproxycfg, internalcfg.ComponentConfigs.KubeProxy, nil)
}
// DefaultKubeletConfiguration assigns default values for the kubelet ComponentConfig
func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
externalkubeletcfg := &kubeletconfigv1beta1.KubeletConfiguration{}
kind := "KubeletConfiguration"
// Do a roundtrip to the external version for defaulting
if internalcfg.ComponentConfigs.Kubelet != nil {
Scheme.Convert(internalcfg.ComponentConfigs.Kubelet, externalkubeletcfg, nil)
if internalcfg.ComponentConfigs.Kubelet == nil {
internalcfg.ComponentConfigs.Kubelet = &kubeletconfigv1beta1.KubeletConfiguration{
FeatureGates: map[string]bool{},
}
}
externalkubeletcfg := internalcfg.ComponentConfigs.Kubelet
if externalkubeletcfg.StaticPodPath == "" {
externalkubeletcfg.StaticPodPath = kubeadmapiv1beta2.DefaultManifestsDir
} else if externalkubeletcfg.StaticPodPath != kubeadmapiv1beta2.DefaultManifestsDir {
@ -181,16 +172,6 @@ func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
// We cannot show a warning for RotateCertificates==false and we must hardcode it to true.
// There is no way to determine if the user has set this or not, given the field is a non-pointer.
externalkubeletcfg.RotateCertificates = kubeletRotateCertificates
Scheme.Default(externalkubeletcfg)
if internalcfg.ComponentConfigs.Kubelet == nil {
internalcfg.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
}
// TODO: Figure out how to handle errors in defaulting code
// Go back to the internal version
Scheme.Convert(externalkubeletcfg, internalcfg.ComponentConfigs.Kubelet, nil)
}
// warnDefaultComponentConfigValue prints a warning if the user modified a field in a certain

View File

@ -26,10 +26,6 @@ import (
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
kubeletconfigv1beta1scheme "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
kubeproxyconfigv1alpha1scheme "k8s.io/kubernetes/pkg/proxy/apis/config/v1alpha1"
)
// AddToSchemeFunc is a function that adds known types and API GroupVersions to a scheme
@ -96,15 +92,15 @@ var Known Registrations = map[RegistrationKind]Registration{
// TODO: When a beta version of the kube-proxy ComponentConfig API is available, start using it
MarshalGroupVersion: kubeproxyconfigv1alpha1.SchemeGroupVersion,
// AddToSchemeFuncs must use v1alpha1scheme defined in k8s.io/kubernetes, because the schema defined in k8s.io/kube-proxy doesn't have defaulting functions
AddToSchemeFuncs: []AddToSchemeFunc{kubeproxyconfig.AddToScheme, kubeproxyconfigv1alpha1scheme.AddToScheme},
AddToSchemeFuncs: []AddToSchemeFunc{kubeproxyconfigv1alpha1.AddToScheme},
DefaulterFunc: DefaultKubeProxyConfiguration,
ValidateFunc: ValidateKubeProxyConfiguration,
EmptyValue: &kubeproxyconfig.KubeProxyConfiguration{},
ValidateFunc: NoValidator("kubelet"),
EmptyValue: &kubeproxyconfigv1alpha1.KubeProxyConfiguration{},
GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) {
return cfg.ComponentConfigs.KubeProxy, cfg.ComponentConfigs.KubeProxy != nil
},
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool {
kubeproxyConfig, ok := obj.(*kubeproxyconfig.KubeProxyConfiguration)
kubeproxyConfig, ok := obj.(*kubeproxyconfigv1alpha1.KubeProxyConfiguration)
if ok {
cfg.ComponentConfigs.KubeProxy = kubeproxyConfig
}
@ -115,15 +111,15 @@ var Known Registrations = map[RegistrationKind]Registration{
KubeletConfigurationKind: {
MarshalGroupVersion: kubeletconfigv1beta1.SchemeGroupVersion,
// PAddToSchemeFuncs must use v1alpha1scheme defined in k8s.io/kubernetes, because the schema defined in k8s.io/kubelet doesn't have defaulting functions
AddToSchemeFuncs: []AddToSchemeFunc{kubeletconfig.AddToScheme, kubeletconfigv1beta1scheme.AddToScheme},
AddToSchemeFuncs: []AddToSchemeFunc{kubeletconfigv1beta1.AddToScheme},
DefaulterFunc: DefaultKubeletConfiguration,
ValidateFunc: ValidateKubeletConfiguration,
EmptyValue: &kubeletconfig.KubeletConfiguration{},
ValidateFunc: NoValidator("kube-proxy"),
EmptyValue: &kubeletconfigv1beta1.KubeletConfiguration{},
GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) {
return cfg.ComponentConfigs.Kubelet, cfg.ComponentConfigs.Kubelet != nil
},
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool {
kubeletConfig, ok := obj.(*kubeletconfig.KubeletConfiguration)
kubeletConfig, ok := obj.(*kubeletconfigv1beta1.KubeletConfiguration)
if ok {
cfg.ComponentConfigs.Kubelet = kubeletConfig
}

View File

@ -18,29 +18,14 @@ package componentconfigs
import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/klog"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeletvalidation "k8s.io/kubernetes/pkg/kubelet/apis/config/validation"
proxyvalidation "k8s.io/kubernetes/pkg/proxy/apis/config/validation"
)
// ValidateKubeProxyConfiguration validates proxy configuration and collects all encountered errors
func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration, _ *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if internalcfg.ComponentConfigs.KubeProxy == nil {
return allErrs
// NoValidator returns a dummy validator function when no validation method is available for the component
func NoValidator(component string) func(*kubeadmapi.ClusterConfiguration, *field.Path) field.ErrorList {
return func(_ *kubeadmapi.ClusterConfiguration, _ *field.Path) field.ErrorList {
klog.Warningf("Cannot validate %s config - no validator is available", component)
return field.ErrorList{}
}
return proxyvalidation.Validate(internalcfg.ComponentConfigs.KubeProxy)
}
// ValidateKubeletConfiguration validates kubelet configuration and collects all encountered errors
func ValidateKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if internalcfg.ComponentConfigs.Kubelet == nil {
return allErrs
}
if err := kubeletvalidation.ValidateKubeletConfiguration(internalcfg.ComponentConfigs.Kubelet); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, "", err.Error()))
}
return allErrs
}

View File

@ -1,365 +0,0 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package componentconfigs
import (
"strings"
"testing"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
utilpointer "k8s.io/utils/pointer"
)
func TestValidateKubeProxyConfiguration(t *testing.T) {
var tests = []struct {
name string
clusterConfig *kubeadm.ClusterConfiguration
msg string
expectErr bool
}{
{
name: "valid config",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
expectErr: false,
},
{
name: "invalid BindAddress",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
// only BindAddress is invalid
BindAddress: "10.10.12.11:2000",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
msg: "not a valid textual representation of an IP address",
expectErr: true,
},
{
name: "invalid HealthzBindAddress",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
// only HealthzBindAddress is invalid
HealthzBindAddress: "0.0.0.0",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
msg: "must be IP:port",
expectErr: true,
},
{
name: "invalid MetricsBindAddress",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345",
// only MetricsBindAddress is invalid
MetricsBindAddress: "127.0.0.1",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
msg: "must be IP:port",
expectErr: true,
},
{
name: "invalid ClusterCIDR",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249",
// only ClusterCIDR is invalid
ClusterCIDR: "192.168.59.0",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
msg: "must be a valid CIDR block (e.g. 10.100.0.0/16 or FD02::0:0:0/96)",
expectErr: true,
},
{
name: "invalid UDPIdleTimeout",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
// only UDPIdleTimeout is invalid
UDPIdleTimeout: metav1.Duration{Duration: -1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
msg: "must be greater than 0",
expectErr: true,
},
{
name: "invalid ConfigSyncPeriod",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
// only ConfigSyncPeriod is invalid
ConfigSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
},
msg: "must be greater than 0",
expectErr: true,
},
}
for i, rt := range tests {
t.Run(rt.name, func(t *testing.T) {
err := ValidateKubeProxyConfiguration(rt.clusterConfig, nil).ToAggregate()
if (err != nil) != rt.expectErr {
t.Errorf("%d failed ValidateKubeProxyConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
}
if err != nil && !strings.Contains(err.Error(), rt.msg) {
t.Errorf("%d failed ValidateKubeProxyConfiguration: unexpected error: %v, expected: %s", i, err, rt.msg)
}
})
}
}
func TestValidateKubeletConfiguration(t *testing.T) {
var tests = []struct {
name string
clusterConfig *kubeadm.ClusterConfiguration
expectErr bool
}{
{
name: "valid configuration",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{
CgroupsPerQOS: true,
EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved"},
SystemReservedCgroup: "/system.slice",
KubeReservedCgroup: "/kubelet.service",
SystemCgroups: "",
CgroupRoot: "",
EventBurst: 10,
EventRecordQPS: 5,
HealthzPort: kubeadmconstants.KubeletHealthzPort,
ImageGCHighThresholdPercent: 85,
ImageGCLowThresholdPercent: 80,
IPTablesDropBit: 15,
IPTablesMasqueradeBit: 14,
KubeAPIBurst: 10,
KubeAPIQPS: 5,
MaxOpenFiles: 1000000,
MaxPods: 110,
OOMScoreAdj: -999,
PodsPerCore: 100,
Port: 65535,
ReadOnlyPort: 0,
RegistryBurst: 10,
RegistryPullQPS: 5,
HairpinMode: "promiscuous-bridge",
NodeLeaseDurationSeconds: 40,
TopologyManagerPolicy: "none",
},
},
},
expectErr: false,
},
{
name: "invalid configuration",
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{
CgroupsPerQOS: false,
EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved", "illegal-key"},
SystemCgroups: "/",
CgroupRoot: "",
EventBurst: -10,
EventRecordQPS: -10,
HealthzPort: -10,
ImageGCHighThresholdPercent: 101,
ImageGCLowThresholdPercent: 101,
IPTablesDropBit: -10,
IPTablesMasqueradeBit: -10,
KubeAPIBurst: -10,
KubeAPIQPS: -10,
MaxOpenFiles: -10,
MaxPods: -10,
OOMScoreAdj: -1001,
PodsPerCore: -10,
Port: 0,
ReadOnlyPort: -10,
RegistryBurst: -10,
RegistryPullQPS: -10,
TopologyManagerPolicy: "",
},
},
},
expectErr: true,
},
}
for i, rt := range tests {
t.Run(rt.name, func(t *testing.T) {
err := ValidateKubeletConfiguration(rt.clusterConfig, nil).ToAggregate()
if (err != nil) != rt.expectErr {
t.Errorf("%d failed ValidateKubeletConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
}
})
}
}

View File

@ -15,7 +15,6 @@ go_test(
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library",
"//pkg/proxy/apis/config:go_default_library",
"//staging/src/k8s.io/api/apps/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
@ -24,6 +23,7 @@ go_test(
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/kube-proxy/config/v1alpha1:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
],
)

View File

@ -29,11 +29,11 @@ import (
clientsetfake "k8s.io/client-go/kubernetes/fake"
clientsetscheme "k8s.io/client-go/kubernetes/scheme"
core "k8s.io/client-go/testing"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
"k8s.io/utils/pointer"
)
@ -206,11 +206,11 @@ func TestEnsureProxyAddon(t *testing.T) {
t.Errorf("test failed to convert external to internal version")
return
}
intControlPlane.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{
intControlPlane.ComponentConfigs.KubeProxy = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{
BindAddress: "",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Conntrack: kubeproxyconfigv1alpha1.KubeProxyConntrackConfiguration{
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},

View File

@ -19,13 +19,13 @@ go_library(
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//cmd/kubeadm/app/util/initsystem:go_default_library",
"//pkg/kubelet/apis/config:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
@ -43,13 +43,13 @@ go_test(
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//pkg/kubelet/apis/config:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],

View File

@ -30,15 +30,15 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/version"
clientset "k8s.io/client-go/kubernetes"
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
)
// WriteConfigToDisk writes the kubelet config object down to a file
// Used at "kubeadm init" and "kubeadm upgrade" time
func WriteConfigToDisk(kubeletConfig *kubeletconfig.KubeletConfiguration, kubeletDir string) error {
func WriteConfigToDisk(kubeletConfig *kubeletconfigv1beta1.KubeletConfiguration, kubeletDir string) error {
kubeletBytes, err := getConfigBytes(kubeletConfig)
if err != nil {
@ -49,7 +49,7 @@ func WriteConfigToDisk(kubeletConfig *kubeletconfig.KubeletConfiguration, kubele
// CreateConfigMap creates a ConfigMap with the generic kubelet configuration.
// Used at "kubeadm init" and "kubeadm upgrade" time
func CreateConfigMap(cfg *kubeletconfig.KubeletConfiguration, k8sVersionStr string, client clientset.Interface) error {
func CreateConfigMap(cfg *kubeletconfigv1beta1.KubeletConfiguration, k8sVersionStr string, client clientset.Interface) error {
k8sVersion, err := version.ParseSemantic(k8sVersionStr)
if err != nil {
@ -153,7 +153,7 @@ func configMapRBACName(k8sVersion *version.Version) string {
}
// getConfigBytes marshals a KubeletConfiguration object to bytes
func getConfigBytes(kubeletConfig *kubeletconfig.KubeletConfiguration) ([]byte, error) {
func getConfigBytes(kubeletConfig *kubeletconfigv1beta1.KubeletConfiguration) ([]byte, error) {
return componentconfigs.Known[componentconfigs.KubeletConfigurationKind].Marshal(kubeletConfig)
}

View File

@ -25,15 +25,15 @@ import (
"k8s.io/apimachinery/pkg/util/version"
"k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing"
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
)
func TestCreateConfigMap(t *testing.T) {
nodeName := "fake-node"
client := fake.NewSimpleClientset()
k8sVersionStr := constants.CurrentKubernetesVersion.String()
cfg := &kubeletconfig.KubeletConfiguration{}
cfg := &kubeletconfigv1beta1.KubeletConfiguration{}
client.PrependReactor("get", "nodes", func(action core.Action) (bool, runtime.Object, error) {
return true, &v1.Node{