kubelet.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. Copyright 2019 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package componentconfigs
  14. import (
  15. "path/filepath"
  16. "k8s.io/apimachinery/pkg/util/version"
  17. clientset "k8s.io/client-go/kubernetes"
  18. kubeletconfig "k8s.io/kubelet/config/v1beta1"
  19. utilpointer "k8s.io/utils/pointer"
  20. kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
  21. kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
  22. "k8s.io/kubernetes/cmd/kubeadm/app/constants"
  23. "k8s.io/kubernetes/cmd/kubeadm/app/features"
  24. )
  25. const (
  26. // KubeletGroup is a pointer to the used API group name for the kubelet config
  27. KubeletGroup = kubeletconfig.GroupName
  28. // kubeletReadOnlyPort specifies the default insecure http server port
  29. // 0 will disable insecure http server.
  30. kubeletReadOnlyPort int32 = 0
  31. // kubeletRotateCertificates specifies the default value to enable certificate rotation
  32. kubeletRotateCertificates = true
  33. // kubeletAuthenticationAnonymousEnabled specifies the default value to disable anonymous access
  34. kubeletAuthenticationAnonymousEnabled = false
  35. // kubeletAuthenticationWebhookEnabled set the default value to enable authentication webhook
  36. kubeletAuthenticationWebhookEnabled = true
  37. // kubeletHealthzBindAddress specifies the default healthz bind address
  38. kubeletHealthzBindAddress = "127.0.0.1"
  39. )
  40. // kubeletHandler is the handler instance for the kubelet component config
  41. var kubeletHandler = handler{
  42. GroupVersion: kubeletconfig.SchemeGroupVersion,
  43. AddToScheme: kubeletconfig.AddToScheme,
  44. CreateEmpty: func() kubeadmapi.ComponentConfig {
  45. return &kubeletConfig{}
  46. },
  47. fromCluster: kubeletConfigFromCluster,
  48. }
  49. func kubeletConfigFromCluster(h *handler, clientset clientset.Interface, clusterCfg *kubeadmapi.ClusterConfiguration) (kubeadmapi.ComponentConfig, error) {
  50. // Read the ConfigMap from the cluster based on what version the kubelet is
  51. k8sVersion, err := version.ParseGeneric(clusterCfg.KubernetesVersion)
  52. if err != nil {
  53. return nil, err
  54. }
  55. configMapName := constants.GetKubeletConfigMapName(k8sVersion)
  56. return h.fromConfigMap(clientset, configMapName, constants.KubeletBaseConfigurationConfigMapKey, true)
  57. }
  58. // kubeletConfig implements the kubeadmapi.ComponentConfig interface for kubelet
  59. type kubeletConfig struct {
  60. config kubeletconfig.KubeletConfiguration
  61. }
  62. func (kc *kubeletConfig) DeepCopy() kubeadmapi.ComponentConfig {
  63. result := &kubeletConfig{}
  64. kc.config.DeepCopyInto(&result.config)
  65. return result
  66. }
  67. func (kc *kubeletConfig) Marshal() ([]byte, error) {
  68. return kubeletHandler.Marshal(&kc.config)
  69. }
  70. func (kc *kubeletConfig) Unmarshal(docmap kubeadmapi.DocumentMap) error {
  71. return kubeletHandler.Unmarshal(docmap, &kc.config)
  72. }
  73. func (kc *kubeletConfig) Default(cfg *kubeadmapi.ClusterConfiguration, _ *kubeadmapi.APIEndpoint) {
  74. const kind = "KubeletConfiguration"
  75. if kc.config.FeatureGates == nil {
  76. kc.config.FeatureGates = map[string]bool{}
  77. }
  78. if kc.config.StaticPodPath == "" {
  79. kc.config.StaticPodPath = kubeadmapiv1beta2.DefaultManifestsDir
  80. } else if kc.config.StaticPodPath != kubeadmapiv1beta2.DefaultManifestsDir {
  81. warnDefaultComponentConfigValue(kind, "staticPodPath", kubeadmapiv1beta2.DefaultManifestsDir, kc.config.StaticPodPath)
  82. }
  83. clusterDNS := ""
  84. dnsIP, err := constants.GetDNSIP(cfg.Networking.ServiceSubnet, features.Enabled(cfg.FeatureGates, features.IPv6DualStack))
  85. if err != nil {
  86. clusterDNS = kubeadmapiv1beta2.DefaultClusterDNSIP
  87. } else {
  88. clusterDNS = dnsIP.String()
  89. }
  90. if kc.config.ClusterDNS == nil {
  91. kc.config.ClusterDNS = []string{clusterDNS}
  92. } else if len(kc.config.ClusterDNS) != 1 || kc.config.ClusterDNS[0] != clusterDNS {
  93. warnDefaultComponentConfigValue(kind, "clusterDNS", []string{clusterDNS}, kc.config.ClusterDNS)
  94. }
  95. if kc.config.ClusterDomain == "" {
  96. kc.config.ClusterDomain = cfg.Networking.DNSDomain
  97. } else if cfg.Networking.DNSDomain != "" && kc.config.ClusterDomain != cfg.Networking.DNSDomain {
  98. warnDefaultComponentConfigValue(kind, "clusterDomain", cfg.Networking.DNSDomain, kc.config.ClusterDomain)
  99. }
  100. // Require all clients to the kubelet API to have client certs signed by the cluster CA
  101. clientCAFile := filepath.Join(cfg.CertificatesDir, constants.CACertName)
  102. if kc.config.Authentication.X509.ClientCAFile == "" {
  103. kc.config.Authentication.X509.ClientCAFile = clientCAFile
  104. } else if kc.config.Authentication.X509.ClientCAFile != clientCAFile {
  105. warnDefaultComponentConfigValue(kind, "authentication.x509.clientCAFile", clientCAFile, kc.config.Authentication.X509.ClientCAFile)
  106. }
  107. if kc.config.Authentication.Anonymous.Enabled == nil {
  108. kc.config.Authentication.Anonymous.Enabled = utilpointer.BoolPtr(kubeletAuthenticationAnonymousEnabled)
  109. } else if *kc.config.Authentication.Anonymous.Enabled != kubeletAuthenticationAnonymousEnabled {
  110. warnDefaultComponentConfigValue(kind, "authentication.anonymous.enabled", kubeletAuthenticationAnonymousEnabled, *kc.config.Authentication.Anonymous.Enabled)
  111. }
  112. // On every client request to the kubelet API, execute a webhook (SubjectAccessReview request) to the API server
  113. // and ask it whether the client is authorized to access the kubelet API
  114. if kc.config.Authorization.Mode == "" {
  115. kc.config.Authorization.Mode = kubeletconfig.KubeletAuthorizationModeWebhook
  116. } else if kc.config.Authorization.Mode != kubeletconfig.KubeletAuthorizationModeWebhook {
  117. warnDefaultComponentConfigValue(kind, "authorization.mode", kubeletconfig.KubeletAuthorizationModeWebhook, kc.config.Authorization.Mode)
  118. }
  119. // Let clients using other authentication methods like ServiceAccount tokens also access the kubelet API
  120. if kc.config.Authentication.Webhook.Enabled == nil {
  121. kc.config.Authentication.Webhook.Enabled = utilpointer.BoolPtr(kubeletAuthenticationWebhookEnabled)
  122. } else if *kc.config.Authentication.Webhook.Enabled != kubeletAuthenticationWebhookEnabled {
  123. warnDefaultComponentConfigValue(kind, "authentication.webhook.enabled", kubeletAuthenticationWebhookEnabled, *kc.config.Authentication.Webhook.Enabled)
  124. }
  125. // Serve a /healthz webserver on localhost:10248 that kubeadm can talk to
  126. if kc.config.HealthzBindAddress == "" {
  127. kc.config.HealthzBindAddress = kubeletHealthzBindAddress
  128. } else if kc.config.HealthzBindAddress != kubeletHealthzBindAddress {
  129. warnDefaultComponentConfigValue(kind, "healthzBindAddress", kubeletHealthzBindAddress, kc.config.HealthzBindAddress)
  130. }
  131. if kc.config.HealthzPort == nil {
  132. kc.config.HealthzPort = utilpointer.Int32Ptr(constants.KubeletHealthzPort)
  133. } else if *kc.config.HealthzPort != constants.KubeletHealthzPort {
  134. warnDefaultComponentConfigValue(kind, "healthzPort", constants.KubeletHealthzPort, *kc.config.HealthzPort)
  135. }
  136. if kc.config.ReadOnlyPort != kubeletReadOnlyPort {
  137. warnDefaultComponentConfigValue(kind, "readOnlyPort", kubeletReadOnlyPort, kc.config.ReadOnlyPort)
  138. }
  139. // We cannot show a warning for RotateCertificates==false and we must hardcode it to true.
  140. // There is no way to determine if the user has set this or not, given the field is a non-pointer.
  141. kc.config.RotateCertificates = kubeletRotateCertificates
  142. }