I wanted isolate separate namespaces in Kubernetes so that resources from one namespace cannot access resources from the another namespace. There could be many reasons for doing this, such as isolating dev and prod environments.
The classical way to achive this is by using NetworkPolicies. Network policies allow you to allow or forbid the communication between pods. Though there are several limitations when it comes to isolating namespaces, there is still a viable alternative.
I implemented the network policies to achieve the desired setup. They were created successfully. But they didn’t work. Why? Network plugin was not enabled.
Below I will outline (1) how to check whether your network policy is working and (2) how to enable the network policy on Google Cloud Platform (GCP)
How to check whether your network policy is working?
There are many ways to do this. Here is how I did it:
1.Create a new namespace called sandbox
kubectl create namespace
2. Create a network policy that disables all egress traffic. This means that all outgoing traffic will be denied. In other words, when I ssh into a pod in that namespace and try to reach an external website, the request will be denied.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sandbox-deny-egress
namespace: sandbox
spec:
podSelector: {}
policyTypes:
- Egress
3. Test outgoing traffic. If you receive response, then the network policy is not working (as in the example below)
kubectl run test --image=nginx --namespace=sandbox --rm --restart=Never -i -- curl google.com
Response should look like:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 219 100 219 0 0 2670 0 --:--:-- --:--:-- --:--:-- 2638
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
pod "test" deleted
Let me unpack the command:
kubectl run test --image=nginx : creates a pod with image nginx
-- namespace=sandbox : creates the pod in namespace sandbox
--rm : deletes the pod after being executed
--restart=Never : if the container fails or finishes, it is not restarted. This is imporant, because if not set, the container will keep restarting after exeucting the command and it will never return any result
--i : “Keep stdin open on the container in the pod, even if nothing is attached” (source: documentation). Necessary so that the command could be executed
-- curl google.com : the command to execute
How to enable the network policy on Google Cloud Platform (GCP)?
Go to Kubernetes Engine Admin on Goolge Cloud Platform Console. Select the cluster and to go to Clusters page → Section Networking → Network policy and enable it
To enable the network policies for the worker nodes, you should first enable the network policy for the master node.
Run the command again. This time the egress traffic should be denied.
kubectl run test --image=nginx --namespace=sandbox --rm --restart=Never -i -- curl google.com
Response should look like:
If you don't see a command prompt, try pressing enter.
0 0 0 0 0 0 0 0 --:--:-- 0:00:19 --:--:-- 0curl: (6) Could not resolve host: google.com
pod "test2" deleted
pod sandbox/test terminated (Error)
Conclusion
Network policy in on GCP is not enabled by default. As a result, though network policy resources are successfully deployed the may not work as expected. I hope that above information helps to save time troubleshooting.