Working with NetworkPolicy

As a resource of Kubernetes, NetworkPolicy uses label selectors to configure the firewall of Pods from infrastructure level. Without a specified NetworkPolicy, any Pod in the same cluster can communicate with each other by default. On the other hand, once a NetworkPolicy with rules is attached to a Pod, either it is for ingress or egress, or both, and all traffic that doesn't follow the rules will be blocked.

Before demonstrating how to build a NetworkPolicy, we should make sure the network plugin in Kubernetes cluster supports it. There are several CNIs that support NetworkPolicy: Calico, Contive, Romana (https://github.com/romana/kube), Weave Net (https://github.com/weaveworks/weave), Trireme (https://github.com/aporeto-inc/trireme-kubernetes), and others.

Enable CNI with NetworkPolicy support as network plugin in minikube
While working on minikube, users will not need to attach a CNI specifically, since it is designed as a single local Kubernetes node. However, to enable the functionality of NetworkPolicy, it is necessary to start a NetworkPolicy-supported CNI. Be careful, as, while you configure the minikube with CNI, the configuration options and procedures could be quite different to various CNI implementations. The following steps show you how to start minikube with CNI, Calico:
  1. We take this issue https://github.com/projectcalico/calico/issues/1013#issuecomment-325689943 as reference for these building steps.
  2. The minikube used here is the latest version, 0.24.1.
  3. Reboot your minikube: minikube start --network-plugin=cni
    --host-only-cidr 172.17.17.1/24
    --extra-config=kubelet.PodCIDR=192.168.0.0/16
    --extra-config=proxy.ClusterCIDR=192.168.0.0/16
    --extra-config=controller-manager.ClusterCIDR=192.168.0.0/16.
  4. Create Calico with the configuration file "minikube-calico.yaml" from the code bundle kubectl create -f minikue-calico.yaml.

To illustrate the functionality of NetworkPolicy, we are going to create a Pod and expose it as a service, then attach a NetworkPolicy on the Pod to see what happens:

// start a pod of our favourite example, nginx
$ kubectl run nginx-pod --image=nginx --port=80 --restart=Never
pod "nginx-pod" created
//expose the pod as a service listening on port 8080
$ kubectl expose pod nginx-pod --port=8080 --target-port=80
service "nginx-pod" exposed
// check the service IP
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
nginx-pod ClusterIP 10.102.153.182 <none> 8080/TCP 1m

Now, we can go ahead and check the Pod's connection from a simple Deployment, busybox, using the command wget with --spider flag to verify the existence of endpoint:

// check the accessibility of the service
// create busybox and open standard input and independent terminal by flag "i" and "t", similar to docker command
$ kubectl run busybox -it --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget --spider 10.102.153.182:8080
Connecting to 10.102.153.182:8080 (10.102.153.182:8080)

As shown in the preceding result, we know that the nginx service can be accessed without any constraints. Later, let's run a NetworkPolicy that restricts that only the Pod tagging <test: inbound> can access nginx service:

// a configuration file defining NetworkPolicy of pod nginx-pod
$ cat networkpolicy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: nginx-networkpolicy
spec:
podSelector:
matchLabels:
run: nginx-pod
ingress:
- from:
- podSelector:
matchLabels:
test: inbound

As you can see, in the spec of NeworkPolicy, it is configured to apply to Pods with the label <run: nginx-pod>, which is the one we have on the pod nginx-pod. Also, a rule of ingress is attached in the policy, which indicates that only Pods with a specific label can access nginx-pod:

// create the NetworkPolicy
$ kubectl create -f networkpolicy.yaml
networkpolicy.networking.k8s.io "nginx-networkpolicy" created
// check the details of NetworkPolicy
$ kubectl describe networkpolicy nginx-networkpolicy
Name: nginx-networkpolicy
Namespace: default
Created on: 2018-05-05 18:36:56 -0400 EDT
Labels: <none>
Annotations: <none>
Spec:
PodSelector: run=nginx-pod
Allowing ingress traffic:
To Port: <any> (traffic allowed to all ports)
From PodSelector: test=inbound
Allowing egress traffic:
<none> (Selected pods are isolated for egress connectivity)
Policy Types: Ingress

Great, everything is looking just like what we expected. Next, check the same service endpoint on our previous busybox Pod:

// if you turned off the terminal, resume it with the subcommand attach
$ kubectl attach busybox-598b87455b-s2mfq -c busybox -i -t
// we add flag to specify timeout interval, otherwise it will just keep hanging on wget
/ # wget --spider 10.102.153.182:8080 --timeout=3
wget: download timed out

As expected again, now we cannot access the nginx-pod service after NetworkPolicy is attached. The nginx-pod can only be touched by Pod labelled with <test: inbound>:

// verify the connection by yourself with new busybox
$ kubectl run busybox-labelled --labels="test=inbound" -it --image=busybox /bin/sh
Catch up with the concept of label and selector in the recipe Working with labels and selectors in Chapter 2, Walking through Kubernetes Concepts.

In this case, you have learned how to create a NetworkPolicy with ingress restriction by Pod selector. Still, there are other settings you may like to build on your Pod:

  • Egress restriction: Egress rules can be applied by .spec.egress, which has similar settings to ingress.
  • Port restriction: Each ingress and egress rule can point out what port, and with what kind of port protocol, is to be accepted or blocked. Port configuration can be applied through .spec.ingress.ports or .spec.egress.ports.
  • Namespace selector: We can also make limitations on certain Namespaces. For example, Pods for the system daemon might only allow access to others in the Namespace kube-system. Namespace selector can be applied with .spec.ingress.from.namespaceSelector or .spec.egress.to.namespaceSelector.
  • IP block: A more customized configuration is to set rules on certain CIDR ranges, which come out as similar ideas to what we work with iptables. We may utilize this configuration through .spec.ingress.from.ipBlock or .spec.egress.to.ipBlock.

It is recommended to check more details in the API document: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#networkpolicyspec-v1-networking. Furthermore, we would like to show you some more interesting setups to fulfill general situations:

  • Apply to all Pod: A NetworkPolicy can be easily pushed to every Pod by setting .spec.podSelector with an empty value.
  • Allow all traffic: We may allow all incoming traffic by assigning .spec.ingress with empty value, an empty array; accordingly, outgoing traffic could be set without any restriction by assigning .spec.egress with empty value.
  • Deny all traffic: We may deny all incoming or outgoing traffic by simply indicating the type of NetworkPolicy without setting any rule. The type of the NetworkPolicy can be set at .spec.policyTypes. At the same time, do not set .spec.ingress or .spec.egress.

Go check the code bundle for the example files networkpolicy-allow-all.yaml and networkpolicy-deny-all.yaml.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.76.175