From 9c156218cc049b17a57756686ad6289b3a12b157 Mon Sep 17 00:00:00 2001 From: "Lubomir I. Ivanov" Date: Thu, 18 Apr 2024 10:56:19 +0300 Subject: [PATCH] kubeadm: don't mount /etc/pki for apiserver and KCM According to kubeadm repo ticket 1665, /etc/pki can contain subdirectories with private keys on some distros. Avoid mounting the entire /etc/pki and mount /etc/pki/ca-trust and /etc/pki/tls/certs instead. These directories are mounted as an extra locations which can be used to search for additional system CAs. --- cmd/kubeadm/app/phases/controlplane/volumes.go | 12 ++++++------ cmd/kubeadm/app/phases/controlplane/volumes_test.go | 13 +++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cmd/kubeadm/app/phases/controlplane/volumes.go b/cmd/kubeadm/app/phases/controlplane/volumes.go index 9aec46ce4df..8e537d85a48 100644 --- a/cmd/kubeadm/app/phases/controlplane/volumes.go +++ b/cmd/kubeadm/app/phases/controlplane/volumes.go @@ -40,7 +40,7 @@ const ( // caCertsExtraVolumePaths specifies the paths that can be conditionally mounted into the apiserver and controller-manager containers // as /etc/ssl/certs might be or contain a symlink to them. It's a variable since it may be changed in unit testing. This var MUST // NOT be changed in normal codepaths during runtime. -var caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates", "/usr/local/share/ca-certificates", "/etc/ca-certificates"} +var caCertsExtraVolumePaths = []string{"/etc/pki/ca-trust", "/etc/pki/tls/certs", "/etc/ca-certificates", "/usr/share/ca-certificates", "/usr/local/share/ca-certificates"} // getHostPathVolumesForTheControlPlane gets the required hostPath volumes and mounts for the control plane func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration) controlPlaneHostPathMounts { @@ -83,7 +83,7 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration) schedulerKubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.SchedulerKubeConfigFileName) mounts.NewHostPathMount(kubeadmconstants.KubeScheduler, kubeadmconstants.KubeConfigVolumeName, schedulerKubeConfigFile, schedulerKubeConfigFile, true, &hostPathFileOrCreate) - // On some systems were we host-mount /etc/ssl/certs, it is also required to mount additional directories. + // On some systems where we host-mount /etc/ssl/certs, it is also required to mount additional directories. // This is needed due to symlinks pointing from files in /etc/ssl/certs to these directories. for _, caCertsExtraVolumePath := range caCertsExtraVolumePaths { if isExtraVolumeMountNeeded(caCertsExtraVolumePath) { @@ -179,7 +179,7 @@ func getEtcdCertVolumes(etcdCfg *kubeadmapi.ExternalEtcd, k8sCertificatesDir str for _, certPath := range certPaths { certDir := filepath.ToSlash(filepath.Dir(certPath)) // Ignore ".", which is the result of passing an empty path. - // Also ignore the cert directories that already may be mounted; /etc/ssl/certs, /etc/pki or Kubernetes CertificatesDir + // Also ignore the cert directories that already may be mounted; /etc/ssl/certs, /etc/pki/ca-trust/ or Kubernetes CertificatesDir // If the etcd certs are in there, it's okay, we don't have to do anything extraVolumePath := false for _, caCertsExtraVolumePath := range caCertsExtraVolumePaths { @@ -219,9 +219,9 @@ func getEtcdCertVolumes(etcdCfg *kubeadmapi.ExternalEtcd, k8sCertificatesDir str return volumes, volumeMounts } -// isExtraVolumeMountNeeded specifies whether /etc/pki should be host-mounted into the containers -// On some systems were we host-mount /etc/ssl/certs, it is also required to mount /etc/pki. This is needed -// due to symlinks pointing from files in /etc/ssl/certs into /etc/pki/ +// isExtraVolumeMountNeeded specifies whether /etc/pki/ca-trust/ should be host-mounted into the containers +// On some systems were we host-mount /etc/ssl/certs, it is also required to mount /etc/pki/ca-trust/. This is needed +// due to symlinks pointing from files in /etc/ssl/certs into /etc/pki/ca-trust/ func isExtraVolumeMountNeeded(caCertsExtraVolumePath string) bool { if _, err := os.Stat(caCertsExtraVolumePath); err == nil { return true diff --git a/cmd/kubeadm/app/phases/controlplane/volumes_test.go b/cmd/kubeadm/app/phases/controlplane/volumes_test.go index 9a481338b44..bcbdcb79f5f 100644 --- a/cmd/kubeadm/app/phases/controlplane/volumes_test.go +++ b/cmd/kubeadm/app/phases/controlplane/volumes_test.go @@ -57,10 +57,10 @@ func TestGetEtcdCertVolumes(t *testing.T) { volMount: []v1.VolumeMount{}, }, { - name: "Should ignore files in /etc/pki", - ca: "/etc/pki/my-etcd-ca.crt", - cert: "/etc/pki/my-etcd.crt", - key: "/etc/pki/my-etcd.key", + name: "Should ignore files in /etc/pki/ca-trust", + ca: "/etc/pki/ca-trust/my-etcd-ca.crt", + cert: "/etc/pki/ca-trust/my-etcd.crt", + key: "/etc/pki/ca-trust/my-etcd.key", vol: []v1.Volume{}, volMount: []v1.VolumeMount{}, }, @@ -519,8 +519,9 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) { defer os.RemoveAll(tmpdir) // set up tmp caCertsExtraVolumePaths for testing - caCertsExtraVolumePaths = []string{fmt.Sprintf("%s/etc/pki", tmpdir), fmt.Sprintf("%s/usr/share/ca-certificates", tmpdir)} - defer func() { caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates"} }() + originalCACertsExtraVolumePaths := caCertsExtraVolumePaths + caCertsExtraVolumePaths = []string{fmt.Sprintf("%s/etc/pki/ca-trust", tmpdir), fmt.Sprintf("%s/usr/share/ca-certificates", tmpdir)} + defer func() { caCertsExtraVolumePaths = originalCACertsExtraVolumePaths }() for _, rt := range tests { t.Run(rt.name, func(t *testing.T) {