mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Allow extra volumes to be defined
This commit is contained in:
parent
6daba6a272
commit
5a64c049e6
@ -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
|
||||
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
@ -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"`
|
||||
}
|
||||
|
@ -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(),
|
||||
@ -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(),
|
||||
@ -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(),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controlPlaneHostPathMounts) GetVolumes(component string) []v1.Volume {
|
||||
// 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) 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}
|
||||
|
@ -249,10 +249,251 @@ func TestGetEtcdCertVolumes(t *testing.T) {
|
||||
func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
||||
hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
|
||||
hostPathFileOrCreate := v1.HostPathFileOrCreate
|
||||
volMap := make(map[string]map[string]v1.Volume)
|
||||
volMap[kubeadmconstants.KubeAPIServer] = map[string]v1.Volume{}
|
||||
volMap[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.Volume{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.Volume{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap[kubeadmconstants.KubeControllerManager] = map[string]v1.Volume{}
|
||||
volMap[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.Volume{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.Volume{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.Volume{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/controller-manager.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap[kubeadmconstants.KubeControllerManager]["flexvolume-dir"] = v1.Volume{
|
||||
Name: "flexvolume-dir",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap[kubeadmconstants.KubeScheduler] = map[string]v1.Volume{}
|
||||
volMap[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.Volume{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/scheduler.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMountMap := make(map[string]map[string]v1.VolumeMount)
|
||||
volMountMap[kubeadmconstants.KubeAPIServer] = map[string]v1.VolumeMount{}
|
||||
volMountMap[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.VolumeMount{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.VolumeMount{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap[kubeadmconstants.KubeControllerManager] = map[string]v1.VolumeMount{}
|
||||
volMountMap[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.VolumeMount{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.VolumeMount{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.VolumeMount{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/controller-manager.conf",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap[kubeadmconstants.KubeControllerManager]["flexvolume-dir"] = v1.VolumeMount{
|
||||
Name: "flexvolume-dir",
|
||||
MountPath: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
ReadOnly: false,
|
||||
}
|
||||
volMountMap[kubeadmconstants.KubeScheduler] = map[string]v1.VolumeMount{}
|
||||
volMountMap[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.VolumeMount{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/scheduler.conf",
|
||||
ReadOnly: true,
|
||||
}
|
||||
|
||||
volMap2 := make(map[string]map[string]v1.Volume)
|
||||
volMap2[kubeadmconstants.KubeAPIServer] = map[string]v1.Volume{}
|
||||
volMap2[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.Volume{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.Volume{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-0"] = v1.Volume{
|
||||
Name: "etcd-certs-0",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/certs/etcd",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-1"] = v1.Volume{
|
||||
Name: "etcd-certs-1",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/var/lib/certs/etcd",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeControllerManager] = map[string]v1.Volume{}
|
||||
volMap2[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.Volume{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.Volume{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.Volume{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/controller-manager.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeControllerManager]["flexvolume-dir"] = v1.Volume{
|
||||
Name: "flexvolume-dir",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMap2[kubeadmconstants.KubeScheduler] = map[string]v1.Volume{}
|
||||
volMap2[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.Volume{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/scheduler.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
}
|
||||
volMountMap2 := make(map[string]map[string]v1.VolumeMount)
|
||||
volMountMap2[kubeadmconstants.KubeAPIServer] = map[string]v1.VolumeMount{}
|
||||
volMountMap2[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.VolumeMount{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.VolumeMount{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-0"] = v1.VolumeMount{
|
||||
Name: "etcd-certs-0",
|
||||
MountPath: "/etc/certs/etcd",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-1"] = v1.VolumeMount{
|
||||
Name: "etcd-certs-1",
|
||||
MountPath: "/var/lib/certs/etcd",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeControllerManager] = map[string]v1.VolumeMount{}
|
||||
volMountMap2[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.VolumeMount{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.VolumeMount{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.VolumeMount{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/controller-manager.conf",
|
||||
ReadOnly: true,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeControllerManager]["flexvolume-dir"] = v1.VolumeMount{
|
||||
Name: "flexvolume-dir",
|
||||
MountPath: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
ReadOnly: false,
|
||||
}
|
||||
volMountMap2[kubeadmconstants.KubeScheduler] = map[string]v1.VolumeMount{}
|
||||
volMountMap2[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.VolumeMount{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/scheduler.conf",
|
||||
ReadOnly: true,
|
||||
}
|
||||
var tests = []struct {
|
||||
cfg *kubeadmapi.MasterConfiguration
|
||||
vol map[string][]v1.Volume
|
||||
volMount map[string][]v1.VolumeMount
|
||||
vol map[string]map[string]v1.Volume
|
||||
volMount map[string]map[string]v1.VolumeMount
|
||||
}{
|
||||
{
|
||||
// Should ignore files in /etc/ssl/certs
|
||||
@ -260,120 +501,8 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
||||
CertificatesDir: testCertsDir,
|
||||
Etcd: kubeadmapi.Etcd{},
|
||||
},
|
||||
vol: map[string][]v1.Volume{
|
||||
kubeadmconstants.KubeAPIServer: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeControllerManager: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/controller-manager.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flexvolume-dir",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeScheduler: {
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/scheduler.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
volMount: map[string][]v1.VolumeMount{
|
||||
kubeadmconstants.KubeAPIServer: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeControllerManager: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/controller-manager.conf",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "flexvolume-dir",
|
||||
MountPath: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeScheduler: {
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/scheduler.conf",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
vol: volMap,
|
||||
volMount: volMountMap,
|
||||
},
|
||||
{
|
||||
// Should ignore files in /etc/ssl/certs
|
||||
@ -386,148 +515,8 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
||||
KeyFile: "/var/lib/certs/etcd/my-etcd.key",
|
||||
},
|
||||
},
|
||||
vol: map[string][]v1.Volume{
|
||||
kubeadmconstants.KubeAPIServer: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "etcd-certs-0",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/certs/etcd",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "etcd-certs-1",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/var/lib/certs/etcd",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeControllerManager: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: testCertsDir,
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/ssl/certs",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/controller-manager.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flexvolume-dir",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeScheduler: {
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/etc/kubernetes/scheduler.conf",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
volMount: map[string][]v1.VolumeMount{
|
||||
kubeadmconstants.KubeAPIServer: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "etcd-certs-0",
|
||||
MountPath: "/etc/certs/etcd",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "etcd-certs-1",
|
||||
MountPath: "/var/lib/certs/etcd",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeControllerManager: {
|
||||
{
|
||||
Name: "k8s-certs",
|
||||
MountPath: testCertsDir,
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "ca-certs",
|
||||
MountPath: "/etc/ssl/certs",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/controller-manager.conf",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "flexvolume-dir",
|
||||
MountPath: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec",
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
kubeadmconstants.KubeScheduler: {
|
||||
{
|
||||
Name: "kubeconfig",
|
||||
MountPath: "/etc/kubernetes/scheduler.conf",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
vol: volMap2,
|
||||
volMount: volMountMap2,
|
||||
},
|
||||
}
|
||||
|
||||
@ -559,3 +548,70 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddExtraHostPathMounts(t *testing.T) {
|
||||
mounts := newControlPlaneHostPathMounts()
|
||||
hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
|
||||
hostPathFileOrCreate := v1.HostPathFileOrCreate
|
||||
vols := []v1.Volume{
|
||||
{
|
||||
Name: "foo",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/tmp/foo",
|
||||
Type: &hostPathDirectoryOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "/tmp/bar",
|
||||
Type: &hostPathFileOrCreate,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
volMounts := []v1.VolumeMount{
|
||||
{
|
||||
Name: "foo",
|
||||
MountPath: "/tmp/foo",
|
||||
ReadOnly: true,
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
MountPath: "/tmp/bar",
|
||||
ReadOnly: true,
|
||||
},
|
||||
}
|
||||
mounts.AddHostPathMounts("component", vols, volMounts)
|
||||
hostPathMounts := []kubeadmapi.HostPathMount{
|
||||
{
|
||||
Name: "foo",
|
||||
HostPath: "/tmp/qux",
|
||||
MountPath: "/tmp/qux",
|
||||
},
|
||||
}
|
||||
mounts.AddExtraHostPathMounts("component", hostPathMounts, true, &hostPathDirectoryOrCreate)
|
||||
if _, ok := mounts.volumes["component"]["foo"]; !ok {
|
||||
t.Errorf("Expected to find volume %q", "foo")
|
||||
}
|
||||
vol, _ := mounts.volumes["component"]["foo"]
|
||||
if vol.Name != "foo" {
|
||||
t.Errorf("Expected volume name %q", "foo")
|
||||
}
|
||||
if vol.HostPath.Path != "/tmp/qux" {
|
||||
t.Errorf("Expected host path %q", "/tmp/qux")
|
||||
}
|
||||
if _, ok := mounts.volumeMounts["component"]["foo"]; !ok {
|
||||
t.Errorf("Expected to find volume mount %q", "foo")
|
||||
}
|
||||
volMount, _ := mounts.volumeMounts["component"]["foo"]
|
||||
if volMount.Name != "foo" {
|
||||
t.Errorf("Expected volume mount name %q", "foo")
|
||||
}
|
||||
if volMount.MountPath != "/tmp/qux" {
|
||||
t.Errorf("Expected container path %q", "/tmp/qux")
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.Ma
|
||||
// NB. GetEtcdPodSpec methods holds the information about how kubeadm creates etcd static pod mainfests.
|
||||
func GetEtcdPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.Pod {
|
||||
pathType := v1.HostPathDirectoryOrCreate
|
||||
etcdMounts := map[string]v1.Volume{
|
||||
etcdVolumeName: staticpodutil.NewVolume(etcdVolumeName, cfg.Etcd.DataDir, &pathType),
|
||||
}
|
||||
return staticpodutil.ComponentPod(v1.Container{
|
||||
Name: kubeadmconstants.Etcd,
|
||||
Command: getEtcdCommand(cfg),
|
||||
@ -57,7 +60,7 @@ func GetEtcdPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.Pod {
|
||||
// Mount the etcd datadir path read-write so etcd can store data in a more persistent manner
|
||||
VolumeMounts: []v1.VolumeMount{staticpodutil.NewVolumeMount(etcdVolumeName, cfg.Etcd.DataDir, false)},
|
||||
LivenessProbe: staticpodutil.ComponentProbe(2379, "/health", v1.URISchemeHTTP),
|
||||
}, []v1.Volume{staticpodutil.NewVolume(etcdVolumeName, cfg.Etcd.DataDir, &pathType)})
|
||||
}, etcdMounts)
|
||||
}
|
||||
|
||||
// getEtcdCommand builds the right etcd command from the given config object
|
||||
|
@ -31,7 +31,7 @@ import (
|
||||
)
|
||||
|
||||
// ComponentPod returns a Pod object from the container and volume specifications
|
||||
func ComponentPod(container v1.Container, volumes []v1.Volume) v1.Pod {
|
||||
func ComponentPod(container v1.Container, volumes map[string]v1.Volume) v1.Pod {
|
||||
return v1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
@ -48,7 +48,7 @@ func ComponentPod(container v1.Container, volumes []v1.Volume) v1.Pod {
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{container},
|
||||
HostNetwork: true,
|
||||
Volumes: volumes,
|
||||
Volumes: VolumeMapToSlice(volumes),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -102,6 +102,28 @@ func NewVolumeMount(name, path string, readOnly bool) v1.VolumeMount {
|
||||
}
|
||||
}
|
||||
|
||||
// VolumeMapToSlice returns a slice of volumes from a map's values
|
||||
func VolumeMapToSlice(volumes map[string]v1.Volume) []v1.Volume {
|
||||
v := make([]v1.Volume, 0, len(volumes))
|
||||
|
||||
for _, vol := range volumes {
|
||||
v = append(v, vol)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// VolumeMountMapToSlice returns a slice of volumes from a map's values
|
||||
func VolumeMountMapToSlice(volumeMounts map[string]v1.VolumeMount) []v1.VolumeMount {
|
||||
v := make([]v1.VolumeMount, 0, len(volumeMounts))
|
||||
|
||||
for _, volMount := range volumeMounts {
|
||||
v = append(v, volMount)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// GetExtraParameters builds a list of flag arguments two string-string maps, one with default, base commands and one with overrides
|
||||
func GetExtraParameters(overrides map[string]string, defaults map[string]string) []string {
|
||||
var command []string
|
||||
|
@ -111,7 +111,7 @@ func TestComponentPod(t *testing.T) {
|
||||
|
||||
for _, rt := range tests {
|
||||
c := v1.Container{Name: rt.name}
|
||||
actual := ComponentPod(c, []v1.Volume{})
|
||||
actual := ComponentPod(c, map[string]v1.Volume{})
|
||||
if !reflect.DeepEqual(rt.expected, actual) {
|
||||
t.Errorf(
|
||||
"failed componentPod:\n\texpected: %v\n\t actual: %v",
|
||||
@ -198,6 +198,35 @@ func TestNewVolumeMount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestVolumeMapToSlice(t *testing.T) {
|
||||
testVolumes := map[string]v1.Volume{
|
||||
"foo": {
|
||||
Name: "foo",
|
||||
},
|
||||
}
|
||||
volumeSlice := VolumeMapToSlice(testVolumes)
|
||||
if len(volumeSlice) != 1 {
|
||||
t.Errorf("Expected slice length of 1, got %d", len(volumeSlice))
|
||||
}
|
||||
if volumeSlice[0].Name != "foo" {
|
||||
t.Errorf("Expected volume name \"foo\", got %s", volumeSlice[0].Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVolumeMountMapToSlice(t *testing.T) {
|
||||
testVolumeMounts := map[string]v1.VolumeMount{
|
||||
"foo": {
|
||||
Name: "foo",
|
||||
},
|
||||
}
|
||||
volumeMountSlice := VolumeMountMapToSlice(testVolumeMounts)
|
||||
if len(volumeMountSlice) != 1 {
|
||||
t.Errorf("Expected slice length of 1, got %d", len(volumeMountSlice))
|
||||
}
|
||||
if volumeMountSlice[0].Name != "foo" {
|
||||
t.Errorf("Expected volume mount name \"foo\", got %s", volumeMountSlice[0].Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExtraParameters(t *testing.T) {
|
||||
var tests = []struct {
|
||||
|
Loading…
Reference in New Issue
Block a user