Homework: NetworkPolicies
Three tasks to reinforce pod-level firewall concepts and Helm templating.
Environment
You need a cluster with a CNI that enforces NetworkPolicies (Calico, Cilium, or Weave). All tasks can be completed on Minikube with --cni=calico or a kind cluster with Calico installed.
Tasks
Task 1 — Three-Tier Isolation
Deploy a three-tier application (frontend, api, database) in a namespace called hw12-tiers. Create NetworkPolicies so that:
- The database (labeled
tier: db) accepts ingress only from the api (labeledtier: api) on TCP port 5432. - The api (labeled
tier: api) accepts ingress only from the frontend (labeledtier: frontend) on TCP port 8080. - The frontend accepts ingress from anywhere on TCP port 80.
- A default-deny ingress policy covers the entire namespace.
Deliverables: Four NetworkPolicy YAML files (one default-deny + three allow policies). Demonstrate with kubectl exec that the frontend can reach the api, the api can reach the database, but the frontend cannot reach the database directly.
Task 2 — Egress Allowlist with AND Logic
In a namespace called hw12-egress, create a NetworkPolicy for pods labeled app: worker that:
- Denies all egress by default (via the policy type).
- Allows DNS egress (UDP and TCP port 53) to any destination.
- Allows HTTPS egress (TCP port 443) only to pods labeled
app: proxyin namespaces labeledzone: dmz(use AND logic -- a singletoitem with both selectors). - Allows egress to an external CIDR
203.0.113.0/24on TCP port 443.
Deliverables: A single NetworkPolicy YAML file. Use kubectl describe to show the policy and explain which to items use AND vs OR logic.
Task 3 — Helm Chart with Environment-Specific Policies
Extend a Helm chart (you may use helm create to scaffold) so that:
- A
templates/networkpolicy.yamltemplate creates a NetworkPolicy only when.Values.networkPolicy.enabledistrue. - A
templates/networkpolicy-default-deny.yamltemplate creates a default-deny policy (both ingress and egress) only when.Values.networkPolicy.defaultDenyistrue. - The default-deny template includes DNS egress automatically.
- Create three values files:
values-dev.yaml— all policies disabledvalues-staging.yaml— default-deny enabled, custom rules disabledvalues-prod.yaml— both default-deny and custom ingress/egress rules enabled
Deliverables: Run helm template with each values file and verify: dev produces no NetworkPolicy resources, staging produces only the default-deny, and prod produces both policies.
Grading Rubric
| Criterion | Excellent | Satisfactory | Needs Work |
|---|---|---|---|
| Default-Deny | Correctly applied to entire namespace; verified with blocked connection tests | Policy exists but tests are incomplete or labels are slightly off | Missing default-deny or policy does not select all pods |
| Selector Logic | Correctly uses AND (single item) and OR (multiple items) where required; can explain the difference | Policies work but AND/OR distinction is not explicitly demonstrated | AND and OR confused; policies are too permissive or too restrictive |
| Egress + DNS | DNS egress always included; pods can resolve names; non-allowed egress is blocked | DNS rule exists but testing is incomplete | DNS egress missing; pods cannot resolve service names |
| Helm Templating | Conditional creation works for all three environments; helm template output is clean YAML |
Template works but only tested for one environment | Template has syntax errors or does not respect the enabled flag |
| Testing | Provides kubectl exec commands showing both allowed and blocked connections for each policy |
Some testing shown but not comprehensive | No testing evidence provided |
Tip
When debugging, remember that NetworkPolicies are additive. If any policy allows a connection, it is allowed. The only way to block traffic is to have a policy that selects the pod (activating default-deny for that direction) without an allow rule for that specific source/destination.