// Module included in the following assemblies:
//
// * nodes/containers/nodes-containers-sysctls.adoc

:_mod-docs-content-type: PROCEDURE
[id="nodes-containers-sysctls-unsafe_{context}"]
= Enabling unsafe sysctls

[role="_abstract"]
As a cluster administrator, you can allow certain unsafe sysctls for very special situations such as high performance or real-time application tuning.

If you want to use unsafe sysctls, a cluster administrator must enable them
individually for a specific type of node. The sysctls must be namespaced.

You can further control which sysctls are set in pods by specifying lists of sysctls or sysctl patterns in the `allowedUnsafeSysctls` field of the Security Context Constraints.

The `allowedUnsafeSysctls` option controls specific needs such as high performance or real-time application tuning.

[WARNING]
====
Because these sysctls are considered unsafe, the use of unsafe sysctls is
at-your-own-risk and can lead to severe problems, such as improper behavior of
containers, resource shortage, or node breakage.
====

.Procedure

. List existing `MachineConfig` objects for your {product-title} cluster to decide how to label your machine config by running the following command:
+
[source,terminal]
----
$ oc get machineconfigpool
----
+
.Example output
[source,terminal]
----
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-bfb92f0cd1684e54d8e234ab7423cc96   True      False      False      3              3                   3                     0                      42m
worker   rendered-worker-21b6cb9a0f8919c88caf39db80ac1fce   True      False      False      3              3                   3                     0                      42m
----

. Add a label to the machine config pool where the containers with the unsafe sysctls are to run by running the following command:
+
[source,terminal]
----
$ oc label machineconfigpool worker custom-kubelet=sysctl
----

. Create a YAML file that defines a `KubeletConfig` custom resource (CR):
+
[source,yaml]
----
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
  name: custom-kubelet
spec:
  machineConfigPoolSelector:
    matchLabels:
      custom-kubelet: sysctl
  kubeletConfig:
    allowedUnsafeSysctls:
      - "kernel.msg*"
      - "net.core.somaxconn"
----
+
where:

`spec.machineConfigPoolSelector.matchLabels`:: Specifies the label from the machine config pool.
`spec.kubeletConfig.allowedUnsafeSysctls`:: Specifies a list of unsafe sysctls to allow.

. Create the object by running the following command:
+
[source,terminal]
----
$ oc apply -f set-sysctl-worker.yaml
----

. Wait for the Machine Config Operator to generate the new rendered configuration and apply it to the machines by running the following command:
+
[source,terminal]
----
$ oc get machineconfigpool worker -w
----
+
After some minutes the `UPDATING` status changes from True to False:
+
[source,terminal]
----
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
worker   rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800   False     True       False      3              2                   2                     0                      71m
worker   rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800   False     True       False      3              2                   3                     0                      72m
worker   rendered-worker-0188658afe1f3a183ec8c4f14186f4d5   True      False      False      3              3                   3                     0                      72m
----

. Create a YAML file that defines a pod and add the `securityContext` spec, as shown in the following example:
+
[source,yaml]
----
apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example-safe-unsafe
spec:
  containers:
  - name: podexample
    image: centos
    command: ["bin/bash", "-c", "sleep INF"]
    securityContext:
      runAsUser: 2000
      runAsGroup: 3000
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
    sysctls:
    - name: kernel.shm_rmid_forced
      value: "0"
    - name: net.core.somaxconn
      value: "1024"
    - name: kernel.msgmax
      value: "65536"
----

. Create the pod by running the following command:
+
[source,terminal]
----
$ oc apply -f sysctl-example-safe-unsafe.yaml
----
+
.Expected output
[source,terminal]
----
Warning: would violate PodSecurity "restricted:latest": forbidden sysctls (net.core.somaxconn, kernel.msgmax)
pod/sysctl-example-safe-unsafe created
----

. Verify that the pod is created by running the following command:
+
[source,terminal]
----
$ oc get pod
----
+
.Example output
[source,terminal]
----
NAME                         READY   STATUS    RESTARTS   AGE
sysctl-example-safe-unsafe   1/1     Running   0          19s
----

. Log in to the pod by running the following command:
+
[source,terminal]
----
$ oc rsh sysctl-example-safe-unsafe
----

. Verify the values of the configured sysctl flags. For example, find the value of the `net.core.somaxconn` parameter by running the following command:
+
[source,terminal]
----
sh-4.4# sysctl net.core.somaxconn
----
+
.Expected output
[source,terminal]
----
net.core.somaxconn = 1024
----
+
The unsafe sysctl is now allowed and the value is set as defined in the `securityContext` spec of the updated pod specification.
