<p>I have some pods running that are talking to each other via Kubernetes services and not via the pod IP's and now I want to lock things down using Network Policies but I can't seem to get the egress right.</p>
<p>In this scenario I have two pods:</p>
<ul>
<li><code>sleeper</code>, the client</li>
<li><code>frontend</code>, the server behind a Service called <code>frontend-svc</code> which forwards port 8080 to the pods port 80</li>
</ul>
<p>Both running in the same namespace: <code>ns</code></p>
<p>In the <code>sleeper</code> pod I simply <code>wget</code> a ping endpoint in the <code>frontend</code> pod:</p>
<p><code>wget -qO- http://frontend-svc.ns:8080/api/Ping</code></p>
<p>Here's my egress policy:</p>
<pre><code>kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-to-frontend-egress
  namespace: ns
spec:
  podSelector:
    matchLabels:
      app: sleeper
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: frontend
</code></pre>
<p>As you can see, nothing special; no ports, no namespace selector, just a single label selector for each pod.</p>
<p>Unfortunately, this breaks my ping:<br />
<code>wget: bad address 'frontend-svc.ns:8080'</code></p>
<p>However if I retrieve the pod's ip (using <code>kubectl get po -o wide</code>) and talk to the frontend directly I do get a response:<br />
<code>wget -qO- 10.x.x.x:80/api/Ping</code> (x obviously replaced with values)</p>
<p>My intuition was that it was related to the pod's egress to the Kube-dns being required so I added another egress policy:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-kube-system
  namespace: ns
spec:
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: &quot;kube-system&quot;
      podSelector: {}
  policyTypes:
  - Egress
</code></pre>
<p>For now I don't want to bother with the exact pod and port, so I allow all pods from the <code>ns</code> namespace to egress to <code>kube-system</code> pods.</p>
<p>However, this didn't help a bit. Even worse: This also breaks the communication by pod ip.</p>
<p>I'm running on Azure Kubernetes with Calico Network Policies.</p>
<p>Any clue what might be the issue, because I'm out of ideas.</p>
<hr />
<p>After getting it up and running, here's a more locked-down version of the DNS egress policy:</p>
<pre><code>kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-all-pods-dns-egress
  namespace: ns
spec:
  policyTypes:
  - Egress
  podSelector: {} 
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          # This label was introduced in version 1.19, if you are running a lower version, label the kube-dns pod manually.
          kubernetes.io/metadata.name: &quot;kube-system&quot;  
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - port: 53
      protocol: UDP
    - port: 53
      protocol: TCP
</code></pre>

<p>I recreated your deployment and the final networkpolicy (egress to <code>kube-system</code> for DNS resolution) solves it for me. Make sure that after applying the last network policy, you're testing the connection to service's port (8080) which you changed in you're <code>wget</code> command when accessing the pod directly (80).</p>
<p>Since network policies are a drag to manage, My team and I wanted to automate their creation and open sourced a tool that you might be interested in: <a href="https://docs.otterize.com/quick-tutorials/k8s-network-policies" rel="nofollow noreferrer">https://docs.otterize.com/quick-tutorials/k8s-network-policies</a>.</p>
<p>It's a way to manage network policies where you declare your access requirements in a separate, human-readable resource and the labeling is done for you on-the-fly.</p>
