Merge pull request #60428 from rosti/kubeadm-readOnly-opt

Automatic merge from submit-queue (batch tested with PRs 60696, 60876, 60901, 60925, 60428). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

kubeadm: Add writable option to *ExtraVolumes init config

**What this PR does / why we need it**:
This PR adds `writable` boolean option for each volume under the `apiServerExtraVolumes`, `controllerManagerExtraVolumes` and `schedulerExtraVolumes` kubeadm init config keys. The option controls write access on a per-volume basis. It is inverted and transferred to the corresponding static pod YAML file as the `readOnly` option of kubelet.

The default value for `writable` is `false`, which does not change the current kubeadm behavior.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Partial fix for #58587

**Special notes for your reviewer**:

/cc @kubernetes/sig-cluster-lifecycle-pr-reviews
/area kubeadm
/assign @luxas
/assign @timothysc

**Release note**:
```release-note
kubeadm: Add the writable boolean option to kubeadm config. The option works on a per-volume basis for *ExtraVolumes config keys.
```
This commit is contained in:
Kubernetes Submit Queue 2018-03-20 13:36:25 -07:00 committed by GitHub
commit ab639118e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 25 deletions

View File

@ -60,6 +60,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
Name: "foo",
HostPath: "foo",
MountPath: "foo",
Writable: false,
}}
obj.Etcd.ExtraArgs = map[string]string{"foo": "foo"}
obj.Etcd.SelfHosted = &kubeadm.SelfHostedEtcd{

View File

@ -281,6 +281,8 @@ type HostPathMount struct {
HostPath string
// MountPath is the path inside the pod where hostPath will be mounted.
MountPath string
// Writable controls write access to the volume
Writable bool
}
// KubeProxy contains elements describing the proxy configuration.

View File

@ -259,6 +259,8 @@ type HostPathMount struct {
HostPath string `json:"hostPath"`
// MountPath is the path inside the pod where hostPath will be mounted.
MountPath string `json:"mountPath"`
// Writable controls write access to the volume
Writable bool `json:"writable,omitempty"`
}
// KubeProxy contains elements describing the proxy configuration.

View File

@ -155,6 +155,7 @@ func autoConvert_v1alpha1_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMou
out.Name = in.Name
out.HostPath = in.HostPath
out.MountPath = in.MountPath
out.Writable = in.Writable
return nil
}
@ -167,6 +168,7 @@ func autoConvert_kubeadm_HostPathMount_To_v1alpha1_HostPathMount(in *kubeadm.Hos
out.Name = in.Name
out.HostPath = in.HostPath
out.MountPath = in.MountPath
out.Writable = in.Writable
return nil
}

View File

@ -105,9 +105,9 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.MasterConfiguration) c
// 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)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeAPIServer, cfg.APIServerExtraVolumes, &hostPathDirectoryOrCreate)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeControllerManager, cfg.ControllerManagerExtraVolumes, &hostPathDirectoryOrCreate)
mounts.AddExtraHostPathMounts(kubeadmconstants.KubeScheduler, cfg.SchedulerExtraVolumes, &hostPathDirectoryOrCreate)
return mounts
}
@ -153,10 +153,10 @@ func (c *controlPlaneHostPathMounts) AddHostPathMounts(component string, vols []
// 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) {
func (c *controlPlaneHostPathMounts) AddExtraHostPathMounts(component string, extraVols []kubeadmapi.HostPathMount, 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)
c.NewHostPathMount(component, extraVol.Name, extraVol.HostPath, extraVol.MountPath, !extraVol.Writable, hostPathType)
}
}

View File

@ -618,27 +618,40 @@ func TestAddExtraHostPathMounts(t *testing.T) {
Name: "foo",
HostPath: "/tmp/qux",
MountPath: "/tmp/qux",
Writable: false,
},
{
Name: "bar",
HostPath: "/tmp/asd",
MountPath: "/tmp/asd",
Writable: true,
},
}
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")
mounts.AddExtraHostPathMounts("component", hostPathMounts, &hostPathDirectoryOrCreate)
for _, hostMount := range hostPathMounts {
volumeName := hostMount.Name
if _, ok := mounts.volumes["component"][volumeName]; !ok {
t.Errorf("Expected to find volume %q", volumeName)
}
vol := mounts.volumes["component"][volumeName]
if vol.Name != volumeName {
t.Errorf("Expected volume name %q", volumeName)
}
if vol.HostPath.Path != hostMount.HostPath {
t.Errorf("Expected host path %q", hostMount.HostPath)
}
if _, ok := mounts.volumeMounts["component"][volumeName]; !ok {
t.Errorf("Expected to find volume mount %q", volumeName)
}
volMount, _ := mounts.volumeMounts["component"][volumeName]
if volMount.Name != volumeName {
t.Errorf("Expected volume mount name %q", volumeName)
}
if volMount.MountPath != hostMount.MountPath {
t.Errorf("Expected container path %q", hostMount.MountPath)
}
if volMount.ReadOnly != !hostMount.Writable {
t.Errorf("Expected volume writable setting %t", hostMount.Writable)
}
}
}