From 6a1398fa1cdb6a83a6f4d287dbc31281247fb29a Mon Sep 17 00:00:00 2001 From: Jiri Mencak Date: Tue, 11 Jun 2024 11:40:57 +0200 Subject: [PATCH] Stop exposing the entire host filesystem With the principle of least privilege in mind, stop exposing the entirety of the host filesystem. Previously, we were mounting the entire host filesystem to "/host". With this change, only the necessary host directories for using TuneD are mounted and a host's /var/lib directory for the operand's persistent /var/lib/ocp-tuned directory. Other changes * For e2e tests, use MCD to write to host's /etc/sysctl.d/ since we are no longer exposing the entire host filesystem for the NTO operand. --- assets/tuned/manifests/ds-tuned.yaml | 10 +++++----- test/e2e/basic/metrics_cert_rotation.go | 5 ++--- test/e2e/basic/sysctl_d_override.go | 19 +++++++++++-------- test/e2e/core/cluster_version.go | 9 ++------- test/e2e/util/util.go | 22 ++++++++++++++++++++++ 5 files changed, 42 insertions(+), 23 deletions(-) diff --git a/assets/tuned/manifests/ds-tuned.yaml b/assets/tuned/manifests/ds-tuned.yaml index 13bb57e5e0..ca74cace9d 100644 --- a/assets/tuned/manifests/ds-tuned.yaml +++ b/assets/tuned/manifests/ds-tuned.yaml @@ -71,8 +71,8 @@ spec: name: var-lib-kubelet mountPropagation: HostToContainer readOnly: true - - mountPath: /host - name: host + - mountPath: /host/var/lib + name: host-var-lib mountPropagation: HostToContainer env: - name: WATCH_NAMESPACE @@ -132,10 +132,10 @@ spec: path: /var/lib/kubelet type: Directory name: var-lib-kubelet - - name: host - hostPath: - path: / + - hostPath: + path: /var/lib type: Directory + name: host-var-lib dnsPolicy: ClusterFirst nodeSelector: kubernetes.io/os: linux diff --git a/test/e2e/basic/metrics_cert_rotation.go b/test/e2e/basic/metrics_cert_rotation.go index e38c4af1a8..e7ac4dd749 100644 --- a/test/e2e/basic/metrics_cert_rotation.go +++ b/test/e2e/basic/metrics_cert_rotation.go @@ -59,9 +59,8 @@ var _ = ginkgo.Describe("[basic][metrics] Node Tuning Operator certificate rotat secretCertContents := string(tlsSecret.Data["tls.crt"]) operatorPodIP := operatorPod.Status.PodIP - // We need chroot because host may be using system libraries incompatible with the container - // image system libraries. Alternatively, use container-shipped openssl. - opensslCmd := "/usr/sbin/chroot /host /usr/bin/openssl s_client -connect " + operatorPodIP + ":60000 2>/dev/null /dev/null %s; sync %s", sysctlVar, sysctlValSet, sysctlFile, sysctlFile)) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - util.ExecAndLogCommand("oc", "rsh", "-n", ntoconfig.WatchNamespace(), pod.Name, "cat", sysctlFile) + util.ExecAndLogCommand("oc", "rsh", "-n", util.MCONamespace, mcdPod.Name, "cat", sysctlFile) ginkgo.By(fmt.Sprintf("deleting Pod %s", pod.Name)) _, _, err = util.ExecAndLogCommand("oc", "delete", "-n", ntoconfig.WatchNamespace(), "pod", pod.Name, "--wait") @@ -118,7 +121,7 @@ var _ = ginkgo.Describe("[basic][sysctl_d_override] Node Tuning Operator /etc/sy gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By(fmt.Sprintf("removing %s override file on the host", sysctlFile)) - _, _, err = util.ExecAndLogCommand("oc", "exec", "-n", ntoconfig.WatchNamespace(), pod.Name, "--", "rm", sysctlFile) + _, _, err = util.ExecAndLogCommand("oc", "exec", "-n", util.MCONamespace, mcdPod.Name, "--", "rm", sysctlFile) gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By(fmt.Sprintf("deleting Pod %s", pod.Name)) diff --git a/test/e2e/core/cluster_version.go b/test/e2e/core/cluster_version.go index 7f9b550392..ba9add0897 100644 --- a/test/e2e/core/cluster_version.go +++ b/test/e2e/core/cluster_version.go @@ -17,7 +17,7 @@ var _ = ginkgo.Describe("[core][cluster_version] Node Tuning Operator host, cont node *coreapi.Node ) - ginkgo.It("host, container OS and cluster version retrievable", func() { + ginkgo.It("container OS and cluster version retrievable", func() { ginkgo.By("getting a list of worker nodes") nodes, err := util.GetNodesByRole(cs, "worker") gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -28,13 +28,8 @@ var _ = ginkgo.Describe("[core][cluster_version] Node Tuning Operator host, cont pod, err := util.GetTunedForNode(cs, node) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By(fmt.Sprintf("getting the host OS version on node %s", node.Name)) - out, err := util.ExecCmdInPod(pod, "cat", "/host/etc/os-release") - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - util.Logf("%s", out) - ginkgo.By("getting the TuneD container OS version") - out, err = util.ExecCmdInPod(pod, "cat", "/etc/os-release") + out, err := util.ExecCmdInPod(pod, "cat", "/etc/os-release") gomega.Expect(err).NotTo(gomega.HaveOccurred()) util.Logf("%s", out) diff --git a/test/e2e/util/util.go b/test/e2e/util/util.go index cf366d09b0..015f66e286 100644 --- a/test/e2e/util/util.go +++ b/test/e2e/util/util.go @@ -29,6 +29,8 @@ const ( DefaultMasterProfile = "openshift-control-plane" // The default worker profile. See: assets/tuned/manifests/default-cr-tuned.yaml DefaultWorkerProfile = "openshift-node" + // MCO namespace + MCONamespace = "openshift-machine-config-operator" ) // Logf formats using the default formats for its operands and writes to @@ -80,6 +82,26 @@ func GetTunedForNode(cs *framework.ClientSet, node *corev1.Node) (*corev1.Pod, e return &podList.Items[0], nil } +// GetMCDForNode returns a MCD Pod that runs on a given node. +func GetMCDForNode(cs *framework.ClientSet, node *corev1.Node) (*corev1.Pod, error) { + listOptions := metav1.ListOptions{ + FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": node.Name}).String(), + } + listOptions.LabelSelector = labels.SelectorFromSet(labels.Set{"k8s-app": "machine-config-daemon"}).String() + + podList, err := cs.Pods(MCONamespace).List(context.TODO(), listOptions) + if err != nil { + return nil, err + } + if len(podList.Items) != 1 { + if len(podList.Items) == 0 { + return nil, fmt.Errorf("failed to find MCD for node %s", node.Name) + } + return nil, fmt.Errorf("too many (%d) MCD Pods for node %s", len(podList.Items), node.Name) + } + return &podList.Items[0], nil +} + // GetNodeTuningOperator returns the node tuning operator Pod. // If more than one operator Pod is running will return the first Pod found. func GetNodeTuningOperatorPod(cs *framework.ClientSet) (*corev1.Pod, error) {