fix: prevent overriding of certain kubelet security configuration parameters if the user wished to modify them.

This commit is contained in:
Jianfei Bai 2019-08-25 21:11:38 +08:00
parent 55e476356f
commit ccc45880a7
2 changed files with 93 additions and 23 deletions

View File

@ -35,6 +35,7 @@ go_library(
"//staging/src/k8s.io/kube-proxy/config/v1alpha1:go_default_library",
"//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
],
)

View File

@ -17,6 +17,7 @@ limitations under the License.
package componentconfigs
import (
"k8s.io/klog"
"path/filepath"
kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
@ -31,8 +32,27 @@ import (
)
const (
// KubeproxyKubeConfigFileName defines the file name for the kube-proxy's kubeconfig file
KubeproxyKubeConfigFileName = "/var/lib/kube-proxy/kubeconfig.conf"
// 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
@ -46,10 +66,14 @@ func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration)
if externalproxycfg.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" {
externalproxycfg.ClusterCIDR = internalcfg.Networking.PodSubnet
} else if internalcfg.Networking.PodSubnet != "" && externalproxycfg.ClusterCIDR != internalcfg.Networking.PodSubnet {
warnDefaultComponentConfigValue(externalproxycfg.Kind, "cluster-cidr", internalcfg.Networking.PodSubnet, externalproxycfg.ClusterCIDR)
}
if externalproxycfg.ClientConnection.Kubeconfig == "" {
externalproxycfg.ClientConnection.Kubeconfig = KubeproxyKubeConfigFileName
externalproxycfg.ClientConnection.Kubeconfig = kubeproxyKubeConfigFileName
} else if externalproxycfg.ClientConnection.Kubeconfig != kubeproxyKubeConfigFileName {
warnDefaultComponentConfigValue(externalproxycfg.Kind, "kubeconfig", kubeproxyKubeConfigFileName, externalproxycfg.ClientConnection.Kubeconfig)
}
// TODO: The following code should be remvoved after dual-stack is GA.
@ -81,41 +105,79 @@ func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
if externalkubeletcfg.StaticPodPath == "" {
externalkubeletcfg.StaticPodPath = kubeadmapiv1beta2.DefaultManifestsDir
} else if externalkubeletcfg.StaticPodPath != kubeadmapiv1beta2.DefaultManifestsDir {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "pod-manifest-path", kubeadmapiv1beta2.DefaultManifestsDir, externalkubeletcfg.StaticPodPath)
}
clusterDNS := ""
dnsIP, err := constants.GetDNSIP(internalcfg.Networking.ServiceSubnet)
if err != nil {
clusterDNS = kubeadmapiv1beta2.DefaultClusterDNSIP
} else {
clusterDNS = dnsIP.String()
}
if externalkubeletcfg.ClusterDNS == nil {
dnsIP, err := constants.GetDNSIP(internalcfg.Networking.ServiceSubnet)
if err != nil {
externalkubeletcfg.ClusterDNS = []string{kubeadmapiv1beta2.DefaultClusterDNSIP}
} else {
externalkubeletcfg.ClusterDNS = []string{dnsIP.String()}
}
externalkubeletcfg.ClusterDNS = []string{clusterDNS}
} else if len(externalkubeletcfg.ClusterDNS) != 1 || externalkubeletcfg.ClusterDNS[0] != clusterDNS {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "cluster-dns", []string{clusterDNS}, externalkubeletcfg.ClusterDNS)
}
if externalkubeletcfg.ClusterDomain == "" {
externalkubeletcfg.ClusterDomain = internalcfg.Networking.DNSDomain
} else if internalcfg.Networking.DNSDomain != "" && externalkubeletcfg.ClusterDomain != internalcfg.Networking.DNSDomain {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "cluster-domain", internalcfg.Networking.DNSDomain, externalkubeletcfg.ClusterDomain)
}
// 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 = filepath.Join(internalcfg.CertificatesDir, constants.CACertName)
externalkubeletcfg.Authentication.Anonymous.Enabled = utilpointer.BoolPtr(false)
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(externalkubeletcfg.Kind, "client-ca-file", 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(externalkubeletcfg.Kind, "anonymous-auth", 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
externalkubeletcfg.Authorization.Mode = kubeletconfigv1beta1.KubeletAuthorizationModeWebhook
if externalkubeletcfg.Authorization.Mode == "" {
externalkubeletcfg.Authorization.Mode = kubeletAuthorizationMode
} else if externalkubeletcfg.Authorization.Mode != kubeletAuthorizationMode {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "authorization-mode", kubeletAuthorizationMode, externalkubeletcfg.Authorization.Mode)
}
// 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
if externalkubeletcfg.Authentication.Webhook.Enabled == nil {
externalkubeletcfg.Authentication.Webhook.Enabled = utilpointer.BoolPtr(kubeletAuthenticationWebhookEnabled)
} else if *externalkubeletcfg.Authentication.Webhook.Enabled != kubeletAuthenticationWebhookEnabled {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "authentication-token-webhook", kubeletAuthenticationWebhookEnabled, *externalkubeletcfg.Authentication.Webhook.Enabled)
}
// Serve a /healthz webserver on localhost:10248 that kubeadm can talk to
externalkubeletcfg.HealthzBindAddress = "127.0.0.1"
externalkubeletcfg.HealthzPort = utilpointer.Int32Ptr(constants.KubeletHealthzPort)
if externalkubeletcfg.HealthzBindAddress == "" {
externalkubeletcfg.HealthzBindAddress = kubeletHealthzBindAddress
} else if externalkubeletcfg.HealthzBindAddress != kubeletHealthzBindAddress {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "healthz-bind-address", kubeletHealthzBindAddress, externalkubeletcfg.HealthzBindAddress)
}
if externalkubeletcfg.HealthzPort == nil {
externalkubeletcfg.HealthzPort = utilpointer.Int32Ptr(constants.KubeletHealthzPort)
} else if *externalkubeletcfg.HealthzPort != constants.KubeletHealthzPort {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "healthz-port", constants.KubeletHealthzPort, *externalkubeletcfg.HealthzPort)
}
if externalkubeletcfg.ReadOnlyPort != kubeletReadOnlyPort {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "read-only-port", kubeletReadOnlyPort, externalkubeletcfg.ReadOnlyPort)
}
if externalkubeletcfg.RotateCertificates != kubeletRotateCertificates {
warnDefaultComponentConfigValue(externalkubeletcfg.Kind, "rotate-certificates", kubeletRotateCertificates, externalkubeletcfg.RotateCertificates)
}
Scheme.Default(externalkubeletcfg)
@ -127,3 +189,10 @@ func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
// Go back to the internal version
Scheme.Convert(externalkubeletcfg, internalcfg.ComponentConfigs.Kubelet, nil)
}
// warnDefaultComponentConfigValue prints a warning if the user modified a field in a certain
// 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)
}