<p>Is it possible to enable <code>net.ipv4.ip_forward</code> on a container's network namespace?</p>

<hr>

<p><strong>Manual</strong></p>

<p>From the host, I can enable it with manually with</p>

<pre><code>sudo nsenter -t \
    $(docker inspect --format '{{.State.Pid}}' $CONTAINER_NAME) \
    -n sysctl -w net.ipv4.ip_forward=1
</code></pre>

<p>and confirm that forwarding begins working within the container.</p>

<p>Is there a way to do this automatically whilst avoiding privileged containers?</p>

<p>In case of some sysctl parameters yes; <code>net.*</code> <strong>is namespaced</strong>, so <code>net.ipv4.ip_forward</code> can be enabled per Pod (per container).</p>

<p>Follow the <a href="https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/" rel="noreferrer">Using Sysctls in a Kubernetes Cluster</a> guide for details and gotchas.</p>

<h2>Longer answer</h2>

<p>While <code>net</code> <strong>is namespaced</strong>, not all sysctl variables can be set in namespace. Some simply await for a <a href="https://github.com/torvalds/linux/commit/13b287e8d1cad951634389f85b8c9b816bd3bb1e" rel="noreferrer">"namespacify"</a> patch, but others will possibly never get implemented. In the specific example of <code>net.ipv4</code> one could browse <a href="https://github.com/torvalds/linux/blob/master/include/net/netns/ipv4.h#L44" rel="noreferrer"><code>include/net/netns/ipv4.h</code></a> to see what is supported at the moment. Such support of course depends on the actual kernel version.</p>

<p>In case you wanted to "empirically" verify whether <em>sysctl</em> (the actual kernel facility, not the tool) supports a particular variable, you could do something like this (as root):</p>

<pre><code># cat /proc/sys/net/ipv4/ip_forward
1
# unshare --net sysctl -w net.ipv4.ip_forward=0
net.ipv4.ip_forward = 0
# cat /proc/sys/net/ipv4/ip_forward
1
</code></pre>

<p>As you can see <em>sysctl</em> (the tool) running in a new namespace could set <code>net.ipv4.ip_forward=0</code>; also that it did not affect the parent namespace.</p>

<p>An example of a variable that <em>can't be set</em> in a namespace (no support for it at the moment):</p>

<pre><code># cat /proc/sys/net/ipv4/icmp_msgs_burst
50
# unshare --net sysctl -w net.ipv4.icmp_msgs_burst=42
sysctl: cannot stat /proc/sys/net/ipv4/icmp_msgs_burst: No such file or directory
</code></pre>

<p>An example of a variable that is <em>not namespaced</em> would be <code>vm.nr_hugepages</code>. This variable exists in namespaces, but the <code>vm</code> subsystem itself is <a href="http://man7.org/linux/man-pages/man7/namespaces.7.html" rel="noreferrer"><strong>not namespaced</strong></a> (setting this variable will affect all processes):</p>

<pre><code># sysctl vm.nr_hugepages
vm.nr_hugepages = 0
# unshare sysctl vm.nr_hugepages=1
vm.nr_hugepages = 1
# sysctl vm.nr_hugepages
vm.nr_hugepages = 1
</code></pre>
