Skip to content

Commit

Permalink
kubeadm: ensure that flex volume path is write-able
Browse files Browse the repository at this point in the history
In kubernetes#84468 we added a host path mount for a flex volume which is needed
by the controller manager. We should pre-check if the path is write-able
at all because the default path might be read-only. To do this, we now
do an `os.MkdirAll` and propagate the error up to to the caller.

Signed-off-by: Sascha Grunert <sgrunert@suse.com>
  • Loading branch information
saschagrunert committed Jan 13, 2020
1 parent 36e40fb commit 19b394b
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 9 deletions.
5 changes: 4 additions & 1 deletion cmd/kubeadm/app/cmd/upgrade/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ func runDiff(flags *diffFlags, args []string) error {

cfg.ClusterConfiguration.KubernetesVersion = flags.newK8sVersionStr

specs := controlplane.GetStaticPodSpecs(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint)
specs, err := controlplane.GetStaticPodSpecs(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint)
if err != nil {
return err
}
for spec, pod := range specs {
var path string
switch spec {
Expand Down
14 changes: 10 additions & 4 deletions cmd/kubeadm/app/phases/controlplane/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ func CreateInitStaticPodManifestFiles(manifestDir, kustomizeDir string, cfg *kub

// GetStaticPodSpecs returns all staticPodSpecs actualized to the context of the current configuration
// NB. this methods 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) (map[string]v1.Pod, error) {
// Get the required hostpath mounts
mounts := getHostPathVolumesForTheControlPlane(cfg)
mounts, err := getHostPathVolumesForTheControlPlane(cfg)
if err != nil {
return nil, err
}

// Prepare static pod specs
staticPodSpecs := map[string]v1.Pod{
Expand Down Expand Up @@ -81,14 +84,17 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
Env: kubeadmutil.GetProxyEnvVars(),
}, mounts.GetVolumes(kubeadmconstants.KubeScheduler)),
}
return staticPodSpecs
return staticPodSpecs, nil
}

// CreateStaticPodFiles creates all the requested static pod files.
func CreateStaticPodFiles(manifestDir, kustomizeDir string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, componentNames ...string) error {
// gets the StaticPodSpecs, actualized for the current ClusterConfiguration
klog.V(1).Infoln("[control-plane] getting StaticPodSpecs")
specs := GetStaticPodSpecs(cfg, endpoint)
specs, err := GetStaticPodSpecs(cfg, endpoint)
if err != nil {
return err
}

// creates required static pod specs
for _, componentName := range componentNames {
Expand Down
5 changes: 4 additions & 1 deletion cmd/kubeadm/app/phases/controlplane/manifests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ func TestGetStaticPodSpecs(t *testing.T) {
}

// Executes GetStaticPodSpecs
specs := GetStaticPodSpecs(cfg, &kubeadmapi.APIEndpoint{})
specs, err := GetStaticPodSpecs(cfg, &kubeadmapi.APIEndpoint{})
if err != nil {
t.Errorf("unable to get static pod specs")
}

var tests = []struct {
name string
Expand Down
10 changes: 8 additions & 2 deletions cmd/kubeadm/app/phases/controlplane/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"path/filepath"
"strings"

"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
Expand All @@ -42,7 +43,7 @@ const (
var caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates", "/usr/local/share/ca-certificates", "/etc/ca-certificates"}

// getHostPathVolumesForTheControlPlane gets the required hostPath volumes and mounts for the control plane
func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration) controlPlaneHostPathMounts {
func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration) (controlPlaneHostPathMounts, error) {
hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
hostPathFileOrCreate := v1.HostPathFileOrCreate
mounts := newControlPlaneHostPathMounts()
Expand Down Expand Up @@ -75,6 +76,11 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration)
if !ok {
flexvolumeDirVolumePath = defaultFlexvolumeDirVolumePath
}

// The flex volume dir mount needs to be write-able by the controller manager
if err := os.MkdirAll(flexvolumeDirVolumeName, 0o755); err != nil {
return mounts, errors.Wrapf(err, "unable to create necessary flex volume dir mount")
}
mounts.NewHostPathMount(kubeadmconstants.KubeControllerManager, flexvolumeDirVolumeName, flexvolumeDirVolumePath, flexvolumeDirVolumePath, false, &hostPathDirectoryOrCreate)

// HostPath volumes for the scheduler
Expand All @@ -98,7 +104,7 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeControllerManager, cfg.ControllerManager.ExtraVolumes)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeScheduler, cfg.Scheduler.ExtraVolumes)

return mounts
return mounts, nil
}

// controlPlaneHostPathMounts is a helper struct for handling all the control plane's hostPath mounts in an easy way
Expand Down
5 changes: 4 additions & 1 deletion cmd/kubeadm/app/phases/controlplane/volumes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,10 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {

for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) {
mounts := getHostPathVolumesForTheControlPlane(rt.cfg)
mounts, err := getHostPathVolumesForTheControlPlane(rt.cfg)
if err != nil {
t.Fatalf("Couldn't get host path volumes for the control plane")
}

// Avoid unit test errors when the flexvolume is mounted
delete(mounts.volumes[kubeadmconstants.KubeControllerManager], flexvolumeDirVolumeName)
Expand Down

0 comments on commit 19b394b

Please sign in to comment.