Kubernetes

Kubernetes Namespace Isolation at the Network Level with Calico

  • Login to the master and install kubelet, kubeadm and kubectl
  • Initialisekubeadm
  • Refer steps 2a, 2b, 2c in document
eCloudControl Engineering Team4 min read
Kubernetes Namespace Isolation at the Network Level with Calico

**KUBERNETES NAMESPACE ISOLATION AT THE NETWORK LEVEL WITH CALICO **

** 1. **Install and setup Docker in master and node

Refer step 1 in document

2. Setup kubernetes master

  • Login to the master and install kubelet, kubeadm and kubectl
  • Initialisekubeadm
  • Refer steps 2a, 2b, 2c in document

3. Setup Calico

Install calico with Kubernetes API datastore

  • Download the Calico networking manifest for the Kubernetes API datastore.
$ curl https://docs.projectcalico.org/manifests/calico.yaml -O
  • You can customize the manifest as necessary
  • Apply the manifest using the following command
$ kubectl apply -f calico.yaml

Now check the pods on kube-system namespace where all the network components will be available.

$ kubectl get pods -n=kube-system

After adding the network, add the node to the cluster using the join command(result of kubeadminit ). For example:

$ kubeadm join XX.X.X.XXX:6443 -- token hdhjsnsnwwww –discovery-token-ca-cert-hash sha256:4d3e70e50a8b3ecfacc64585942b93564c9af555ab90c576c59e63def90245ac

Now check the cluster for master and node

$ kubectl get nodes

4. Creating a test environment

  • For testing, we are creating two nginx HTTP-Servers in two namespaces and block all traffic between the two namespaces. Which means you will not get any content from namespace1 if you are sitting in namespace2.
  • Setup the namespace with required resources.

# Create two namespaces

$ kubectl create ns test1
$ kubectl create ns test2

# Apply name labels to the newly created namespaces

$ kubectl label ns test1 name=test1
$ kubectl label ns test2 name=test2

# Create a standard HTTP web server

$ kubectl create deployment nginx --image=nginx -n=test1
$ kubectl create deployment nginx --image=nginx -n=test2

# Expose the port 80 for external access

$ kubectl expose deployment nginx --port=80 --type=NodePort -n=test1
$ kubectl expose deployment nginx --port=80 --type=NodePort -n=test2

# Check the components created in two namespaces.

$ kubectl get all -n=test1
$ kubectl get all -n=test2

**5. **Testing Phase 1 (Without network policy)

  • Get the IP of all pods using the following commands
$ kubectl get pods -o wide -n=test1
$ kubectl get pods -o wide -n=test2

Create a pod with curl preinstalled inside the namespace test1

$ kubectl run -i --tty client0 --image=tutum/curl -n=test1

Get the index.html from the nginx of the namespace "test1"

$ curl http://nginx-pod-ip-test1
$ curl http://nginx-pod-ip-test2

Both calls are done in a pod within namespace test1 and both nginx servers are always reachable, no matter in what namespace.

6. Testing Phase 2 (With network policy)

  • Inorder to isolate the namespace at network level, we have to apply network policy on both namespaces. A sample network policy is given below.
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
  name: deny-namespaces
spec:
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'test1'
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'kube-system'
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'kube-public'
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'kube-node-lease'
  egress:
  - action: Allow
  • This policy will block the access from namespace2
  • Create a file networkpolicy-ns1.yaml and paste the above code.
$ vim networkpolicy-ns1.yaml

To apply the policy on namespace1, run the following command

$ kubectl create -f networkpolicy-ns1.yaml -n=test1

For namespace2, create another policy yaml

apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
  name: deny-namespaces
spec:
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'test2'
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'kube-system'
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'kube-public'
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: name == 'kube-node-lease'
  egress:
  - action: Allow
$  kubectl create -f networkpolicy-ns2.yaml -n=test2
  • Now check the connectivity between the pods again.
  • Get the IP of all pods using the following commands
$ kubectl get pods -o wide -n=test1
$ kubectl get pods -o wide -n=test2

Create a pod with curl preinstalled inside the namespace test1

$ kubectl run -i --tty client1 --image=tutum/curl -n=test1

Get the index.html from the nginx of the namespace "test1"

$ curl http://nginx-pod-ip-test1
$ curl http://nginx-pod-ip-test2

Please find more networking policies on the below link.

https://docs.projectcalico.org/networking/determine-best-networking

About The Author

Ancy Paul

Cloud Dev

Ops Engineer | Cloud Control

Cloud DevOps Engineer with 3+ years of experience in cloud infrastructure automation and management, supporting, automating, and optimizing deployments to hybrid cloud platforms using DevOps processes, and containers in both Production and Development environments

On Linked-In