3 Using Calico
This section provides examples of using the Kubernetes and Calico network policies to define network policies for traffic in an NGINX web server application. The Kubernetes network policy example uses the network policy available in the Kubernetes Network Policy API. The Calico network policy example uses extensions available in the Calico policy, and provides more options for setting network policies.
Kubernetes Network Policy
This section shows a basic example of using the Kubernetes network policy. More examples of the Kubernetes network policy are available in the upstream Calico documentation.
The example defines a NetworkPolicy to disable all network traffic between pods in a namespace. NetworkPolicy resources are created to define rules to specify allowed network traffic between the application pods. If a NetworkPolicy in a namespace selects a pod, that pod rejects any connections that aren't allowed by the NetworkPolicy.
To create a test application to use a Kubernetes network policy:
-
Create a Kubernetes namespace for the test application:
kubectl create namespace myapp
-
Create an NGINX pod with label of
app: nginx
. This is created in themyapp
namespace. On a control plane node, create a file namednginx.yaml
and copy the following into the file.apiVersion: v1 kind: Pod metadata: name: nginx namespace: myapp labels: app: nginx spec: containers: - name: nginx image: container-registry.oracle.com/olcne/nginx:1.17.7 ports: - containerPort: 80
-
Start the NGINX pod:
kubectl apply -f nginx.yaml
-
Create an Oracle Linux 9 pod with label of
app: nginx
. This is created in themyapp
namespace. Create a file namedol9.yaml
and copy the following into the file:apiVersion: v1 kind: Pod metadata: name: ol9 namespace: myapp labels: app: nginx spec: containers: - name: ol9 command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"] image: container-registry.oracle.com/os/oraclelinux:9-slim
-
Start the pod using the
kubectl
command:kubectl apply -f ol9.yaml
-
You can see the
nginx-app
andol9
pods are running using thekubectl get pods
command:kubectl get pods --namespace myapp -o wide
The output looks similar to:
NAME READY STATUS RESTARTS AGE IP NODE ... nginx 1/1 Running 0 38s 10.244.140.68 worker1.example.com ... ol9 1/1 Running 0 22h 10.244.80.196 worker2.example.com ...
- Mount the Oracle Linux 9 pod,
ol9
, and runcurl
to connect to the NGINX server pod,nginx
, using the IP address assigned to the pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
The output looks similar to:
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
- Create a NetworkPolicy to deny all traffic to all pods in
the
myapp
namespace. Create a file nameddeny-all.yaml
and copy the following into the file.kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: default-deny namespace: myapp spec: podSelector: matchLabels: {}
-
Create the NetworkPolicy using the
kubectl
command:kubectl apply -f deny-all.yaml
Tip:
You can get a list of all NetworkPolicies in the
myapp
namespace using:kubectl get networkpolicies --namespace myapp
In addition, adding the
-o yaml
option lists details about the NetworkPolicies. - Mount the Oracle Linux 9 pod,
ol9
, again and runcurl
to connect to the NGINX server pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
This time no results are returned as the traffic between pods on that namespace isn't allowed. You can enter
Ctrl+C
to exit the command. - Create a NetworkPolicy to allow ingress traffic on port 80 for pods in
the
myapp
namespace. This lets pods connect to the NGINX server. Create a file namedingress.yaml
and copy the following into the file:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: myapp-ingress namespace: myapp spec: podSelector: matchLabels: app: nginx ingress: - from: - podSelector: matchLabels: app: nginx ports: - port: 80
-
Create the NetworkPolicy using the
kubectl
command:kubectl apply -f ingress.yaml
- Mount the Oracle Linux 9 pod,
ol9
, again and runcurl
to connect to the NGINX server pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
The NGINX page is now returned as ingress is allowed to the pods.
-
You can delete the resources created in this Calico test using:
kubectl delete pod --namespace myapp nginx kubectl delete pod --namespace myapp ol9 kubectl delete networkpolicies --namespace myapp myapp-ingress kubectl delete networkpolicies --namespace myapp default-deny kubectl delete namespace myapp
Calico Network Policy
This section shows a basic example of using the Calico policy extensions for the Kubernetes Network Policy API. More examples of the Calico policy are available in the upstream documentation.
The example defines a GlobalNetworkPolicy to disable all network traffic, except for Kubernetes system and Calico pods. NetworkPolicy resources are created to define rules to specify allowed network traffic between the application pods. Any other pod traffic isn't allowed.
To create a test application to use a Calico network policy:
-
Create a Kubernetes namespace for the test application:
kubectl create namespace myapp
-
Create an NGINX pod with label of
app: nginx
. This is created in themyapp
namespace. On a control plane node, create a file namednginx.yaml
and copy the following into the file.apiVersion: v1 kind: Pod metadata: name: nginx namespace: myapp labels: app: nginx spec: containers: - name: nginx image: container-registry.oracle.com/olcne/nginx:1.17.7 ports: - containerPort: 80
-
Start the NGINX pod:
kubectl apply -f nginx.yaml
-
Create an Oracle Linux 9 pod with label of
app: nginx
. This is created in themyapp
namespace. Create a file namedol9.yaml
and copy the following into the file:apiVersion: v1 kind: Pod metadata: name: ol9 namespace: myapp labels: app: nginx spec: containers: - name: ol9 command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"] image: container-registry.oracle.com/os/oraclelinux:9-slim
-
Start the pod using the
kubectl
command:kubectl apply -f ol9.yaml
-
You can see the
nginx-app
andol9
pods are running using thekubectl get pods
command:kubectl get pods --namespace myapp -o wide
The output looks similar to:
NAME READY STATUS RESTARTS AGE IP NODE ... nginx 1/1 Running 0 38s 10.244.140.68 worker1.example.com ... ol9 1/1 Running 0 22h 10.244.80.196 worker2.example.com ...
- Mount the Oracle Linux 9 pod,
ol9
, and runcurl
to connect to the NGINX server pod,nginx
, using the IP address assigned to the pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
The output looks similar to:
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
- Create a GlobalNetworkPolicy to deny all traffic to all pods in the namespaces
that aren't in the
kube-system
,calico-system
orcalico-apiserver
namespaces. Create a file nameddeny-all.yaml
and copy the following into the file.apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: default-deny spec: selector: projectcalico.org/namespace not in {'kube-system', 'calico-system', 'calico-apiserver'} types: - Ingress - Egress
-
Create the GlobalNetworkPolicy using the
kubectl
command:kubectl apply -f deny-all.yaml
Tip:
You can get a list of all Calico GlobalNetworkPolicies in the
myapp
namespace using:kubectl get globalnetworkpolicies.crd.projectcalico.org --namespace myapp
In addition, adding the
-o yaml
option lists details about the GlobalNetworkPolicies. - Mount the Oracle Linux 9 pod,
ol9
, again and runcurl
to connect to the NGINX server pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
This time no results are returned as the traffic between pods on that namespace isn't allowed. You can enter
Ctrl+C
to exit the command. - Create a NetworkPolicy to allow ingress traffic on port 80 for pods in the
myapp
namespace. This lets pods connect to the NGINX server. Create a file namedingress.yaml
and copy the following into the file:apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-nginx-ingress namespace: myapp spec: selector: app == 'nginx' types: - Ingress ingress: - action: Allow protocol: TCP source: selector: app == 'nginx' destination: ports: - 80
-
Create the NetworkPolicy using the
kubectl
command:kubectl apply -f ingress.yaml
Tip:
You can get a list of all Calico NetworkPolicies in the
myapp
namespace using:kubectl get networkpolicies.crd.projectcalico.org --namespace myapp
In addition, adding the
-o yaml
option lists details about the NetworkPolicies. - Mount the Oracle Linux 9 pod,
ol9
, again and runcurl
to connect to the NGINX server pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
No results are returned as egress traffic between pods on that namespace isn't allowed. You can enter
Ctrl+C
to exit the command. - Create a NetworkPolicy to allow egress traffic for pods in the
myapp
namespace. Create a file namedegress.yaml
and copy the following into the file:apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-nginx-egress namespace: myapp spec: selector: app == 'nginx' types: - Egress egress: - action: Allow
-
Create the NetworkPolicy using the
kubectl
command:kubectl apply -f egress.yaml
- Mount the Oracle Linux 9 pod,
ol9
, again and runcurl
to connect to the NGINX server pod.kubectl exec -it ol9 --namespace myapp -- curl 10.244.140.68
The NGINX page is now returned as both ingress and egress is allowed for the pods.
-
You can delete the resources created in this Calico test using:
kubectl delete pod --namespace myapp nginx kubectl delete pod --namespace myapp ol9 kubectl delete networkpolicies.crd.projectcalico.org --namespace myapp default.allow-nginx-egress kubectl delete networkpolicies.crd.projectcalico.org --namespace myapp default.allow-nginx-ingress kubectl delete globalnetworkpolicies.crd.projectcalico.org --namespace myapp default.default-deny kubectl delete namespace myapp