kubeadm: Writable to ReadOnly in HostPathMount

Writable was added to HostPathMount in v1alpha1 in order to control if an extra
volume is mounted in read only or writable mode.
Usually, in Kubernetes, this option is referred to as ReadOnly, instead of
Writable and is defaulted to `false`. However, at the time, all extra volumes
to pods were defaulted to read-only. Therefore, to avoid changes to existing
v1alpha1 configs, this option had to be added with reversed meaning.

Hence, it's called `writable`.

Now, with the migration towards v1beta1, we can safely change this to ReadOnly
and get it in sync with the reset of Kubernetes.

Signed-off-by: Rostislav M. Georgiev <rostislavg@vmware.com>
This commit is contained in:
Rostislav M. Georgiev 2018-10-31 19:12:43 +02:00
parent 879312205f
commit 6c9e347e31
11 changed files with 119 additions and 37 deletions

View File

@ -369,8 +369,8 @@ type HostPathMount struct {
HostPath string HostPath string
// MountPath is the path inside the pod where hostPath will be mounted. // MountPath is the path inside the pod where hostPath will be mounted.
MountPath string MountPath string
// Writable controls write access to the volume // ReadOnly controls write access to the volume
Writable bool ReadOnly bool
// PathType is the type of the HostPath. // PathType is the type of the HostPath.
PathType v1.HostPathType PathType v1.HostPathType
} }

View File

@ -17,8 +17,6 @@ limitations under the License.
package v1alpha3 package v1alpha3
import ( import (
"unsafe"
"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"
) )
@ -85,14 +83,20 @@ func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *C
} }
out.APIServer.ExtraArgs = in.APIServerExtraArgs out.APIServer.ExtraArgs = in.APIServerExtraArgs
out.APIServer.ExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes))
out.APIServer.CertSANs = in.APIServerCertSANs out.APIServer.CertSANs = in.APIServerCertSANs
if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.APIServerExtraVolumes, &out.APIServer.ExtraVolumes, s); err != nil {
return err
}
out.ControllerManager.ExtraArgs = in.ControllerManagerExtraArgs out.ControllerManager.ExtraArgs = in.ControllerManagerExtraArgs
out.ControllerManager.ExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.ControllerManagerExtraVolumes, &out.ControllerManager.ExtraVolumes, s); err != nil {
return err
}
out.Scheduler.ExtraArgs = in.SchedulerExtraArgs out.Scheduler.ExtraArgs = in.SchedulerExtraArgs
out.Scheduler.ExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) if err := convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&in.SchedulerExtraVolumes, &out.Scheduler.ExtraVolumes, s); err != nil {
return err
}
return nil return nil
} }
@ -103,14 +107,66 @@ func Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *k
} }
out.APIServerExtraArgs = in.APIServer.ExtraArgs out.APIServerExtraArgs = in.APIServer.ExtraArgs
out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServer.ExtraVolumes))
out.APIServerCertSANs = in.APIServer.CertSANs out.APIServerCertSANs = in.APIServer.CertSANs
if err := convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&in.APIServer.ExtraVolumes, &out.APIServerExtraVolumes, s); err != nil {
return err
}
out.ControllerManagerExtraArgs = in.ControllerManager.ExtraArgs out.ControllerManagerExtraArgs = in.ControllerManager.ExtraArgs
out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManager.ExtraVolumes)) if err := convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&in.ControllerManager.ExtraVolumes, &out.ControllerManagerExtraVolumes, s); err != nil {
return err
}
out.SchedulerExtraArgs = in.Scheduler.ExtraArgs out.SchedulerExtraArgs = in.Scheduler.ExtraArgs
out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.Scheduler.ExtraVolumes)) if err := convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&in.Scheduler.ExtraVolumes, &out.SchedulerExtraVolumes, s); err != nil {
return err
}
return nil return nil
} }
func Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMount, out *kubeadm.HostPathMount, s conversion.Scope) error {
if err := autoConvert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in, out, s); err != nil {
return err
}
out.ReadOnly = !in.Writable
return nil
}
func Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error {
if err := autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in, out, s); err != nil {
return err
}
out.Writable = !in.ReadOnly
return nil
}
func convertSlice_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *[]HostPathMount, out *[]kubeadm.HostPathMount, s conversion.Scope) error {
if *in != nil {
*out = make([]kubeadm.HostPathMount, len(*in))
for i := range *in {
if err := Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
*out = nil
}
return nil
}
func convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *[]kubeadm.HostPathMount, out *[]HostPathMount, s conversion.Scope) error {
if *in != nil {
*out = make([]HostPathMount, len(*in))
for i := range *in {
if err := Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
*out = nil
}
return nil
}

View File

@ -182,6 +182,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*kubeadm.HostPathMount)(nil), (*HostPathMount)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(a.(*kubeadm.HostPathMount), b.(*HostPathMount), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*kubeadm.JoinConfiguration)(nil), (*JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*kubeadm.JoinConfiguration)(nil), (*JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(a.(*kubeadm.JoinConfiguration), b.(*JoinConfiguration), scope) return Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(a.(*kubeadm.JoinConfiguration), b.(*JoinConfiguration), scope)
}); err != nil { }); err != nil {
@ -192,6 +197,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*HostPathMount)(nil), (*kubeadm.HostPathMount)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(a.(*HostPathMount), b.(*kubeadm.HostPathMount), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*JoinConfiguration)(nil), (*kubeadm.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*JoinConfiguration)(nil), (*kubeadm.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(a.(*JoinConfiguration), b.(*kubeadm.JoinConfiguration), scope) return Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(a.(*JoinConfiguration), b.(*kubeadm.JoinConfiguration), scope)
}); err != nil { }); err != nil {
@ -422,30 +432,20 @@ func autoConvert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMou
out.Name = in.Name out.Name = in.Name
out.HostPath = in.HostPath out.HostPath = in.HostPath
out.MountPath = in.MountPath out.MountPath = in.MountPath
out.Writable = in.Writable // WARNING: in.Writable requires manual conversion: does not exist in peer-type
out.PathType = corev1.HostPathType(in.PathType) out.PathType = corev1.HostPathType(in.PathType)
return nil return nil
} }
// Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount is an autogenerated conversion function.
func Convert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMount, out *kubeadm.HostPathMount, s conversion.Scope) error {
return autoConvert_v1alpha3_HostPathMount_To_kubeadm_HostPathMount(in, out, s)
}
func autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error { func autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error {
out.Name = in.Name out.Name = in.Name
out.HostPath = in.HostPath out.HostPath = in.HostPath
out.MountPath = in.MountPath out.MountPath = in.MountPath
out.Writable = in.Writable // WARNING: in.ReadOnly requires manual conversion: does not exist in peer-type
out.PathType = corev1.HostPathType(in.PathType) out.PathType = corev1.HostPathType(in.PathType)
return nil return nil
} }
// Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount is an autogenerated conversion function.
func Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPathMount, out *HostPathMount, s conversion.Scope) error {
return autoConvert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in, out, s)
}
func autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { func autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
if err := Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil { if err := Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil {
return err return err

View File

@ -207,7 +207,7 @@ limitations under the License.
// - name: "some-volume" // - name: "some-volume"
// hostPath: "/etc/some-path" // hostPath: "/etc/some-path"
// mountPath: "/etc/some-pod-path" // mountPath: "/etc/some-pod-path"
// writable: true // readOnly: false
// pathType: File // pathType: File
// certSANs: // certSANs:
// - "10.100.1.1" // - "10.100.1.1"
@ -219,7 +219,7 @@ limitations under the License.
// - name: "some-volume" // - name: "some-volume"
// hostPath: "/etc/some-path" // hostPath: "/etc/some-path"
// mountPath: "/etc/some-pod-path" // mountPath: "/etc/some-pod-path"
// writable: true // readOnly: false
// pathType: File // pathType: File
// scheduler: // scheduler:
// extraArgs: // extraArgs:
@ -228,7 +228,7 @@ limitations under the License.
// - name: "some-volume" // - name: "some-volume"
// hostPath: "/etc/some-path" // hostPath: "/etc/some-path"
// mountPath: "/etc/some-pod-path" // mountPath: "/etc/some-pod-path"
// writable: true // readOnly: false
// pathType: File // pathType: File
// certificatesDir: "/etc/kubernetes/pki" // certificatesDir: "/etc/kubernetes/pki"
// imageRepository: "k8s.gcr.io" // imageRepository: "k8s.gcr.io"

View File

@ -336,8 +336,8 @@ type HostPathMount struct {
HostPath string `json:"hostPath"` HostPath string `json:"hostPath"`
// MountPath is the path inside the pod where hostPath will be mounted. // MountPath is the path inside the pod where hostPath will be mounted.
MountPath string `json:"mountPath"` MountPath string `json:"mountPath"`
// Writable controls write access to the volume // ReadOnly controls write access to the volume
Writable bool `json:"writable,omitempty"` ReadOnly bool `json:"readOnly,omitempty"`
// PathType is the type of the HostPath. // PathType is the type of the HostPath.
PathType v1.HostPathType `json:"pathType,omitempty"` PathType v1.HostPathType `json:"pathType,omitempty"`
} }

View File

@ -590,7 +590,7 @@ func autoConvert_v1beta1_HostPathMount_To_kubeadm_HostPathMount(in *HostPathMoun
out.Name = in.Name out.Name = in.Name
out.HostPath = in.HostPath out.HostPath = in.HostPath
out.MountPath = in.MountPath out.MountPath = in.MountPath
out.Writable = in.Writable out.ReadOnly = in.ReadOnly
out.PathType = corev1.HostPathType(in.PathType) out.PathType = corev1.HostPathType(in.PathType)
return nil return nil
} }
@ -604,7 +604,7 @@ func autoConvert_kubeadm_HostPathMount_To_v1beta1_HostPathMount(in *kubeadm.Host
out.Name = in.Name out.Name = in.Name
out.HostPath = in.HostPath out.HostPath = in.HostPath
out.MountPath = in.MountPath out.MountPath = in.MountPath
out.Writable = in.Writable out.ReadOnly = in.ReadOnly
out.PathType = corev1.HostPathType(in.PathType) out.PathType = corev1.HostPathType(in.PathType)
return nil return nil
} }

View File

@ -151,7 +151,7 @@ func (c *controlPlaneHostPathMounts) AddExtraHostPathMounts(component string, ex
for _, extraVol := range extraVols { for _, extraVol := range extraVols {
fmt.Printf("[controlplane] Adding extra host path mount %q to %q\n", extraVol.Name, component) fmt.Printf("[controlplane] Adding extra host path mount %q to %q\n", extraVol.Name, component)
hostPathType := extraVol.PathType hostPathType := extraVol.PathType
c.NewHostPathMount(component, extraVol.Name, extraVol.HostPath, extraVol.MountPath, !extraVol.Writable, &hostPathType) c.NewHostPathMount(component, extraVol.Name, extraVol.HostPath, extraVol.MountPath, extraVol.ReadOnly, &hostPathType)
} }
} }

View File

@ -621,28 +621,28 @@ func TestAddExtraHostPathMounts(t *testing.T) {
Name: "foo-0", Name: "foo-0",
HostPath: "/tmp/qux-0", HostPath: "/tmp/qux-0",
MountPath: "/tmp/qux-0", MountPath: "/tmp/qux-0",
Writable: false, ReadOnly: true,
PathType: v1.HostPathFile, PathType: v1.HostPathFile,
}, },
{ {
Name: "bar-0", Name: "bar-0",
HostPath: "/tmp/asd-0", HostPath: "/tmp/asd-0",
MountPath: "/tmp/asd-0", MountPath: "/tmp/asd-0",
Writable: true, ReadOnly: false,
PathType: v1.HostPathDirectory, PathType: v1.HostPathDirectory,
}, },
{ {
Name: "foo-1", Name: "foo-1",
HostPath: "/tmp/qux-1", HostPath: "/tmp/qux-1",
MountPath: "/tmp/qux-1", MountPath: "/tmp/qux-1",
Writable: false, ReadOnly: true,
PathType: v1.HostPathFileOrCreate, PathType: v1.HostPathFileOrCreate,
}, },
{ {
Name: "bar-1", Name: "bar-1",
HostPath: "/tmp/asd-1", HostPath: "/tmp/asd-1",
MountPath: "/tmp/asd-1", MountPath: "/tmp/asd-1",
Writable: true, ReadOnly: false,
PathType: v1.HostPathDirectoryOrCreate, PathType: v1.HostPathDirectoryOrCreate,
}, },
} }
@ -672,8 +672,8 @@ func TestAddExtraHostPathMounts(t *testing.T) {
if volMount.MountPath != hostMount.MountPath { if volMount.MountPath != hostMount.MountPath {
t.Errorf("Expected container path %q", hostMount.MountPath) t.Errorf("Expected container path %q", hostMount.MountPath)
} }
if volMount.ReadOnly != !hostMount.Writable { if volMount.ReadOnly != hostMount.ReadOnly {
t.Errorf("Expected volume writable setting %t", hostMount.Writable) t.Errorf("Expected volume readOnly setting %t", hostMount.ReadOnly)
} }
} }
} }

View File

@ -5,7 +5,17 @@ APIServer:
CertSANs: null CertSANs: null
ExtraArgs: ExtraArgs:
authorization-mode: Node,RBAC,Webhook authorization-mode: Node,RBAC,Webhook
ExtraVolumes: null ExtraVolumes:
- HostPath: /host/read-only
MountPath: /mount/read-only
Name: ReadOnlyVolume
PathType: ""
ReadOnly: true
- HostPath: /host/writable
MountPath: /mount/writable
Name: WritableVolume
PathType: ""
ReadOnly: false
AuditPolicyConfiguration: AuditPolicyConfiguration:
LogDir: /var/log/kubernetes/audit LogDir: /var/log/kubernetes/audit
LogMaxAge: 2 LogMaxAge: 2

View File

@ -20,6 +20,14 @@ nodeRegistration:
--- ---
apiServerExtraArgs: apiServerExtraArgs:
authorization-mode: Node,RBAC,Webhook authorization-mode: Node,RBAC,Webhook
apiServerExtraVolumes:
- hostPath: /host/read-only
mountPath: /mount/read-only
name: ReadOnlyVolume
- hostPath: /host/writable
mountPath: /mount/writable
name: WritableVolume
writable: true
apiVersion: kubeadm.k8s.io/v1alpha3 apiVersion: kubeadm.k8s.io/v1alpha3
auditPolicy: auditPolicy:
logDir: /var/log/kubernetes/audit logDir: /var/log/kubernetes/audit

View File

@ -21,6 +21,14 @@ nodeRegistration:
apiServer: apiServer:
extraArgs: extraArgs:
authorization-mode: Node,RBAC,Webhook authorization-mode: Node,RBAC,Webhook
extraVolumes:
- hostPath: /host/read-only
mountPath: /mount/read-only
name: ReadOnlyVolume
readOnly: true
- hostPath: /host/writable
mountPath: /mount/writable
name: WritableVolume
apiVersion: kubeadm.k8s.io/v1beta1 apiVersion: kubeadm.k8s.io/v1beta1
auditPolicy: auditPolicy:
logDir: /var/log/kubernetes/audit logDir: /var/log/kubernetes/audit