<p>I am new to Kubernetes networking.</p>

<p>We have separated a Kubernetes cluster into a set of namespaces (e.g. <code>namespace-a</code>, <code>namespace-b</code>). Every namespace has a set of Kubernetes pods. Every pod has a service that is available at <code>my-svc.namespace-x.svc.cluster.local</code>.</p>

<p>Now, we want to <strong>prevent</strong> pods of namespace <code>namespace-a</code> to talk with services or pods that are part of <code>namespace-b</code> and <strong>vice versa</strong>. Communication <strong>within</strong> a namespace should be unrestricted. </p>

<p>This is what I found as an example in the network policies documentation:
<a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/#the-networkpolicy-resource" rel="noreferrer">https://kubernetes.io/docs/concepts/services-networking/network-policies/#the-networkpolicy-resource</a></p>

<pre><code>apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
</code></pre>

<p>As far as I understand, this prevents network communication completely, for all pods across a namespace. </p>

<ul>
<li>How can I allow all network traffic, but only <strong>within</strong> a particular namespace?</li>
<li>Do I need a networking plugin, such as Calico, Flannel or Weave? Which one should I choose?</li>
</ul>

<blockquote>
  <p>Do I need a networking plugin, such as Calico, Flannel or Weave?</p>
</blockquote>

<p>No matter what you need a networking plugin, but not all plugins support the <code>NetworkPolicy</code> API object. According to the <a href="https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/" rel="noreferrer">Declare Network Policy walkthrough</a>, the following is a (probably non-exhaustive) list of plugins that do support <code>NetworkPolicy</code>:</p>

<ul>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/calico-network-policy/" rel="noreferrer">Calico</a></li>
<li><a href="https://kubernetes.io/docs/tasks/administer-cluster/cilium-network-policy/" rel="noreferrer">Cilium</a></li>
<li><a href="https://kubernetes.io/docs/tasks/administer-cluster/kube-router-network-policy/" rel="noreferrer">Kube-router</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/romana-network-policy/" rel="noreferrer">Romana</a></li>
<li><a href="https://kubernetes.io/docs/tasks/administer-cluster/weave-network-policy/" rel="noreferrer">Weave Net</a></li>
</ul>

<p>Without a plugin that supports <code>NetworkPolicy</code>, creating the resource would have no effect.</p>

<blockquote>
  <p>Which one should I choose?</p>
</blockquote>

<p>As for which one you should choose, stackoverflow is not the place for soliciting that kind of advice. What I can recommend is reading the overview/features documentation for the various options available. Maybe try one or two different plugins in a local development cluster to get a feel for how difficult or easy they are to install, maintain, and update.</p>

<blockquote>
  <p>How can I allow all network traffic, but only within a particular namespace?</p>
</blockquote>

<p>Given your example setup, I think the following <code>NetworkPolicy</code> resources would address your need:</p>

<p>For pods in <code>namespace-a</code>, only allow ingress from <code>namspace-a</code> pods, denying ingress from any other source. Egress is unrestricted:</p>

<pre><code>apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: namespace-a
spec:
  policyTypes:
  - Ingress
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: namespace-a
</code></pre>

<p>For pods in <code>namespace-b</code>, only allow ingress from <code>namspace-b</code> pods, denying ingress from any other source. Egress is unrestricted:</p>

<pre><code>apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: namespace-b
spec:
  policyTypes:
  - Ingress
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: namespace-b
</code></pre>

<p>Note that this assumes you have set the <code>name: namespace-a</code> and <code>name: namespace-b</code> labels on your namespaces, similar to this:</p>

<pre><code>apiVersion: v1
kind: Namespace
metadata:
  name: namespace-a
  labels:
    name: namespace-a
    other: labelname
</code></pre>

<p>I only point this out to avoid confusing you with regard to the fact that the labels I showed above happen to match up with your hypothetical namespace names. The labels can be arbitrary and potentially inclusive of mulitple namespaces -- for example you might have <code>namespace-a</code> and <code>namespace-c</code> both with a label called <code>other: labelname</code> which would allow you to select multiple namespaces using a single <code>namespaceSelector</code> in your <code>NetworkPolicy</code> resource.</p>
