Update kubeadm config generation to be compatible with v1.14.0-beta.1
parent
79c1e7d955
commit
327fdd8d4b
|
@ -510,11 +510,15 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
}
|
||||
|
||||
b := bytes.Buffer{}
|
||||
kubeadmConfigTemplate := kubeadmConfigTemplateV1Alpha1
|
||||
configTmpl := configTmplV1Alpha1
|
||||
if version.GTE(semver.MustParse("1.12.0")) {
|
||||
kubeadmConfigTemplate = kubeadmConfigTemplateV1Alpha3
|
||||
configTmpl = configTmplV1Alpha3
|
||||
}
|
||||
if err := kubeadmConfigTemplate.Execute(&b, opts); err != nil {
|
||||
// v1beta1 works in v1.13, but isn't required until v1.14.
|
||||
if version.GTE(semver.MustParse("1.14.0-alpha.0")) {
|
||||
configTmpl = configTmplV1Beta1
|
||||
}
|
||||
if err := configTmpl.Execute(&b, opts); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,10 @@ limitations under the License.
|
|||
package kubeadm
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/cruntime"
|
||||
"k8s.io/minikube/pkg/util"
|
||||
|
@ -104,6 +106,72 @@ schedulerExtraArgs:
|
|||
`,
|
||||
},
|
||||
{
|
||||
description: "extra args, v1.14.0",
|
||||
cfg: config.KubernetesConfig{
|
||||
NodeIP: "192.168.1.101",
|
||||
KubernetesVersion: "v1.14.0-beta1",
|
||||
NodeName: "extra-args-minikube-114",
|
||||
ExtraOptions: util.ExtraOptionSlice{
|
||||
util.ExtraOption{
|
||||
Component: Apiserver,
|
||||
Key: "fail-no-swap",
|
||||
Value: "true",
|
||||
},
|
||||
util.ExtraOption{
|
||||
Component: ControllerManager,
|
||||
Key: "kube-api-burst",
|
||||
Value: "32",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedCfg: `apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: InitConfiguration
|
||||
localAPIEndpoint:
|
||||
advertiseAddress: 192.168.1.101
|
||||
bindPort: 8443
|
||||
bootstrapTokens:
|
||||
- groups:
|
||||
- system:bootstrappers:kubeadm:default-node-token
|
||||
ttl: 24h0m0s
|
||||
usages:
|
||||
- signing
|
||||
- authentication
|
||||
nodeRegistration:
|
||||
criSocket: /var/run/dockershim.sock
|
||||
name: extra-args-minikube-114
|
||||
taints: []
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: ClusterConfiguration
|
||||
apiServer:
|
||||
extraArgs:
|
||||
enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"fail-no-swap: "true"
|
||||
controllerManager:
|
||||
extraArgs:
|
||||
kube-api-burst: "32"
|
||||
certificatesDir: /var/lib/minikube/certs/
|
||||
clusterName: kubernetes
|
||||
controlPlaneEndpoint: localhost:8443
|
||||
dns:
|
||||
type: CoreDNS
|
||||
etcd:
|
||||
local:
|
||||
dataDir: /data/minikube
|
||||
kubernetesVersion: v1.14.0-beta1
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: ""
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
imageGCHighThresholdPercent: 100
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
`,
|
||||
}, {
|
||||
description: "two extra args for one component",
|
||||
cfg: config.KubernetesConfig{
|
||||
NodeIP: "192.168.1.101",
|
||||
|
@ -264,18 +332,21 @@ apiServerExtraArgs:
|
|||
}
|
||||
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
actualCfg, err := generateConfig(test.cfg, runtime)
|
||||
got, err := generateConfig(test.cfg, runtime)
|
||||
if err != nil && !test.shouldErr {
|
||||
t.Errorf("got unexpected error generating config: %v", err)
|
||||
return
|
||||
}
|
||||
if err == nil && test.shouldErr {
|
||||
t.Errorf("expected error but got none, config: %s", actualCfg)
|
||||
t.Errorf("expected error but got none, config: %s", got)
|
||||
return
|
||||
}
|
||||
if actualCfg != test.expectedCfg {
|
||||
t.Errorf("actual config does not match expected. actual:\n%sexpected:\n%s", actualCfg, test.expectedCfg)
|
||||
return
|
||||
|
||||
// cmp.Diff doesn't present diffs of multi-line text well
|
||||
gotSplit := strings.Split(got, "\n")
|
||||
wantSplit := strings.Split(test.expectedCfg, "\n")
|
||||
if diff := cmp.Diff(gotSplit, wantSplit); diff != "" {
|
||||
t.Errorf("unexpected diff: (-want +got)\n%s\ngot: %s\n", diff, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ import (
|
|||
"text/template"
|
||||
)
|
||||
|
||||
var kubeadmConfigTemplateV1Alpha1 = template.Must(template.New("kubeadmConfigTemplate-v1alpha1").Funcs(template.FuncMap{
|
||||
// configTmplV1Alpha1 is for Kubernetes v1.11
|
||||
var configTmplV1Alpha1 = template.Must(template.New("configTmpl-v1alpha1").Funcs(template.FuncMap{
|
||||
"printMapInOrder": printMapInOrder,
|
||||
}).Parse(`apiVersion: kubeadm.k8s.io/v1alpha1
|
||||
kind: MasterConfiguration
|
||||
|
@ -39,16 +40,16 @@ etcd:
|
|||
dataDir: {{.EtcdDataDir}}
|
||||
nodeName: {{.NodeName}}
|
||||
{{if .CRISocket}}criSocket: {{.CRISocket}}
|
||||
{{end}}{{range .ExtraArgs}}{{.Component}}:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{end}}{{range .ExtraArgs}}{{.Component}}ExtraArgs:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{$val}}{{end}}
|
||||
{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}}
|
||||
{{$i}}: {{$val}}{{end}}
|
||||
{{end}}`))
|
||||
|
||||
var kubeadmConfigTemplateV1Alpha3 = template.Must(template.New("kubeadmConfigTemplate-v1alpha3").Funcs(template.FuncMap{
|
||||
// configTmplV1Alpha3 is for Kubernetes v1.12
|
||||
var configTmplV1Alpha3 = template.Must(template.New("configTmpl-v1alpha3").Funcs(template.FuncMap{
|
||||
"printMapInOrder": printMapInOrder,
|
||||
}).Parse(`
|
||||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
}).Parse(`apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: InitConfiguration
|
||||
apiEndpoint:
|
||||
advertiseAddress: {{.AdvertiseAddress}}
|
||||
|
@ -67,7 +68,7 @@ nodeRegistration:
|
|||
---
|
||||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: ClusterConfiguration
|
||||
{{range .ExtraArgs}}{{.Component}}:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{range .ExtraArgs}}{{.Component}}ExtraArgs:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{$val}}{{end}}
|
||||
{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}}
|
||||
{{$i}}: {{$val}}{{end}}
|
||||
|
@ -86,14 +87,62 @@ networking:
|
|||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
# disable disk resource management by default, as it doesn't work well within the minikube environment.
|
||||
imageGCHighThresholdPercent: 100
|
||||
# Don't evict jobs, as we only have a single node to run on.
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
`))
|
||||
`))
|
||||
|
||||
// configTmplV1Beta1 is for Kubernetes v1.13+
|
||||
var configTmplV1Beta1 = template.Must(template.New("configTmpl-v1beta1").Funcs(template.FuncMap{
|
||||
"printMapInOrder": printMapInOrder,
|
||||
}).Parse(`apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: InitConfiguration
|
||||
localAPIEndpoint:
|
||||
advertiseAddress: {{.AdvertiseAddress}}
|
||||
bindPort: {{.APIServerPort}}
|
||||
bootstrapTokens:
|
||||
- groups:
|
||||
- system:bootstrappers:kubeadm:default-node-token
|
||||
ttl: 24h0m0s
|
||||
usages:
|
||||
- signing
|
||||
- authentication
|
||||
nodeRegistration:
|
||||
criSocket: {{if .CRISocket}}{{.CRISocket}}{{else}}/var/run/dockershim.sock{{end}}
|
||||
name: {{.NodeName}}
|
||||
taints: []
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: ClusterConfiguration
|
||||
{{range .ExtraArgs}}{{.Component}}:
|
||||
extraArgs:
|
||||
{{range $i, $val := printMapInOrder .Options ": " }}{{$val}}{{end}}
|
||||
{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}}
|
||||
{{$i}}: {{$val}}{{end}}
|
||||
{{end -}}
|
||||
certificatesDir: {{.CertDir}}
|
||||
clusterName: kubernetes
|
||||
controlPlaneEndpoint: localhost:{{.APIServerPort}}
|
||||
dns:
|
||||
type: CoreDNS
|
||||
etcd:
|
||||
local:
|
||||
dataDir: {{.EtcdDataDir}}
|
||||
kubernetesVersion: {{.KubernetesVersion}}
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
podSubnet: ""
|
||||
serviceSubnet: {{.ServiceCIDR}}
|
||||
---
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
imageGCHighThresholdPercent: 100
|
||||
evictionHard:
|
||||
nodefs.available: "0%"
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
`))
|
||||
|
||||
var kubeletSystemdTemplate = template.Must(template.New("kubeletSystemdTemplate").Parse(`
|
||||
[Unit]
|
||||
|
|
|
@ -65,10 +65,11 @@ type ComponentExtraArgs struct {
|
|||
Options map[string]string
|
||||
}
|
||||
|
||||
// mapping of component to the section name in kubeadm.
|
||||
var componentToKubeadmConfigKey = map[string]string{
|
||||
Apiserver: "apiServerExtraArgs",
|
||||
ControllerManager: "controllerManagerExtraArgs",
|
||||
Scheduler: "schedulerExtraArgs",
|
||||
Apiserver: "apiServer",
|
||||
ControllerManager: "controllerManager",
|
||||
Scheduler: "scheduler",
|
||||
// The Kubelet is not configured in kubeadm, only in systemd.
|
||||
Kubelet: "",
|
||||
}
|
||||
|
@ -246,7 +247,7 @@ var versionSpecificOpts = []VersionedExtraOption{
|
|||
Option: util.ExtraOption{
|
||||
Component: Apiserver,
|
||||
Key: "admission-control",
|
||||
Value: strings.Join(util.DefaultAdmissionControllers, ","),
|
||||
Value: strings.Join(util.DefaultLegacyAdmissionControllers, ","),
|
||||
},
|
||||
LessThanOrEqual: semver.MustParse("1.10.1000"), // Semver doesn't support wildcards.
|
||||
GreaterThanOrEqual: semver.MustParse("1.9.0-alpha.0"),
|
||||
|
@ -255,10 +256,20 @@ var versionSpecificOpts = []VersionedExtraOption{
|
|||
Option: util.ExtraOption{
|
||||
Component: Apiserver,
|
||||
Key: "enable-admission-plugins",
|
||||
Value: strings.Join(util.DefaultAdmissionControllers, ","),
|
||||
Value: strings.Join(util.DefaultLegacyAdmissionControllers, ","),
|
||||
},
|
||||
GreaterThanOrEqual: semver.MustParse("1.11.0-alpha.0"),
|
||||
LessThanOrEqual: semver.MustParse("1.13.1000"),
|
||||
},
|
||||
{
|
||||
Option: util.ExtraOption{
|
||||
Component: Apiserver,
|
||||
Key: "enable-admission-plugins",
|
||||
Value: strings.Join(util.DefaultV114AdmissionControllers, ","),
|
||||
},
|
||||
GreaterThanOrEqual: semver.MustParse("1.14.0-alpha.0"),
|
||||
},
|
||||
|
||||
{
|
||||
Option: util.ExtraOption{
|
||||
Component: Kubelet,
|
||||
|
|
|
@ -32,8 +32,8 @@ const (
|
|||
DefaultServiceCIDR = "10.96.0.0/12"
|
||||
)
|
||||
|
||||
var DefaultAdmissionControllers = []string{
|
||||
"Initializers",
|
||||
// DefaultV114AdmissionControllers are admission controllers we default to in v1.14.x
|
||||
var DefaultV114AdmissionControllers = []string{
|
||||
"NamespaceLifecycle",
|
||||
"LimitRanger",
|
||||
"ServiceAccount",
|
||||
|
@ -45,6 +45,9 @@ var DefaultAdmissionControllers = []string{
|
|||
"ResourceQuota",
|
||||
}
|
||||
|
||||
// DefaultLegacyAdmissionControllers are admission controllers we default to in order Kubernetes releases
|
||||
var DefaultLegacyAdmissionControllers = append(DefaultV114AdmissionControllers, "Initializers")
|
||||
|
||||
// GetServiceClusterIP returns the first IP of the ServiceCIDR
|
||||
func GetServiceClusterIP(serviceCIDR string) (net.IP, error) {
|
||||
ip, _, err := net.ParseCIDR(serviceCIDR)
|
||||
|
|
Loading…
Reference in New Issue