Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubeadm: Make it possible to configure volume mounts via the config file #49840

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ type MasterConfiguration struct {
ControllerManagerExtraArgs map[string]string
SchedulerExtraArgs map[string]string

APIServerExtraVolumes []HostPathMount
ControllerManagerExtraVolumes []HostPathMount
SchedulerExtraVolumes []HostPathMount

// APIServerCertSANs sets extra Subject Alternative Names for the API Server signing cert
APIServerCertSANs []string
// CertificatesDir specifies where to store or look for all required certificates
Expand Down Expand Up @@ -137,3 +141,11 @@ func (cfg *MasterConfiguration) GetControlPlaneImageRepository() string {
}
return cfg.ImageRepository
}

// HostPathMount contains elements describing volumes that are mounted from the
// host
type HostPathMount struct {
Name string
HostPath string
MountPath string
}
12 changes: 12 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ type MasterConfiguration struct {
ControllerManagerExtraArgs map[string]string `json:"controllerManagerExtraArgs,omitempty"`
SchedulerExtraArgs map[string]string `json:"schedulerExtraArgs,omitempty"`

APIServerExtraVolumes []HostPathMount `json:"apiServerExtraVolumes,omitempty"`
ControllerManagerExtraVolumes []HostPathMount `json:"controllerManagerExtraVolumes,omitempty"`
SchedulerExtraVolumes []HostPathMount `json:"schedulerExtraVolumes,omitempty"`

// APIServerCertSANs sets extra Subject Alternative Names for the API Server signing cert
APIServerCertSANs []string `json:"apiServerCertSANs,omitempty"`
// CertificatesDir specifies where to store or look for all required certificates
Expand Down Expand Up @@ -119,3 +123,11 @@ type NodeConfiguration struct {
// the security of kubeadm since other nodes can impersonate the master.
DiscoveryTokenUnsafeSkipCAVerification bool `json:"discoveryTokenUnsafeSkipCAVerification"`
}

// HostPathMount contains elements describing volumes that are mounted from the
// host
type HostPathMount struct {
Name string `json:"name"`
HostPath string `json:"hostPath"`
MountPath string `json:"mountPath"`
}
32 changes: 32 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_kubeadm_API_To_v1alpha1_API,
Convert_v1alpha1_Etcd_To_kubeadm_Etcd,
Convert_kubeadm_Etcd_To_v1alpha1_Etcd,
Convert_v1alpha1_HostPathMount_To_kubeadm_HostPathMount,
Convert_kubeadm_HostPathMount_To_v1alpha1_HostPathMount,
Convert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration,
Convert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration,
Convert_v1alpha1_Networking_To_kubeadm_Networking,
Expand Down Expand Up @@ -104,6 +106,30 @@ func Convert_kubeadm_Etcd_To_v1alpha1_Etcd(in *kubeadm.Etcd, out *Etcd, s conver
return autoConvert_kubeadm_Etcd_To_v1alpha1_Etcd(in, out, s)
}

func autoConvert_v1alpha1_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMount, out *kubeadm.HostPathMount, s conversion.Scope) error {
out.Name = in.Name
out.HostPath = in.HostPath
out.MountPath = in.MountPath
return nil
}

// Convert_v1alpha1_HostPathMount_To_kubeadm_HostPathMount is an autogenerated conversion function.
func Convert_v1alpha1_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMount, out *kubeadm.HostPathMount, s conversion.Scope) error {
return autoConvert_v1alpha1_HostPathMount_To_kubeadm_HostPathMount(in, out, s)
}

func autoConvert_kubeadm_HostPathMount_To_v1alpha1_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error {
out.Name = in.Name
out.HostPath = in.HostPath
out.MountPath = in.MountPath
return nil
}

// Convert_kubeadm_HostPathMount_To_v1alpha1_HostPathMount is an autogenerated conversion function.
func Convert_kubeadm_HostPathMount_To_v1alpha1_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error {
return autoConvert_kubeadm_HostPathMount_To_v1alpha1_HostPathMount(in, out, s)
}

func autoConvert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration(in *MasterConfiguration, out *kubeadm.MasterConfiguration, s conversion.Scope) error {
if err := Convert_v1alpha1_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
return err
Expand All @@ -123,6 +149,9 @@ func autoConvert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration(in
out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs))
out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs))
out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs))
out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes))
out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes))
out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes))
out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs))
out.CertificatesDir = in.CertificatesDir
out.ImageRepository = in.ImageRepository
Expand Down Expand Up @@ -155,6 +184,9 @@ func autoConvert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration(in
out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs))
out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs))
out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs))
out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes))
out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes))
out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes))
out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs))
out.CertificatesDir = in.CertificatesDir
out.ImageRepository = in.ImageRepository
Expand Down
35 changes: 35 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
in.(*Etcd).DeepCopyInto(out.(*Etcd))
return nil
}, InType: reflect.TypeOf(&Etcd{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*HostPathMount).DeepCopyInto(out.(*HostPathMount))
return nil
}, InType: reflect.TypeOf(&HostPathMount{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*MasterConfiguration).DeepCopyInto(out.(*MasterConfiguration))
return nil
Expand Down Expand Up @@ -102,6 +106,22 @@ func (in *Etcd) DeepCopy() *Etcd {
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostPathMount) DeepCopyInto(out *HostPathMount) {
*out = *in
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPathMount.
func (in *HostPathMount) DeepCopy() *HostPathMount {
if in == nil {
return nil
}
out := new(HostPathMount)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
*out = *in
Expand Down Expand Up @@ -136,6 +156,21 @@ func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
(*out)[key] = val
}
}
if in.APIServerExtraVolumes != nil {
in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.ControllerManagerExtraVolumes != nil {
in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.SchedulerExtraVolumes != nil {
in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.APIServerCertSANs != nil {
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
*out = make([]string, len(*in))
Expand Down
35 changes: 35 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
in.(*Etcd).DeepCopyInto(out.(*Etcd))
return nil
}, InType: reflect.TypeOf(&Etcd{})},
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*HostPathMount).DeepCopyInto(out.(*HostPathMount))
return nil
}, InType: reflect.TypeOf(&HostPathMount{})},
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*MasterConfiguration).DeepCopyInto(out.(*MasterConfiguration))
return nil
Expand Down Expand Up @@ -107,6 +111,22 @@ func (in *Etcd) DeepCopy() *Etcd {
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostPathMount) DeepCopyInto(out *HostPathMount) {
*out = *in
return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPathMount.
func (in *HostPathMount) DeepCopy() *HostPathMount {
if in == nil {
return nil
}
out := new(HostPathMount)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
*out = *in
Expand Down Expand Up @@ -141,6 +161,21 @@ func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
(*out)[key] = val
}
}
if in.APIServerExtraVolumes != nil {
in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.ControllerManagerExtraVolumes != nil {
in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.SchedulerExtraVolumes != nil {
in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.APIServerCertSANs != nil {
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
*out = make([]string, len(*in))
Expand Down
6 changes: 3 additions & 3 deletions cmd/kubeadm/app/phases/controlplane/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.MasterConfiguration, k8sVersion *version.
Name: kubeadmconstants.KubeAPIServer,
Image: images.GetCoreImage(kubeadmconstants.KubeAPIServer, cfg.GetControlPlaneImageRepository(), cfg.KubernetesVersion, cfg.UnifiedControlPlaneImage),
Command: getAPIServerCommand(cfg, k8sVersion),
VolumeMounts: mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer),
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer)),
LivenessProbe: staticpodutil.ComponentProbe(int(cfg.API.BindPort), "/healthz", v1.URISchemeHTTPS),
Resources: staticpodutil.ComponentResources("250m"),
Env: getProxyEnvVars(),
Expand All @@ -86,7 +86,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.MasterConfiguration, k8sVersion *version.
Name: kubeadmconstants.KubeControllerManager,
Image: images.GetCoreImage(kubeadmconstants.KubeControllerManager, cfg.GetControlPlaneImageRepository(), cfg.KubernetesVersion, cfg.UnifiedControlPlaneImage),
Command: getControllerManagerCommand(cfg, k8sVersion),
VolumeMounts: mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager),
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager)),
LivenessProbe: staticpodutil.ComponentProbe(10252, "/healthz", v1.URISchemeHTTP),
Resources: staticpodutil.ComponentResources("200m"),
Env: getProxyEnvVars(),
Expand All @@ -95,7 +95,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.MasterConfiguration, k8sVersion *version.
Name: kubeadmconstants.KubeScheduler,
Image: images.GetCoreImage(kubeadmconstants.KubeScheduler, cfg.GetControlPlaneImageRepository(), cfg.KubernetesVersion, cfg.UnifiedControlPlaneImage),
Command: getSchedulerCommand(cfg),
VolumeMounts: mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler),
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler)),
LivenessProbe: staticpodutil.ComponentProbe(10251, "/healthz", v1.URISchemeHTTP),
Resources: staticpodutil.ComponentResources("100m"),
Env: getProxyEnvVars(),
Expand Down
65 changes: 55 additions & 10 deletions cmd/kubeadm/app/phases/controlplane/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,40 +86,85 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.MasterConfiguration) c
mounts.NewHostPathMount(kubeadmconstants.KubeControllerManager, caCertsPkiVolumeName, caCertsPkiVolumePath, caCertsPkiVolumePath, true, &hostPathDirectoryOrCreate)
}

// Merge user defined mounts and ensure unique volume and volume mount
// names
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeAPIServer, cfg.APIServerExtraVolumes, true, &hostPathDirectoryOrCreate)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeControllerManager, cfg.ControllerManagerExtraVolumes, true, &hostPathDirectoryOrCreate)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeScheduler, cfg.SchedulerExtraVolumes, true, &hostPathDirectoryOrCreate)

return mounts
}

// controlPlaneHostPathMounts is a helper struct for handling all the control plane's hostPath mounts in an easy way
type controlPlaneHostPathMounts struct {
volumes map[string][]v1.Volume
volumeMounts map[string][]v1.VolumeMount
// volumes is a nested map that forces a unique volumes. The outer map's
// keys are a string that should specify the target component to add the
// volume to. The values (inner map) of the outer map are maps with string
// keys and v1.Volume values. The inner map's key should specify the volume
// name.
volumes map[string]map[string]v1.Volume
// volumeMounts is a nested map that forces a unique volume mounts. The
// outer map's keys are a string that should specify the target component
// to add the volume mount to. The values (inner map) of the outer map are
// maps with string keys and v1.VolumeMount values. The inner map's key
// should specify the volume mount name.
volumeMounts map[string]map[string]v1.VolumeMount
}

func newControlPlaneHostPathMounts() controlPlaneHostPathMounts {
return controlPlaneHostPathMounts{
volumes: map[string][]v1.Volume{},
volumeMounts: map[string][]v1.VolumeMount{},
volumes: map[string]map[string]v1.Volume{},
volumeMounts: map[string]map[string]v1.VolumeMount{},
}
}

func (c *controlPlaneHostPathMounts) NewHostPathMount(component, mountName, hostPath, containerPath string, readOnly bool, hostPathType *v1.HostPathType) {
c.volumes[component] = append(c.volumes[component], staticpodutil.NewVolume(mountName, hostPath, hostPathType))
c.volumeMounts[component] = append(c.volumeMounts[component], staticpodutil.NewVolumeMount(mountName, containerPath, readOnly))
vol := staticpodutil.NewVolume(mountName, hostPath, hostPathType)
c.addComponentVolume(component, vol)
volMount := staticpodutil.NewVolumeMount(mountName, containerPath, readOnly)
c.addComponentVolumeMount(component, volMount)
}

func (c *controlPlaneHostPathMounts) AddHostPathMounts(component string, vols []v1.Volume, volMounts []v1.VolumeMount) {
c.volumes[component] = append(c.volumes[component], vols...)
c.volumeMounts[component] = append(c.volumeMounts[component], volMounts...)
for _, v := range vols {
c.addComponentVolume(component, v)
}
for _, v := range volMounts {
c.addComponentVolumeMount(component, v)
}
}

// AddExtraHostPathMounts adds host path mounts and overwrites the default
// paths in the case that a user specifies the same volume/volume mount name.
func (c *controlPlaneHostPathMounts) AddExtraHostPathMounts(component string, extraVols []kubeadmapi.HostPathMount, readOnly bool, hostPathType *v1.HostPathType) {
for _, extraVol := range extraVols {
fmt.Printf("[controlplane] Adding extra host path mount %q to %q\n", extraVol.Name, component)
c.NewHostPathMount(component, extraVol.Name, extraVol.HostPath, extraVol.MountPath, readOnly, hostPathType)
}
}

func (c *controlPlaneHostPathMounts) GetVolumes(component string) []v1.Volume {
func (c *controlPlaneHostPathMounts) GetVolumes(component string) map[string]v1.Volume {
return c.volumes[component]
}

func (c *controlPlaneHostPathMounts) GetVolumeMounts(component string) []v1.VolumeMount {
func (c *controlPlaneHostPathMounts) GetVolumeMounts(component string) map[string]v1.VolumeMount {
return c.volumeMounts[component]
}

func (c *controlPlaneHostPathMounts) addComponentVolume(component string, vol v1.Volume) {
if _, ok := c.volumes[component]; !ok {
c.volumes[component] = map[string]v1.Volume{}
}
c.volumes[component][vol.Name] = vol
}

func (c *controlPlaneHostPathMounts) addComponentVolumeMount(component string, volMount v1.VolumeMount) {
if _, ok := c.volumeMounts[component]; !ok {
c.volumeMounts[component] = map[string]v1.VolumeMount{}
}
c.volumeMounts[component][volMount.Name] = volMount
}

// getEtcdCertVolumes returns the volumes/volumemounts needed for talking to an external etcd cluster
func getEtcdCertVolumes(etcdCfg kubeadmapi.Etcd) ([]v1.Volume, []v1.VolumeMount) {
certPaths := []string{etcdCfg.CAFile, etcdCfg.CertFile, etcdCfg.KeyFile}
Expand Down
Loading