Skip to content

Commit

Permalink
Stop exposing the entire host filesystem
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jmencak committed Jul 10, 2024
1 parent 35bfa29 commit 6a1398f
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 23 deletions.
10 changes: 5 additions & 5 deletions assets/tuned/manifests/ds-tuned.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions test/e2e/basic/metrics_cert_rotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'"
// Use container-shipped openssl.
opensslCmd := "/usr/bin/openssl s_client -connect " + operatorPodIP + ":60000 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'"

serverCertContents, err := util.ExecCmdInPod(tunedPod, "/bin/bash", "-c", opensslCmd)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
Expand Down
19 changes: 11 additions & 8 deletions test/e2e/basic/sysctl_d_override.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ var _ = ginkgo.Describe("[basic][sysctl_d_override] Node Tuning Operator /etc/sy
const (
sysctlVar = "net.ipv4.neigh.default.gc_thresh1"
sysctlValSet = "256"
sysctlFile = "/host/etc/sysctl.d/zzz.conf"
sysctlFile = "/rootfs/etc/sysctl.d/zzz.conf"
profileSysctlOverride = "../testing_manifests/sysctl_override.yaml"
nodeLabelSysctlOverride = "tuned.openshift.io/sysctl-override"
)

ginkgo.Context("sysctl.d override", func() {
var (
node *coreapi.Node
pod *coreapi.Pod
node *coreapi.Node
pod, mcdPod *coreapi.Pod
)

// Cleanup code to roll back cluster changes done by this test even if it fails in the middle of ginkgo.It()
Expand All @@ -39,8 +39,8 @@ var _ = ginkgo.Describe("[basic][sysctl_d_override] Node Tuning Operator /etc/sy
if node != nil {
util.ExecAndLogCommand("oc", "label", "node", "--overwrite", node.Name, nodeLabelSysctlOverride+"-")
}
if pod != nil {
util.ExecAndLogCommand("oc", "exec", "-n", ntoconfig.WatchNamespace(), pod.Name, "--", "rm", sysctlFile)
if mcdPod != nil {
util.ExecAndLogCommand("oc", "exec", "-n", util.MCONamespace, mcdPod.Name, "--", "rm", sysctlFile)
}
util.ExecAndLogCommand("oc", "delete", "-n", ntoconfig.WatchNamespace(), "-f", profileSysctlOverride)
})
Expand All @@ -62,6 +62,9 @@ var _ = ginkgo.Describe("[basic][sysctl_d_override] Node Tuning Operator /etc/sy
pod, err = util.GetTunedForNode(cs, node)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

mcdPod, err = util.GetMCDForNode(cs, node)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

// Expect the default worker node profile applied prior to getting any current values.
ginkgo.By(fmt.Sprintf("waiting for TuneD profile %s on node %s", util.GetDefaultWorkerProfile(node), node.Name))
err = util.WaitForProfileConditionStatus(cs, pollInterval, waitDuration, node.Name, util.GetDefaultWorkerProfile(node), tunedv1.TunedProfileApplied, coreapi.ConditionTrue)
Expand All @@ -72,11 +75,11 @@ var _ = ginkgo.Describe("[basic][sysctl_d_override] Node Tuning Operator /etc/sy
gomega.Expect(err).NotTo(gomega.HaveOccurred())

ginkgo.By(fmt.Sprintf("writing %s override file on the host with %s=%s", sysctlFile, sysctlVar, sysctlValSet))
_, _, err = util.ExecAndLogCommand("oc", "exec", "-n", ntoconfig.WatchNamespace(), pod.Name, "--", "sh", "-c",
_, _, err = util.ExecAndLogCommand("oc", "exec", "-n", util.MCONamespace, mcdPod.Name, "--", "sh", "-c",
fmt.Sprintf("echo %s=%s > %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")
Expand Down Expand Up @@ -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))
Expand Down
9 changes: 2 additions & 7 deletions test/e2e/core/cluster_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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)

Expand Down
22 changes: 22 additions & 0 deletions test/e2e/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 6a1398f

Please sign in to comment.