<p>Afaik, the K8s <code>NetworkPolicy</code> can only allow pods matching a label to do something. I do not want to:</p>
<ul>
<li>Deny all traffic</li>
<li>Allow traffic for all pods except the ones matching my label</li>
</ul>
<p>but instead:</p>
<ul>
<li>Allow all traffic</li>
<li>Deny traffic for pods matching my label</li>
</ul>
<p>How do I do that?</p>
<p>From <code>kubectl explain NetworkPolicy.spec.ingress.from</code>:</p>
<pre><code>DESCRIPTION:
     List of sources which should be able to access the pods selected for this
     rule. Items in this list are combined using a logical OR operation. If this
     field is empty or missing, this rule matches all sources (traffic not
     restricted by source). If this field is present and contains at least one
     item, this rule allows traffic only if the traffic matches at least one
     item in the from list.
</code></pre>
<p>As far as I understand this, we can only allow, not deny.</p>

<p>As you mentioned in the comments, you are using the Kind tool for running Kubernetes. Instead of <a href="https://github.com/aojea/kindnet" rel="nofollow noreferrer">kindnet CNI plugin</a> (default CNI plugin for Kind) which does not support <a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/" rel="nofollow noreferrer">Kubernetes network policies</a>, you can use <a href="https://github.com/projectcalico/cni-plugin" rel="nofollow noreferrer">Calico CNI plugin</a> which support Kubernetes network policies + it has its own, similar solution called <a href="https://docs.projectcalico.org/security/calico-network-policy" rel="nofollow noreferrer">Calico network policies</a>.</p>
<hr />
<p>Example - I will create cluster with disabled default kind CNI plugin + <a href="https://stackoverflow.com/a/62433164/16391991">enabled NodePort</a> for testing (assuming that you have <code>kind</code> + <code>kubectl</code> tools already installed):</p>
<p><em>kind-cluster-config.yaml</em> file:</p>
<pre class="lang-yaml prettyprint-override"><code>kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  disableDefaultCNI: true # disable kindnet
  podSubnet: 192.168.0.0/16 # set to Calico's default subnet
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
    listenAddress: &quot;0.0.0.0&quot; # Optional, defaults to &quot;0.0.0.0&quot;
    protocol: tcp # Optional, defaults to tcp
</code></pre>
<p>Time for create a cluster using above config:</p>
<pre><code>kind create cluster --config kind-cluster-config.yaml
</code></pre>
<p>When cluster is ready, I will install Calico CNI plugin:</p>
<pre><code>kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
</code></pre>
<p>I will wait until all calico pods are ready (<code>kubectl get pods -n kube-system</code> command to check). Then, I will create sample <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment" rel="nofollow noreferrer">nginx deployment</a> + service type NodePort for accessing:</p>
<p><em>nginx-deploy-service.yaml</em></p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30000
</code></pre>
<p>Let's apply it: <code>kubectl apply -f nginx-deploy-service.yaml</code></p>
<p>So far so good. Now I will try to access <code>nginx-service</code> using node IP (<code>kubectl get nodes -o wide</code> command to check node IP address):</p>
<pre><code>curl 172.18.0.2:30000
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
...
</code></pre>
<p>Okay, it's working.</p>
<p>Now time to <a href="https://docs.projectcalico.org/getting-started/clis/calicoctl/install" rel="nofollow noreferrer">install <code>calicoctl</code></a> and apply some example policy - <a href="https://docs.projectcalico.org/security/tutorials/calico-policy" rel="nofollow noreferrer">based on this tutorial</a> - to block ingress traffic only for pods with label <code>app</code> with value <code>nginx</code>:</p>
<p><em>calico-rule.yaml</em>:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: default-deny
spec:
  selector: app == &quot;nginx&quot;
  types:
  - Ingress
</code></pre>
<p>Apply it:</p>
<pre><code>calicoctl apply -f calico-rule.yaml 
Successfully applied 1 'GlobalNetworkPolicy' resource(s)
</code></pre>
<p>Now I can't reach the address <code>172.18.0.2:30000</code> which was working previously. The policy is working fine!</p>
<p>Read more about calico policies:</p>
<ul>
<li><a href="https://docs.projectcalico.org/security/calico-network-policy" rel="nofollow noreferrer">Get started with Calico network policy</a></li>
<li><a href="https://docs.projectcalico.org/security/tutorials/calico-policy" rel="nofollow noreferrer">Calico policy tutorial</a></li>
</ul>
<p>Also check <a href="https://github.com/kubernetes-sigs/kind/issues/842" rel="nofollow noreferrer">this GitHub topic</a> for more information about NetworkPolicy support in Kind.</p>
<p><strong>EDIT:</strong></p>
<p>Seems like Calico plugin <a href="https://docs.projectcalico.org/security/kubernetes-network-policy" rel="nofollow noreferrer">supports as well Kubernetes NetworkPolicy</a>, so you can just install Calico CNI plugin and apply the following policy:</p>
<pre class="lang-yaml prettyprint-override"><code>kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
  - Ingress
</code></pre>
<p>I tested it and seems it's working fine as well.</p>
