netw_policies
Kubernetes Network Policy Examples
This guide demonstrates how Kubernetes Network Policies and Calico Network Policies can be used to control traffic flow to and from Pods. We will set up a demo application, implement a default deny policy, and then incrementally allow specific traffic.
(Assumption: The examples use a custom Docker image named xxradar/hackon for testing with curl. If this image is not available, you can substitute it with a standard image like alpine/curl or curlimages/curl.)
1. Setup and Initial Access Tests
1.1 Cleanup Previous Environment (Optional)
If you have run this lab before, clean up old resources.
kubectl delete ns hacker --ignore-not-found=true
kubectl delete ns friend --ignore-not-found=true
kubectl delete ns wwwnginx --ignore-not-found=true
# The 'demo' directory operations are for local file management
rm -rf demo
mkdir demo
cd demo(Added --ignore-not-found=true to delete commands.)
1.2 Deploy a Demo Application
We'll create a simple Nginx deployment and service in the wwwnginx namespace.
Verify the deployment:
1.3 Test Initial Access
Before applying any network policies, all pods should be able to communicate.
Test access from within the
wwwnginxnamespace:Inside the
curler-wwwpod's shell:Test access from other namespaces: Create two additional namespaces,
hackerandfriend.Test from
hackernamespace:Inside
curler-hackerpod's shell:Test from
friendnamespace:Inside
curler-friendpod's shell:(At this point, all curl commands should succeed as there are no network policies in place.)
2. Implementing a Default Deny Policy
Now, let's apply a policy in the wwwnginx namespace that denies all ingress traffic by default.
Create
default-deny-ingress.yaml:Apply the policy and inspect it:
Retest Access: All access attempts to
my-nginx-clusteripfrom any namespace (includingwwwnginxitself) should now fail (timeout).(Added
-m 5for timeout and informative echo.)
3. Allowing Traffic with Kubernetes NetworkPolicy
We will now create policies to allow specific ingress traffic to our Nginx pods (which have the label app: nginx). The curler pods we run for testing will be assumed to have the label run: curler (kubectl run adds this label by default).
3.1 Allow Ingress on Port 80 from Pods with Label run: curler (within same namespace)
run: curler (within same namespace)Create
allow-nginx-ingress-podselector.yaml: This policy applies to pods withapp: nginxinwwwnginxnamespace. It allows ingress on TCP port 80 from any pod in thewwwnginxnamespace that has the labelrun: curler.Apply the policy:
Retest Access:
Access from
curlerpod inwwwnginxnamespace should now succeed.Access from
curlerpods inhackerandfriendnamespaces should still fail.
3.2 Allow Ingress also from friend Namespace
friend NamespaceLet's modify the policy to also allow access from pods labeled run: curler in any namespace labeled project: friend.
Label the
friendandhackernamespaces:(Added
--overwrite)Create
allow-nginx-ingress-namespaceselector.yaml: This policy builds upon the previous one.(Modified the policy to show a common way to allow from other namespaces. The original had a combined rule which might be confusing. This one has two
fromentries - one for local pods, one for pods in 'friend' namespaces. If the intent was that pods in 'friend' namespace must also haverun:curler, then the podSelector needs to be nested under the namespaceSelector entry.)Self-correction: The original policy had the second
podSelectorat the same level asnamespaceSelector, which is not how it's combined. Aningressrule is a list ofNetworkPolicyIngressRule, eachfromis a list ofNetworkPolicyPeer. A peer can havepodSelectorORnamespaceSelectorORipBlock. If bothnamespaceSelectorandpodSelectorare specified within the sameNetworkPolicyPeerentry, they are ANDed. Let me refine the policy to correctly reflect allowing fromrun:curlerpods inwwwnginxAND from any pod inproject:friendnamespaces, then a more specific version.Refined
allow-nginx-ingress-friend-ns.yaml(allowing any pod from 'friend' namespace AND specific pods from local namespace):Apply the updated policy:
Retest Access:
wwwnginx(withrun: curlerlabel): Should succeed.hacker(no specific allow rule for this namespace label): Should fail.friend(any pod, due tonamespaceSelector): Should succeed.
(Added labels to test pods for clarity, especially if the policy were to combine namespace and pod selectors.)
3.3 Allow Ingress from All Namespaces (but only specific pods)
Let's create a policy that allows access from pods labeled run: curler irrespective of their namespace.(The original document's "allow from all namespaces" policy still had a specific podSelector: { matchLabels: { run: curler } } combined with namespaceSelector: { matchLabels: {} }. This means it allows pods labeled run: curler from any namespace that itself has any label. A true "allow all pods from all namespaces" would be just from: {} or from: - namespaceSelector: {} without a podSelector in that rule.)
Let's interpret the original intent as "allow run:curler pods from any namespace".
Create
allow-nginx-ingress-all-ns-curler-pods.yaml:Apply the policy:
Retest Access: Now,
curlerpods fromwwwnginx,hacker, andfriendnamespaces should all succeed.
4. Calico Network Policies (Advanced)
Calico offers its own CRDs for network policies (NetworkPolicy, GlobalNetworkPolicy) which provide more features than Kubernetes' built-in NetworkPolicy.
Note: To use Calico policies, Calico must be installed as the CNI plugin in your cluster.
4.1 Example: Calico Policy to Deny hacker Namespace
hacker NamespaceThis policy denies traffic from pods in any namespace labeled project: hacker to Nginx pods in wwwnginx on TCP port 80, and it has an order of 510.
Create
calico-deny-hacker.yaml: (Original filename wascalico-allow-port80.yamlbut the rule is a Deny)(Corrected filename and metadata.name for clarity based on the rule's action. Adjusted order slightly.)
Apply using
calicoctl: You might need to install calicoctl.Verify:
Test Access (Conceptual): At this point, if you have a Kubernetes NetworkPolicy that allows traffic from
project=hacker(like the "Allow Ingress from All Namespaces (but only specific pods)" one), and this Calico policy which denies it, the Deny action in Calico (especially with a lower order number, making it process earlier) would typically take precedence for traffic matching its source. Testing this combined behavior would require careful setup of both K8s and Calico policies.
4.2 Example: Calico Global Quarantine Rule
This GlobalNetworkPolicy aims to quarantine pods labeled quarantine == "true" by denying all their ingress and egress traffic, and logging attempts.
Create
calico-quarantine-gnp.yaml:(Simplified Log/Deny rules for clarity of a blanket deny after log. Adjusted name.)
Apply the Global Network Policy:
Now, any pod in any namespace that you label with
quarantine=true(e.g.,kubectl label pod mypod -n myns quarantine=true) should be isolated.
Last updated