top of page
Writer's pictureSathish Kumar

Kubernetes Administration - Network Policies with Calico network plugin



Note: If you have missed my previous articles on Docker and Kubernetes, you can find them here: 
Application deployment models evolution.
Getting started with Docker.
Docker file and images.
Publishing images to Docker Hub and re-using them.
Docker- Find out what's going on.
Docker Networking- Part 1.
Docker Networking- Part 2.
Docker Swarm-Multi-Host container Cluster.
Docker Networking- Part 3 (Overlay Driver).
Introduction to Kubernetes.
Kubernetes- Diving in (Part 1)-Installing Kubernetes multi-node cluster.
Kubernetes-Diving in (Part2)- Services.
Kubernetes- Infrastructure As Code with Yaml (part 1).
Kubernetes- Infrastructure As Code Part 2- Creating PODs with YAML.
Kubernetes Infrastructure-as-Code part 3- Replicasets with YAML.
Kubernetes Infrastructure-as-Code part 4 - Deployments and Services with YAML.
Deploying a microservices APP with Kubernetes.
Kubernetes- Time based scaling of deployments with python client.
Kubernetes Networking - The Flannel network explained.
Kubernetes- Installing and using kubectl top for monitoring nodes and PoDs
Kubernetes Administration- Scheduling
Kubernetes Administration- Storage
Kubernetes Administration- Users 

Microservices applications are made up of multiple components that run as PoDs, replicasets, or deployment. These components communicate with each other and with the external world through Kubernetes networking capabilities. Kubernetes does not have builtin networking modules but relies on third-party networking plugins that confirm to Container Networking Specification.


At a high level, any plugin should satisfy the following requirements:

  • Allow containers in the same PoD to communicate with each other and share the IP address.

  • Allow PoDs, agents to communicate with other PoDs on the Kubernetes cluster without requiring NAT.

  • Enforce network access control between PoDs, Namespaces, services etc with support for Network policies.

Not all networking plugins support policies. The Flannel plugin does not have support for policy controller, hence it is not possible to restrict communication between different PoDs running on the same cluster. Few others like, Calico networking plugin provides support for network policies along with a few other enhancements. In this article, I am going to show how easy it is to implement network policies with Calico.


To get started, we need to install Calico. Steps for installations are provided here.


Note: If you have installed flannel before, you need to uninstall it. To uninstall flannel:
root@sathish-vm2:/home/sathish# kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

I chose to install Calico with Kubernetes API datastore and the steps given in the installation URL works perfectly. The PoD network is default i.e 192.168.0.0/16



root@sathish-vm2:/home/sathish# curl https://docs.projectcalico.org/manifests/calico.yaml -O
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  183k  100  183k    0     0   323k      0 --:--:-- --:--:-- --:--:--  323k
root@sathish-vm2:/home/sathish# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
poddisruptionbudget.policy/calico-kube-controllers created

root@sathish-vm2:/home/sathish# kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-744cfdf676-67qmc   1/1     Running   2          2m20s
calico-node-2dxjf                          1/1     Running   0          2m28s
calico-node-pz8d2                          1/1     Running   0          2m27s
coredns-f9fd979d6-d8wzr                    1/1     Running   0          93d
coredns-f9fd979d6-xcxzc                    1/1     Running   0          93d
etcd-sathish-vm2                           1/1     Running   0          93d
kube-apiserver-sathish-vm2                 1/1     Running   1          93d
kube-controller-manager-sathish-vm2        1/1     Running   0          29d
kube-proxy-lcf25                           1/1     Running   0          93d
kube-proxy-tf8z8                           1/1     Running   0          93d
kube-scheduler-sathish-vm2                 1/1     Running   0          29d

Now that the calico plugin is installed, let's tryout network policies. For this, I will be using a pod running httpd server with a service (ClusterIP) and another pod with busybox that will emulate a client.


root@sathish-vm2:/home/sathish# kubectl run mywebserv --image=nginx
pod/mywebserv created
#Expose PoD as clusterIP
root@sathish-vm2:/home/sathish# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   93d
mywebserv    ClusterIP   10.107.110.226   <none>        80/TCP    4s

As the service type is ClusterIP, it should be accessible to all PoDs. Let's check this out.


root@sathish-vm2:/home/sathish# kubectl run mybusybox --image=busybox --rm -it
/ # nc -z -v -w 2 10.107.110.226 80
10.107.110.226 (10.107.110.226:80) open

Lets now create a policy to block access from all pods to this service



root@sathish-vm2:/home/sathish# kubectl get pods --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
mywebserv   1/1     Running   0          22m   run=mywebserv

root@sathish-vm2:/home/sathish# cat denyweb.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-webservice
spec:
  podSelector:
    matchLabels:
      run: mywebserv
  policyTypes:
  - Ingress

root@sathish-vm2:/home/sathish# kubectl create -f denyweb.yaml
networkpolicy.networking.k8s.io/deny-webservice created
root@sathish-vm2:/home/sathish# kubectl get networkpolicy
NAME              POD-SELECTOR    AGE
deny-webservice   run=mywebserv   64s

The type of policy is Ingress, which means traffic inbound to the PoD. The default behaviour for policy is to drop all traffic. Since we did not specify any permit rules, all traffic is dropped. Let's check this out by running a simple test again with busybox.


root@sathish-vm2:/home/sathish# kubectl run mybusybox --image=busybox --rm -it
If you don't see a command prompt, try pressing enter.
/ # nc -z -v -w 2 10.107.110.226 80
nc: 10.107.110.226 (10.107.110.226:80): Connection timed out

It is possible to allow traffic selectively from certain PoDs by matching labels. Let's modify the created policy to try this out


root@sathish-vm2:/home/sathish# cat denyweb.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-webservice
spec:
  podSelector:
    matchLabels:
      run: mywebserv
  policyTypes:
  - Ingress
  ingress:
  - from:
      - podSelector:
          matchLabels:
            client: specialclient
#Delete  and recreate the policy
kubectl delete -f denyweb.yaml
networkpolicy.networking.k8s.io "deny-webservice" deleted
kubectl create -f denyweb.yaml
networkpolicy.networking.k8s.io/deny-webservice created

Let's try accessing from a busybox PoD without specialclient label.


root@sathish-vm2:/home/sathish# kubectl run mybusybox --image=busybox --rm -it
If you don't see a command prompt, try pressing enter.
/ # nc -z -v -w 2 10.107.110.226 80
nc: 10.107.110.226 (10.107.110.226:80): Connection timed out

Now let's try from busybox PoD with proper label


root@sathish-vm2:/home/sathish# kubectl run mybusybox --image=busybox --rm -it --labels "client=specialclient"

If you don't see a command prompt, try pressing enter.

/ # nc -z -v -w 2 10.107.110.226 80
10.107.110.226 (10.107.110.226:80) open

Bingo it works!!


Ingress traffic can also be filtered on basis of the namespace, tcp/UDP ports, IP CIDR blocks etc. It is also possible to filter out Egress traffic with egress ACL rules. For a list of what's supported, you can refer the Kubernetes documentation here.


Hope this short intro to network policies was useful. Thanks for your visit and happy weekend :)

633 views0 comments

Comments


bottom of page