4

I'm setting up a namespace in my kubernetes cluster to deny any outgoing network calls like http://company.com but to allow inter pod communication within my namespace like http://my-nginx where my-nginx is a kubernetes service pointing to my nginx pod.

How to achieve this using network policy. Below network policy helps in blocking all outgoing network calls

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-all-egress
  namespace: sample
spec:
  policyTypes:
  - Egress
  podSelector: {}

How to white list only the inter pod calls?

Pradeep
  • 153
  • 1
  • 10
  • Have you perused https://github.com/ahmetb/kubernetes-network-policy-recipes already? – Michael Hausenblas Jan 18 '19 at 13:41
  • Thank you for pointing it out. This particular example works for me https://github.com/ahmetb/kubernetes-network-policy-recipes/blob/master/11-deny-egress-traffic-from-an-application.md but with the catch that if there is a host with port 53 then it will not stop the call, isn't it? – Pradeep Jan 18 '19 at 17:33
  • What do you mean by a host with port 53? Services run on ports. This would result in any inter pod communication over port 53 will be allowed only. – Raunak Jhawar Jan 24 '19 at 12:54

3 Answers3

1

Using Network Policies you can whitelist all pods in a namespace:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-egress-to-sample
  namespace: sample
spec:
  policyTypes:
  - Egress
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: sample

As you probably already know, pods with at least one Network Policy applied to them can only communicate to targets allowed by any Network Policy applied to them.

Names don't actually matter. Selectors (namespaceSelector and podSelector in this case) only care about labels. Labels are key-value pairs associated with resources. The above example assumes the namespace called sample has a label of name=sample.

If you want to whitelist the namespace called http://my-nginx, first you need to add a label to your namespace (if it doesn't already have one). name is a good key IMO, and the value can be the name of the service, http://my-nginx in this particular case (not sure if : and / can be a part of a label though). Then, just using this in your Network Policies will allow you to target the namespace (either for ingress or egress)

    - namespaceSelector:
        matchLabels:
          name: http://my-nginx

If you want to allow communication to a service called my-nginx, the service's name doesn't really matter. You need to select the target pods using podSelector, which should be done with the same label that the service uses to know which pods belong to it. Check your service to get the label, and use the key: value in the Network Policy. For example, for a key=value pair of role=nginx you should use

    - podSelector:
        matchLabels:
          role: nginx
Blueriver
  • 3,212
  • 3
  • 16
  • 33
1

This can be done using the following combination of network policies:

# The same as yours
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-all-egress
  namespace: sample
spec:
  policyTypes:
  - Egress
  podSelector: {}
---
# allows connections to all pods in your namespace from all pods in your namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-namespace-egress
  namespace: sample
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels: {}
---
# allows connections from all pods in your namespace to all pods in your namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-namespace-internal
  namespace: sample
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels: {}

assuming your network policy implementation implements the full spec.

dippynark
  • 2,743
  • 20
  • 58
  • This will achieve the original request but it will block access to the Kubernetes DNS service (which is usually in the kube-system namespace). This will prevent all communications from the pods in the "sample" namespace. Details here: https://medium.com/@reuvenharrison/an-introduction-to-kubernetes-network-policies-for-security-people-ba92dd4c809d#b8e1 – Mark Jul 17 '19 at 22:29
  • @Mark true, but as you said this was not what was asked for and not all workloads require access to Kubernetes DNS - access to the DNS service can easily be allowed with further policies – dippynark Jul 18 '19 at 13:20
0

I am not sure if you can do it by using Kubernetes NetworkPolicy, but you can achieve this by Istio-enabled pods.

Note: First make sure that Istio installed on your cluster. For installation see.

See quote from Istio's documentation about Egress Traffic.

By default, Istio-enabled services are unable to access URLs outside of the cluster because the pod uses iptables to transparently redirect all outbound traffic to the sidecar proxy, which only handles intra-cluster destinations.

Also, you can whitelist domains outside of the cluster by adding ServiceEntry and VirtualService to your cluster, example in Configuring the external services in Istio documentation.

I hope it can be useful for you.

Black_Bacardi
  • 324
  • 4
  • 10
clxoid
  • 2,577
  • 12
  • 21
  • This quote was changed in 1.1. [this issue](https://discuss.istio.io/t/by-default-all-external-access-is-allowed-but-it-shouldnt/1370) mentions that – manasouza Aug 02 '19 at 17:38