-
Notifications
You must be signed in to change notification settings - Fork 38.6k
/
defaults.go
188 lines (152 loc) · 9.14 KB
/
defaults.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
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 (
"path/filepath"
"k8s.io/klog"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
utilpointer "k8s.io/utils/pointer"
)
const (
// kubeproxyKubeConfigFileName defines the file name for the kube-proxy's kubeconfig file
kubeproxyKubeConfigFileName = "/var/lib/kube-proxy/kubeconfig.conf"
// kubeletReadOnlyPort specifies the default insecure http server port
// 0 will disable insecure http server.
kubeletReadOnlyPort int32 = 0
// kubeletRotateCertificates specifies the default value to enable certificate rotation
kubeletRotateCertificates = true
// kubeletAuthenticationAnonymousEnabled specifies the default value to disable anonymous access
kubeletAuthenticationAnonymousEnabled = false
// kubeletAuthorizationMode specifies the default authorization mode
kubeletAuthorizationMode = kubeletconfigv1beta1.KubeletAuthorizationModeWebhook
// kubeletAuthenticationWebhookEnabled set the default value to enable authentication webhook
kubeletAuthenticationWebhookEnabled = true
// kubeletHealthzBindAddress specifies the default healthz bind address
kubeletHealthzBindAddress = "127.0.0.1"
)
// DefaultKubeProxyConfiguration assigns default values for the kube-proxy ComponentConfig
func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
kind := "KubeProxyConfiguration"
if internalcfg.ComponentConfigs.KubeProxy == nil {
internalcfg.ComponentConfigs.KubeProxy = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{
FeatureGates: map[string]bool{},
}
}
// The below code is necessary because while KubeProxy may be defined, the user may not
// have defined any feature-gates, thus FeatureGates will be nil and the later insertion
// of any feature-gates (e.g. IPv6DualStack) will cause a panic.
if internalcfg.ComponentConfigs.KubeProxy.FeatureGates == nil {
internalcfg.ComponentConfigs.KubeProxy.FeatureGates = map[string]bool{}
}
externalproxycfg := internalcfg.ComponentConfigs.KubeProxy
if externalproxycfg.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" {
externalproxycfg.ClusterCIDR = internalcfg.Networking.PodSubnet
} else if internalcfg.Networking.PodSubnet != "" && externalproxycfg.ClusterCIDR != internalcfg.Networking.PodSubnet {
warnDefaultComponentConfigValue(kind, "clusterCIDR", internalcfg.Networking.PodSubnet, externalproxycfg.ClusterCIDR)
}
if externalproxycfg.ClientConnection.Kubeconfig == "" {
externalproxycfg.ClientConnection.Kubeconfig = kubeproxyKubeConfigFileName
} else if externalproxycfg.ClientConnection.Kubeconfig != kubeproxyKubeConfigFileName {
warnDefaultComponentConfigValue(kind, "clientConnection.kubeconfig", kubeproxyKubeConfigFileName, externalproxycfg.ClientConnection.Kubeconfig)
}
// TODO: The following code should be remvoved after dual-stack is GA.
// Note: The user still retains the ability to explicitly set feature-gates and that value will overwrite this base value.
if enabled, present := internalcfg.FeatureGates[features.IPv6DualStack]; present {
externalproxycfg.FeatureGates[features.IPv6DualStack] = enabled
}
}
// DefaultKubeletConfiguration assigns default values for the kubelet ComponentConfig
func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
kind := "KubeletConfiguration"
if internalcfg.ComponentConfigs.Kubelet == nil {
internalcfg.ComponentConfigs.Kubelet = &kubeletconfigv1beta1.KubeletConfiguration{
FeatureGates: map[string]bool{},
}
}
externalkubeletcfg := internalcfg.ComponentConfigs.Kubelet
if externalkubeletcfg.StaticPodPath == "" {
externalkubeletcfg.StaticPodPath = kubeadmapiv1beta2.DefaultManifestsDir
} else if externalkubeletcfg.StaticPodPath != kubeadmapiv1beta2.DefaultManifestsDir {
warnDefaultComponentConfigValue(kind, "staticPodPath", kubeadmapiv1beta2.DefaultManifestsDir, externalkubeletcfg.StaticPodPath)
}
clusterDNS := ""
dnsIP, err := constants.GetDNSIP(internalcfg.Networking.ServiceSubnet, features.Enabled(internalcfg.FeatureGates, features.IPv6DualStack))
if err != nil {
clusterDNS = kubeadmapiv1beta2.DefaultClusterDNSIP
} else {
clusterDNS = dnsIP.String()
}
if externalkubeletcfg.ClusterDNS == nil {
externalkubeletcfg.ClusterDNS = []string{clusterDNS}
} else if len(externalkubeletcfg.ClusterDNS) != 1 || externalkubeletcfg.ClusterDNS[0] != clusterDNS {
warnDefaultComponentConfigValue(kind, "clusterDNS", []string{clusterDNS}, externalkubeletcfg.ClusterDNS)
}
if externalkubeletcfg.ClusterDomain == "" {
externalkubeletcfg.ClusterDomain = internalcfg.Networking.DNSDomain
} else if internalcfg.Networking.DNSDomain != "" && externalkubeletcfg.ClusterDomain != internalcfg.Networking.DNSDomain {
warnDefaultComponentConfigValue(kind, "clusterDomain", internalcfg.Networking.DNSDomain, externalkubeletcfg.ClusterDomain)
}
// Require all clients to the kubelet API to have client certs signed by the cluster CA
clientCAFile := filepath.Join(internalcfg.CertificatesDir, constants.CACertName)
if externalkubeletcfg.Authentication.X509.ClientCAFile == "" {
externalkubeletcfg.Authentication.X509.ClientCAFile = clientCAFile
} else if externalkubeletcfg.Authentication.X509.ClientCAFile != clientCAFile {
warnDefaultComponentConfigValue(kind, "authentication.x509.clientCAFile", clientCAFile, externalkubeletcfg.Authentication.X509.ClientCAFile)
}
if externalkubeletcfg.Authentication.Anonymous.Enabled == nil {
externalkubeletcfg.Authentication.Anonymous.Enabled = utilpointer.BoolPtr(kubeletAuthenticationAnonymousEnabled)
} else if *externalkubeletcfg.Authentication.Anonymous.Enabled != kubeletAuthenticationAnonymousEnabled {
warnDefaultComponentConfigValue(kind, "authentication.anonymous.enabled", kubeletAuthenticationAnonymousEnabled, *externalkubeletcfg.Authentication.Anonymous.Enabled)
}
// 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
if externalkubeletcfg.Authorization.Mode == "" {
externalkubeletcfg.Authorization.Mode = kubeletAuthorizationMode
} else if externalkubeletcfg.Authorization.Mode != kubeletAuthorizationMode {
warnDefaultComponentConfigValue(kind, "authorization.mode", kubeletAuthorizationMode, externalkubeletcfg.Authorization.Mode)
}
// Let clients using other authentication methods like ServiceAccount tokens also access the kubelet API
if externalkubeletcfg.Authentication.Webhook.Enabled == nil {
externalkubeletcfg.Authentication.Webhook.Enabled = utilpointer.BoolPtr(kubeletAuthenticationWebhookEnabled)
} else if *externalkubeletcfg.Authentication.Webhook.Enabled != kubeletAuthenticationWebhookEnabled {
warnDefaultComponentConfigValue(kind, "authentication.webhook.enabled", kubeletAuthenticationWebhookEnabled, *externalkubeletcfg.Authentication.Webhook.Enabled)
}
// Serve a /healthz webserver on localhost:10248 that kubeadm can talk to
if externalkubeletcfg.HealthzBindAddress == "" {
externalkubeletcfg.HealthzBindAddress = kubeletHealthzBindAddress
} else if externalkubeletcfg.HealthzBindAddress != kubeletHealthzBindAddress {
warnDefaultComponentConfigValue(kind, "healthzBindAddress", kubeletHealthzBindAddress, externalkubeletcfg.HealthzBindAddress)
}
if externalkubeletcfg.HealthzPort == nil {
externalkubeletcfg.HealthzPort = utilpointer.Int32Ptr(constants.KubeletHealthzPort)
} else if *externalkubeletcfg.HealthzPort != constants.KubeletHealthzPort {
warnDefaultComponentConfigValue(kind, "healthzPort", constants.KubeletHealthzPort, *externalkubeletcfg.HealthzPort)
}
if externalkubeletcfg.ReadOnlyPort != kubeletReadOnlyPort {
warnDefaultComponentConfigValue(kind, "readOnlyPort", kubeletReadOnlyPort, externalkubeletcfg.ReadOnlyPort)
}
// We cannot show a warning for RotateCertificates==false and we must hardcode it to true.
// There is no way to determine if the user has set this or not, given the field is a non-pointer.
externalkubeletcfg.RotateCertificates = kubeletRotateCertificates
}
// warnDefaultComponentConfigValue prints a warning if the user modified a field in a certain
// CompomentConfig from the default recommended value in kubeadm.
func warnDefaultComponentConfigValue(componentConfigKind, paramName string, defaultValue, userValue interface{}) {
klog.Warningf("The recommended value for %q in %q is: %v; the provided value is: %v",
paramName, componentConfigKind, defaultValue, userValue)
}