mirror of https://github.com/kubernetes/kops.git
nodeup: Use functional options pattern for HostPathMapping
This means that the object is not mutated after construction, making it easier to do validity checks (such as whether we have mounted the same path twice).
This commit is contained in:
parent
9af580f1ab
commit
6bdbbc4fd4
|
@ -667,7 +667,7 @@ func (b *KubeAPIServerBuilder) buildPod(ctx context.Context, kubeAPIServer *kops
|
|||
}
|
||||
|
||||
// Log both to docker and to the logfile
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-apiserver.log").WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-apiserver.log", kubemanifest.WithReadWrite())
|
||||
// We use lighter containers that don't include shells
|
||||
// But they have richer logging support via klog
|
||||
if b.IsKubernetesGTE("1.23") {
|
||||
|
@ -718,7 +718,7 @@ func (b *KubeAPIServerBuilder) buildPod(ctx context.Context, kubeAPIServer *kops
|
|||
// Renaming is not possible when the file is mounted as the host path, and will return a
|
||||
// 'Device or resource busy' error
|
||||
auditLogPathDir := filepath.Dir(auditLogPath)
|
||||
kubemanifest.AddHostPathMapping(pod, container, "auditlogpathdir", auditLogPathDir).WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "auditlogpathdir", auditLogPathDir, kubemanifest.WithReadWrite())
|
||||
}
|
||||
if kubeAPIServer.AuditPolicyFile != "" {
|
||||
// The audit config dir will be used for both the audit policy and the audit webhook config
|
||||
|
|
|
@ -228,7 +228,7 @@ func (b *KubeControllerManagerBuilder) buildPod(kcm *kops.KubeControllerManagerC
|
|||
}
|
||||
|
||||
// Log both to docker and to the logfile
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-controller-manager.log").WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-controller-manager.log", kubemanifest.WithReadWrite())
|
||||
// We use lighter containers that don't include shells
|
||||
// But they have richer logging support via klog
|
||||
if b.IsKubernetesGTE("1.23") {
|
||||
|
@ -266,7 +266,7 @@ func (b *KubeControllerManagerBuilder) buildPod(kcm *kops.KubeControllerManagerC
|
|||
|
||||
kubemanifest.AddHostPathMapping(pod, container, "varlibkcm", "/var/lib/kube-controller-manager")
|
||||
|
||||
kubemanifest.AddHostPathMapping(pod, container, "volplugins", volumePluginDir).WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "volplugins", volumePluginDir, kubemanifest.WithReadWrite())
|
||||
|
||||
pod.Spec.Containers = append(pod.Spec.Containers, *container)
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ func (b *KubeProxyBuilder) buildPod() (*v1.Pod, error) {
|
|||
}
|
||||
|
||||
// Log both to docker and to the logfile
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-proxy.log").WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-proxy.log", kubemanifest.WithReadWrite())
|
||||
// We use lighter containers that don't include shells
|
||||
// But they have richer logging support via klog
|
||||
if b.IsKubernetesGTE("1.23") {
|
||||
|
@ -205,8 +205,7 @@ func (b *KubeProxyBuilder) buildPod() (*v1.Pod, error) {
|
|||
kubemanifest.AddHostPathMapping(pod, container, "modules", "/lib/modules")
|
||||
|
||||
// Map SSL certs from host: /usr/share/ca-certificates -> /etc/ssl/certs
|
||||
sslCertsHost := kubemanifest.AddHostPathMapping(pod, container, "ssl-certs-hosts", "/usr/share/ca-certificates")
|
||||
sslCertsHost.VolumeMount.MountPath = "/etc/ssl/certs"
|
||||
kubemanifest.AddHostPathMapping(pod, container, "ssl-certs-hosts", "/usr/share/ca-certificates", kubemanifest.WithMountPath("/etc/ssl/certs"))
|
||||
}
|
||||
|
||||
if b.IsGossip {
|
||||
|
@ -216,7 +215,7 @@ func (b *KubeProxyBuilder) buildPod() (*v1.Pod, error) {
|
|||
|
||||
// Mount the iptables lock file
|
||||
{
|
||||
kubemanifest.AddHostPathMapping(pod, container, "iptableslock", "/run/xtables.lock").WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "iptableslock", "/run/xtables.lock", kubemanifest.WithReadWrite())
|
||||
|
||||
vol := pod.Spec.Volumes[len(pod.Spec.Volumes)-1]
|
||||
if vol.Name != "iptableslock" {
|
||||
|
|
|
@ -248,7 +248,7 @@ func (b *KubeSchedulerBuilder) buildPod(kubeScheduler *kops.KubeSchedulerConfig)
|
|||
kubemanifest.AddHostPathMapping(pod, container, "srvscheduler", pathSrvScheduler)
|
||||
|
||||
// Log both to docker and to the logfile
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-scheduler.log").WithReadWrite()
|
||||
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-scheduler.log", kubemanifest.WithReadWrite())
|
||||
// We use lighter containers that don't include shells
|
||||
// But they have richer logging support via klog
|
||||
if b.IsKubernetesGTE("1.23") {
|
||||
|
|
|
@ -20,21 +20,12 @@ import (
|
|||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// MapEtcHosts maps the /etc/hosts file into the pod (useful for gossip DNS)
|
||||
func MapEtcHosts(pod *v1.Pod, container *v1.Container, readOnly bool) {
|
||||
mapping := AddHostPathMapping(pod, container, "hosts", "/etc/hosts").WithType(v1.HostPathFile)
|
||||
mapping.VolumeMount.ReadOnly = readOnly
|
||||
}
|
||||
|
||||
// HostPathMapping allows fluent construction of a hostpath mount
|
||||
type HostPathMapping struct {
|
||||
VolumeMount *v1.VolumeMount
|
||||
Volume *v1.Volume
|
||||
}
|
||||
// HostPathMappingOption implements the "functional options pattern" for named variable parameters.
|
||||
type HostPathMappingOption func(volumeMount *v1.VolumeMount, volume *v1.Volume)
|
||||
|
||||
// AddHostPathMapping is a helper function for mapping a host path into a container
|
||||
// It returns a HostPathMapping for tweaking the defaults (which are notably read-only)
|
||||
func AddHostPathMapping(pod *v1.Pod, container *v1.Container, name, path string) *HostPathMapping {
|
||||
func AddHostPathMapping(pod *v1.Pod, container *v1.Container, name, path string, options ...HostPathMappingOption) {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
|
||||
Name: name,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
|
@ -50,26 +41,38 @@ func AddHostPathMapping(pod *v1.Pod, container *v1.Container, name, path string)
|
|||
ReadOnly: true,
|
||||
})
|
||||
|
||||
return &HostPathMapping{
|
||||
Volume: &pod.Spec.Volumes[len(pod.Spec.Volumes)-1],
|
||||
VolumeMount: &container.VolumeMounts[len(container.VolumeMounts)-1],
|
||||
volume := &pod.Spec.Volumes[len(pod.Spec.Volumes)-1]
|
||||
volumeMount := &container.VolumeMounts[len(container.VolumeMounts)-1]
|
||||
|
||||
for _, option := range options {
|
||||
option(volumeMount, volume)
|
||||
}
|
||||
}
|
||||
|
||||
// WithReadWrite changes the hostpath mapping to be read-write (the default is read-only)
|
||||
func (m *HostPathMapping) WithReadWrite() *HostPathMapping {
|
||||
m.VolumeMount.ReadOnly = false
|
||||
return m
|
||||
func WithReadWrite() HostPathMappingOption {
|
||||
return func(volumeMount *v1.VolumeMount, volume *v1.Volume) {
|
||||
volumeMount.ReadOnly = false
|
||||
}
|
||||
}
|
||||
|
||||
// WithType changes the hostpath mount type
|
||||
func (m *HostPathMapping) WithType(t v1.HostPathType) *HostPathMapping {
|
||||
m.Volume.VolumeSource.HostPath.Type = &t
|
||||
return m
|
||||
func WithType(t v1.HostPathType) HostPathMappingOption {
|
||||
return func(volumeMount *v1.VolumeMount, volume *v1.Volume) {
|
||||
volume.VolumeSource.HostPath.Type = &t
|
||||
}
|
||||
}
|
||||
|
||||
// WithHostPath changes the hostpath path
|
||||
func (m *HostPathMapping) WithHostPath(p string) *HostPathMapping {
|
||||
m.Volume.VolumeSource.HostPath.Path = p
|
||||
return m
|
||||
// WithHostPath changes the host path (the path in the host)
|
||||
func WithHostPath(p string) HostPathMappingOption {
|
||||
return func(volumeMount *v1.VolumeMount, volume *v1.Volume) {
|
||||
volume.VolumeSource.HostPath.Path = p
|
||||
}
|
||||
}
|
||||
|
||||
// WithMountPath changes the mount path (the path in the container)
|
||||
func WithMountPath(p string) HostPathMappingOption {
|
||||
return func(volumeMount *v1.VolumeMount, volume *v1.Volume) {
|
||||
volumeMount.MountPath = p
|
||||
}
|
||||
}
|
||||
|
|
|
@ -518,10 +518,13 @@ func (b *EtcdManagerBuilder) buildPod(etcdCluster kops.EtcdClusterSpec, instance
|
|||
},
|
||||
}
|
||||
|
||||
kubemanifest.AddHostPathMapping(pod, container, "varlogetcd", "/var/log/etcd.log").WithReadWrite().WithType(v1.HostPathFileOrCreate).WithHostPath(logFile)
|
||||
kubemanifest.AddHostPathMapping(pod, container, "varlogetcd", "/var/log/etcd.log",
|
||||
kubemanifest.WithReadWrite(),
|
||||
kubemanifest.WithType(v1.HostPathFileOrCreate),
|
||||
kubemanifest.WithHostPath(logFile))
|
||||
|
||||
if fi.ValueOf(b.Cluster.Spec.UseHostCertificates) {
|
||||
kubemanifest.AddHostPathMapping(pod, container, "etc-ssl-certs", "/etc/ssl/certs").WithType(v1.HostPathDirectoryOrCreate)
|
||||
kubemanifest.AddHostPathMapping(pod, container, "etc-ssl-certs", "/etc/ssl/certs", kubemanifest.WithType(v1.HostPathDirectoryOrCreate))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue