mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
Merge pull request #65787 from luxas/kubeadm_split_componentconfig_from_api
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. kubeadm: Use separate YAML docs for the kubelet and kube-proxy ComponentConfigs **What this PR does / why we need it**: This PR makes kubeadm load the ComponentConfig for the kubelet and kube-proxy from separate YAML documents in the `kubeadm init` config file. This is backwards-compatible with `v1alpha2`. The ComponentConfigs are stored internally in the internal kubeadm `MasterConfiguration` struct, but when marshalling the componentconfigs are written as separate YAML documents. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: ref: kubernetes/kubeadm#911 Depends on: - [x] https://github.com/kubernetes/kubernetes/pull/65776 - [x] https://github.com/kubernetes/kubernetes/pull/65628 - [x] https://github.com/kubernetes/kubernetes/pull/65629 - [x] https://github.com/kubernetes/kubernetes/pull/65631 - [x] https://github.com/kubernetes/kubernetes/pull/65940 **Special notes for your reviewer**: Only review the last five commits please. (The last commit is purely autogenerated, so can be skipped) **Release note**: ```release-note kubeadm: Use separate YAML documents for the kubelet and kube-proxy ComponentConfigs ``` @kubernetes/sig-cluster-lifecycle-pr-reviews /assign @timothysc
This commit is contained in:
commit
ac99da5e3e
@ -30,6 +30,7 @@ filegroup(
|
|||||||
":package-srcs",
|
":package-srcs",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:all-srcs",
|
"//cmd/kubeadm/app/apis/kubeadm:all-srcs",
|
||||||
"//cmd/kubeadm/app/cmd:all-srcs",
|
"//cmd/kubeadm/app/cmd:all-srcs",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:all-srcs",
|
||||||
"//cmd/kubeadm/app/constants:all-srcs",
|
"//cmd/kubeadm/app/constants:all-srcs",
|
||||||
"//cmd/kubeadm/app/discovery:all-srcs",
|
"//cmd/kubeadm/app/discovery:all-srcs",
|
||||||
"//cmd/kubeadm/app/features:all-srcs",
|
"//cmd/kubeadm/app/features:all-srcs",
|
||||||
|
@ -26,6 +26,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
||||||
|
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,10 +12,11 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer",
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
|
||||||
"//pkg/kubelet/apis/kubeletconfig/v1beta1:go_default_library",
|
"//pkg/kubelet/apis/kubeletconfig/v1beta1:go_default_library",
|
||||||
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||||
|
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
||||||
"//pkg/util/pointer:go_default_library",
|
"//pkg/util/pointer:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
|
||||||
|
@ -25,10 +25,11 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
||||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
|
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
||||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,11 +41,10 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||||||
obj.KubernetesVersion = "v10"
|
obj.KubernetesVersion = "v10"
|
||||||
obj.API.BindPort = 20
|
obj.API.BindPort = 20
|
||||||
obj.API.AdvertiseAddress = "foo"
|
obj.API.AdvertiseAddress = "foo"
|
||||||
obj.Networking.ServiceSubnet = "foo"
|
obj.Networking.ServiceSubnet = "10.96.0.0/12"
|
||||||
obj.Networking.DNSDomain = "foo"
|
obj.Networking.DNSDomain = "cluster.local"
|
||||||
obj.CertificatesDir = "foo"
|
obj.CertificatesDir = "foo"
|
||||||
obj.APIServerCertSANs = []string{"foo"}
|
obj.APIServerCertSANs = []string{"foo"}
|
||||||
|
|
||||||
obj.BootstrapTokens = []kubeadm.BootstrapToken{
|
obj.BootstrapTokens = []kubeadm.BootstrapToken{
|
||||||
{
|
{
|
||||||
Token: &kubeadm.BootstrapTokenString{
|
Token: &kubeadm.BootstrapTokenString{
|
||||||
@ -68,9 +68,6 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||||||
MountPath: "foo",
|
MountPath: "foo",
|
||||||
Writable: false,
|
Writable: false,
|
||||||
}}
|
}}
|
||||||
// Note: We don't set values here for obj.Etcd.External, as these are mutually exlusive.
|
|
||||||
// And to make sure the fuzzer doesn't set a random value for obj.Etcd.External, we let
|
|
||||||
// kubeadmapi.Etcd implement fuzz.Interface (we handle that ourselves)
|
|
||||||
obj.Etcd.Local = &kubeadm.LocalEtcd{
|
obj.Etcd.Local = &kubeadm.LocalEtcd{
|
||||||
Image: "foo",
|
Image: "foo",
|
||||||
DataDir: "foo",
|
DataDir: "foo",
|
||||||
@ -83,65 +80,23 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||||||
Name: "foo",
|
Name: "foo",
|
||||||
Taints: []v1.Taint{},
|
Taints: []v1.Taint{},
|
||||||
}
|
}
|
||||||
extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{
|
|
||||||
StaticPodPath: "foo",
|
|
||||||
ClusterDNS: []string{"foo"},
|
|
||||||
ClusterDomain: "foo",
|
|
||||||
Authorization: kubeletconfigv1beta1.KubeletAuthorization{
|
|
||||||
Mode: "Webhook",
|
|
||||||
},
|
|
||||||
Authentication: kubeletconfigv1beta1.KubeletAuthentication{
|
|
||||||
X509: kubeletconfigv1beta1.KubeletX509Authentication{
|
|
||||||
ClientCAFile: "/etc/kubernetes/pki/ca.crt",
|
|
||||||
},
|
|
||||||
Anonymous: kubeletconfigv1beta1.KubeletAnonymousAuthentication{
|
|
||||||
Enabled: utilpointer.BoolPtr(false),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RotateCertificates: true,
|
|
||||||
}
|
|
||||||
obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
|
|
||||||
kubeletconfigv1beta1.SetDefaults_KubeletConfiguration(extkubeletconfig)
|
|
||||||
scheme, _, _ := kubeletconfigscheme.NewSchemeAndCodecs()
|
|
||||||
scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil)
|
|
||||||
obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{
|
|
||||||
FeatureGates: map[string]bool{"foo": true},
|
|
||||||
BindAddress: "foo",
|
|
||||||
HealthzBindAddress: "foo:10256",
|
|
||||||
MetricsBindAddress: "foo:",
|
|
||||||
EnableProfiling: bool(true),
|
|
||||||
ClusterCIDR: "foo",
|
|
||||||
HostnameOverride: "foo",
|
|
||||||
ClientConnection: kubeproxyconfig.ClientConnectionConfiguration{
|
|
||||||
KubeConfigFile: "foo",
|
|
||||||
AcceptContentTypes: "foo",
|
|
||||||
ContentType: "foo",
|
|
||||||
QPS: float32(5),
|
|
||||||
Burst: 10,
|
|
||||||
},
|
|
||||||
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 1},
|
|
||||||
},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeBit: utilpointer.Int32Ptr(0),
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 1},
|
|
||||||
},
|
|
||||||
OOMScoreAdj: utilpointer.Int32Ptr(0),
|
|
||||||
ResourceContainer: "foo",
|
|
||||||
UDPIdleTimeout: metav1.Duration{Duration: 1},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: utilpointer.Int32Ptr(2),
|
|
||||||
Min: utilpointer.Int32Ptr(1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5},
|
|
||||||
},
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1},
|
|
||||||
}
|
|
||||||
obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{
|
obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{
|
||||||
Path: "foo",
|
Path: "foo",
|
||||||
LogDir: "/foo",
|
LogDir: "/foo",
|
||||||
LogMaxAge: utilpointer.Int32Ptr(0),
|
LogMaxAge: utilpointer.Int32Ptr(0),
|
||||||
}
|
}
|
||||||
|
// Set the Kubelet ComponentConfig to an empty, defaulted struct
|
||||||
|
extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{}
|
||||||
|
obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
|
||||||
|
componentconfigs.Scheme.Default(extkubeletconfig)
|
||||||
|
componentconfigs.Scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil)
|
||||||
|
componentconfigs.DefaultKubeletConfiguration(obj)
|
||||||
|
// Set the KubeProxy ComponentConfig to an empty, defaulted struct
|
||||||
|
extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
||||||
|
obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
|
||||||
|
componentconfigs.Scheme.Default(extkubeproxyconfig)
|
||||||
|
componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil)
|
||||||
|
componentconfigs.DefaultKubeProxyConfiguration(obj)
|
||||||
},
|
},
|
||||||
func(obj *kubeadm.NodeConfiguration, c fuzz.Continue) {
|
func(obj *kubeadm.NodeConfiguration, c fuzz.Continue) {
|
||||||
c.FuzzNoCustom(obj)
|
c.FuzzNoCustom(obj)
|
||||||
|
@ -17,6 +17,8 @@ limitations under the License.
|
|||||||
package kubeadm
|
package kubeadm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
fuzz "github.com/google/gofuzz"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
@ -42,6 +44,7 @@ type MasterConfiguration struct {
|
|||||||
NodeRegistration NodeRegistrationOptions
|
NodeRegistration NodeRegistrationOptions
|
||||||
|
|
||||||
// ComponentConfigs holds internal ComponentConfig struct types known to kubeadm, should long-term only exist in the internal kubeadm API
|
// ComponentConfigs holds internal ComponentConfig struct types known to kubeadm, should long-term only exist in the internal kubeadm API
|
||||||
|
// +k8s:conversion-gen=false
|
||||||
ComponentConfigs ComponentConfigs
|
ComponentConfigs ComponentConfigs
|
||||||
|
|
||||||
// Cluster-wide configuration
|
// Cluster-wide configuration
|
||||||
@ -117,6 +120,12 @@ type ComponentConfigs struct {
|
|||||||
KubeProxy *kubeproxyconfig.KubeProxyConfiguration
|
KubeProxy *kubeproxyconfig.KubeProxyConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fuzz is a dummy function here to get the roundtrip tests working in cmd/kubeadm/app/apis/kubeadm/fuzzer working.
|
||||||
|
// This makes the fuzzer not go and randomize all fields in the ComponentConfigs struct, as that wouldn't work for
|
||||||
|
// a roundtrip. A roundtrip to the v1alpha3 API obviously doesn't work as it's not stored there at all. With this,
|
||||||
|
// the roundtrip is considered valid, as semi-static values are set and preserved during a roundtrip.
|
||||||
|
func (cc ComponentConfigs) Fuzz(c fuzz.Continue) {}
|
||||||
|
|
||||||
// API struct contains elements of API server address.
|
// API struct contains elements of API server address.
|
||||||
type API struct {
|
type API struct {
|
||||||
// AdvertiseAddress sets the IP address for the API server to advertise.
|
// AdvertiseAddress sets the IP address for the API server to advertise.
|
||||||
|
@ -19,6 +19,7 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||||
|
@ -19,11 +19,10 @@ package v1alpha2
|
|||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
||||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
kubeproxyconfigscheme "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/scheme"
|
|
||||||
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ func Convert_v1alpha2_MasterConfiguration_To_kubeadm_MasterConfiguration(in *Mas
|
|||||||
out.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
|
out.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := kubeproxyconfigscheme.Scheme.Convert(in.KubeProxy.Config, out.ComponentConfigs.KubeProxy, nil); err != nil {
|
if err := componentconfigs.Scheme.Convert(in.KubeProxy.Config, out.ComponentConfigs.KubeProxy, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,12 +45,7 @@ func Convert_v1alpha2_MasterConfiguration_To_kubeadm_MasterConfiguration(in *Mas
|
|||||||
out.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
|
out.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
if err := componentconfigs.Scheme.Convert(in.KubeletConfiguration.BaseConfig, out.ComponentConfigs.Kubelet, nil); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scheme.Convert(in.KubeletConfiguration.BaseConfig, out.ComponentConfigs.Kubelet, nil); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +63,7 @@ func Convert_kubeadm_MasterConfiguration_To_v1alpha2_MasterConfiguration(in *kub
|
|||||||
out.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
out.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := kubeproxyconfigscheme.Scheme.Convert(in.ComponentConfigs.KubeProxy, out.KubeProxy.Config, nil); err != nil {
|
if err := componentconfigs.Scheme.Convert(in.ComponentConfigs.KubeProxy, out.KubeProxy.Config, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,12 +72,7 @@ func Convert_kubeadm_MasterConfiguration_To_v1alpha2_MasterConfiguration(in *kub
|
|||||||
out.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{}
|
out.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{}
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
if err := componentconfigs.Scheme.Convert(in.ComponentConfigs.Kubelet, out.KubeletConfiguration.BaseConfig, nil); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scheme.Convert(in.ComponentConfigs.Kubelet, out.KubeletConfiguration.BaseConfig, nil); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,8 @@ func SetDefaults_Etcd(obj *MasterConfiguration) {
|
|||||||
|
|
||||||
// SetDefaults_ProxyConfiguration assigns default values for the Proxy
|
// SetDefaults_ProxyConfiguration assigns default values for the Proxy
|
||||||
func SetDefaults_ProxyConfiguration(obj *MasterConfiguration) {
|
func SetDefaults_ProxyConfiguration(obj *MasterConfiguration) {
|
||||||
|
// IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/componentconfig/defaults.go
|
||||||
|
// and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go.
|
||||||
if obj.KubeProxy.Config == nil {
|
if obj.KubeProxy.Config == nil {
|
||||||
obj.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
obj.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
||||||
}
|
}
|
||||||
@ -173,6 +175,8 @@ func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
|
|||||||
|
|
||||||
// SetDefaults_KubeletConfiguration assigns default values to kubelet
|
// SetDefaults_KubeletConfiguration assigns default values to kubelet
|
||||||
func SetDefaults_KubeletConfiguration(obj *MasterConfiguration) {
|
func SetDefaults_KubeletConfiguration(obj *MasterConfiguration) {
|
||||||
|
// IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/componentconfig/defaults.go
|
||||||
|
// and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go.
|
||||||
if obj.KubeletConfiguration.BaseConfig == nil {
|
if obj.KubeletConfiguration.BaseConfig == nil {
|
||||||
obj.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{}
|
obj.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{}
|
||||||
}
|
}
|
||||||
@ -247,8 +251,8 @@ func SetDefaults_BootstrapTokens(obj *MasterConfiguration) {
|
|||||||
obj.BootstrapTokens = []BootstrapToken{{}}
|
obj.BootstrapTokens = []BootstrapToken{{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bt := range obj.BootstrapTokens {
|
for i := range obj.BootstrapTokens {
|
||||||
SetDefaults_BootstrapToken(&bt)
|
SetDefaults_BootstrapToken(&obj.BootstrapTokens[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ func autoConvert_kubeadm_MasterConfiguration_To_v1alpha2_MasterConfiguration(in
|
|||||||
if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
|
if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// WARNING: in.ComponentConfigs requires manual conversion: does not exist in peer-type
|
// INFO: in.ComponentConfigs opted out of conversion generation
|
||||||
if err := Convert_kubeadm_API_To_v1alpha2_API(&in.API, &out.API, s); err != nil {
|
if err := Convert_kubeadm_API_To_v1alpha2_API(&in.API, &out.API, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ go_library(
|
|||||||
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||||
"//pkg/proxy/apis/kubeproxyconfig/scheme:go_default_library",
|
"//pkg/proxy/apis/kubeproxyconfig/scheme:go_default_library",
|
||||||
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
||||||
"//pkg/util/pointer:go_default_library",
|
|
||||||
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||||
|
@ -19,6 +19,7 @@ package v1alpha3
|
|||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
||||||
@ -32,64 +33,80 @@ func Convert_v1alpha3_MasterConfiguration_To_kubeadm_MasterConfiguration(in *Mas
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this conversion code ASAP, as the ComponentConfig structs should not be in the external version of the kubeadm API, but be marshalled as
|
// TODO: This conversion code is here ONLY for fuzzing tests. When we remove the v1alpha2 API, we can remove this (unnecessary)
|
||||||
// different YAML documents
|
// code. Right now this defaulting code has to be kept in sync with the defaulting code in cmd/kubeadm/app/apis/kubeadm/v1alpha2 and cmd/kubeadm/app/componentconfig
|
||||||
if in.KubeProxy.Config != nil {
|
if out.ComponentConfigs.Kubelet == nil {
|
||||||
if out.ComponentConfigs.KubeProxy == nil {
|
// Set the Kubelet ComponentConfig to an empty, defaulted struct
|
||||||
out.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
|
out.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
|
||||||
}
|
extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{}
|
||||||
|
|
||||||
if err := kubeproxyconfigscheme.Scheme.Convert(in.KubeProxy.Config, out.ComponentConfigs.KubeProxy, nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if in.KubeletConfiguration.BaseConfig != nil {
|
|
||||||
if out.ComponentConfigs.Kubelet == nil {
|
|
||||||
out.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
|
|
||||||
}
|
|
||||||
|
|
||||||
scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scheme.Convert(in.KubeletConfiguration.BaseConfig, out.ComponentConfigs.Kubelet, nil); err != nil {
|
scheme.Default(extkubeletconfig)
|
||||||
return err
|
scheme.Convert(extkubeletconfig, out.ComponentConfigs.Kubelet, nil)
|
||||||
}
|
defaultKubeletConfiguration(in, out.ComponentConfigs.Kubelet)
|
||||||
|
}
|
||||||
|
if out.ComponentConfigs.KubeProxy == nil {
|
||||||
|
// Set the KubeProxy ComponentConfig to an empty, defaulted struct
|
||||||
|
out.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
|
||||||
|
extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
||||||
|
kubeproxyconfigscheme.Scheme.Default(extkubeproxyconfig)
|
||||||
|
kubeproxyconfigscheme.Scheme.Convert(extkubeproxyconfig, out.ComponentConfigs.KubeProxy, nil)
|
||||||
|
defaultKubeProxyConfiguration(in, out.ComponentConfigs.KubeProxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Convert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration(in *kubeadm.MasterConfiguration, out *MasterConfiguration, s conversion.Scope) error {
|
func defaultKubeProxyConfiguration(internalcfg *MasterConfiguration, obj *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
if err := autoConvert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration(in, out, s); err != nil {
|
// NOTE: This code should be mirrored from cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go and cmd/kubeadm/app/componentconfig/defaults.go
|
||||||
return err
|
if obj.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" {
|
||||||
|
obj.ClusterCIDR = internalcfg.Networking.PodSubnet
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this conversion code ASAP, as the ComponentConfig structs should not be in the external version of the kubeadm API, but be marshalled as
|
if obj.ClientConnection.KubeConfigFile == "" {
|
||||||
// different YAML documents
|
obj.ClientConnection.KubeConfigFile = "/var/lib/kube-proxy/kubeconfig.conf"
|
||||||
if in.ComponentConfigs.KubeProxy != nil {
|
|
||||||
if out.KubeProxy.Config == nil {
|
|
||||||
out.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := kubeproxyconfigscheme.Scheme.Convert(in.ComponentConfigs.KubeProxy, out.KubeProxy.Config, nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if in.ComponentConfigs.Kubelet != nil {
|
}
|
||||||
if out.KubeletConfiguration.BaseConfig == nil {
|
|
||||||
out.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{}
|
|
||||||
}
|
|
||||||
|
|
||||||
scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
func defaultKubeletConfiguration(internalcfg *MasterConfiguration, obj *kubeletconfig.KubeletConfiguration) {
|
||||||
|
// NOTE: This code should be mirrored from cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go and cmd/kubeadm/app/componentconfig/defaults.go
|
||||||
|
if obj.StaticPodPath == "" {
|
||||||
|
obj.StaticPodPath = DefaultManifestsDir
|
||||||
|
}
|
||||||
|
if obj.ClusterDNS == nil {
|
||||||
|
dnsIP, err := constants.GetDNSIP(internalcfg.Networking.ServiceSubnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
obj.ClusterDNS = []string{DefaultClusterDNSIP}
|
||||||
}
|
} else {
|
||||||
|
obj.ClusterDNS = []string{dnsIP.String()}
|
||||||
if err := scheme.Convert(in.ComponentConfigs.Kubelet, out.KubeletConfiguration.BaseConfig, nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
if obj.ClusterDomain == "" {
|
||||||
|
obj.ClusterDomain = internalcfg.Networking.DNSDomain
|
||||||
|
}
|
||||||
|
// Enforce security-related kubelet options
|
||||||
|
|
||||||
|
// Require all clients to the kubelet API to have client certs signed by the cluster CA
|
||||||
|
obj.Authentication.X509.ClientCAFile = DefaultCACertPath
|
||||||
|
obj.Authentication.Anonymous.Enabled = false
|
||||||
|
|
||||||
|
// On every client request to the kubelet API, execute a webhook (SubjectAccessReview request) to the API server
|
||||||
|
// and ask it whether the client is authorized to access the kubelet API
|
||||||
|
obj.Authorization.Mode = kubeletconfig.KubeletAuthorizationModeWebhook
|
||||||
|
|
||||||
|
// Let clients using other authentication methods like ServiceAccount tokens also access the kubelet API
|
||||||
|
obj.Authentication.Webhook.Enabled = true
|
||||||
|
|
||||||
|
// Disable the readonly port of the kubelet, in order to not expose unnecessary information
|
||||||
|
obj.ReadOnlyPort = 0
|
||||||
|
|
||||||
|
// Enables client certificate rotation for the kubelet
|
||||||
|
obj.RotateCertificates = true
|
||||||
|
|
||||||
|
// Serve a /healthz webserver on localhost:10248 that kubeadm can talk to
|
||||||
|
obj.HealthzBindAddress = "127.0.0.1"
|
||||||
|
obj.HealthzPort = 10248
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,6 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
|
||||||
kubeproxyscheme "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/scheme"
|
|
||||||
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
|
||||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -58,9 +53,6 @@ const (
|
|||||||
DefaultProxyBindAddressv4 = "0.0.0.0"
|
DefaultProxyBindAddressv4 = "0.0.0.0"
|
||||||
// DefaultProxyBindAddressv6 is the default bind address when the advertise address is v6
|
// DefaultProxyBindAddressv6 is the default bind address when the advertise address is v6
|
||||||
DefaultProxyBindAddressv6 = "::"
|
DefaultProxyBindAddressv6 = "::"
|
||||||
// KubeproxyKubeConfigFileName defines the file name for the kube-proxy's KubeConfig file
|
|
||||||
KubeproxyKubeConfigFileName = "/var/lib/kube-proxy/kubeconfig.conf"
|
|
||||||
|
|
||||||
// DefaultDiscoveryTimeout specifies the default discovery timeout for kubeadm (used unless one is specified in the NodeConfiguration)
|
// DefaultDiscoveryTimeout specifies the default discovery timeout for kubeadm (used unless one is specified in the NodeConfiguration)
|
||||||
DefaultDiscoveryTimeout = 5 * time.Minute
|
DefaultDiscoveryTimeout = 5 * time.Minute
|
||||||
)
|
)
|
||||||
@ -107,9 +99,7 @@ func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
|
|||||||
|
|
||||||
SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration)
|
SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration)
|
||||||
SetDefaults_BootstrapTokens(obj)
|
SetDefaults_BootstrapTokens(obj)
|
||||||
SetDefaults_KubeletConfiguration(obj)
|
|
||||||
SetDefaults_Etcd(obj)
|
SetDefaults_Etcd(obj)
|
||||||
SetDefaults_ProxyConfiguration(obj)
|
|
||||||
SetDefaults_AuditPolicyConfiguration(obj)
|
SetDefaults_AuditPolicyConfiguration(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,22 +115,6 @@ func SetDefaults_Etcd(obj *MasterConfiguration) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaults_ProxyConfiguration assigns default values for the Proxy
|
|
||||||
func SetDefaults_ProxyConfiguration(obj *MasterConfiguration) {
|
|
||||||
if obj.KubeProxy.Config == nil {
|
|
||||||
obj.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
|
||||||
}
|
|
||||||
if obj.KubeProxy.Config.ClusterCIDR == "" && obj.Networking.PodSubnet != "" {
|
|
||||||
obj.KubeProxy.Config.ClusterCIDR = obj.Networking.PodSubnet
|
|
||||||
}
|
|
||||||
|
|
||||||
if obj.KubeProxy.Config.ClientConnection.KubeConfigFile == "" {
|
|
||||||
obj.KubeProxy.Config.ClientConnection.KubeConfigFile = KubeproxyKubeConfigFileName
|
|
||||||
}
|
|
||||||
|
|
||||||
kubeproxyscheme.Scheme.Default(obj.KubeProxy.Config)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaults_NodeConfiguration assigns default values to a regular node
|
// SetDefaults_NodeConfiguration assigns default values to a regular node
|
||||||
func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
|
func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
|
||||||
if obj.CACertPath == "" {
|
if obj.CACertPath == "" {
|
||||||
@ -171,55 +145,6 @@ func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
|
|||||||
SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration)
|
SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaults_KubeletConfiguration assigns default values to kubelet
|
|
||||||
func SetDefaults_KubeletConfiguration(obj *MasterConfiguration) {
|
|
||||||
if obj.KubeletConfiguration.BaseConfig == nil {
|
|
||||||
obj.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{}
|
|
||||||
}
|
|
||||||
if obj.KubeletConfiguration.BaseConfig.StaticPodPath == "" {
|
|
||||||
obj.KubeletConfiguration.BaseConfig.StaticPodPath = DefaultManifestsDir
|
|
||||||
}
|
|
||||||
if obj.KubeletConfiguration.BaseConfig.ClusterDNS == nil {
|
|
||||||
dnsIP, err := constants.GetDNSIP(obj.Networking.ServiceSubnet)
|
|
||||||
if err != nil {
|
|
||||||
obj.KubeletConfiguration.BaseConfig.ClusterDNS = []string{DefaultClusterDNSIP}
|
|
||||||
} else {
|
|
||||||
obj.KubeletConfiguration.BaseConfig.ClusterDNS = []string{dnsIP.String()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if obj.KubeletConfiguration.BaseConfig.ClusterDomain == "" {
|
|
||||||
obj.KubeletConfiguration.BaseConfig.ClusterDomain = obj.Networking.DNSDomain
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce security-related kubelet options
|
|
||||||
|
|
||||||
// Require all clients to the kubelet API to have client certs signed by the cluster CA
|
|
||||||
obj.KubeletConfiguration.BaseConfig.Authentication.X509.ClientCAFile = DefaultCACertPath
|
|
||||||
obj.KubeletConfiguration.BaseConfig.Authentication.Anonymous.Enabled = utilpointer.BoolPtr(false)
|
|
||||||
|
|
||||||
// On every client request to the kubelet API, execute a webhook (SubjectAccessReview request) to the API server
|
|
||||||
// and ask it whether the client is authorized to access the kubelet API
|
|
||||||
obj.KubeletConfiguration.BaseConfig.Authorization.Mode = kubeletconfigv1beta1.KubeletAuthorizationModeWebhook
|
|
||||||
|
|
||||||
// Let clients using other authentication methods like ServiceAccount tokens also access the kubelet API
|
|
||||||
obj.KubeletConfiguration.BaseConfig.Authentication.Webhook.Enabled = utilpointer.BoolPtr(true)
|
|
||||||
|
|
||||||
// Disable the readonly port of the kubelet, in order to not expose unnecessary information
|
|
||||||
obj.KubeletConfiguration.BaseConfig.ReadOnlyPort = 0
|
|
||||||
|
|
||||||
// Enables client certificate rotation for the kubelet
|
|
||||||
obj.KubeletConfiguration.BaseConfig.RotateCertificates = true
|
|
||||||
|
|
||||||
// Serve a /healthz webserver on localhost:10248 that kubeadm can talk to
|
|
||||||
obj.KubeletConfiguration.BaseConfig.HealthzBindAddress = "127.0.0.1"
|
|
||||||
obj.KubeletConfiguration.BaseConfig.HealthzPort = utilpointer.Int32Ptr(10248)
|
|
||||||
|
|
||||||
scheme, _, _ := kubeletscheme.NewSchemeAndCodecs()
|
|
||||||
if scheme != nil {
|
|
||||||
scheme.Default(obj.KubeletConfiguration.BaseConfig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetDefaults_NodeRegistrationOptions(obj *NodeRegistrationOptions) {
|
func SetDefaults_NodeRegistrationOptions(obj *NodeRegistrationOptions) {
|
||||||
if obj.CRISocket == "" {
|
if obj.CRISocket == "" {
|
||||||
obj.CRISocket = DefaultCRISocket
|
obj.CRISocket = DefaultCRISocket
|
||||||
@ -247,8 +172,8 @@ func SetDefaults_BootstrapTokens(obj *MasterConfiguration) {
|
|||||||
obj.BootstrapTokens = []BootstrapToken{{}}
|
obj.BootstrapTokens = []BootstrapToken{{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bt := range obj.BootstrapTokens {
|
for i := range obj.BootstrapTokens {
|
||||||
SetDefaults_BootstrapToken(&bt)
|
SetDefaults_BootstrapToken(&obj.BootstrapTokens[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ package v1alpha3
|
|||||||
import (
|
import (
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
|
||||||
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
@ -47,12 +45,8 @@ type MasterConfiguration struct {
|
|||||||
|
|
||||||
// API holds configuration for the k8s apiserver.
|
// API holds configuration for the k8s apiserver.
|
||||||
API API `json:"api"`
|
API API `json:"api"`
|
||||||
// KubeProxy holds configuration for the k8s service proxy.
|
|
||||||
KubeProxy KubeProxy `json:"kubeProxy"`
|
|
||||||
// Etcd holds configuration for etcd.
|
// Etcd holds configuration for etcd.
|
||||||
Etcd Etcd `json:"etcd"`
|
Etcd Etcd `json:"etcd"`
|
||||||
// KubeletConfiguration holds configuration for the kubelet.
|
|
||||||
KubeletConfiguration KubeletConfiguration `json:"kubeletConfiguration"`
|
|
||||||
// Networking holds configuration for the networking topology of the cluster.
|
// Networking holds configuration for the networking topology of the cluster.
|
||||||
Networking Networking `json:"networking"`
|
Networking Networking `json:"networking"`
|
||||||
|
|
||||||
@ -281,11 +275,6 @@ type NodeConfiguration struct {
|
|||||||
FeatureGates map[string]bool `json:"featureGates,omitempty"`
|
FeatureGates map[string]bool `json:"featureGates,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeletConfiguration contains elements describing initial remote configuration of kubelet.
|
|
||||||
type KubeletConfiguration struct {
|
|
||||||
BaseConfig *kubeletconfigv1beta1.KubeletConfiguration `json:"baseConfig,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HostPathMount contains elements describing volumes that are mounted from the
|
// HostPathMount contains elements describing volumes that are mounted from the
|
||||||
// host.
|
// host.
|
||||||
type HostPathMount struct {
|
type HostPathMount struct {
|
||||||
@ -302,11 +291,6 @@ type HostPathMount struct {
|
|||||||
PathType v1.HostPathType `json:"pathType,omitempty"`
|
PathType v1.HostPathType `json:"pathType,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeProxy contains elements describing the proxy configuration.
|
|
||||||
type KubeProxy struct {
|
|
||||||
Config *kubeproxyconfigv1alpha1.KubeProxyConfiguration `json:"config,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuditPolicyConfiguration holds the options for configuring the api server audit policy.
|
// AuditPolicyConfiguration holds the options for configuring the api server audit policy.
|
||||||
type AuditPolicyConfiguration struct {
|
type AuditPolicyConfiguration struct {
|
||||||
// Path is the local path to an audit policy.
|
// Path is the local path to an audit policy.
|
||||||
|
@ -277,11 +277,9 @@ func autoConvert_v1alpha3_MasterConfiguration_To_kubeadm_MasterConfiguration(in
|
|||||||
if err := Convert_v1alpha3_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
|
if err := Convert_v1alpha3_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// WARNING: in.KubeProxy requires manual conversion: does not exist in peer-type
|
|
||||||
if err := Convert_v1alpha3_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
|
if err := Convert_v1alpha3_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// WARNING: in.KubeletConfiguration requires manual conversion: does not exist in peer-type
|
|
||||||
if err := Convert_v1alpha3_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil {
|
if err := Convert_v1alpha3_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -309,7 +307,7 @@ func autoConvert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration(in
|
|||||||
if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
|
if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// WARNING: in.ComponentConfigs requires manual conversion: does not exist in peer-type
|
// INFO: in.ComponentConfigs opted out of conversion generation
|
||||||
if err := Convert_kubeadm_API_To_v1alpha3_API(&in.API, &out.API, s); err != nil {
|
if err := Convert_kubeadm_API_To_v1alpha3_API(&in.API, &out.API, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -339,6 +337,11 @@ func autoConvert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration(in
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration is an autogenerated conversion function.
|
||||||
|
func Convert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration(in *kubeadm.MasterConfiguration, out *MasterConfiguration, s conversion.Scope) error {
|
||||||
|
return autoConvert_kubeadm_MasterConfiguration_To_v1alpha3_MasterConfiguration(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
func autoConvert_v1alpha3_Networking_To_kubeadm_Networking(in *Networking, out *kubeadm.Networking, s conversion.Scope) error {
|
func autoConvert_v1alpha3_Networking_To_kubeadm_Networking(in *Networking, out *kubeadm.Networking, s conversion.Scope) error {
|
||||||
out.ServiceSubnet = in.ServiceSubnet
|
out.ServiceSubnet = in.ServiceSubnet
|
||||||
out.PodSubnet = in.PodSubnet
|
out.PodSubnet = in.PodSubnet
|
||||||
|
@ -24,8 +24,6 @@ import (
|
|||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
v1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
|
||||||
v1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
@ -184,48 +182,6 @@ func (in *HostPathMount) DeepCopy() *HostPathMount {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *KubeProxy) DeepCopyInto(out *KubeProxy) {
|
|
||||||
*out = *in
|
|
||||||
if in.Config != nil {
|
|
||||||
in, out := &in.Config, &out.Config
|
|
||||||
*out = new(v1alpha1.KubeProxyConfiguration)
|
|
||||||
(*in).DeepCopyInto(*out)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProxy.
|
|
||||||
func (in *KubeProxy) DeepCopy() *KubeProxy {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(KubeProxy)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
|
||||||
*out = *in
|
|
||||||
if in.BaseConfig != nil {
|
|
||||||
in, out := &in.BaseConfig, &out.BaseConfig
|
|
||||||
*out = new(v1beta1.KubeletConfiguration)
|
|
||||||
(*in).DeepCopyInto(*out)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletConfiguration.
|
|
||||||
func (in *KubeletConfiguration) DeepCopy() *KubeletConfiguration {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(KubeletConfiguration)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) {
|
func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -272,9 +228,7 @@ func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
|
|||||||
}
|
}
|
||||||
in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
|
in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
|
||||||
out.API = in.API
|
out.API = in.API
|
||||||
in.KubeProxy.DeepCopyInto(&out.KubeProxy)
|
|
||||||
in.Etcd.DeepCopyInto(&out.Etcd)
|
in.Etcd.DeepCopyInto(&out.Etcd)
|
||||||
in.KubeletConfiguration.DeepCopyInto(&out.KubeletConfiguration)
|
|
||||||
out.Networking = in.Networking
|
out.Networking = in.Networking
|
||||||
if in.APIServerExtraArgs != nil {
|
if in.APIServerExtraArgs != nil {
|
||||||
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
|
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
|
||||||
|
@ -22,8 +22,6 @@ package v1alpha3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
v1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
|
||||||
v1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||||
@ -42,12 +40,6 @@ func SetObjectDefaults_MasterConfiguration(in *MasterConfiguration) {
|
|||||||
SetDefaults_BootstrapToken(a)
|
SetDefaults_BootstrapToken(a)
|
||||||
}
|
}
|
||||||
SetDefaults_NodeRegistrationOptions(&in.NodeRegistration)
|
SetDefaults_NodeRegistrationOptions(&in.NodeRegistration)
|
||||||
if in.KubeProxy.Config != nil {
|
|
||||||
v1alpha1.SetDefaults_KubeProxyConfiguration(in.KubeProxy.Config)
|
|
||||||
}
|
|
||||||
if in.KubeletConfiguration.BaseConfig != nil {
|
|
||||||
v1beta1.SetDefaults_KubeletConfiguration(in.KubeletConfiguration.BaseConfig)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetObjectDefaults_NodeConfiguration(in *NodeConfiguration) {
|
func SetObjectDefaults_NodeConfiguration(in *NodeConfiguration) {
|
||||||
|
@ -7,14 +7,11 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/features:go_default_library",
|
"//cmd/kubeadm/app/features:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//pkg/apis/core/validation:go_default_library",
|
"//pkg/apis/core/validation:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
|
||||||
"//pkg/kubelet/apis/kubeletconfig/validation:go_default_library",
|
|
||||||
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
|
||||||
"//pkg/proxy/apis/kubeproxyconfig/validation:go_default_library",
|
|
||||||
"//pkg/registry/core/service/ipallocator:go_default_library",
|
"//pkg/registry/core/service/ipallocator:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||||
@ -31,7 +28,6 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
|
||||||
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||||
"//pkg/util/pointer:go_default_library",
|
"//pkg/util/pointer:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
@ -32,14 +32,11 @@ import (
|
|||||||
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
||||||
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
|
||||||
kubeletvalidation "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation"
|
|
||||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
|
||||||
proxyvalidation "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/validation"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,20 +51,10 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList
|
|||||||
allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...)
|
allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...)
|
||||||
allErrs = append(allErrs, ValidateAPIEndpoint(&c.API, field.NewPath("api"))...)
|
allErrs = append(allErrs, ValidateAPIEndpoint(&c.API, field.NewPath("api"))...)
|
||||||
allErrs = append(allErrs, ValidateEtcd(&c.Etcd, field.NewPath("etcd"))...)
|
allErrs = append(allErrs, ValidateEtcd(&c.Etcd, field.NewPath("etcd"))...)
|
||||||
// Validate other ComponentConfigs
|
allErrs = append(allErrs, componentconfigs.Known.Validate(c)...)
|
||||||
allErrs = append(allErrs, ValidateProxy(c.ComponentConfigs.KubeProxy, field.NewPath("componentConfigs").Child("kubeProxy"))...)
|
|
||||||
allErrs = append(allErrs, ValidateKubeletConfiguration(c.ComponentConfigs.Kubelet, field.NewPath("componentConfigs").Child("kubelet"))...)
|
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateProxy validates proxy configuration and collects all encountered errors
|
|
||||||
func ValidateProxy(kubeProxyConfig *kubeproxyconfig.KubeProxyConfiguration, fldPath *field.Path) field.ErrorList {
|
|
||||||
if kubeProxyConfig == nil {
|
|
||||||
return field.ErrorList{}
|
|
||||||
}
|
|
||||||
return proxyvalidation.Validate(kubeProxyConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateNodeConfiguration validates node configuration and collects all encountered errors
|
// ValidateNodeConfiguration validates node configuration and collects all encountered errors
|
||||||
func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
|
func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
@ -420,15 +407,3 @@ func ValidateIgnorePreflightErrors(ignorePreflightErrors []string, skipPreflight
|
|||||||
|
|
||||||
return ignoreErrors, allErrs.ToAggregate()
|
return ignoreErrors, allErrs.ToAggregate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateKubeletConfiguration validates kubelet configuration and collects all encountered errors
|
|
||||||
func ValidateKubeletConfiguration(kubeletConfig *kubeletconfig.KubeletConfiguration, fldPath *field.Path) field.ErrorList {
|
|
||||||
allErrs := field.ErrorList{}
|
|
||||||
if kubeletConfig == nil {
|
|
||||||
return allErrs
|
|
||||||
}
|
|
||||||
if err := kubeletvalidation.ValidateKubeletConfiguration(kubeletConfig); err != nil {
|
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, "", err.Error()))
|
|
||||||
}
|
|
||||||
return allErrs
|
|
||||||
}
|
|
||||||
|
@ -19,7 +19,6 @@ package validation
|
|||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -28,7 +27,6 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
|
||||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||||
)
|
)
|
||||||
@ -678,308 +676,6 @@ func TestValidateIgnorePreflightErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateKubeletConfiguration(t *testing.T) {
|
|
||||||
successCase := &kubeletconfig.KubeletConfiguration{
|
|
||||||
CgroupsPerQOS: true,
|
|
||||||
EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved"},
|
|
||||||
SystemCgroups: "",
|
|
||||||
CgroupRoot: "",
|
|
||||||
EventBurst: 10,
|
|
||||||
EventRecordQPS: 5,
|
|
||||||
HealthzPort: 10248,
|
|
||||||
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",
|
|
||||||
}
|
|
||||||
if allErrors := ValidateKubeletConfiguration(successCase, nil); len(allErrors) != 0 {
|
|
||||||
t.Errorf("failed ValidateKubeletConfiguration: expect no errors but got %v", allErrors)
|
|
||||||
}
|
|
||||||
|
|
||||||
errorCase := &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,
|
|
||||||
}
|
|
||||||
if allErrors := ValidateKubeletConfiguration(errorCase, nil); len(allErrors) == 0 {
|
|
||||||
t.Errorf("failed ValidateKubeletConfiguration: expect errors but got no error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|
||||||
successCases := []kubeadm.MasterConfiguration{
|
|
||||||
{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
MaxPerCore: utilpointer.Int32Ptr(1),
|
|
||||||
Min: utilpointer.Int32Ptr(1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, successCase := range successCases {
|
|
||||||
if errs := ValidateProxy(successCase.ComponentConfigs.KubeProxy, nil); len(errs) != 0 {
|
|
||||||
t.Errorf("failed ValidateProxy: expect no errors but got %v", errs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorCases := []struct {
|
|
||||||
masterConfig kubeadm.MasterConfiguration
|
|
||||||
msg string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
masterConfig: kubeadm.MasterConfiguration{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
masterConfig: kubeadm.MasterConfiguration{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
masterConfig: kubeadm.MasterConfiguration{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
masterConfig: kubeadm.MasterConfiguration{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
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)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
masterConfig: kubeadm.MasterConfiguration{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
masterConfig: kubeadm.MasterConfiguration{
|
|
||||||
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{
|
|
||||||
Max: utilpointer.Int32Ptr(2),
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, errorCase := range errorCases {
|
|
||||||
if errs := ValidateProxy(errorCase.masterConfig.ComponentConfigs.KubeProxy, nil); len(errs) == 0 {
|
|
||||||
t.Errorf("%d failed ValidateProxy: expected error for %s, but got no error", i, errorCase.msg)
|
|
||||||
} else if !strings.Contains(errs[0].Error(), errorCase.msg) {
|
|
||||||
t.Errorf("%d failed ValidateProxy: unexpected error: %v, expected: %s", i, errs[0], errorCase.msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateArgSelection(t *testing.T) {
|
func TestValidateArgSelection(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -89,6 +89,7 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdConfigPrintDefault returns cobra.Command for "kubeadm config print-default" command
|
// NewCmdConfigPrintDefault returns cobra.Command for "kubeadm config print-default" command
|
||||||
|
// TODO: Make it possible to print the defaults for the componentconfig API objects, and default to printing them out as well
|
||||||
func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
|
func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
|
||||||
apiObjects := []string{}
|
apiObjects := []string{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -143,7 +144,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
return kubeadmutil.MarshalToYamlForCodecs(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs)
|
return configutil.MarshalKubeadmConfigObject(internalcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdConfigMigrate returns cobra.Command for "kubeadm config migrate" command
|
// NewCmdConfigMigrate returns cobra.Command for "kubeadm config migrate" command
|
||||||
@ -175,7 +176,7 @@ func NewCmdConfigMigrate(out io.Writer) *cobra.Command {
|
|||||||
internalcfg, err := configutil.AnyConfigFileAndDefaultsToInternal(oldCfgPath)
|
internalcfg, err := configutil.AnyConfigFileAndDefaultsToInternal(oldCfgPath)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
outputBytes, err := kubeadmutil.MarshalToYamlForCodecs(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs)
|
outputBytes, err := configutil.MarshalKubeadmConfigObject(internalcfg)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
if newCfgPath == "" {
|
if newCfgPath == "" {
|
||||||
|
@ -14,7 +14,6 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||||
|
@ -30,13 +30,10 @@ import (
|
|||||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||||
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
||||||
@ -118,10 +115,7 @@ func printConfiguration(cfg *kubeadmapi.MasterConfiguration, w io.Writer) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
externalcfg := &kubeadmapiv1alpha3.MasterConfiguration{}
|
cfgYaml, err := configutil.MarshalKubeadmConfigObject(cfg)
|
||||||
kubeadmscheme.Scheme.Convert(cfg, externalcfg, nil)
|
|
||||||
|
|
||||||
cfgYaml, err := kubeadmutil.MarshalToYamlForCodecs(externalcfg, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Fprintln(w, "[upgrade/config] Configuration used:")
|
fmt.Fprintln(w, "[upgrade/config] Configuration used:")
|
||||||
|
|
||||||
|
@ -58,8 +58,6 @@ func TestPrintConfiguration(t *testing.T) {
|
|||||||
image: ""
|
image: ""
|
||||||
imageRepository: ""
|
imageRepository: ""
|
||||||
kind: MasterConfiguration
|
kind: MasterConfiguration
|
||||||
kubeProxy: {}
|
|
||||||
kubeletConfiguration: {}
|
|
||||||
kubernetesVersion: v1.7.1
|
kubernetesVersion: v1.7.1
|
||||||
networking:
|
networking:
|
||||||
dnsDomain: ""
|
dnsDomain: ""
|
||||||
@ -100,8 +98,6 @@ func TestPrintConfiguration(t *testing.T) {
|
|||||||
keyFile: ""
|
keyFile: ""
|
||||||
imageRepository: ""
|
imageRepository: ""
|
||||||
kind: MasterConfiguration
|
kind: MasterConfiguration
|
||||||
kubeProxy: {}
|
|
||||||
kubeletConfiguration: {}
|
|
||||||
kubernetesVersion: v1.7.1
|
kubernetesVersion: v1.7.1
|
||||||
networking:
|
networking:
|
||||||
dnsDomain: ""
|
dnsDomain: ""
|
||||||
|
59
cmd/kubeadm/app/componentconfigs/BUILD
Normal file
59
cmd/kubeadm/app/componentconfigs/BUILD
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"defaults.go",
|
||||||
|
"registrations.go",
|
||||||
|
"scheme.go",
|
||||||
|
"validation.go",
|
||||||
|
],
|
||||||
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
|
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||||
|
"//pkg/kubelet/apis/kubeletconfig/v1beta1:go_default_library",
|
||||||
|
"//pkg/kubelet/apis/kubeletconfig/validation:go_default_library",
|
||||||
|
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||||
|
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
||||||
|
"//pkg/proxy/apis/kubeproxyconfig/validation:go_default_library",
|
||||||
|
"//pkg/util/pointer: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/runtime/schema:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["validation_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
|
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||||
|
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||||
|
"//pkg/util/pointer:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
120
cmd/kubeadm/app/componentconfigs/defaults.go
Normal file
120
cmd/kubeadm/app/componentconfigs/defaults.go
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
|
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
||||||
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
|
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
||||||
|
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KubeproxyKubeConfigFileName defines the file name for the kube-proxy's KubeConfig file
|
||||||
|
KubeproxyKubeConfigFileName = "/var/lib/kube-proxy/kubeconfig.conf"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultKubeProxyConfiguration assigns default values for the kube-proxy ComponentConfig
|
||||||
|
func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.MasterConfiguration) {
|
||||||
|
// IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
|
||||||
|
// and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go. TODO: Remove this requirement when v1alpha2 is removed.
|
||||||
|
externalproxycfg := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
|
||||||
|
|
||||||
|
// Do a roundtrip to the external version for defaulting
|
||||||
|
Scheme.Convert(internalcfg.ComponentConfigs.KubeProxy, externalproxycfg, nil)
|
||||||
|
|
||||||
|
if externalproxycfg.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" {
|
||||||
|
externalproxycfg.ClusterCIDR = internalcfg.Networking.PodSubnet
|
||||||
|
}
|
||||||
|
|
||||||
|
if externalproxycfg.ClientConnection.KubeConfigFile == "" {
|
||||||
|
externalproxycfg.ClientConnection.KubeConfigFile = KubeproxyKubeConfigFileName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the rest of the kube-proxy defaulting code
|
||||||
|
kubeproxyconfigv1alpha1.SetDefaults_KubeProxyConfiguration(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.MasterConfiguration) {
|
||||||
|
// IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
|
||||||
|
// and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go. TODO: Remove this requirement when v1alpha2 is removed.
|
||||||
|
externalkubeletcfg := &kubeletconfigv1beta1.KubeletConfiguration{}
|
||||||
|
|
||||||
|
// Do a roundtrip to the external version for defaulting
|
||||||
|
Scheme.Convert(internalcfg.ComponentConfigs.Kubelet, externalkubeletcfg, nil)
|
||||||
|
|
||||||
|
if externalkubeletcfg.StaticPodPath == "" {
|
||||||
|
externalkubeletcfg.StaticPodPath = kubeadmapiv1alpha3.DefaultManifestsDir
|
||||||
|
}
|
||||||
|
if externalkubeletcfg.ClusterDNS == nil {
|
||||||
|
dnsIP, err := constants.GetDNSIP(internalcfg.Networking.ServiceSubnet)
|
||||||
|
if err != nil {
|
||||||
|
externalkubeletcfg.ClusterDNS = []string{kubeadmapiv1alpha3.DefaultClusterDNSIP}
|
||||||
|
} else {
|
||||||
|
externalkubeletcfg.ClusterDNS = []string{dnsIP.String()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if externalkubeletcfg.ClusterDomain == "" {
|
||||||
|
externalkubeletcfg.ClusterDomain = internalcfg.Networking.DNSDomain
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce security-related kubelet options
|
||||||
|
|
||||||
|
// Require all clients to the kubelet API to have client certs signed by the cluster CA
|
||||||
|
externalkubeletcfg.Authentication.X509.ClientCAFile = kubeadmapiv1alpha3.DefaultCACertPath
|
||||||
|
externalkubeletcfg.Authentication.Anonymous.Enabled = utilpointer.BoolPtr(false)
|
||||||
|
|
||||||
|
// On every client request to the kubelet API, execute a webhook (SubjectAccessReview request) to the API server
|
||||||
|
// and ask it whether the client is authorized to access the kubelet API
|
||||||
|
externalkubeletcfg.Authorization.Mode = kubeletconfigv1beta1.KubeletAuthorizationModeWebhook
|
||||||
|
|
||||||
|
// Let clients using other authentication methods like ServiceAccount tokens also access the kubelet API
|
||||||
|
externalkubeletcfg.Authentication.Webhook.Enabled = utilpointer.BoolPtr(true)
|
||||||
|
|
||||||
|
// Disable the readonly port of the kubelet, in order to not expose unnecessary information
|
||||||
|
externalkubeletcfg.ReadOnlyPort = 0
|
||||||
|
|
||||||
|
// Enables client certificate rotation for the kubelet
|
||||||
|
externalkubeletcfg.RotateCertificates = true
|
||||||
|
|
||||||
|
// Serve a /healthz webserver on localhost:10248 that kubeadm can talk to
|
||||||
|
externalkubeletcfg.HealthzBindAddress = "127.0.0.1"
|
||||||
|
externalkubeletcfg.HealthzPort = utilpointer.Int32Ptr(10248)
|
||||||
|
|
||||||
|
kubeletconfigv1beta1.SetDefaults_KubeletConfiguration(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)
|
||||||
|
}
|
148
cmd/kubeadm/app/componentconfigs/registrations.go
Normal file
148
cmd/kubeadm/app/componentconfigs/registrations.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
|
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
||||||
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
|
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AddToSchemeFunc is a function that adds known types and API GroupVersions to a scheme
|
||||||
|
type AddToSchemeFunc func(*runtime.Scheme) error
|
||||||
|
|
||||||
|
// Registration is an object for registering a Kubernetes ComponentConfig type to be recognized and handled by kubeadm
|
||||||
|
type Registration struct {
|
||||||
|
// MarshalGroupVersion is the preferred external API version to use when marshalling the ComponentConfig
|
||||||
|
MarshalGroupVersion schema.GroupVersion
|
||||||
|
// AddToSchemeFuncs are a set of functions that register APIs to the scheme
|
||||||
|
AddToSchemeFuncs []AddToSchemeFunc
|
||||||
|
// DefaulterFunc is a function that based on the internal kubeadm configuration defaults the ComponentConfig struct
|
||||||
|
DefaulterFunc func(*kubeadmapi.MasterConfiguration)
|
||||||
|
// ValidateFunc is a function that should validate the ComponentConfig type embedded in the internal kubeadm config struct
|
||||||
|
ValidateFunc func(*kubeadmapi.MasterConfiguration, *field.Path) field.ErrorList
|
||||||
|
// EmptyValue holds a pointer to an empty struct of the internal ComponentConfig type
|
||||||
|
EmptyValue runtime.Object
|
||||||
|
// GetFromInternalConfig returns the pointer to the ComponentConfig API object from the internal kubeadm config struct
|
||||||
|
GetFromInternalConfig func(*kubeadmapi.MasterConfiguration) (runtime.Object, bool)
|
||||||
|
// SetToInternalConfig sets the pointer to a ComponentConfig API object embedded in the internal kubeadm config struct
|
||||||
|
SetToInternalConfig func(runtime.Object, *kubeadmapi.MasterConfiguration) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal marshals obj to bytes for the current Registration
|
||||||
|
func (r Registration) Marshal(obj runtime.Object) ([]byte, error) {
|
||||||
|
return kubeadmutil.MarshalToYamlForCodecs(obj, r.MarshalGroupVersion, Codecs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal unmarshals the bytes to a runtime.Object using the Codecs registered in this Scheme
|
||||||
|
func (r Registration) Unmarshal(fileContent []byte) (runtime.Object, error) {
|
||||||
|
// Do a deepcopy of the empty value so we don't mutate it, which could lead to strange errors
|
||||||
|
obj := r.EmptyValue.DeepCopyObject()
|
||||||
|
|
||||||
|
// Decode the file content into obj which is a pointer to an empty struct of the internal ComponentConfig
|
||||||
|
// object, using the componentconfig Codecs that knows about all APIs
|
||||||
|
if err := runtime.DecodeInto(Codecs.UniversalDecoder(), fileContent, obj); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KubeletConfigurationKind is the kind for the kubelet ComponentConfig
|
||||||
|
KubeletConfigurationKind RegistrationKind = "KubeletConfiguration"
|
||||||
|
// KubeProxyConfigurationKind is the kind for the kubelet ComponentConfig
|
||||||
|
KubeProxyConfigurationKind RegistrationKind = "KubeProxyConfiguration"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegistrationKind is a string type to ensure not any string can be a key in the Registrations map
|
||||||
|
type RegistrationKind string
|
||||||
|
|
||||||
|
// Registrations holds a set of ComponentConfig Registration objects, where the map key is the kind
|
||||||
|
type Registrations map[RegistrationKind]Registration
|
||||||
|
|
||||||
|
// Known contains the known ComponentConfig registrations to kubeadm
|
||||||
|
var Known Registrations = map[RegistrationKind]Registration{
|
||||||
|
KubeProxyConfigurationKind: {
|
||||||
|
// TODO: When a beta version of the kube-proxy ComponentConfig API is available, start using it
|
||||||
|
MarshalGroupVersion: kubeproxyconfigv1alpha1.SchemeGroupVersion,
|
||||||
|
AddToSchemeFuncs: []AddToSchemeFunc{kubeproxyconfig.AddToScheme, kubeproxyconfigv1alpha1.AddToScheme},
|
||||||
|
DefaulterFunc: DefaultKubeProxyConfiguration,
|
||||||
|
ValidateFunc: ValidateKubeProxyConfiguration,
|
||||||
|
EmptyValue: &kubeproxyconfig.KubeProxyConfiguration{},
|
||||||
|
GetFromInternalConfig: func(cfg *kubeadmapi.MasterConfiguration) (runtime.Object, bool) {
|
||||||
|
return cfg.ComponentConfigs.KubeProxy, cfg.ComponentConfigs.KubeProxy != nil
|
||||||
|
},
|
||||||
|
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.MasterConfiguration) bool {
|
||||||
|
kubeproxyConfig, ok := obj.(*kubeproxyconfig.KubeProxyConfiguration)
|
||||||
|
if ok {
|
||||||
|
cfg.ComponentConfigs.KubeProxy = kubeproxyConfig
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
},
|
||||||
|
},
|
||||||
|
KubeletConfigurationKind: {
|
||||||
|
MarshalGroupVersion: kubeletconfigv1beta1.SchemeGroupVersion,
|
||||||
|
AddToSchemeFuncs: []AddToSchemeFunc{kubeletconfig.AddToScheme, kubeletconfigv1beta1.AddToScheme},
|
||||||
|
DefaulterFunc: DefaultKubeletConfiguration,
|
||||||
|
ValidateFunc: ValidateKubeletConfiguration,
|
||||||
|
EmptyValue: &kubeletconfig.KubeletConfiguration{},
|
||||||
|
GetFromInternalConfig: func(cfg *kubeadmapi.MasterConfiguration) (runtime.Object, bool) {
|
||||||
|
return cfg.ComponentConfigs.Kubelet, cfg.ComponentConfigs.Kubelet != nil
|
||||||
|
},
|
||||||
|
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.MasterConfiguration) bool {
|
||||||
|
kubeletConfig, ok := obj.(*kubeletconfig.KubeletConfiguration)
|
||||||
|
if ok {
|
||||||
|
cfg.ComponentConfigs.Kubelet = kubeletConfig
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddToScheme adds all the known ComponentConfig API types referenced in the Registrations object to the scheme
|
||||||
|
func (rs *Registrations) AddToScheme(scheme *runtime.Scheme) error {
|
||||||
|
for _, registration := range *rs {
|
||||||
|
for _, addToSchemeFunc := range registration.AddToSchemeFuncs {
|
||||||
|
if err := addToSchemeFunc(scheme); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default applies to the ComponentConfig defaults to the internal kubeadm API type
|
||||||
|
func (rs *Registrations) Default(internalcfg *kubeadmapi.MasterConfiguration) {
|
||||||
|
for _, registration := range *rs {
|
||||||
|
registration.DefaulterFunc(internalcfg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates the ComponentConfig parts of the internal kubeadm API type
|
||||||
|
func (rs *Registrations) Validate(internalcfg *kubeadmapi.MasterConfiguration) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
for kind, registration := range *rs {
|
||||||
|
allErrs = append(allErrs, registration.ValidateFunc(internalcfg, field.NewPath(string(kind)))...)
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
|
}
|
41
cmd/kubeadm/app/componentconfigs/scheme.go
Normal file
41
cmd/kubeadm/app/componentconfigs/scheme.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scheme is the runtime.Scheme to which all supported kubeadm ComponentConfig API types are registered.
|
||||||
|
var Scheme = runtime.NewScheme()
|
||||||
|
|
||||||
|
// Codecs provides access to encoding and decoding for the scheme.
|
||||||
|
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
||||||
|
AddToScheme(Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddToScheme builds the kubeadm ComponentConfig scheme using all known ComponentConfig versions.
|
||||||
|
func AddToScheme(scheme *runtime.Scheme) {
|
||||||
|
utilruntime.Must(Known.AddToScheme(scheme))
|
||||||
|
}
|
46
cmd/kubeadm/app/componentconfigs/validation.go
Normal file
46
cmd/kubeadm/app/componentconfigs/validation.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeletvalidation "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation"
|
||||||
|
proxyvalidation "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidateKubeProxyConfiguration validates proxy configuration and collects all encountered errors
|
||||||
|
func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.MasterConfiguration, _ *field.Path) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
if internalcfg.ComponentConfigs.KubeProxy == nil {
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
return proxyvalidation.Validate(internalcfg.ComponentConfigs.KubeProxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateKubeletConfiguration validates kubelet configuration and collects all encountered errors
|
||||||
|
func ValidateKubeletConfiguration(internalcfg *kubeadmapi.MasterConfiguration, 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
|
||||||
|
}
|
351
cmd/kubeadm/app/componentconfigs/validation_test.go
Normal file
351
cmd/kubeadm/app/componentconfigs/validation_test.go
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
|
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
masterConfig *kubeadm.MasterConfiguration
|
||||||
|
msg string
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
MaxPerCore: utilpointer.Int32Ptr(1),
|
||||||
|
Min: utilpointer.Int32Ptr(1),
|
||||||
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
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)",
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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{
|
||||||
|
Max: utilpointer.Int32Ptr(2),
|
||||||
|
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 {
|
||||||
|
err := ValidateKubeProxyConfiguration(rt.masterConfig, 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 {
|
||||||
|
masterConfig *kubeadm.MasterConfiguration
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
ComponentConfigs: kubeadm.ComponentConfigs{
|
||||||
|
Kubelet: &kubeletconfig.KubeletConfiguration{
|
||||||
|
CgroupsPerQOS: true,
|
||||||
|
EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved"},
|
||||||
|
SystemCgroups: "",
|
||||||
|
CgroupRoot: "",
|
||||||
|
EventBurst: 10,
|
||||||
|
EventRecordQPS: 5,
|
||||||
|
HealthzPort: 10248,
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
masterConfig: &kubeadm.MasterConfiguration{
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, rt := range tests {
|
||||||
|
err := ValidateKubeletConfiguration(rt.masterConfig, nil).ToAggregate()
|
||||||
|
if (err != nil) != rt.expectErr {
|
||||||
|
t.Errorf("%d failed ValidateKubeletConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ go_test(
|
|||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||||
"//pkg/util/pointer:go_default_library",
|
"//pkg/util/pointer:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors: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/apis/meta/v1:go_default_library",
|
||||||
@ -34,11 +34,10 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy",
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||||
"//pkg/proxy/apis/kubeproxyconfig/scheme:go_default_library",
|
|
||||||
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1: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/api/rbac/v1:go_default_library",
|
||||||
|
@ -29,11 +29,10 @@ import (
|
|||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
kubeproxyconfigscheme "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/scheme"
|
|
||||||
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -57,7 +56,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.MasterConfiguration, client clientset.Inte
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyBytes, err := kubeadmutil.MarshalToYamlForCodecs(cfg.ComponentConfigs.KubeProxy, kubeproxyconfigv1alpha1.SchemeGroupVersion, kubeproxyconfigscheme.Codecs)
|
proxyBytes, err := componentconfigs.Known[componentconfigs.KubeProxyConfigurationKind].Marshal(cfg.ComponentConfigs.KubeProxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when marshaling: %v", err)
|
return fmt.Errorf("error when marshaling: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ import (
|
|||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||||
"k8s.io/kubernetes/pkg/util/pointer"
|
"k8s.io/kubernetes/pkg/util/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -173,32 +173,17 @@ func TestEnsureProxyAddon(t *testing.T) {
|
|||||||
|
|
||||||
// Create a fake client and set up default test configuration
|
// Create a fake client and set up default test configuration
|
||||||
client := clientsetfake.NewSimpleClientset()
|
client := clientsetfake.NewSimpleClientset()
|
||||||
|
// TODO: Consider using a YAML file instead for this that makes it possible to specify YAML documents for the ComponentConfigs
|
||||||
masterConfig := &kubeadmapiv1alpha3.MasterConfiguration{
|
masterConfig := &kubeadmapiv1alpha3.MasterConfiguration{
|
||||||
API: kubeadmapiv1alpha3.API{
|
API: kubeadmapiv1alpha3.API{
|
||||||
AdvertiseAddress: "1.2.3.4",
|
AdvertiseAddress: "1.2.3.4",
|
||||||
BindPort: 1234,
|
BindPort: 1234,
|
||||||
},
|
},
|
||||||
KubeProxy: kubeadmapiv1alpha3.KubeProxy{
|
|
||||||
Config: &kubeproxyconfigv1alpha1.KubeProxyConfiguration{
|
|
||||||
BindAddress: "",
|
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
Conntrack: kubeproxyconfigv1alpha1.KubeProxyConntrackConfiguration{
|
|
||||||
Max: pointer.Int32Ptr(2),
|
|
||||||
MaxPerCore: pointer.Int32Ptr(1),
|
|
||||||
Min: pointer.Int32Ptr(1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Networking: kubeadmapiv1alpha3.Networking{
|
Networking: kubeadmapiv1alpha3.Networking{
|
||||||
PodSubnet: "5.6.7.8/24",
|
PodSubnet: "5.6.7.8/24",
|
||||||
},
|
},
|
||||||
ImageRepository: "someRepo",
|
ImageRepository: "someRepo",
|
||||||
KubernetesVersion: "v1.10.0",
|
KubernetesVersion: "v1.10.0",
|
||||||
UnifiedControlPlaneImage: "someImage",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate an error if necessary
|
// Simulate an error if necessary
|
||||||
@ -214,10 +199,26 @@ func TestEnsureProxyAddon(t *testing.T) {
|
|||||||
masterConfig.Networking.PodSubnet = "2001:101::/96"
|
masterConfig.Networking.PodSubnet = "2001:101::/96"
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeadmapiv1alpha3.SetDefaults_MasterConfiguration(masterConfig)
|
intMaster, err := configutil.ConfigFileAndDefaultsToInternalConfig("", masterConfig)
|
||||||
intMaster, err := cmdutil.ConfigFileAndDefaultsToInternalConfig("", masterConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(" test failed to convert v1alpha1 to internal version")
|
t.Errorf("test failed to convert external to internal version")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
intMaster.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{
|
||||||
|
BindAddress: "",
|
||||||
|
HealthzBindAddress: "0.0.0.0:10256",
|
||||||
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
|
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
||||||
|
Max: pointer.Int32Ptr(2),
|
||||||
|
MaxPerCore: pointer.Int32Ptr(1),
|
||||||
|
Min: pointer.Int32Ptr(1),
|
||||||
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// Run dynamic defaulting again as we changed the internal cfg
|
||||||
|
if err := configutil.SetInitDynamicDefaults(intMaster); err != nil {
|
||||||
|
t.Errorf("test failed to set dynamic defaults: %v", err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = EnsureProxyAddon(intMaster, client)
|
err = EnsureProxyAddon(intMaster, client)
|
||||||
|
@ -13,14 +13,13 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/features:go_default_library",
|
"//cmd/kubeadm/app/features:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||||
"//pkg/apis/rbac/v1:go_default_library",
|
"//pkg/apis/rbac/v1:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
|
||||||
"//pkg/kubelet/apis/kubeletconfig/v1beta1:go_default_library",
|
|
||||||
"//pkg/util/initsystem:go_default_library",
|
"//pkg/util/initsystem:go_default_library",
|
||||||
"//pkg/util/node:go_default_library",
|
"//pkg/util/node:go_default_library",
|
||||||
"//pkg/util/procfs:go_default_library",
|
"//pkg/util/procfs:go_default_library",
|
||||||
|
@ -28,13 +28,11 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
rbachelper "k8s.io/kubernetes/pkg/apis/rbac/v1"
|
rbachelper "k8s.io/kubernetes/pkg/apis/rbac/v1"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||||
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
|
||||||
"k8s.io/kubernetes/pkg/util/version"
|
"k8s.io/kubernetes/pkg/util/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -154,14 +152,9 @@ func configMapRBACName(k8sVersion *version.Version) string {
|
|||||||
return fmt.Sprintf("%s%d.%d", kubeadmconstants.KubeletBaseConfigMapRolePrefix, k8sVersion.Major(), k8sVersion.Minor())
|
return fmt.Sprintf("%s%d.%d", kubeadmconstants.KubeletBaseConfigMapRolePrefix, k8sVersion.Major(), k8sVersion.Minor())
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConfigBytes marshals a kubeletconfiguration object to bytes
|
// getConfigBytes marshals a KubeletConfiguration object to bytes
|
||||||
func getConfigBytes(kubeletConfig *kubeletconfig.KubeletConfiguration) ([]byte, error) {
|
func getConfigBytes(kubeletConfig *kubeletconfig.KubeletConfiguration) ([]byte, error) {
|
||||||
_, kubeletCodecs, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
return componentconfigs.Known[componentconfigs.KubeletConfigurationKind].Marshal(kubeletConfig)
|
||||||
if err != nil {
|
|
||||||
return []byte{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return kubeadmutil.MarshalToYamlForCodecs(kubeletConfig, kubeletconfigv1beta1.SchemeGroupVersion, *kubeletCodecs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeConfigBytesToDisk writes a byte slice down to disk at the specific location of the kubelet config file
|
// writeConfigBytesToDisk writes a byte slice down to disk at the specific location of the kubelet config file
|
||||||
|
@ -12,11 +12,9 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig",
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
|
@ -23,11 +23,9 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
|
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UploadConfiguration saves the MasterConfiguration used for later reference (when upgrading for instance)
|
// UploadConfiguration saves the MasterConfiguration used for later reference (when upgrading for instance)
|
||||||
@ -41,9 +39,17 @@ func UploadConfiguration(cfg *kubeadmapi.MasterConfiguration, client clientset.I
|
|||||||
cfgToUpload.BootstrapTokens = nil
|
cfgToUpload.BootstrapTokens = nil
|
||||||
// Clear the NodeRegistration object.
|
// Clear the NodeRegistration object.
|
||||||
cfgToUpload.NodeRegistration = kubeadmapi.NodeRegistrationOptions{}
|
cfgToUpload.NodeRegistration = kubeadmapi.NodeRegistrationOptions{}
|
||||||
|
// TODO: Reset the .ComponentConfig struct like this:
|
||||||
|
// cfgToUpload.ComponentConfigs = kubeadmapi.ComponentConfigs{}
|
||||||
|
// in order to not upload any other components' config to the kubeadm-config
|
||||||
|
// ConfigMap. The components store their config in their own ConfigMaps.
|
||||||
|
// Before this line can be uncommented util/config.loadConfigurationBytes()
|
||||||
|
// needs to support reading the different components' ConfigMaps first.
|
||||||
|
|
||||||
// Marshal the object into YAML
|
// Marshal the object into YAML
|
||||||
cfgYaml, err := kubeadmutil.MarshalToYamlForCodecs(cfgToUpload, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs)
|
cfgYaml, err := configutil.MarshalKubeadmConfigObject(cfgToUpload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("err", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ func TestUploadConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t2 *testing.T) {
|
||||||
cfg := &kubeadmapi.MasterConfiguration{
|
cfg := &kubeadmapi.MasterConfiguration{
|
||||||
KubernetesVersion: "v1.10.3",
|
KubernetesVersion: "v1.10.3",
|
||||||
BootstrapTokens: []kubeadmapi.BootstrapToken{
|
BootstrapTokens: []kubeadmapi.BootstrapToken{
|
||||||
@ -85,7 +85,7 @@ func TestUploadConfiguration(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// For idempotent test, we check the result of the second call.
|
// For idempotent test, we check the result of the second call.
|
||||||
if err := UploadConfiguration(cfg, client); !tt.updateExisting && (err != nil) != tt.errExpected {
|
if err := UploadConfiguration(cfg, client); !tt.updateExisting && (err != nil) != tt.errExpected {
|
||||||
t.Errorf("UploadConfiguration() error = %v, wantErr %v", err, tt.errExpected)
|
t2.Fatalf("UploadConfiguration() error = %v, wantErr %v", err, tt.errExpected)
|
||||||
}
|
}
|
||||||
if tt.updateExisting {
|
if tt.updateExisting {
|
||||||
if tt.errOnUpdate != nil {
|
if tt.errOnUpdate != nil {
|
||||||
@ -94,49 +94,36 @@ func TestUploadConfiguration(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err := UploadConfiguration(cfg, client); (err != nil) != tt.errExpected {
|
if err := UploadConfiguration(cfg, client); (err != nil) != tt.errExpected {
|
||||||
t.Errorf("UploadConfiguration() error = %v", err)
|
t2.Fatalf("UploadConfiguration() error = %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tt.verifyResult {
|
if tt.verifyResult {
|
||||||
masterCfg, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.MasterConfigurationConfigMap, metav1.GetOptions{})
|
masterCfg, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.MasterConfigurationConfigMap, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Fail to query ConfigMap error = %v", err)
|
t2.Fatalf("Fail to query ConfigMap error = %v", err)
|
||||||
}
|
}
|
||||||
configData := masterCfg.Data[kubeadmconstants.MasterConfigurationConfigMapKey]
|
configData := masterCfg.Data[kubeadmconstants.MasterConfigurationConfigMapKey]
|
||||||
if configData == "" {
|
if configData == "" {
|
||||||
t.Errorf("Fail to find ConfigMap key")
|
t2.Fatalf("Fail to find ConfigMap key")
|
||||||
}
|
}
|
||||||
|
|
||||||
decodedExtCfg := &kubeadmapiv1alpha3.MasterConfiguration{}
|
|
||||||
decodedCfg := &kubeadmapi.MasterConfiguration{}
|
decodedCfg := &kubeadmapi.MasterConfiguration{}
|
||||||
|
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(configData), decodedCfg); err != nil {
|
||||||
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(configData), decodedExtCfg); err != nil {
|
t2.Fatalf("unable to decode config from bytes: %v", err)
|
||||||
t.Errorf("unable to decode config from bytes: %v", err)
|
|
||||||
}
|
}
|
||||||
// Default and convert to the internal version
|
|
||||||
kubeadmscheme.Scheme.Default(decodedExtCfg)
|
|
||||||
kubeadmscheme.Scheme.Convert(decodedExtCfg, decodedCfg, nil)
|
|
||||||
|
|
||||||
if decodedCfg.KubernetesVersion != cfg.KubernetesVersion {
|
if decodedCfg.KubernetesVersion != cfg.KubernetesVersion {
|
||||||
t.Errorf("Decoded value doesn't match, decoded = %#v, expected = %#v", decodedCfg.KubernetesVersion, cfg.KubernetesVersion)
|
t2.Errorf("Decoded value doesn't match, decoded = %#v, expected = %#v", decodedCfg.KubernetesVersion, cfg.KubernetesVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the decoded cfg has a BootstrapTokens array, verify the sensitive information we had isn't still there.
|
// If the decoded cfg has a BootstrapTokens array, verify the sensitive information we had isn't still there.
|
||||||
if len(decodedCfg.BootstrapTokens) > 0 && decodedCfg.BootstrapTokens[0].Token != nil && decodedCfg.BootstrapTokens[0].Token.String() == cfg.BootstrapTokens[0].Token.String() {
|
if len(decodedCfg.BootstrapTokens) > 0 && decodedCfg.BootstrapTokens[0].Token != nil && decodedCfg.BootstrapTokens[0].Token.String() == cfg.BootstrapTokens[0].Token.String() {
|
||||||
t.Errorf("Decoded value contains .BootstrapTokens (sensitive info), decoded = %#v, expected = empty", decodedCfg.BootstrapTokens)
|
t2.Errorf("Decoded value contains .BootstrapTokens (sensitive info), decoded = %#v, expected = empty", decodedCfg.BootstrapTokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure no information from NodeRegistrationOptions was uploaded.
|
// Make sure no information from NodeRegistrationOptions was uploaded.
|
||||||
if decodedCfg.NodeRegistration.Name == cfg.NodeRegistration.Name || decodedCfg.NodeRegistration.CRISocket != kubeadmapiv1alpha3.DefaultCRISocket {
|
if decodedCfg.NodeRegistration.Name == cfg.NodeRegistration.Name || decodedCfg.NodeRegistration.CRISocket != kubeadmapiv1alpha3.DefaultCRISocket {
|
||||||
t.Errorf("Decoded value contains .NodeRegistration (node-specific info shouldn't be uploaded), decoded = %#v, expected = empty", decodedCfg.NodeRegistration)
|
t2.Errorf("Decoded value contains .NodeRegistration (node-specific info shouldn't be uploaded), decoded = %#v, expected = empty", decodedCfg.NodeRegistration)
|
||||||
}
|
|
||||||
|
|
||||||
if decodedExtCfg.Kind != "MasterConfiguration" {
|
|
||||||
t.Errorf("Expected kind MasterConfiguration, got %v", decodedExtCfg.Kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
if decodedExtCfg.APIVersion != "kubeadm.k8s.io/v1alpha3" {
|
|
||||||
t.Errorf("Expected apiVersion kubeadm.k8s.io/v1alpha3, got %v", decodedExtCfg.APIVersion)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -49,12 +49,13 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
||||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/componentconfigs:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//pkg/util/node:go_default_library",
|
"//pkg/util/node:go_default_library",
|
||||||
@ -28,6 +29,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors: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/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
||||||
|
@ -59,6 +59,7 @@ func loadConfigurationBytes(client clientset.Interface, w io.Writer, logPrefix,
|
|||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return []byte{}, fmt.Errorf("an unexpected error happened when trying to get the ConfigMap %q in the %s namespace: %v", constants.MasterConfigurationConfigMap, metav1.NamespaceSystem, err)
|
return []byte{}, fmt.Errorf("an unexpected error happened when trying to get the ConfigMap %q in the %s namespace: %v", constants.MasterConfigurationConfigMap, metav1.NamespaceSystem, err)
|
||||||
}
|
}
|
||||||
|
// TODO: Load the kube-proxy and kubelet ComponentConfig ConfigMaps here as different YAML documents and append to the byte slice
|
||||||
|
|
||||||
fmt.Fprintf(w, "[%s] FYI: You can look at this config file with 'kubectl -n %s get cm %s -oyaml'\n", logPrefix, metav1.NamespaceSystem, constants.MasterConfigurationConfigMap)
|
fmt.Fprintf(w, "[%s] FYI: You can look at this config file with 'kubectl -n %s get cm %s -oyaml'\n", logPrefix, metav1.NamespaceSystem, constants.MasterConfigurationConfigMap)
|
||||||
return []byte(configMap.Data[constants.MasterConfigurationConfigMapKey]), nil
|
return []byte(configMap.Data[constants.MasterConfigurationConfigMapKey]), nil
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
@ -53,6 +54,16 @@ func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error)
|
|||||||
return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks)
|
return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a MasterConfiguration, some extra logic is run
|
||||||
|
func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, error) {
|
||||||
|
switch internalcfg := obj.(type) {
|
||||||
|
case *kubeadmapi.MasterConfiguration:
|
||||||
|
return MarshalMasterConfigurationToBytes(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion)
|
||||||
|
default:
|
||||||
|
return kubeadmutil.MarshalToYamlForCodecs(obj, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DetectUnsupportedVersion reads YAML bytes, extracts the TypeMeta information and errors out with an user-friendly message if the API spec is too old for this kubeadm version
|
// DetectUnsupportedVersion reads YAML bytes, extracts the TypeMeta information and errors out with an user-friendly message if the API spec is too old for this kubeadm version
|
||||||
func DetectUnsupportedVersion(b []byte) error {
|
func DetectUnsupportedVersion(b []byte) error {
|
||||||
gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
|
gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
|
||||||
|
@ -17,27 +17,36 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||||
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetInitDynamicDefaults checks and sets configuration values for the MasterConfiguration object
|
// SetInitDynamicDefaults checks and sets configuration values for the MasterConfiguration object
|
||||||
func SetInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
func SetInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
||||||
|
|
||||||
|
// Default all the embedded ComponentConfig structs
|
||||||
|
componentconfigs.Known.Default(cfg)
|
||||||
|
|
||||||
// validate cfg.API.AdvertiseAddress.
|
// validate cfg.API.AdvertiseAddress.
|
||||||
addressIP := net.ParseIP(cfg.API.AdvertiseAddress)
|
addressIP := net.ParseIP(cfg.API.AdvertiseAddress)
|
||||||
if addressIP == nil && cfg.API.AdvertiseAddress != "" {
|
if addressIP == nil && cfg.API.AdvertiseAddress != "" {
|
||||||
@ -115,7 +124,7 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *
|
|||||||
return BytesToInternalConfig(b)
|
return BytesToInternalConfig(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes passed flags into account; the defaulting is executed once again enforcing assignement of
|
// Takes passed flags into account; the defaulting is executed once again enforcing assignment of
|
||||||
// static default values to cfg only for values not provided with flags
|
// static default values to cfg only for values not provided with flags
|
||||||
kubeadmscheme.Scheme.Default(defaultversionedcfg)
|
kubeadmscheme.Scheme.Default(defaultversionedcfg)
|
||||||
kubeadmscheme.Scheme.Convert(defaultversionedcfg, internalcfg, nil)
|
kubeadmscheme.Scheme.Convert(defaultversionedcfg, internalcfg, nil)
|
||||||
@ -123,18 +132,65 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *
|
|||||||
return defaultAndValidate(internalcfg)
|
return defaultAndValidate(internalcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BytesToInternalConfig converts a byte array to an internal, defaulted and validated configuration object
|
// BytesToInternalConfig converts a byte slice to an internal, defaulted and validated configuration object.
|
||||||
|
// The byte slice may contain one or many different YAML documents. These YAML documents are parsed one-by-one
|
||||||
|
// and well-known ComponentConfig GroupVersionKinds are stored inside of the internal MasterConfiguration struct
|
||||||
func BytesToInternalConfig(b []byte) (*kubeadmapi.MasterConfiguration, error) {
|
func BytesToInternalConfig(b []byte) (*kubeadmapi.MasterConfiguration, error) {
|
||||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||||
|
decodedObjs := map[componentconfigs.RegistrationKind]runtime.Object{}
|
||||||
|
masterConfigFound := false
|
||||||
|
|
||||||
if err := DetectUnsupportedVersion(b); err != nil {
|
if err := DetectUnsupportedVersion(b); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), b, internalcfg); err != nil {
|
gvkmap, err := kubeadmutil.SplitYAMLDocuments(b)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for gvk, fileContent := range gvkmap {
|
||||||
|
// Try to get the registration for the ComponentConfig based on the kind
|
||||||
|
regKind := componentconfigs.RegistrationKind(gvk.Kind)
|
||||||
|
registration, found := componentconfigs.Known[regKind]
|
||||||
|
if found {
|
||||||
|
// Unmarshal the bytes from the YAML document into a runtime.Object containing the ComponentConfiguration struct
|
||||||
|
obj, err := registration.Unmarshal(fileContent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
decodedObjs[regKind] = obj
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if gvk.Kind == kubeadmconstants.MasterConfigurationKind {
|
||||||
|
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, internalcfg); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
masterConfigFound = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[config] WARNING: Ignored YAML document with GroupVersionKind %v\n", gvk)
|
||||||
|
}
|
||||||
|
// Just as an extra safety check, don't proceed if a MasterConfiguration object wasn't found
|
||||||
|
if !masterConfigFound {
|
||||||
|
return nil, fmt.Errorf("no MasterConfiguration kind was found in the YAML file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the loaded ComponentConfig objects in the internalcfg object
|
||||||
|
for kind, obj := range decodedObjs {
|
||||||
|
registration, found := componentconfigs.Known[kind]
|
||||||
|
if found {
|
||||||
|
if ok := registration.SetToInternalConfig(obj, internalcfg); !ok {
|
||||||
|
return nil, fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This should never happen in practice
|
||||||
|
fmt.Printf("[config] WARNING: Decoded a kind that couldn't be saved to the internal configuration: %q\n", string(kind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return defaultAndValidate(internalcfg)
|
return defaultAndValidate(internalcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,5 +203,80 @@ func defaultAndValidate(cfg *kubeadmapi.MasterConfiguration) (*kubeadmapi.Master
|
|||||||
if err := validation.ValidateMasterConfiguration(cfg).ToAggregate(); err != nil {
|
if err := validation.ValidateMasterConfiguration(cfg).ToAggregate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func defaultedInternalConfig() *kubeadmapi.MasterConfiguration {
|
||||||
|
externalcfg := &kubeadmapiv1alpha3.MasterConfiguration{}
|
||||||
|
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||||
|
|
||||||
|
kubeadmscheme.Scheme.Default(externalcfg)
|
||||||
|
kubeadmscheme.Scheme.Convert(externalcfg, internalcfg, nil)
|
||||||
|
|
||||||
|
// Default the embedded ComponentConfig structs
|
||||||
|
componentconfigs.Known.Default(internalcfg)
|
||||||
|
return internalcfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalMasterConfigurationToBytes marshals the internal MasterConfiguration object to bytes. It writes the embedded
|
||||||
|
// ComponentConfiguration objects out as separate YAML documents
|
||||||
|
func MarshalMasterConfigurationToBytes(cfg *kubeadmapi.MasterConfiguration, gv schema.GroupVersion) ([]byte, error) {
|
||||||
|
masterbytes, err := kubeadmutil.MarshalToYamlForCodecs(cfg, gv, kubeadmscheme.Codecs)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
allFiles := [][]byte{masterbytes}
|
||||||
|
componentConfigContent := map[string][]byte{}
|
||||||
|
|
||||||
|
// If the specified groupversion is targeting the internal type, don't print the extra componentconfig YAML documents
|
||||||
|
if gv.Version != runtime.APIVersionInternal {
|
||||||
|
|
||||||
|
defaultedcfg := defaultedInternalConfig()
|
||||||
|
|
||||||
|
for kind, registration := range componentconfigs.Known {
|
||||||
|
// If the ComponentConfig struct for the current registration is nil, skip it when marshalling
|
||||||
|
realobj, ok := registration.GetFromInternalConfig(cfg)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg)
|
||||||
|
// Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference
|
||||||
|
if !ok {
|
||||||
|
return []byte{}, fmt.Errorf("couldn't create a default componentconfig object")
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it
|
||||||
|
if !reflect.DeepEqual(realobj, defaultedobj) {
|
||||||
|
contentBytes, err := registration.Marshal(realobj)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
componentConfigContent[string(kind)] = contentBytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the ComponentConfig files by kind when marshalling
|
||||||
|
sortedComponentConfigFiles := consistentOrderByteSlice(componentConfigContent)
|
||||||
|
allFiles = append(allFiles, sortedComponentConfigFiles...)
|
||||||
|
return bytes.Join(allFiles, []byte(kubeadmconstants.YAMLDocumentSeparator)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// consistentOrderByteSlice takes a map of a string key and a byte slice, and returns a byte slice of byte slices
|
||||||
|
// with consistent ordering, where the keys in the map determine the ordering of the return value. This has to be
|
||||||
|
// done as the order of a for...range loop over a map in go is undeterministic, and could otherwise lead to flakes
|
||||||
|
// in e.g. unit tests when marshalling content with a random order
|
||||||
|
func consistentOrderByteSlice(content map[string][]byte) [][]byte {
|
||||||
|
keys := []string{}
|
||||||
|
sortedContent := [][]byte{}
|
||||||
|
for key := range content {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
for _, key := range keys {
|
||||||
|
sortedContent = append(sortedContent, content[key])
|
||||||
|
}
|
||||||
|
return sortedContent
|
||||||
|
}
|
||||||
|
@ -19,15 +19,14 @@ package config
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pmezard/go-difflib/difflib"
|
"github.com/pmezard/go-difflib/difflib"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -87,7 +86,7 @@ func TestConfigFileAndDefaultsToInternalConfig(t *testing.T) {
|
|||||||
// These tests are reading one file that has only a subset of the fields populated, loading it using ConfigFileAndDefaultsToInternalConfig,
|
// These tests are reading one file that has only a subset of the fields populated, loading it using ConfigFileAndDefaultsToInternalConfig,
|
||||||
// and then marshals the internal object to the expected groupVersion
|
// and then marshals the internal object to the expected groupVersion
|
||||||
{ // v1alpha2 -> default -> validate -> internal -> v1alpha3
|
{ // v1alpha2 -> default -> validate -> internal -> v1alpha3
|
||||||
name: "incompleteYAMLToDefaultedv1alpha2",
|
name: "incompleteYAMLToDefaultedv1alpha3",
|
||||||
in: master_incompleteYAML,
|
in: master_incompleteYAML,
|
||||||
out: master_defaultedYAML,
|
out: master_defaultedYAML,
|
||||||
groupVersion: kubeadmapiv1alpha3.SchemeGroupVersion,
|
groupVersion: kubeadmapiv1alpha3.SchemeGroupVersion,
|
||||||
@ -110,7 +109,7 @@ func TestConfigFileAndDefaultsToInternalConfig(t *testing.T) {
|
|||||||
t2.Fatalf("couldn't unmarshal test data: %v", err)
|
t2.Fatalf("couldn't unmarshal test data: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual, err := kubeadmutil.MarshalToYamlForCodecs(internalcfg, rt.groupVersion, scheme.Codecs)
|
actual, err := MarshalMasterConfigurationToBytes(internalcfg, rt.groupVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t2.Fatalf("couldn't marshal internal object: %v", err)
|
t2.Fatalf("couldn't marshal internal object: %v", err)
|
||||||
}
|
}
|
||||||
@ -127,3 +126,92 @@ func TestConfigFileAndDefaultsToInternalConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConsistentOrderByteSlice(t *testing.T) {
|
||||||
|
var (
|
||||||
|
aKind = "Akind"
|
||||||
|
aFile = []byte(`
|
||||||
|
kind: Akind
|
||||||
|
apiVersion: foo.k8s.io/v1
|
||||||
|
`)
|
||||||
|
aaKind = "Aakind"
|
||||||
|
aaFile = []byte(`
|
||||||
|
kind: Aakind
|
||||||
|
apiVersion: foo.k8s.io/v1
|
||||||
|
`)
|
||||||
|
abKind = "Abkind"
|
||||||
|
abFile = []byte(`
|
||||||
|
kind: Abkind
|
||||||
|
apiVersion: foo.k8s.io/v1
|
||||||
|
`)
|
||||||
|
)
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
in map[string][]byte
|
||||||
|
expected [][]byte
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "a_aa_ab",
|
||||||
|
in: map[string][]byte{
|
||||||
|
aKind: aFile,
|
||||||
|
aaKind: aaFile,
|
||||||
|
abKind: abFile,
|
||||||
|
},
|
||||||
|
expected: [][]byte{aaFile, abFile, aFile},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "a_ab_aa",
|
||||||
|
in: map[string][]byte{
|
||||||
|
aKind: aFile,
|
||||||
|
abKind: abFile,
|
||||||
|
aaKind: aaFile,
|
||||||
|
},
|
||||||
|
expected: [][]byte{aaFile, abFile, aFile},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aa_a_ab",
|
||||||
|
in: map[string][]byte{
|
||||||
|
aaKind: aaFile,
|
||||||
|
aKind: aFile,
|
||||||
|
abKind: abFile,
|
||||||
|
},
|
||||||
|
expected: [][]byte{aaFile, abFile, aFile},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aa_ab_a",
|
||||||
|
in: map[string][]byte{
|
||||||
|
aaKind: aaFile,
|
||||||
|
abKind: abFile,
|
||||||
|
aKind: aFile,
|
||||||
|
},
|
||||||
|
expected: [][]byte{aaFile, abFile, aFile},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ab_a_aa",
|
||||||
|
in: map[string][]byte{
|
||||||
|
abKind: abFile,
|
||||||
|
aKind: aFile,
|
||||||
|
aaKind: aaFile,
|
||||||
|
},
|
||||||
|
expected: [][]byte{aaFile, abFile, aFile},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ab_aa_a",
|
||||||
|
in: map[string][]byte{
|
||||||
|
abKind: abFile,
|
||||||
|
aaKind: aaFile,
|
||||||
|
aKind: aFile,
|
||||||
|
},
|
||||||
|
expected: [][]byte{aaFile, abFile, aFile},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rt := range tests {
|
||||||
|
t.Run(rt.name, func(t2 *testing.T) {
|
||||||
|
actual := consistentOrderByteSlice(rt.in)
|
||||||
|
if !reflect.DeepEqual(rt.expected, actual) {
|
||||||
|
t2.Errorf("the expected and actual output differs.\n\texpected: %s\n\tout: %s\n", rt.expected, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -25,116 +25,6 @@ etcd:
|
|||||||
image: ""
|
image: ""
|
||||||
imageRepository: k8s.gcr.io
|
imageRepository: k8s.gcr.io
|
||||||
kind: MasterConfiguration
|
kind: MasterConfiguration
|
||||||
kubeProxy:
|
|
||||||
config:
|
|
||||||
bindAddress: 0.0.0.0
|
|
||||||
clientConnection:
|
|
||||||
acceptContentTypes: ""
|
|
||||||
burst: 10
|
|
||||||
contentType: application/vnd.kubernetes.protobuf
|
|
||||||
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
|
|
||||||
qps: 5
|
|
||||||
clusterCIDR: ""
|
|
||||||
configSyncPeriod: 15m0s
|
|
||||||
conntrack:
|
|
||||||
max: null
|
|
||||||
maxPerCore: 32768
|
|
||||||
min: 131072
|
|
||||||
tcpCloseWaitTimeout: 1h0m0s
|
|
||||||
tcpEstablishedTimeout: 24h0m0s
|
|
||||||
enableProfiling: false
|
|
||||||
featureGates:
|
|
||||||
ServiceNodeExclusion: true
|
|
||||||
SupportIPVSProxyMode: true
|
|
||||||
healthzBindAddress: 0.0.0.0:10256
|
|
||||||
hostnameOverride: ""
|
|
||||||
iptables:
|
|
||||||
masqueradeAll: false
|
|
||||||
masqueradeBit: 14
|
|
||||||
minSyncPeriod: 0s
|
|
||||||
syncPeriod: 30s
|
|
||||||
ipvs:
|
|
||||||
excludeCIDRs: null
|
|
||||||
minSyncPeriod: 0s
|
|
||||||
scheduler: ""
|
|
||||||
syncPeriod: 30s
|
|
||||||
metricsBindAddress: 127.0.0.1:10249
|
|
||||||
mode: iptables
|
|
||||||
nodePortAddresses: null
|
|
||||||
oomScoreAdj: -999
|
|
||||||
portRange: ""
|
|
||||||
resourceContainer: /kube-proxy
|
|
||||||
udpIdleTimeout: 250ms
|
|
||||||
kubeletConfiguration:
|
|
||||||
baseConfig:
|
|
||||||
address: 1.2.3.4
|
|
||||||
authentication:
|
|
||||||
anonymous:
|
|
||||||
enabled: false
|
|
||||||
webhook:
|
|
||||||
cacheTTL: 2m0s
|
|
||||||
enabled: true
|
|
||||||
x509:
|
|
||||||
clientCAFile: /etc/kubernetes/pki/ca.crt
|
|
||||||
authorization:
|
|
||||||
mode: Webhook
|
|
||||||
webhook:
|
|
||||||
cacheAuthorizedTTL: 5m0s
|
|
||||||
cacheUnauthorizedTTL: 30s
|
|
||||||
cgroupDriver: cgroupfs
|
|
||||||
cgroupsPerQOS: true
|
|
||||||
clusterDNS:
|
|
||||||
- 10.96.0.10
|
|
||||||
clusterDomain: cluster.local
|
|
||||||
configMapAndSecretChangeDetectionStrategy: Watch
|
|
||||||
containerLogMaxFiles: 5
|
|
||||||
containerLogMaxSize: 10Mi
|
|
||||||
contentType: application/vnd.kubernetes.protobuf
|
|
||||||
cpuCFSQuota: true
|
|
||||||
cpuManagerPolicy: none
|
|
||||||
cpuManagerReconcilePeriod: 10s
|
|
||||||
enableControllerAttachDetach: true
|
|
||||||
enableDebuggingHandlers: true
|
|
||||||
enforceNodeAllocatable:
|
|
||||||
- pods
|
|
||||||
eventBurst: 10
|
|
||||||
eventRecordQPS: 5
|
|
||||||
evictionHard:
|
|
||||||
imagefs.available: 15%
|
|
||||||
memory.available: 100Mi
|
|
||||||
nodefs.available: 10%
|
|
||||||
nodefs.inodesFree: 5%
|
|
||||||
evictionPressureTransitionPeriod: 5m0s
|
|
||||||
failSwapOn: true
|
|
||||||
fileCheckFrequency: 20s
|
|
||||||
hairpinMode: promiscuous-bridge
|
|
||||||
healthzBindAddress: 127.0.0.1
|
|
||||||
healthzPort: 10248
|
|
||||||
httpCheckFrequency: 20s
|
|
||||||
imageGCHighThresholdPercent: 85
|
|
||||||
imageGCLowThresholdPercent: 80
|
|
||||||
imageMinimumGCAge: 2m0s
|
|
||||||
iptablesDropBit: 15
|
|
||||||
iptablesMasqueradeBit: 14
|
|
||||||
kubeAPIBurst: 10
|
|
||||||
kubeAPIQPS: 5
|
|
||||||
makeIPTablesUtilChains: true
|
|
||||||
maxOpenFiles: 1000000
|
|
||||||
maxPods: 110
|
|
||||||
nodeStatusUpdateFrequency: 10s
|
|
||||||
oomScoreAdj: -999
|
|
||||||
podPidsLimit: -1
|
|
||||||
port: 10250
|
|
||||||
registryBurst: 10
|
|
||||||
registryPullQPS: 5
|
|
||||||
resolvConf: /etc/resolv.conf
|
|
||||||
rotateCertificates: true
|
|
||||||
runtimeRequestTimeout: 2m0s
|
|
||||||
serializeImagePulls: true
|
|
||||||
staticPodPath: /etc/kubernetes/manifests
|
|
||||||
streamingConnectionIdleTimeout: 4h0m0s
|
|
||||||
syncFrequency: 1m0s
|
|
||||||
volumeStatsAggPeriod: 1m0s
|
|
||||||
kubernetesVersion: v1.10.2
|
kubernetesVersion: v1.10.2
|
||||||
networking:
|
networking:
|
||||||
dnsDomain: cluster.local
|
dnsDomain: cluster.local
|
||||||
@ -147,3 +37,115 @@ nodeRegistration:
|
|||||||
- effect: NoSchedule
|
- effect: NoSchedule
|
||||||
key: node-role.kubernetes.io/master
|
key: node-role.kubernetes.io/master
|
||||||
unifiedControlPlaneImage: ""
|
unifiedControlPlaneImage: ""
|
||||||
|
---
|
||||||
|
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||||
|
bindAddress: 0.0.0.0
|
||||||
|
clientConnection:
|
||||||
|
acceptContentTypes: ""
|
||||||
|
burst: 10
|
||||||
|
contentType: application/vnd.kubernetes.protobuf
|
||||||
|
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
|
||||||
|
qps: 5
|
||||||
|
clusterCIDR: ""
|
||||||
|
configSyncPeriod: 15m0s
|
||||||
|
conntrack:
|
||||||
|
max: null
|
||||||
|
maxPerCore: 32768
|
||||||
|
min: 131072
|
||||||
|
tcpCloseWaitTimeout: 1h0m0s
|
||||||
|
tcpEstablishedTimeout: 24h0m0s
|
||||||
|
enableProfiling: false
|
||||||
|
featureGates:
|
||||||
|
ServiceNodeExclusion: true
|
||||||
|
SupportIPVSProxyMode: true
|
||||||
|
healthzBindAddress: 0.0.0.0:10256
|
||||||
|
hostnameOverride: ""
|
||||||
|
iptables:
|
||||||
|
masqueradeAll: false
|
||||||
|
masqueradeBit: 14
|
||||||
|
minSyncPeriod: 0s
|
||||||
|
syncPeriod: 30s
|
||||||
|
ipvs:
|
||||||
|
excludeCIDRs: null
|
||||||
|
minSyncPeriod: 0s
|
||||||
|
scheduler: ""
|
||||||
|
syncPeriod: 30s
|
||||||
|
kind: KubeProxyConfiguration
|
||||||
|
metricsBindAddress: 127.0.0.1:10249
|
||||||
|
mode: iptables
|
||||||
|
nodePortAddresses: null
|
||||||
|
oomScoreAdj: -999
|
||||||
|
portRange: ""
|
||||||
|
resourceContainer: /kube-proxy
|
||||||
|
udpIdleTimeout: 250ms
|
||||||
|
---
|
||||||
|
address: 1.2.3.4
|
||||||
|
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||||
|
authentication:
|
||||||
|
anonymous:
|
||||||
|
enabled: false
|
||||||
|
webhook:
|
||||||
|
cacheTTL: 2m0s
|
||||||
|
enabled: true
|
||||||
|
x509:
|
||||||
|
clientCAFile: /etc/kubernetes/pki/ca.crt
|
||||||
|
authorization:
|
||||||
|
mode: Webhook
|
||||||
|
webhook:
|
||||||
|
cacheAuthorizedTTL: 5m0s
|
||||||
|
cacheUnauthorizedTTL: 30s
|
||||||
|
cgroupDriver: cgroupfs
|
||||||
|
cgroupsPerQOS: true
|
||||||
|
clusterDNS:
|
||||||
|
- 10.96.0.10
|
||||||
|
clusterDomain: cluster.local
|
||||||
|
configMapAndSecretChangeDetectionStrategy: Watch
|
||||||
|
containerLogMaxFiles: 5
|
||||||
|
containerLogMaxSize: 10Mi
|
||||||
|
contentType: application/vnd.kubernetes.protobuf
|
||||||
|
cpuCFSQuota: true
|
||||||
|
cpuManagerPolicy: none
|
||||||
|
cpuManagerReconcilePeriod: 10s
|
||||||
|
enableControllerAttachDetach: true
|
||||||
|
enableDebuggingHandlers: true
|
||||||
|
enforceNodeAllocatable:
|
||||||
|
- pods
|
||||||
|
eventBurst: 10
|
||||||
|
eventRecordQPS: 5
|
||||||
|
evictionHard:
|
||||||
|
imagefs.available: 15%
|
||||||
|
memory.available: 100Mi
|
||||||
|
nodefs.available: 10%
|
||||||
|
nodefs.inodesFree: 5%
|
||||||
|
evictionPressureTransitionPeriod: 5m0s
|
||||||
|
failSwapOn: true
|
||||||
|
fileCheckFrequency: 20s
|
||||||
|
hairpinMode: promiscuous-bridge
|
||||||
|
healthzBindAddress: 127.0.0.1
|
||||||
|
healthzPort: 10248
|
||||||
|
httpCheckFrequency: 20s
|
||||||
|
imageGCHighThresholdPercent: 85
|
||||||
|
imageGCLowThresholdPercent: 80
|
||||||
|
imageMinimumGCAge: 2m0s
|
||||||
|
iptablesDropBit: 15
|
||||||
|
iptablesMasqueradeBit: 14
|
||||||
|
kind: KubeletConfiguration
|
||||||
|
kubeAPIBurst: 10
|
||||||
|
kubeAPIQPS: 5
|
||||||
|
makeIPTablesUtilChains: true
|
||||||
|
maxOpenFiles: 1000000
|
||||||
|
maxPods: 110
|
||||||
|
nodeStatusUpdateFrequency: 10s
|
||||||
|
oomScoreAdj: -999
|
||||||
|
podPidsLimit: -1
|
||||||
|
port: 10250
|
||||||
|
registryBurst: 10
|
||||||
|
registryPullQPS: 5
|
||||||
|
resolvConf: /etc/resolv.conf
|
||||||
|
rotateCertificates: true
|
||||||
|
runtimeRequestTimeout: 2m0s
|
||||||
|
serializeImagePulls: true
|
||||||
|
staticPodPath: /etc/kubernetes/manifests
|
||||||
|
streamingConnectionIdleTimeout: 4h0m0s
|
||||||
|
syncFrequency: 1m0s
|
||||||
|
volumeStatsAggPeriod: 1m0s
|
||||||
|
@ -23,117 +23,10 @@ etcd:
|
|||||||
image: ""
|
image: ""
|
||||||
imageRepository: my-company.com
|
imageRepository: my-company.com
|
||||||
kind: MasterConfiguration
|
kind: MasterConfiguration
|
||||||
kubeProxy:
|
|
||||||
config:
|
|
||||||
bindAddress: 0.0.0.0
|
|
||||||
clientConnection:
|
|
||||||
acceptContentTypes: ""
|
|
||||||
burst: 10
|
|
||||||
contentType: application/vnd.kubernetes.protobuf
|
|
||||||
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
|
|
||||||
qps: 5
|
|
||||||
clusterCIDR: ""
|
|
||||||
configSyncPeriod: 15m0s
|
|
||||||
conntrack:
|
|
||||||
max: null
|
|
||||||
maxPerCore: 32768
|
|
||||||
min: 131072
|
|
||||||
tcpCloseWaitTimeout: 1h0m0s
|
|
||||||
tcpEstablishedTimeout: 24h0m0s
|
|
||||||
enableProfiling: false
|
|
||||||
healthzBindAddress: 0.0.0.0:10256
|
|
||||||
hostnameOverride: ""
|
|
||||||
iptables:
|
|
||||||
masqueradeAll: false
|
|
||||||
masqueradeBit: 14
|
|
||||||
minSyncPeriod: 0s
|
|
||||||
syncPeriod: 30s
|
|
||||||
ipvs:
|
|
||||||
excludeCIDRs: null
|
|
||||||
minSyncPeriod: 0s
|
|
||||||
scheduler: ""
|
|
||||||
syncPeriod: 30s
|
|
||||||
metricsBindAddress: 127.0.0.1:10249
|
|
||||||
mode: ""
|
|
||||||
nodePortAddresses: null
|
|
||||||
oomScoreAdj: -999
|
|
||||||
portRange: ""
|
|
||||||
resourceContainer: /kube-proxy
|
|
||||||
udpIdleTimeout: 250ms
|
|
||||||
kubeletConfiguration:
|
|
||||||
baseConfig:
|
|
||||||
address: 0.0.0.0
|
|
||||||
authentication:
|
|
||||||
anonymous:
|
|
||||||
enabled: false
|
|
||||||
webhook:
|
|
||||||
cacheTTL: 2m0s
|
|
||||||
enabled: true
|
|
||||||
x509:
|
|
||||||
clientCAFile: /etc/kubernetes/pki/ca.crt
|
|
||||||
authorization:
|
|
||||||
mode: Webhook
|
|
||||||
webhook:
|
|
||||||
cacheAuthorizedTTL: 5m0s
|
|
||||||
cacheUnauthorizedTTL: 30s
|
|
||||||
cgroupDriver: cgroupfs
|
|
||||||
cgroupsPerQOS: true
|
|
||||||
clusterDNS:
|
|
||||||
- 10.192.0.10
|
|
||||||
clusterDomain: cluster.global
|
|
||||||
configMapAndSecretChangeDetectionStrategy: Watch
|
|
||||||
containerLogMaxFiles: 5
|
|
||||||
containerLogMaxSize: 10Mi
|
|
||||||
contentType: application/vnd.kubernetes.protobuf
|
|
||||||
cpuCFSQuota: true
|
|
||||||
cpuManagerPolicy: none
|
|
||||||
cpuManagerReconcilePeriod: 10s
|
|
||||||
enableControllerAttachDetach: true
|
|
||||||
enableDebuggingHandlers: true
|
|
||||||
enforceNodeAllocatable:
|
|
||||||
- pods
|
|
||||||
eventBurst: 10
|
|
||||||
eventRecordQPS: 5
|
|
||||||
evictionHard:
|
|
||||||
imagefs.available: 15%
|
|
||||||
memory.available: 100Mi
|
|
||||||
nodefs.available: 10%
|
|
||||||
nodefs.inodesFree: 5%
|
|
||||||
evictionPressureTransitionPeriod: 5m0s
|
|
||||||
failSwapOn: true
|
|
||||||
fileCheckFrequency: 20s
|
|
||||||
hairpinMode: promiscuous-bridge
|
|
||||||
healthzBindAddress: 127.0.0.1
|
|
||||||
healthzPort: 10248
|
|
||||||
httpCheckFrequency: 20s
|
|
||||||
imageGCHighThresholdPercent: 85
|
|
||||||
imageGCLowThresholdPercent: 80
|
|
||||||
imageMinimumGCAge: 2m0s
|
|
||||||
iptablesDropBit: 15
|
|
||||||
iptablesMasqueradeBit: 14
|
|
||||||
kubeAPIBurst: 10
|
|
||||||
kubeAPIQPS: 5
|
|
||||||
makeIPTablesUtilChains: true
|
|
||||||
maxOpenFiles: 1000000
|
|
||||||
maxPods: 110
|
|
||||||
nodeStatusUpdateFrequency: 10s
|
|
||||||
oomScoreAdj: -999
|
|
||||||
podPidsLimit: -1
|
|
||||||
port: 10250
|
|
||||||
registryBurst: 10
|
|
||||||
registryPullQPS: 5
|
|
||||||
resolvConf: /etc/resolv.conf
|
|
||||||
rotateCertificates: true
|
|
||||||
runtimeRequestTimeout: 2m0s
|
|
||||||
serializeImagePulls: true
|
|
||||||
staticPodPath: /etc/kubernetes/manifests
|
|
||||||
streamingConnectionIdleTimeout: 4h0m0s
|
|
||||||
syncFrequency: 1m0s
|
|
||||||
volumeStatsAggPeriod: 1m0s
|
|
||||||
kubernetesVersion: v1.10.2
|
kubernetesVersion: v1.10.2
|
||||||
networking:
|
networking:
|
||||||
dnsDomain: cluster.global
|
dnsDomain: cluster.global
|
||||||
podSubnet: ""
|
podSubnet: 10.148.0.0/16
|
||||||
serviceSubnet: 10.196.0.0/12
|
serviceSubnet: 10.196.0.0/12
|
||||||
nodeRegistration:
|
nodeRegistration:
|
||||||
criSocket: /var/run/criruntime.sock
|
criSocket: /var/run/criruntime.sock
|
||||||
@ -142,3 +35,112 @@ nodeRegistration:
|
|||||||
- effect: NoSchedule
|
- effect: NoSchedule
|
||||||
key: node-role.kubernetes.io/master
|
key: node-role.kubernetes.io/master
|
||||||
unifiedControlPlaneImage: ""
|
unifiedControlPlaneImage: ""
|
||||||
|
---
|
||||||
|
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||||
|
bindAddress: 0.0.0.0
|
||||||
|
clientConnection:
|
||||||
|
acceptContentTypes: ""
|
||||||
|
burst: 10
|
||||||
|
contentType: application/vnd.kubernetes.protobuf
|
||||||
|
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
|
||||||
|
qps: 5
|
||||||
|
clusterCIDR: 10.148.0.0/16
|
||||||
|
configSyncPeriod: 15m0s
|
||||||
|
conntrack:
|
||||||
|
max: null
|
||||||
|
maxPerCore: 32768
|
||||||
|
min: 131072
|
||||||
|
tcpCloseWaitTimeout: 1h0m0s
|
||||||
|
tcpEstablishedTimeout: 24h0m0s
|
||||||
|
enableProfiling: false
|
||||||
|
healthzBindAddress: 0.0.0.0:10256
|
||||||
|
hostnameOverride: ""
|
||||||
|
iptables:
|
||||||
|
masqueradeAll: false
|
||||||
|
masqueradeBit: 14
|
||||||
|
minSyncPeriod: 0s
|
||||||
|
syncPeriod: 30s
|
||||||
|
ipvs:
|
||||||
|
excludeCIDRs: null
|
||||||
|
minSyncPeriod: 0s
|
||||||
|
scheduler: ""
|
||||||
|
syncPeriod: 30s
|
||||||
|
kind: KubeProxyConfiguration
|
||||||
|
metricsBindAddress: 127.0.0.1:10249
|
||||||
|
mode: ""
|
||||||
|
nodePortAddresses: null
|
||||||
|
oomScoreAdj: -999
|
||||||
|
portRange: ""
|
||||||
|
resourceContainer: /kube-proxy
|
||||||
|
udpIdleTimeout: 250ms
|
||||||
|
---
|
||||||
|
address: 0.0.0.0
|
||||||
|
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||||
|
authentication:
|
||||||
|
anonymous:
|
||||||
|
enabled: false
|
||||||
|
webhook:
|
||||||
|
cacheTTL: 2m0s
|
||||||
|
enabled: true
|
||||||
|
x509:
|
||||||
|
clientCAFile: /etc/kubernetes/pki/ca.crt
|
||||||
|
authorization:
|
||||||
|
mode: Webhook
|
||||||
|
webhook:
|
||||||
|
cacheAuthorizedTTL: 5m0s
|
||||||
|
cacheUnauthorizedTTL: 30s
|
||||||
|
cgroupDriver: cgroupfs
|
||||||
|
cgroupsPerQOS: true
|
||||||
|
clusterDNS:
|
||||||
|
- 10.192.0.10
|
||||||
|
clusterDomain: cluster.global
|
||||||
|
configMapAndSecretChangeDetectionStrategy: Watch
|
||||||
|
containerLogMaxFiles: 5
|
||||||
|
containerLogMaxSize: 10Mi
|
||||||
|
contentType: application/vnd.kubernetes.protobuf
|
||||||
|
cpuCFSQuota: true
|
||||||
|
cpuManagerPolicy: none
|
||||||
|
cpuManagerReconcilePeriod: 10s
|
||||||
|
enableControllerAttachDetach: true
|
||||||
|
enableDebuggingHandlers: true
|
||||||
|
enforceNodeAllocatable:
|
||||||
|
- pods
|
||||||
|
eventBurst: 10
|
||||||
|
eventRecordQPS: 5
|
||||||
|
evictionHard:
|
||||||
|
imagefs.available: 15%
|
||||||
|
memory.available: 100Mi
|
||||||
|
nodefs.available: 10%
|
||||||
|
nodefs.inodesFree: 5%
|
||||||
|
evictionPressureTransitionPeriod: 5m0s
|
||||||
|
failSwapOn: true
|
||||||
|
fileCheckFrequency: 20s
|
||||||
|
hairpinMode: promiscuous-bridge
|
||||||
|
healthzBindAddress: 127.0.0.1
|
||||||
|
healthzPort: 10248
|
||||||
|
httpCheckFrequency: 20s
|
||||||
|
imageGCHighThresholdPercent: 85
|
||||||
|
imageGCLowThresholdPercent: 80
|
||||||
|
imageMinimumGCAge: 2m0s
|
||||||
|
iptablesDropBit: 15
|
||||||
|
iptablesMasqueradeBit: 14
|
||||||
|
kind: KubeletConfiguration
|
||||||
|
kubeAPIBurst: 10
|
||||||
|
kubeAPIQPS: 5
|
||||||
|
makeIPTablesUtilChains: true
|
||||||
|
maxOpenFiles: 1000000
|
||||||
|
maxPods: 110
|
||||||
|
nodeStatusUpdateFrequency: 10s
|
||||||
|
oomScoreAdj: -999
|
||||||
|
podPidsLimit: -1
|
||||||
|
port: 10250
|
||||||
|
registryBurst: 10
|
||||||
|
registryPullQPS: 5
|
||||||
|
resolvConf: /etc/resolv.conf
|
||||||
|
rotateCertificates: true
|
||||||
|
runtimeRequestTimeout: 2m0s
|
||||||
|
serializeImagePulls: true
|
||||||
|
staticPodPath: /etc/kubernetes/manifests
|
||||||
|
streamingConnectionIdleTimeout: 4h0m0s
|
||||||
|
syncFrequency: 1m0s
|
||||||
|
volumeStatsAggPeriod: 1m0s
|
||||||
|
@ -12,6 +12,7 @@ kubernetesVersion: v1.10.2
|
|||||||
networking:
|
networking:
|
||||||
dnsDomain: cluster.global
|
dnsDomain: cluster.global
|
||||||
serviceSubnet: 10.196.0.0/12
|
serviceSubnet: 10.196.0.0/12
|
||||||
|
podSubnet: 10.148.0.0/16
|
||||||
nodeRegistration:
|
nodeRegistration:
|
||||||
criSocket: /var/run/criruntime.sock
|
criSocket: /var/run/criruntime.sock
|
||||||
name: master-1
|
name: master-1
|
||||||
|
@ -24,8 +24,9 @@ import (
|
|||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
)
|
)
|
||||||
@ -125,16 +126,25 @@ func TestMarshalUnmarshalToYamlForCodecs(t *testing.T) {
|
|||||||
ServiceSubnet: "10.100.0.0/24",
|
ServiceSubnet: "10.100.0.0/24",
|
||||||
PodSubnet: "10.100.1.0/24",
|
PodSubnet: "10.100.1.0/24",
|
||||||
},
|
},
|
||||||
|
BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{
|
||||||
|
{
|
||||||
|
Token: &kubeadmapiv1alpha3.BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
scheme.Scheme.Default(cfg)
|
|
||||||
|
|
||||||
bytes, err := MarshalToYamlForCodecs(cfg, kubeadmapiv1alpha3.SchemeGroupVersion, scheme.Codecs)
|
kubeadmapiv1alpha3.SetDefaults_MasterConfiguration(cfg)
|
||||||
|
scheme := runtime.NewScheme()
|
||||||
|
kubeadmapiv1alpha3.AddToScheme(scheme)
|
||||||
|
codecs := serializer.NewCodecFactory(scheme)
|
||||||
|
|
||||||
|
bytes, err := MarshalToYamlForCodecs(cfg, kubeadmapiv1alpha3.SchemeGroupVersion, codecs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error marshalling MasterConfiguration: %v", err)
|
t.Fatalf("unexpected error marshalling MasterConfiguration: %v", err)
|
||||||
}
|
}
|
||||||
t.Logf("\n%s", bytes)
|
t.Logf("\n%s", bytes)
|
||||||
|
|
||||||
obj, err := UnmarshalFromYamlForCodecs(bytes, kubeadmapiv1alpha3.SchemeGroupVersion, scheme.Codecs)
|
obj, err := UnmarshalFromYamlForCodecs(bytes, kubeadmapiv1alpha3.SchemeGroupVersion, codecs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error unmarshalling MasterConfiguration: %v", err)
|
t.Fatalf("unexpected error unmarshalling MasterConfiguration: %v", err)
|
||||||
}
|
}
|
||||||
@ -148,6 +158,12 @@ func TestMarshalUnmarshalToYamlForCodecs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {{MasterConfiguration kubeadm.k8s.io/v1alpha3} [{<nil> nil <nil> [] []}] {testNode /var/run/cri.sock [] map[]} {10.100.0.1 4332} {0xc4200ad2c0 <nil>} {10.100.0.0/24 10.100.1.0/24 cluster.local} stable-1.11 map[] map[] map[] [] [] [] [] /etc/kubernetes/pki k8s.gcr.io { /var/log/kubernetes/audit 0x156e2f4} map[] kubernetes}
|
||||||
|
// {{MasterConfiguration kubeadm.k8s.io/v1alpha3} [{<nil> &Duration{Duration:24h0m0s,} <nil> [signing authentication] [system:bootstrappers:kubeadm:default-node-token]}] {testNode /var/run/cri.sock [] map[]} {10.100.0.1 4332} {0xc4205c5260 <nil>} {10.100.0.0/24 10.100.1.0/24 cluster.local} stable-1.11 map[] map[] map[] [] [] [] [] /etc/kubernetes/pki k8s.gcr.io { /var/log/kubernetes/audit 0xc4204dd82c} map[] kubernetes}
|
||||||
|
|
||||||
|
// {{MasterConfiguration kubeadm.k8s.io/v1alpha3} [{abcdef.abcdef0123456789 nil <nil> [] []}] {testNode /var/run/cri.sock [] map[]} {10.100.0.1 4332} {0xc42012ca80 <nil>} {10.100.0.0/24 10.100.1.0/24 cluster.local} stable-1.11 map[] map[] map[] [] [] [] [] /etc/kubernetes/pki k8s.gcr.io { /var/log/kubernetes/audit 0x156e2f4} map[] kubernetes}
|
||||||
|
// {{MasterConfiguration kubeadm.k8s.io/v1alpha3} [{abcdef.abcdef0123456789 &Duration{Duration:24h0m0s,} <nil> [signing authentication] [system:bootstrappers:kubeadm:default-node-token]}] {testNode /var/run/cri.sock [] map[]} {10.100.0.1 4332} {0xc42039d1a0 <nil>} {10.100.0.0/24 10.100.1.0/24 cluster.local} stable-1.11 map[] map[] map[] [] [] [] [] /etc/kubernetes/pki k8s.gcr.io { /var/log/kubernetes/audit 0xc4204fef3c} map[] kubernetes}
|
||||||
|
|
||||||
func TestSplitYAMLDocuments(t *testing.T) {
|
func TestSplitYAMLDocuments(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
|
Loading…
Reference in New Issue
Block a user