Merge pull request #118867 from chendave/env_custom

kubeadm: Support custom env in control plane component
This commit is contained in:
Kubernetes Prow Robot 2023-07-03 22:02:52 -07:00 committed by GitHub
commit 746b88c6ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 278 additions and 53 deletions

View File

@ -85,6 +85,10 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
obj.APIServer.TimeoutForControlPlane = &metav1.Duration{ obj.APIServer.TimeoutForControlPlane = &metav1.Duration{
Duration: constants.DefaultControlPlaneTimeout, Duration: constants.DefaultControlPlaneTimeout,
} }
obj.ControllerManager.ExtraEnvs = []corev1.EnvVar{}
obj.APIServer.ExtraEnvs = []corev1.EnvVar{}
obj.Scheduler.ExtraEnvs = []corev1.EnvVar{}
obj.Etcd.Local.ExtraEnvs = []corev1.EnvVar{}
} }
func fuzzDNS(obj *kubeadm.DNS, c fuzz.Continue) { func fuzzDNS(obj *kubeadm.DNS, c fuzz.Continue) {

View File

@ -150,6 +150,11 @@ type ControlPlaneComponent struct {
// ExtraVolumes is an extra set of host volumes, mounted to the control plane component. // ExtraVolumes is an extra set of host volumes, mounted to the control plane component.
ExtraVolumes []HostPathMount ExtraVolumes []HostPathMount
// ExtraEnvs is an extra set of environment variables to pass to the control plane component.
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
// +optional
ExtraEnvs []v1.EnvVar
} }
// APIServer holds settings necessary for API server deployments in the cluster // APIServer holds settings necessary for API server deployments in the cluster
@ -262,6 +267,11 @@ type LocalEtcd struct {
// command line except without leading dash(es). // command line except without leading dash(es).
ExtraArgs map[string]string ExtraArgs map[string]string
// ExtraEnvs is an extra set of environment variables to pass to the control plane component.
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
// +optional
ExtraEnvs []v1.EnvVar
// ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert.
ServerCertSANs []string ServerCertSANs []string
// PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert. // PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert.

View File

@ -17,6 +17,7 @@ limitations under the License.
package v1beta3 package v1beta3
import ( import (
v1 "k8s.io/api/core/v1"
"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"
@ -34,3 +35,23 @@ func Convert_v1beta3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConf
err = Convert_v1beta3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&ClusterConfiguration{}, &out.ClusterConfiguration, s) err = Convert_v1beta3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&ClusterConfiguration{}, &out.ClusterConfiguration, s)
return err return err
} }
// Convert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent is required due to the missing ControlPlaneComponent.ExtraEnvs in v1beta3.
func Convert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *ControlPlaneComponent, out *kubeadm.ControlPlaneComponent, s conversion.Scope) error {
out.ExtraEnvs = []v1.EnvVar{}
return autoConvert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in, out, s)
}
func Convert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error {
return autoConvert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(in, out, s)
}
// Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd is required due to the missing LocalEtcd.ExtraEnvs in v1beta3.
func Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kubeadm.LocalEtcd, s conversion.Scope) error {
out.ExtraEnvs = []v1.EnvVar{}
return autoConvert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(in, out, s)
}
func Convert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(in *kubeadm.LocalEtcd, out *LocalEtcd, s conversion.Scope) error {
return autoConvert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(in, out, s)
}

View File

@ -79,16 +79,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*ControlPlaneComponent)(nil), (*kubeadm.ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(a.(*ControlPlaneComponent), b.(*kubeadm.ControlPlaneComponent), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kubeadm.ControlPlaneComponent)(nil), (*ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(a.(*kubeadm.ControlPlaneComponent), b.(*ControlPlaneComponent), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*DNS)(nil), (*kubeadm.DNS)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*DNS)(nil), (*kubeadm.DNS)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_DNS_To_kubeadm_DNS(a.(*DNS), b.(*kubeadm.DNS), scope) return Convert_v1beta3_DNS_To_kubeadm_DNS(a.(*DNS), b.(*kubeadm.DNS), scope)
}); err != nil { }); err != nil {
@ -179,16 +169,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*LocalEtcd)(nil), (*kubeadm.LocalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(a.(*LocalEtcd), b.(*kubeadm.LocalEtcd), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kubeadm.LocalEtcd)(nil), (*LocalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(a.(*kubeadm.LocalEtcd), b.(*LocalEtcd), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Networking)(nil), (*kubeadm.Networking)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*Networking)(nil), (*kubeadm.Networking)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_Networking_To_kubeadm_Networking(a.(*Networking), b.(*kubeadm.Networking), scope) return Convert_v1beta3_Networking_To_kubeadm_Networking(a.(*Networking), b.(*kubeadm.Networking), scope)
}); err != nil { }); err != nil {
@ -219,16 +199,36 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*kubeadm.ControlPlaneComponent)(nil), (*ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(a.(*kubeadm.ControlPlaneComponent), b.(*ControlPlaneComponent), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*kubeadm.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*kubeadm.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_InitConfiguration_To_v1beta3_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope) return Convert_kubeadm_InitConfiguration_To_v1beta3_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope)
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*kubeadm.LocalEtcd)(nil), (*LocalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(a.(*kubeadm.LocalEtcd), b.(*LocalEtcd), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*ControlPlaneComponent)(nil), (*kubeadm.ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(a.(*ControlPlaneComponent), b.(*kubeadm.ControlPlaneComponent), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope) return Convert_v1beta3_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope)
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*LocalEtcd)(nil), (*kubeadm.LocalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(a.(*LocalEtcd), b.(*kubeadm.LocalEtcd), scope)
}); err != nil {
return err
}
return nil return nil
} }
@ -383,22 +383,13 @@ func autoConvert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(
return nil return nil
} }
// Convert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent is an autogenerated conversion function.
func Convert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *ControlPlaneComponent, out *kubeadm.ControlPlaneComponent, s conversion.Scope) error {
return autoConvert_v1beta3_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in, out, s)
}
func autoConvert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error { func autoConvert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error {
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
out.ExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) out.ExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ExtraVolumes))
// WARNING: in.ExtraEnvs requires manual conversion: does not exist in peer-type
return nil return nil
} }
// Convert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent is an autogenerated conversion function.
func Convert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error {
return autoConvert_kubeadm_ControlPlaneComponent_To_v1beta3_ControlPlaneComponent(in, out, s)
}
func autoConvert_v1beta3_DNS_To_kubeadm_DNS(in *DNS, out *kubeadm.DNS, s conversion.Scope) error { func autoConvert_v1beta3_DNS_To_kubeadm_DNS(in *DNS, out *kubeadm.DNS, s conversion.Scope) error {
if err := Convert_v1beta3_ImageMeta_To_kubeadm_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil { if err := Convert_v1beta3_ImageMeta_To_kubeadm_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil {
return err return err
@ -450,7 +441,15 @@ func Convert_kubeadm_Discovery_To_v1beta3_Discovery(in *kubeadm.Discovery, out *
} }
func autoConvert_v1beta3_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s conversion.Scope) error { func autoConvert_v1beta3_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s conversion.Scope) error {
out.Local = (*kubeadm.LocalEtcd)(unsafe.Pointer(in.Local)) if in.Local != nil {
in, out := &in.Local, &out.Local
*out = new(kubeadm.LocalEtcd)
if err := Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(*in, *out, s); err != nil {
return err
}
} else {
out.Local = nil
}
out.External = (*kubeadm.ExternalEtcd)(unsafe.Pointer(in.External)) out.External = (*kubeadm.ExternalEtcd)(unsafe.Pointer(in.External))
return nil return nil
} }
@ -461,7 +460,15 @@ func Convert_v1beta3_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s convers
} }
func autoConvert_kubeadm_Etcd_To_v1beta3_Etcd(in *kubeadm.Etcd, out *Etcd, s conversion.Scope) error { func autoConvert_kubeadm_Etcd_To_v1beta3_Etcd(in *kubeadm.Etcd, out *Etcd, s conversion.Scope) error {
out.Local = (*LocalEtcd)(unsafe.Pointer(in.Local)) if in.Local != nil {
in, out := &in.Local, &out.Local
*out = new(LocalEtcd)
if err := Convert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(*in, *out, s); err != nil {
return err
}
} else {
out.Local = nil
}
out.External = (*ExternalEtcd)(unsafe.Pointer(in.External)) out.External = (*ExternalEtcd)(unsafe.Pointer(in.External))
return nil return nil
} }
@ -671,27 +678,18 @@ func autoConvert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kube
return nil return nil
} }
// Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd is an autogenerated conversion function.
func Convert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kubeadm.LocalEtcd, s conversion.Scope) error {
return autoConvert_v1beta3_LocalEtcd_To_kubeadm_LocalEtcd(in, out, s)
}
func autoConvert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(in *kubeadm.LocalEtcd, out *LocalEtcd, s conversion.Scope) error { func autoConvert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(in *kubeadm.LocalEtcd, out *LocalEtcd, s conversion.Scope) error {
if err := Convert_kubeadm_ImageMeta_To_v1beta3_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil { if err := Convert_kubeadm_ImageMeta_To_v1beta3_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil {
return err return err
} }
out.DataDir = in.DataDir out.DataDir = in.DataDir
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
// WARNING: in.ExtraEnvs requires manual conversion: does not exist in peer-type
out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs))
out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs))
return nil return nil
} }
// Convert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd is an autogenerated conversion function.
func Convert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(in *kubeadm.LocalEtcd, out *LocalEtcd, s conversion.Scope) error {
return autoConvert_kubeadm_LocalEtcd_To_v1beta3_LocalEtcd(in, out, s)
}
func autoConvert_v1beta3_Networking_To_kubeadm_Networking(in *Networking, out *kubeadm.Networking, s conversion.Scope) error { func autoConvert_v1beta3_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

View File

@ -20,10 +20,13 @@ limitations under the License.
// +k8s:conversion-gen=k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm // +k8s:conversion-gen=k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm
// Package v1beta4 defines the v1beta4 version of the kubeadm configuration file format. // Package v1beta4 defines the v1beta4 version of the kubeadm configuration file format.
// This version improves on the v1beta2 format by fixing some minor issues and adding a few new fields. // This version improves on the v1beta3 format by fixing some minor issues and adding a few new fields.
// //
// A list of changes since v1beta3: // A list of changes since v1beta3:
//
// - TODO https://github.com/kubernetes/kubeadm/issues/2890 // - TODO https://github.com/kubernetes/kubeadm/issues/2890
// - Support custom environment variables in control plane components under `ClusterConfiguration`.
// Use `APIServer.ExtraEnvs`, `ControllerManager.ExtraEnvs`, `Scheduler.ExtraEnvs`, `Etcd.Local.ExtraEnvs`.
// //
// Migration from old kubeadm config versions // Migration from old kubeadm config versions
// //
@ -39,7 +42,7 @@ limitations under the License.
// configuration options defined in the kubeadm config file are also available as command line flags, but only // configuration options defined in the kubeadm config file are also available as command line flags, but only
// the most common/simple use case are supported with this approach. // the most common/simple use case are supported with this approach.
// //
// A kubeadm config file could contain multiple configuration types separated using three dashes (“---”). // A kubeadm config file could contain multiple configuration types separated using three dashes ("---").
// //
// kubeadm supports the following configuration types: // kubeadm supports the following configuration types:
// //

View File

@ -150,6 +150,11 @@ type ControlPlaneComponent struct {
// ExtraVolumes is an extra set of host volumes, mounted to the control plane component. // ExtraVolumes is an extra set of host volumes, mounted to the control plane component.
// +optional // +optional
ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"` ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"`
// ExtraEnvs is an extra set of environment variables to pass to the control plane component.
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
// +optional
ExtraEnvs []corev1.EnvVar `json:"extraEnvs,omitempty"`
} }
// APIServer holds settings necessary for API server deployments in the cluster // APIServer holds settings necessary for API server deployments in the cluster
@ -282,6 +287,11 @@ type LocalEtcd struct {
// +optional // +optional
ExtraArgs map[string]string `json:"extraArgs,omitempty"` ExtraArgs map[string]string `json:"extraArgs,omitempty"`
// ExtraEnvs is an extra set of environment variables to pass to the control plane component.
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
// +optional
ExtraEnvs []corev1.EnvVar `json:"extraEnvs,omitempty"`
// ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert.
// +optional // +optional
ServerCertSANs []string `json:"serverCertSANs,omitempty"` ServerCertSANs []string `json:"serverCertSANs,omitempty"`

View File

@ -380,6 +380,7 @@ func Convert_kubeadm_ClusterConfiguration_To_v1beta4_ClusterConfiguration(in *ku
func autoConvert_v1beta4_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *ControlPlaneComponent, out *kubeadm.ControlPlaneComponent, s conversion.Scope) error { func autoConvert_v1beta4_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *ControlPlaneComponent, out *kubeadm.ControlPlaneComponent, s conversion.Scope) error {
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
out.ExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) out.ExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ExtraVolumes))
out.ExtraEnvs = *(*[]corev1.EnvVar)(unsafe.Pointer(&in.ExtraEnvs))
return nil return nil
} }
@ -391,6 +392,7 @@ func Convert_v1beta4_ControlPlaneComponent_To_kubeadm_ControlPlaneComponent(in *
func autoConvert_kubeadm_ControlPlaneComponent_To_v1beta4_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error { func autoConvert_kubeadm_ControlPlaneComponent_To_v1beta4_ControlPlaneComponent(in *kubeadm.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error {
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
out.ExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) out.ExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ExtraVolumes))
out.ExtraEnvs = *(*[]corev1.EnvVar)(unsafe.Pointer(&in.ExtraEnvs))
return nil return nil
} }
@ -666,6 +668,7 @@ func autoConvert_v1beta4_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kube
} }
out.DataDir = in.DataDir out.DataDir = in.DataDir
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
out.ExtraEnvs = *(*[]corev1.EnvVar)(unsafe.Pointer(&in.ExtraEnvs))
out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs))
out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs))
return nil return nil
@ -682,6 +685,7 @@ func autoConvert_kubeadm_LocalEtcd_To_v1beta4_LocalEtcd(in *kubeadm.LocalEtcd, o
} }
out.DataDir = in.DataDir out.DataDir = in.DataDir
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
out.ExtraEnvs = *(*[]corev1.EnvVar)(unsafe.Pointer(&in.ExtraEnvs))
out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs))
out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs))
return nil return nil

View File

@ -145,6 +145,13 @@ func (in *ControlPlaneComponent) DeepCopyInto(out *ControlPlaneComponent) {
*out = make([]HostPathMount, len(*in)) *out = make([]HostPathMount, len(*in))
copy(*out, *in) copy(*out, *in)
} }
if in.ExtraEnvs != nil {
in, out := &in.ExtraEnvs, &out.ExtraEnvs
*out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return return
} }
@ -415,6 +422,13 @@ func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) {
(*out)[key] = val (*out)[key] = val
} }
} }
if in.ExtraEnvs != nil {
in, out := &in.ExtraEnvs, &out.ExtraEnvs
*out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.ServerCertSANs != nil { if in.ServerCertSANs != nil {
in, out := &in.ServerCertSANs, &out.ServerCertSANs in, out := &in.ServerCertSANs, &out.ServerCertSANs
*out = make([]string, len(*in)) *out = make([]string, len(*in))

View File

@ -23,6 +23,7 @@ package v1beta4
import ( import (
runtime "k8s.io/apimachinery/pkg/runtime" runtime "k8s.io/apimachinery/pkg/runtime"
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
) )
// RegisterDefaults adds defaulters functions to the given scheme. // RegisterDefaults adds defaulters functions to the given scheme.
@ -37,7 +38,41 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_ClusterConfiguration(in *ClusterConfiguration) { func SetObjectDefaults_ClusterConfiguration(in *ClusterConfiguration) {
SetDefaults_ClusterConfiguration(in) SetDefaults_ClusterConfiguration(in)
if in.Etcd.Local != nil {
for i := range in.Etcd.Local.ExtraEnvs {
a := &in.Etcd.Local.ExtraEnvs[i]
if a.ValueFrom != nil {
if a.ValueFrom.FieldRef != nil {
v1.SetDefaults_ObjectFieldSelector(a.ValueFrom.FieldRef)
}
}
}
}
SetDefaults_APIServer(&in.APIServer) SetDefaults_APIServer(&in.APIServer)
for i := range in.APIServer.ControlPlaneComponent.ExtraEnvs {
a := &in.APIServer.ControlPlaneComponent.ExtraEnvs[i]
if a.ValueFrom != nil {
if a.ValueFrom.FieldRef != nil {
v1.SetDefaults_ObjectFieldSelector(a.ValueFrom.FieldRef)
}
}
}
for i := range in.ControllerManager.ExtraEnvs {
a := &in.ControllerManager.ExtraEnvs[i]
if a.ValueFrom != nil {
if a.ValueFrom.FieldRef != nil {
v1.SetDefaults_ObjectFieldSelector(a.ValueFrom.FieldRef)
}
}
}
for i := range in.Scheduler.ExtraEnvs {
a := &in.Scheduler.ExtraEnvs[i]
if a.ValueFrom != nil {
if a.ValueFrom.FieldRef != nil {
v1.SetDefaults_ObjectFieldSelector(a.ValueFrom.FieldRef)
}
}
}
} }
func SetObjectDefaults_InitConfiguration(in *InitConfiguration) { func SetObjectDefaults_InitConfiguration(in *InitConfiguration) {

View File

@ -174,6 +174,13 @@ func (in *ControlPlaneComponent) DeepCopyInto(out *ControlPlaneComponent) {
*out = make([]HostPathMount, len(*in)) *out = make([]HostPathMount, len(*in))
copy(*out, *in) copy(*out, *in)
} }
if in.ExtraEnvs != nil {
in, out := &in.ExtraEnvs, &out.ExtraEnvs
*out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return return
} }
@ -445,6 +452,13 @@ func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) {
(*out)[key] = val (*out)[key] = val
} }
} }
if in.ExtraEnvs != nil {
in, out := &in.ExtraEnvs, &out.ExtraEnvs
*out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.ServerCertSANs != nil { if in.ServerCertSANs != nil {
in, out := &in.ServerCertSANs, &out.ServerCertSANs in, out := &in.ServerCertSANs, &out.ServerCertSANs
*out = make([]string, len(*in)) *out = make([]string, len(*in))

View File

@ -148,7 +148,7 @@ func runDiff(flags *diffFlags, args []string) error {
cfg.ClusterConfiguration.KubernetesVersion = flags.newK8sVersionStr cfg.ClusterConfiguration.KubernetesVersion = flags.newK8sVersionStr
specs := controlplane.GetStaticPodSpecs(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint) specs := controlplane.GetStaticPodSpecs(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, nil)
for spec, pod := range specs { for spec, pod := range specs {
var path string var path string
switch spec { switch spec {

View File

@ -48,9 +48,12 @@ func CreateInitStaticPodManifestFiles(manifestDir, patchesDir string, cfg *kubea
// GetStaticPodSpecs returns all staticPodSpecs actualized to the context of the current configuration // GetStaticPodSpecs returns all staticPodSpecs actualized to the context of the current configuration
// NB. this method holds the information about how kubeadm creates static pod manifests. // NB. this method holds the information about how kubeadm creates static pod manifests.
func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint) map[string]v1.Pod { func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, proxyEnvs []v1.EnvVar) map[string]v1.Pod {
// Get the required hostpath mounts // Get the required hostpath mounts
mounts := getHostPathVolumesForTheControlPlane(cfg) mounts := getHostPathVolumesForTheControlPlane(cfg)
if proxyEnvs == nil {
proxyEnvs = kubeadmutil.GetProxyEnvVars()
}
// Prepare static pod specs // Prepare static pod specs
staticPodSpecs := map[string]v1.Pod{ staticPodSpecs := map[string]v1.Pod{
@ -64,7 +67,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
ReadinessProbe: staticpodutil.ReadinessProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), "/readyz", int(endpoint.BindPort), v1.URISchemeHTTPS), ReadinessProbe: staticpodutil.ReadinessProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), "/readyz", int(endpoint.BindPort), v1.URISchemeHTTPS),
StartupProbe: staticpodutil.StartupProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), "/livez", int(endpoint.BindPort), v1.URISchemeHTTPS, cfg.APIServer.TimeoutForControlPlane), StartupProbe: staticpodutil.StartupProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), "/livez", int(endpoint.BindPort), v1.URISchemeHTTPS, cfg.APIServer.TimeoutForControlPlane),
Resources: staticpodutil.ComponentResources("250m"), Resources: staticpodutil.ComponentResources("250m"),
Env: kubeadmutil.GetProxyEnvVars(), Env: kubeadmutil.MergeEnv(proxyEnvs, cfg.APIServer.ExtraEnvs),
}, mounts.GetVolumes(kubeadmconstants.KubeAPIServer), }, mounts.GetVolumes(kubeadmconstants.KubeAPIServer),
map[string]string{kubeadmconstants.KubeAPIServerAdvertiseAddressEndpointAnnotationKey: endpoint.String()}), map[string]string{kubeadmconstants.KubeAPIServerAdvertiseAddressEndpointAnnotationKey: endpoint.String()}),
kubeadmconstants.KubeControllerManager: staticpodutil.ComponentPod(v1.Container{ kubeadmconstants.KubeControllerManager: staticpodutil.ComponentPod(v1.Container{
@ -76,7 +79,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeControllerManagerPort, v1.URISchemeHTTPS), LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeControllerManagerPort, v1.URISchemeHTTPS),
StartupProbe: staticpodutil.StartupProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeControllerManagerPort, v1.URISchemeHTTPS, cfg.APIServer.TimeoutForControlPlane), StartupProbe: staticpodutil.StartupProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeControllerManagerPort, v1.URISchemeHTTPS, cfg.APIServer.TimeoutForControlPlane),
Resources: staticpodutil.ComponentResources("200m"), Resources: staticpodutil.ComponentResources("200m"),
Env: kubeadmutil.GetProxyEnvVars(), Env: kubeadmutil.MergeEnv(proxyEnvs, cfg.ControllerManager.ExtraEnvs),
}, mounts.GetVolumes(kubeadmconstants.KubeControllerManager), nil), }, mounts.GetVolumes(kubeadmconstants.KubeControllerManager), nil),
kubeadmconstants.KubeScheduler: staticpodutil.ComponentPod(v1.Container{ kubeadmconstants.KubeScheduler: staticpodutil.ComponentPod(v1.Container{
Name: kubeadmconstants.KubeScheduler, Name: kubeadmconstants.KubeScheduler,
@ -87,7 +90,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetSchedulerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeSchedulerPort, v1.URISchemeHTTPS), LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetSchedulerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeSchedulerPort, v1.URISchemeHTTPS),
StartupProbe: staticpodutil.StartupProbe(staticpodutil.GetSchedulerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeSchedulerPort, v1.URISchemeHTTPS, cfg.APIServer.TimeoutForControlPlane), StartupProbe: staticpodutil.StartupProbe(staticpodutil.GetSchedulerProbeAddress(cfg), "/healthz", kubeadmconstants.KubeSchedulerPort, v1.URISchemeHTTPS, cfg.APIServer.TimeoutForControlPlane),
Resources: staticpodutil.ComponentResources("100m"), Resources: staticpodutil.ComponentResources("100m"),
Env: kubeadmutil.GetProxyEnvVars(), Env: kubeadmutil.MergeEnv(proxyEnvs, cfg.Scheduler.ExtraEnvs),
}, mounts.GetVolumes(kubeadmconstants.KubeScheduler), nil), }, mounts.GetVolumes(kubeadmconstants.KubeScheduler), nil),
} }
return staticPodSpecs return staticPodSpecs
@ -97,7 +100,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
func CreateStaticPodFiles(manifestDir, patchesDir string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, isDryRun bool, componentNames ...string) error { func CreateStaticPodFiles(manifestDir, patchesDir string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, isDryRun bool, componentNames ...string) error {
// gets the StaticPodSpecs, actualized for the current ClusterConfiguration // gets the StaticPodSpecs, actualized for the current ClusterConfiguration
klog.V(1).Infoln("[control-plane] getting StaticPodSpecs") klog.V(1).Infoln("[control-plane] getting StaticPodSpecs")
specs := GetStaticPodSpecs(cfg, endpoint) specs := GetStaticPodSpecs(cfg, endpoint, nil)
var usersAndGroups *users.UsersAndGroups var usersAndGroups *users.UsersAndGroups
var err error var err error

View File

@ -30,6 +30,7 @@ import (
"github.com/lithammer/dedent" "github.com/lithammer/dedent"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
@ -51,14 +52,18 @@ func TestGetStaticPodSpecs(t *testing.T) {
// Creates a Cluster Configuration // Creates a Cluster Configuration
cfg := &kubeadmapi.ClusterConfiguration{ cfg := &kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.9.0", KubernetesVersion: "v1.9.0",
Scheduler: kubeadmapi.ControlPlaneComponent{ExtraEnvs: []v1.EnvVar{
{Name: "Foo", Value: "Bar"},
}},
} }
// Executes GetStaticPodSpecs // Executes GetStaticPodSpecs
specs := GetStaticPodSpecs(cfg, &kubeadmapi.APIEndpoint{}) specs := GetStaticPodSpecs(cfg, &kubeadmapi.APIEndpoint{}, []v1.EnvVar{})
var tests = []struct { var tests = []struct {
name string name string
staticPodName string staticPodName string
env []v1.EnvVar
}{ }{
{ {
name: "KubeAPIServer", name: "KubeAPIServer",
@ -71,6 +76,7 @@ func TestGetStaticPodSpecs(t *testing.T) {
{ {
name: "KubeScheduler", name: "KubeScheduler",
staticPodName: kubeadmconstants.KubeScheduler, staticPodName: kubeadmconstants.KubeScheduler,
env: []v1.EnvVar{{Name: "Foo", Value: "Bar"}},
}, },
} }
@ -78,12 +84,15 @@ func TestGetStaticPodSpecs(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
// assert the spec for the staticPodName exists // assert the spec for the staticPodName exists
if spec, ok := specs[tc.staticPodName]; ok { if spec, ok := specs[tc.staticPodName]; ok {
// Assert each specs refers to the right pod // Assert each specs refers to the right pod
if spec.Spec.Containers[0].Name != tc.staticPodName { if spec.Spec.Containers[0].Name != tc.staticPodName {
t.Errorf("getKubeConfigSpecs spec for %s contains pod %s, expects %s", tc.staticPodName, spec.Spec.Containers[0].Name, tc.staticPodName) t.Errorf("getKubeConfigSpecs spec for %s contains pod %s, expects %s", tc.staticPodName, spec.Spec.Containers[0].Name, tc.staticPodName)
} }
if tc.env != nil {
if !reflect.DeepEqual(spec.Spec.Containers[0].Env, tc.env) {
t.Errorf("expected env: %v, got: %v", tc.env, spec.Spec.Containers[0].Env)
}
}
} else { } else {
t.Errorf("getStaticPodSpecs didn't create spec for %s ", tc.staticPodName) t.Errorf("getStaticPodSpecs didn't create spec for %s ", tc.staticPodName)
} }

View File

@ -224,6 +224,7 @@ func GetEtcdPodSpec(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.A
}, },
LivenessProbe: staticpodutil.LivenessProbe(probeHostname, "/health?exclude=NOSPACE&serializable=true", probePort, probeScheme), LivenessProbe: staticpodutil.LivenessProbe(probeHostname, "/health?exclude=NOSPACE&serializable=true", probePort, probeScheme),
StartupProbe: staticpodutil.StartupProbe(probeHostname, "/health?serializable=false", probePort, probeScheme, cfg.APIServer.TimeoutForControlPlane), StartupProbe: staticpodutil.StartupProbe(probeHostname, "/health?serializable=false", probePort, probeScheme, cfg.APIServer.TimeoutForControlPlane),
Env: cfg.Etcd.Local.ExtraEnvs,
}, },
etcdMounts, etcdMounts,
// etcd will listen on the advertise address of the API server, in a different port (2379) // etcd will listen on the advertise address of the API server, in a different port (2379)

View File

@ -29,6 +29,7 @@ import (
"github.com/lithammer/dedent" "github.com/lithammer/dedent"
v1 "k8s.io/api/core/v1"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd"
@ -43,6 +44,9 @@ func TestGetEtcdPodSpec(t *testing.T) {
Etcd: kubeadmapi.Etcd{ Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{ Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd", DataDir: "/var/lib/etcd",
ExtraEnvs: []v1.EnvVar{
{Name: "Foo", Value: "Bar"},
},
}, },
}, },
} }
@ -55,6 +59,10 @@ func TestGetEtcdPodSpec(t *testing.T) {
if spec.Spec.Containers[0].Name != kubeadmconstants.Etcd { if spec.Spec.Containers[0].Name != kubeadmconstants.Etcd {
t.Errorf("getKubeConfigSpecs spec for etcd contains pod %s, expects %s", spec.Spec.Containers[0].Name, kubeadmconstants.Etcd) t.Errorf("getKubeConfigSpecs spec for etcd contains pod %s, expects %s", spec.Spec.Containers[0].Name, kubeadmconstants.Etcd)
} }
env := []v1.EnvVar{{Name: "Foo", Value: "Bar"}}
if !reflect.DeepEqual(spec.Spec.Containers[0].Env, env) {
t.Errorf("expected env: %v, got: %v", env, spec.Spec.Containers[0].Env)
}
} }
func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) { func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) {

View File

@ -41,3 +41,18 @@ func GetProxyEnvVars() []v1.EnvVar {
} }
return envs return envs
} }
// MergeEnv merges values of environment variable slices. The values defined in later slices overwrite values in previous ones.
func MergeEnv(envList ...[]v1.EnvVar) []v1.EnvVar {
m := make(map[string]v1.EnvVar)
merged := []v1.EnvVar{}
for _, envs := range envList {
for _, env := range envs {
m[env.Name] = env
}
}
for _, v := range m {
merged = append(merged, v)
}
return merged
}

View File

@ -0,0 +1,76 @@
/*
Copyright 2023 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 util
import (
"testing"
"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
)
func TestMergeEnv(t *testing.T) {
baseEnv := []v1.EnvVar{}
extraEnv := []v1.EnvVar{}
MergeEnv(append(baseEnv, extraEnv...))
var tests = []struct {
name string
proxyEnv []v1.EnvVar
extraEnv []v1.EnvVar
mergedEnv []v1.EnvVar
}{
{
name: "normal case without duplicated env",
proxyEnv: []v1.EnvVar{
{Name: "Foo1", Value: "Bar1"},
{Name: "Foo2", Value: "Bar2"},
},
extraEnv: []v1.EnvVar{
{Name: "Foo3", Value: "Bar3"},
},
mergedEnv: []v1.EnvVar{
{Name: "Foo1", Value: "Bar1"},
{Name: "Foo2", Value: "Bar2"},
{Name: "Foo3", Value: "Bar3"},
},
},
{
name: "extraEnv env take precedence over the proxyEnv",
proxyEnv: []v1.EnvVar{
{Name: "Foo1", Value: "Bar1"},
{Name: "Foo2", Value: "Bar2"},
},
extraEnv: []v1.EnvVar{
{Name: "Foo2", Value: "Bar3"},
},
mergedEnv: []v1.EnvVar{
{Name: "Foo1", Value: "Bar1"},
{Name: "Foo2", Value: "Bar3"},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
envs := MergeEnv(test.proxyEnv, test.extraEnv)
if !assert.ElementsMatch(t, envs, test.mergedEnv) {
t.Errorf("expected env: %v, got: %v", test.mergedEnv, envs)
}
})
}
}