Enhance AddHostPathMapping to support a fluent style

This allows for the helper to be used in more places.
This commit is contained in:
justinsb 2021-12-31 12:06:29 -05:00
parent d708d7008f
commit 45ad8b50ae
7 changed files with 71 additions and 86 deletions

View File

@ -20,7 +20,6 @@ import (
"fmt"
"sort"
v1 "k8s.io/api/core/v1"
"k8s.io/kops/upup/pkg/fi"
)
@ -50,23 +49,3 @@ func sortedStrings(list []string) []string {
return list
}
// addHostPathMapping is shorthand for mapping a host path into a container
func addHostPathMapping(pod *v1.Pod, container *v1.Container, name, path string) *v1.VolumeMount {
pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
Name: name,
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: path,
},
},
})
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
Name: name,
MountPath: path,
ReadOnly: true,
})
return &container.VolumeMounts[len(container.VolumeMounts)-1]
}

View File

@ -625,7 +625,7 @@ func (b *KubeAPIServerBuilder) buildPod(kubeAPIServer *kops.KubeAPIServerConfig)
}
// Log both to docker and to the logfile
addHostPathMapping(pod, container, "logfile", "/var/log/kube-apiserver.log").ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-apiserver.log").WithReadWrite()
// We use lighter containers that don't include shells
// But they have richer logging support via klog
if b.IsKubernetesGTE("1.23") {
@ -647,22 +647,22 @@ func (b *KubeAPIServerBuilder) buildPod(kubeAPIServer *kops.KubeAPIServerConfig)
for _, path := range b.SSLHostPaths() {
name := strings.Replace(path, "/", "", -1)
addHostPathMapping(pod, container, name, path)
kubemanifest.AddHostPathMapping(pod, container, name, path)
}
// Add cloud config file if needed
if b.Cluster.Spec.CloudConfig != nil {
addHostPathMapping(pod, container, "cloudconfig", InTreeCloudConfigFilePath)
kubemanifest.AddHostPathMapping(pod, container, "cloudconfig", InTreeCloudConfigFilePath)
}
addHostPathMapping(pod, container, "kubernetesca", filepath.Join(b.PathSrvKubernetes(), "ca.crt"))
kubemanifest.AddHostPathMapping(pod, container, "kubernetesca", filepath.Join(b.PathSrvKubernetes(), "ca.crt"))
pathSrvKAPI := filepath.Join(b.PathSrvKubernetes(), "kube-apiserver")
addHostPathMapping(pod, container, "srvkapi", pathSrvKAPI)
kubemanifest.AddHostPathMapping(pod, container, "srvkapi", pathSrvKAPI)
pathSrvSshproxy := b.PathSrvSshproxy()
if pathSrvSshproxy != "" {
addHostPathMapping(pod, container, "srvsshproxy", pathSrvSshproxy)
kubemanifest.AddHostPathMapping(pod, container, "srvsshproxy", pathSrvSshproxy)
}
auditLogPath := kubeAPIServer.AuditLogPath
@ -673,12 +673,12 @@ func (b *KubeAPIServerBuilder) buildPod(kubeAPIServer *kops.KubeAPIServerConfig)
// 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)
addHostPathMapping(pod, container, "auditlogpathdir", auditLogPathDir).ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "auditlogpathdir", auditLogPathDir).WithReadWrite()
}
if b.Cluster.Spec.Authentication != nil {
if b.Cluster.Spec.Authentication.Kopeio != nil || b.Cluster.Spec.Authentication.AWS != nil {
addHostPathMapping(pod, container, "authn-config", PathAuthnConfig)
kubemanifest.AddHostPathMapping(pod, container, "authn-config", PathAuthnConfig)
}
}

View File

@ -235,7 +235,7 @@ func (b *KubeControllerManagerBuilder) buildPod(kcm *kops.KubeControllerManagerC
}
// Log both to docker and to the logfile
addHostPathMapping(pod, container, "logfile", "/var/log/kube-controller-manager.log").ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-controller-manager.log").WithReadWrite()
// We use lighter containers that don't include shells
// But they have richer logging support via klog
if b.IsKubernetesGTE("1.23") {
@ -256,21 +256,21 @@ func (b *KubeControllerManagerBuilder) buildPod(kcm *kops.KubeControllerManagerC
}
for _, path := range b.SSLHostPaths() {
name := strings.Replace(path, "/", "", -1)
addHostPathMapping(pod, container, name, path)
kubemanifest.AddHostPathMapping(pod, container, name, path)
}
// Add cloud config file if needed
if b.Cluster.Spec.CloudConfig != nil {
addHostPathMapping(pod, container, "cloudconfig", InTreeCloudConfigFilePath)
kubemanifest.AddHostPathMapping(pod, container, "cloudconfig", InTreeCloudConfigFilePath)
}
addHostPathMapping(pod, container, "cabundle", filepath.Join(b.PathSrvKubernetes(), "ca.crt"))
kubemanifest.AddHostPathMapping(pod, container, "cabundle", filepath.Join(b.PathSrvKubernetes(), "ca.crt"))
addHostPathMapping(pod, container, "srvkcm", pathSrvKCM)
kubemanifest.AddHostPathMapping(pod, container, "srvkcm", pathSrvKCM)
addHostPathMapping(pod, container, "varlibkcm", "/var/lib/kube-controller-manager")
kubemanifest.AddHostPathMapping(pod, container, "varlibkcm", "/var/lib/kube-controller-manager")
addHostPathMapping(pod, container, "volplugins", volumePluginDir).ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "volplugins", volumePluginDir).WithReadWrite()
pod.Spec.Containers = append(pod.Spec.Containers, *container)

View File

@ -191,7 +191,7 @@ func (b *KubeProxyBuilder) buildPod() (*v1.Pod, error) {
}
// Log both to docker and to the logfile
addHostPathMapping(pod, container, "logfile", "/var/log/kube-proxy.log").ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-proxy.log").WithReadWrite()
// We use lighter containers that don't include shells
// But they have richer logging support via klog
if b.IsKubernetesGTE("1.23") {
@ -211,23 +211,23 @@ func (b *KubeProxyBuilder) buildPod() (*v1.Pod, error) {
"--log-file=/var/log/kube-proxy.log")
}
{
addHostPathMapping(pod, container, "kubeconfig", "/var/lib/kube-proxy/kubeconfig")
kubemanifest.AddHostPathMapping(pod, container, "kubeconfig", "/var/lib/kube-proxy/kubeconfig")
// @note: mapping the host modules directory to fix the missing ipvs kernel module
addHostPathMapping(pod, container, "modules", "/lib/modules")
kubemanifest.AddHostPathMapping(pod, container, "modules", "/lib/modules")
// Map SSL certs from host: /usr/share/ca-certificates -> /etc/ssl/certs
sslCertsHost := addHostPathMapping(pod, container, "ssl-certs-hosts", "/usr/share/ca-certificates")
sslCertsHost.MountPath = "/etc/ssl/certs"
sslCertsHost := kubemanifest.AddHostPathMapping(pod, container, "ssl-certs-hosts", "/usr/share/ca-certificates")
sslCertsHost.VolumeMount.MountPath = "/etc/ssl/certs"
}
if dns.IsGossipHostname(b.Cluster.Name) {
// Map /etc/hosts from host, so that we see the updates that are made by protokube
addHostPathMapping(pod, container, "etchosts", "/etc/hosts")
kubemanifest.AddHostPathMapping(pod, container, "etchosts", "/etc/hosts")
}
// Mount the iptables lock file
{
addHostPathMapping(pod, container, "iptableslock", "/run/xtables.lock").ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "iptableslock", "/run/xtables.lock").WithReadWrite()
vol := pod.Spec.Volumes[len(pod.Spec.Volumes)-1]
if vol.Name != "iptableslock" {

View File

@ -243,11 +243,11 @@ func (b *KubeSchedulerBuilder) buildPod(kubeScheduler *kops.KubeSchedulerConfig)
},
},
}
addHostPathMapping(pod, container, "varlibkubescheduler", "/var/lib/kube-scheduler")
addHostPathMapping(pod, container, "srvscheduler", pathSrvScheduler)
kubemanifest.AddHostPathMapping(pod, container, "varlibkubescheduler", "/var/lib/kube-scheduler")
kubemanifest.AddHostPathMapping(pod, container, "srvscheduler", pathSrvScheduler)
// Log both to docker and to the logfile
addHostPathMapping(pod, container, "logfile", "/var/log/kube-scheduler.log").ReadOnly = false
kubemanifest.AddHostPathMapping(pod, container, "logfile", "/var/log/kube-scheduler.log").WithReadWrite()
// We use lighter containers that don't include shells
// But they have richer logging support via klog
if b.IsKubernetesGTE("1.23") {

View File

@ -22,19 +22,54 @@ import (
// MapEtcHosts maps the /etc/hosts file into the pod (useful for gossip DNS)
func MapEtcHosts(pod *v1.Pod, container *v1.Container, readOnly bool) {
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
Name: "hosts",
MountPath: "/etc/hosts",
ReadOnly: readOnly,
})
hostPathFile := v1.HostPathFile
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
}
// 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 {
pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
Name: "hosts",
Name: name,
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/etc/hosts",
Type: &hostPathFile,
Path: path,
},
},
})
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
Name: name,
MountPath: path,
ReadOnly: true,
})
return &HostPathMapping{
Volume: &pod.Spec.Volumes[len(pod.Spec.Volumes)-1],
VolumeMount: &container.VolumeMounts[len(container.VolumeMounts)-1],
}
}
// 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
}
// WithType changes the hostpath mount type
func (m *HostPathMapping) WithType(t v1.HostPathType) *HostPathMapping {
m.Volume.VolumeSource.HostPath.Type = &t
return m
}
// WithHostPath changes the hostpath path
func (m *HostPathMapping) WithHostPath(p string) *HostPathMapping {
m.Volume.VolumeSource.HostPath.Path = p
return m
}

View File

@ -455,39 +455,10 @@ func (b *EtcdManagerBuilder) buildPod(etcdCluster kops.EtcdClusterSpec) (*v1.Pod
},
}
// TODO: Use helper function here
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
Name: "varlogetcd",
MountPath: "/var/log/etcd.log",
ReadOnly: false,
})
hostPathFileOrCreate := v1.HostPathFileOrCreate
pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
Name: "varlogetcd",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: logFile,
Type: &hostPathFileOrCreate,
},
},
})
kubemanifest.AddHostPathMapping(pod, container, "varlogetcd", "/var/log/etcd.log").WithReadWrite().WithType(v1.HostPathFileOrCreate).WithHostPath(logFile)
if fi.BoolValue(b.Cluster.Spec.UseHostCertificates) {
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
Name: "etc-ssl-certs",
MountPath: "/etc/ssl/certs",
ReadOnly: true,
})
hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
Name: "etc-ssl-certs",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/etc/ssl/certs",
Type: &hostPathDirectoryOrCreate,
},
},
})
kubemanifest.AddHostPathMapping(pod, container, "etc-ssl-certs", "/etc/ssl/certs").WithType(v1.HostPathDirectoryOrCreate)
}
}