Lab 04 — Network Policies
In the previous labs, you secured Kubernetes in several layers:
Lab 01Kubernetes Fundamentals ↓Understand Resources
Lab 02Kubernetes RBAC ↓Control Identity and Permissions
Lab 03Kyverno ↓Control Workload ConfigurationNow you will secure:
Workload CommunicationThis lab focuses on Kubernetes NetworkPolicy.
The key question is:
Which workloadsshould be allowedto communicate?Without proper segmentation, a compromised workload may be able to communicate with systems it never legitimately needed to reach.
Your goal is to move from:
Broad Internal Connectivityto:
Explicitly Allowed CommunicationMission Information
Section titled “Mission Information”Difficulty: Intermediate
Estimated Time: 90–120 minutes
Primary Skills:
Kubernetes Networking
NetworkPolicy
Ingress Controls
Egress Controls
Default-Deny
Pod Selectors
Namespace Selectors
Application Segmentation
Connectivity Validation
Network TroubleshootingLab Scenario
Section titled “Lab Scenario”Your organization is running a three-tier application in Kubernetes.
The application architecture is:
Frontend ↓Backend API ↓DatabaseThe security team has discovered that workloads inside the application namespace can communicate more broadly than required.
Your mission is to enforce the following communication model:
Frontend → Backend
Backend → Databasewhile preventing unnecessary communication such as:
Frontend → Database
Unknown Pod → Backend
Unknown Pod → DatabaseYou will implement this gradually so that you can observe how each policy changes the network behavior.
Lab Objectives
Section titled “Lab Objectives”By the end of this lab, you should be able to:
- Explain Kubernetes NetworkPolicy
- Understand Pod-to-Pod communication
- Understand ingress and egress
- Identify required application flows
- Use Pod labels in network policy
- Implement default-deny policies
- Allow specific application traffic
- Restrict unnecessary lateral movement
- Understand namespace-based segmentation
- Validate allowed and denied communication
- Troubleshoot NetworkPolicy behavior
- Document network-security findings
- Apply least-connectivity principles
Security Principle
Section titled “Security Principle”The objective is similar to least privilege.
For identity:
Minimum Required PermissionsFor networking:
Minimum Required CommunicationThis can be thought of as:
Least Privilege +Least ConnectivityLab Architecture
Section titled “Lab Architecture”You will build:
Kubernetes Cluster│└── ghc-network-lab │ ├── Frontend │ ↓ │ frontend-service │ ├── Backend │ ↓ │ backend-service │ ├── Database │ ↓ │ database-service │ └── Test ClientRequired flow:
Frontend │ ▼Backend │ ▼DatabaseBlocked flow:
Frontend ─X─> Databaseand:
Unknown Workload ─X─> BackendBefore You Start
Section titled “Before You Start”You need:
Authorized Kubernetes Training Cluster
kubectl
Permission to Create:NamespacesDeploymentsServicesNetworkPoliciesYour Kubernetes networking implementation must support NetworkPolicy.
Not every networking plugin enforces NetworkPolicy in the same way.
Important Environment Check
Section titled “Important Environment Check”NetworkPolicy resources may exist in Kubernetes even if the underlying network implementation does not actually enforce them.
Therefore this lab has two levels of validation:
Policy Object Exists ↓Network Behavior ChangesYou must verify both.
Lab Safety Rules
Section titled “Lab Safety Rules”Perform this lab only in:
Your Own Cluster
Training Cluster
Explicitly Authorized EnvironmentNetwork policies can break legitimate application traffic.
In production, policy changes should include:
Application Flow Mapping
Testing
Change Approval
Rollback Planning
MonitoringPart 01 — Understand Kubernetes Networking
Section titled “Part 01 — Understand Kubernetes Networking”Kubernetes generally gives Pods network connectivity through the cluster networking layer.
Conceptually:
Pod A ↕Pod B ↕Pod CWithout additional segmentation, workloads may have broader internal reachability than required.
This creates potential:
Lateral MovementLateral Movement Example
Section titled “Lateral Movement Example”Suppose:
Internet ↓Frontend Vulnerability ↓Frontend Pod CompromisedIf the frontend can communicate freely with:
Backend
Database
Monitoring
Other Applicationsthe attacker’s opportunity increases.
Better Design
Section titled “Better Design”Frontend ↓Only Backend
Backend ↓Only Database
Database ↓Only Required ClientsPart 02 — What Is NetworkPolicy?
Section titled “Part 02 — What Is NetworkPolicy?”A NetworkPolicy defines which network connections are permitted for selected Pods.
Conceptually:
Selected Pod ↓NetworkPolicy ↓Allowed Sources / Destinations ↓Allowed PortsTwo Main Directions
Section titled “Two Main Directions”NetworkPolicy can regulate:
Ingressand:
EgressIngress
Section titled “Ingress”Ingress means:
Traffic Coming Into a PodExample:
Frontend → BackendFrom the backend’s perspective:
IngressEgress
Section titled “Egress”Egress means:
Traffic Leaving a PodExample:
Backend → DatabaseFrom the backend’s perspective:
EgressPart 03 — NetworkPolicy Mental Model
Section titled “Part 03 — NetworkPolicy Mental Model”For every policy ask:
Which Pods Are Selected?
Which Direction?
Who Is Allowed?
Which Port?
Which Protocol?Policy Structure
Section titled “Policy Structure”Think:
podSelector ↓Selected Workload
policyTypes ↓Ingress / Egress
ingress / egress ↓Allowed FlowsPart 04 — Verify the Cluster
Section titled “Part 04 — Verify the Cluster”Check:
kubectl config current-contextThen:
kubectl cluster-infoConfirm:
Correct Cluster
Correct Context
Training EnvironmentPart 05 — Check NetworkPolicy Support
Section titled “Part 05 — Check NetworkPolicy Support”List the API resource:
kubectl api-resources | grep -i networkpolicyYou should see:
networkpoliciesThis confirms the Kubernetes API supports the object.
It does not yet prove the network plugin enforces it.
That will be validated later through connectivity tests.
Part 06 — Create the Lab Namespace
Section titled “Part 06 — Create the Lab Namespace”Create:
kubectl create namespace ghc-network-labSet your working namespace:
kubectl config set-context --current --namespace=ghc-network-labVerify:
kubectl config view --minifyPart 07 — Build the Frontend
Section titled “Part 07 — Build the Frontend”Create:
frontend.yamlAdd:
apiVersion: apps/v1kind: Deploymentmetadata: name: frontend namespace: ghc-network-labspec: replicas: 1 selector: matchLabels: app: frontend template: metadata: labels: app: frontend tier: frontend spec: containers: - name: frontend image: nginx ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: frontend-service namespace: ghc-network-labspec: selector: app: frontend ports: - port: 80 targetPort: 80Apply:
kubectl apply -f frontend.yamlPart 08 — Build the Backend
Section titled “Part 08 — Build the Backend”Create:
backend.yamlAdd:
apiVersion: apps/v1kind: Deploymentmetadata: name: backend namespace: ghc-network-labspec: replicas: 1 selector: matchLabels: app: backend template: metadata: labels: app: backend tier: backend spec: containers: - name: backend image: nginx ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: backend-service namespace: ghc-network-labspec: selector: app: backend ports: - port: 80 targetPort: 80Apply:
kubectl apply -f backend.yamlPart 09 — Build the Database Simulation
Section titled “Part 09 — Build the Database Simulation”For this networking lab, you can use another simple HTTP workload to simulate the database network endpoint.
Create:
database.yamlAdd:
apiVersion: apps/v1kind: Deploymentmetadata: name: database namespace: ghc-network-labspec: replicas: 1 selector: matchLabels: app: database template: metadata: labels: app: database tier: database spec: containers: - name: database image: nginx ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: database-service namespace: ghc-network-labspec: selector: app: database ports: - port: 80 targetPort: 80Apply:
kubectl apply -f database.yamlWhy Simulate the Database?
Section titled “Why Simulate the Database?”The purpose of this lab is network segmentation rather than database administration.
You need three reachable tiers:
Frontend
Backend
Databaseto test network controls safely.
Part 10 — Verify the Workloads
Section titled “Part 10 — Verify the Workloads”Run:
kubectl get podsThen:
kubectl get servicesCheck labels:
kubectl get pods --show-labelsYou should see:
app=frontend
app=backend
app=databaseLabel Importance
Section titled “Label Importance”NetworkPolicies frequently depend on:
Pod LabelsA wrong label can produce:
Policy Not Appliedor:
Wrong Workload SelectedPart 11 — Create a Test Client
Section titled “Part 11 — Create a Test Client”Create a temporary client workload.
Create:
test-client.yamlAdd:
apiVersion: apps/v1kind: Deploymentmetadata: name: test-client namespace: ghc-network-labspec: replicas: 1 selector: matchLabels: app: test-client template: metadata: labels: app: test-client tier: test spec: containers: - name: client image: curlimages/curl command: - sleep - "3600"Apply:
kubectl apply -f test-client.yamlVerify:
kubectl get podsPart 12 — Test Baseline Connectivity
Section titled “Part 12 — Test Baseline Connectivity”Get the test-client Pod name:
kubectl get pods -l app=test-clientOpen a shell:
kubectl exec -it <test-client-pod> -- shFrom inside the Pod, test:
curl frontend-serviceThen:
curl backend-serviceThen:
curl database-serviceBefore policies are applied, your cluster may allow all three.
Record Baseline
Section titled “Record Baseline”Use:
Test Client → Frontend:Allowed / Denied
Test Client → Backend:Allowed / Denied
Test Client → Database:Allowed / DeniedSecurity Finding
Section titled “Security Finding”If everything is reachable:
Unknown Application Workload ↓Can Reach Every TierThis illustrates broad east-west connectivity.
Part 13 — Test Frontend Connectivity
Section titled “Part 13 — Test Frontend Connectivity”Get the frontend Pod:
kubectl get pods -l app=frontendRun:
kubectl exec -it <frontend-pod> -- shIf the image includes an HTTP client, use it.
If not, perform tests using your dedicated test client with appropriate labels, or use a lab-approved debugging image.
The target connectivity model is:
Frontend → Backendand not:
Frontend → DatabasePart 14 — Map Required Communication Before Blocking
Section titled “Part 14 — Map Required Communication Before Blocking”Before creating policies, document required flows.
Use:
| Source | Destination | Port | Required? |
|---|---|---|---|
| Frontend | Backend | 80 | Yes |
| Frontend | Database | 80 | No |
| Backend | Database | 80 | Yes |
| Test Client | Backend | 80 | No |
| Test Client | Database | 80 | No |
Professional Principle
Section titled “Professional Principle”Never start segmentation with:
Block Random TrafficStart with:
Understand Required Trafficthen implement controls.
Part 15 — Create Default-Deny Ingress
Section titled “Part 15 — Create Default-Deny Ingress”Create:
default-deny-ingress.yamlAdd:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-ingress namespace: ghc-network-labspec: podSelector: {} policyTypes: - IngressApply:
kubectl apply -f default-deny-ingress.yamlWhat Does podSelector {} Mean?
Section titled “What Does podSelector {} Mean?”It selects:
All Podsin the namespace.
Result
Section titled “Result”Conceptually:
All Pods Selected ↓Ingress Isolated ↓No Ingress AllowedUnless Another Policy Allows ItPart 16 — Validate Default-Deny
Section titled “Part 16 — Validate Default-Deny”From the test client, try:
curl backend-serviceand:
curl database-serviceThey should no longer succeed if NetworkPolicy is being enforced.
Critical Validation
Section titled “Critical Validation”If traffic continues to work exactly as before:
NetworkPolicy Object Existsbut:
Policy May Not Be EnforcedInvestigate the network implementation in your training cluster.
Part 17 — Inspect the Policy
Section titled “Part 17 — Inspect the Policy”Run:
kubectl get networkpoliciesThen:
kubectl describe networkpolicy default-deny-ingressInspect YAML:
kubectl get networkpolicy default-deny-ingress -o yamlPart 18 — Allow Frontend to Backend
Section titled “Part 18 — Allow Frontend to Backend”Create:
allow-frontend-to-backend.yamlAdd:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-frontend-to-backend namespace: ghc-network-labspec: podSelector: matchLabels: app: backend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: frontend ports: - protocol: TCP port: 80Apply:
kubectl apply -f allow-frontend-to-backend.yamlPolicy Meaning
Section titled “Policy Meaning”Selected destination:
Backend PodsAllowed source:
Frontend PodsAllowed port:
TCP 80Architecture
Section titled “Architecture”Frontend │ │ TCP 80 ▼Backendbut:
Test Client ─X─> BackendPart 19 — Validate Frontend-to-Backend
Section titled “Part 19 — Validate Frontend-to-Backend”Test the allowed path using an appropriate frontend-labelled client or the actual frontend workload if it contains suitable tools.
Expected:
Frontend → BackendAllowedThen test:
Test Client → BackendExpected:
DeniedSecurity Milestone
Section titled “Security Milestone”You now have:
Identity-Based Traffic Selectionthrough Pod labels.
Part 20 — Allow Backend to Database
Section titled “Part 20 — Allow Backend to Database”Create:
allow-backend-to-database.yamlAdd:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-backend-to-database namespace: ghc-network-labspec: podSelector: matchLabels: app: database policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 80Apply:
kubectl apply -f allow-backend-to-database.yamlDesired Result
Section titled “Desired Result”Backend → DatabaseAllowedwhile:
Frontend ─X─> Databaseand:
Test Client ─X─> DatabasePart 21 — Full Allowed Communication Model
Section titled “Part 21 — Full Allowed Communication Model”Your allowed paths are now:
Frontend ↓Backend ↓DatabaseUnnecessary direct paths should remain unavailable.
Attack Surface Reduction
Section titled “Attack Surface Reduction”Before:
Frontend ──────────────→ Database │ ├──────────────→ Backend │Test Client ──────→ EverythingAfter:
Frontend → Backend → DatabasePart 22 — Test Frontend-to-Database
Section titled “Part 22 — Test Frontend-to-Database”Attempt:
Frontend → DatabaseExpected:
DeniedThe database policy allows ingress only from:
app=backendThe frontend has:
app=frontendTherefore it does not match.
Part 23 — Understand Additive Policies
Section titled “Part 23 — Understand Additive Policies”NetworkPolicies are generally additive.
Suppose one policy allows:
Frontend → Backendand another allows:
Monitoring → BackendThe backend may receive traffic from both permitted sources.
Think:
Allowed by Policy A +Allowed by Policy B ↓Effective Allowed TrafficThis is conceptually similar to cumulative RBAC permissions.
Part 24 — Multiple Policies and Security Review
Section titled “Part 24 — Multiple Policies and Security Review”Do not inspect only one policy.
Ask:
Which Policies Select This Pod?Then determine:
What Is the Combined Effective Access?Part 25 — Default-Deny Egress
Section titled “Part 25 — Default-Deny Egress”So far, you have focused mainly on inbound traffic.
Now consider outbound traffic.
A compromised Pod might attempt:
Malicious Download
Command-and-Control
Data ExfiltrationCreate:
default-deny-egress.yamlAdd:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-egress namespace: ghc-network-labspec: podSelector: {} policyTypes: - EgressApply:
kubectl apply -f default-deny-egress.yamlWarning
Section titled “Warning”This will isolate egress for selected Pods.
It may also affect:
DNSwhich means service names may stop resolving.
This is an important real-world lesson.
Part 26 — Observe DNS Failure
Section titled “Part 26 — Observe DNS Failure”After default-deny egress, attempt:
curl backend-serviceYou may see a failure related to name resolution.
Why?
Because:
Application ↓Needs DNS ↓DNS Traffic BlockedSecurity Lesson
Section titled “Security Lesson”Policy design must include supporting infrastructure.
Do not think only:
Application PortThink:
Application DependenciesPart 27 — DNS as a Dependency
Section titled “Part 27 — DNS as a Dependency”Service discovery often depends on cluster DNS.
Conceptually:
Frontend ↓backend-service ↓DNS Resolution ↓Service IP ↓BackendIf DNS is blocked:
Application Communication Failseven if the application traffic itself is allowed.
Part 28 — Allow DNS Egress
Section titled “Part 28 — Allow DNS Egress”A production-grade DNS policy should be designed for the DNS service and network architecture in your cluster.
For training, first identify the cluster DNS service:
kubectl get services -n kube-systemLook for the DNS service used by your environment.
Then design egress allowing:
UDP 53
TCP 53toward the appropriate DNS destination.
Important
Section titled “Important”Do not blindly hardcode DNS IP addresses from another environment.
Discover:
Your Cluster DNSfirst.
Part 29 — Why TCP and UDP DNS?
Section titled “Part 29 — Why TCP and UDP DNS?”DNS commonly uses:
UDP 53but can also use:
TCP 53Therefore mature policies often consider both.
Part 30 — Allow Frontend Egress to Backend
Section titled “Part 30 — Allow Frontend Egress to Backend”Create a policy selecting:
app=frontendand allow outbound traffic toward:
app=backendon:
TCP 80Conceptually:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: frontend-egress namespace: ghc-network-labspec: podSelector: matchLabels: app: frontend policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 80You must also account for DNS if service-name resolution is required.
Part 31 — Allow Backend Egress to Database
Section titled “Part 31 — Allow Backend Egress to Database”Similarly:
Backend ↓DatabaseCreate a policy selecting:
app=backendwith egress toward:
app=databaseon the required port.
Final Two-Way Policy Logic
Section titled “Final Two-Way Policy Logic”For traffic to succeed in a fully isolated design, consider both sides:
Source Egress +Destination IngressPart 32 — Ingress and Egress Together
Section titled “Part 32 — Ingress and Egress Together”Example:
Frontendmust be allowed to send:
Egress → Backendand backend must allow:
Ingress ← FrontendThink:
Frontend Egress ↓Network ↓Backend IngressPart 33 — Application Communication Matrix
Section titled “Part 33 — Application Communication Matrix”Create a matrix like:
| Source | Destination | Ingress Required | Egress Required | Result |
|---|---|---|---|---|
| Frontend | Backend | Yes | Yes | Allow |
| Frontend | Database | No | No | Block |
| Backend | Database | Yes | Yes | Allow |
| Test Client | Backend | No | No | Block |
| Test Client | Database | No | No | Block |
This is an excellent enterprise design technique.
Part 34 — Namespace Selectors
Section titled “Part 34 — Namespace Selectors”NetworkPolicies can also use:
namespaceSelectorThis can allow traffic based on namespace labels.
Example architecture:
monitoring Namespace ↓Application NamespaceThe application may need to allow monitoring traffic without identifying every monitoring Pod individually.
Part 35 — Label the Namespace
Section titled “Part 35 — Label the Namespace”Inspect:
kubectl get namespace ghc-network-lab --show-labelsAdd a training label if desired:
kubectl label namespace ghc-network-lab environment=trainingVerify:
kubectl get namespace ghc-network-lab --show-labelsPart 36 — Namespace-Based Policy Thinking
Section titled “Part 36 — Namespace-Based Policy Thinking”Suppose:
monitoring Namespacehas:
purpose=monitoringA policy could conceptually allow traffic from:
namespaceSelector:purpose=monitoringSecurity Risk
Section titled “Security Risk”Do not use overly broad namespace selectors.
For example:
Any Namespacemay unintentionally reopen the application.
Part 37 — Combine Namespace and Pod Selection
Section titled “Part 37 — Combine Namespace and Pod Selection”A strong policy can conceptually require:
Namespace = monitoring
AND
Pod = approved-monitorThis is more specific than allowing an entire broad namespace population.
Part 38 — IP-Based Controls
Section titled “Part 38 — IP-Based Controls”NetworkPolicy can also represent some IP-based network requirements using IP blocks.
Conceptually:
Pod ↓Allowed External CIDRThis may be useful for controlled egress patterns.
Security Warning
Section titled “Security Warning”IP-based policy needs careful consideration around:
NAT
Cloud Networking
Service Routing
External Address ChangesDo not assume an IP-based rule always represents application identity.
Part 39 — Default-Deny Strategy
Section titled “Part 39 — Default-Deny Strategy”A common segmentation strategy is:
01 Default Deny
02 Identify Required Flows
03 Add Explicit Allows
04 Validate
05 MonitorThis produces a stronger baseline than:
Allow Everything
Try to Block Bad Traffic IndividuallyPart 40 — Default-Deny Risks
Section titled “Part 40 — Default-Deny Risks”Default-deny is powerful but can break:
DNS
Monitoring
Logging
Service Mesh
Health Checks
External APIs
Package Repositories
Cloud Metadata Access
Management TrafficTherefore:
Map Dependencies FirstPart 41 — NetworkPolicy Troubleshooting
Section titled “Part 41 — NetworkPolicy Troubleshooting”If traffic fails unexpectedly, use:
01 Source Pod Healthy?
02 Destination Pod Healthy?
03 Service Correct?
04 DNS Working?
05 NetworkPolicy Selecting Pod?
06 Ingress Allowed?
07 Egress Allowed?
08 Correct Labels?
09 Correct Port?
10 Network Plugin Enforcing Policy?Part 42 — Inspect All Policies
Section titled “Part 42 — Inspect All Policies”Run:
kubectl get networkpoliciesThen inspect each:
kubectl describe networkpolicy <policy-name>Look For
Section titled “Look For”Pod Selector
Policy Types
Allowed Sources
Allowed Destinations
PortsPart 43 — Check Labels
Section titled “Part 43 — Check Labels”Run:
kubectl get pods --show-labelsCompare labels with:
podSelectorA common issue is:
Policy Expects:app=backend
Pod Has:app=backend-apiThe policy will not select the intended workload.
Part 44 — Check Service Endpoints
Section titled “Part 44 — Check Service Endpoints”If connectivity is failing:
kubectl get endpointsor:
kubectl get endpointslicesConfirm the Service has healthy backend Pods.
Important
Section titled “Important”Not every network failure is caused by NetworkPolicy.
You must separate:
Application Problem
Service Problem
DNS Problem
Policy ProblemPart 45 — Controlled Troubleshooting Exercise
Section titled “Part 45 — Controlled Troubleshooting Exercise”Modify the backend allow policy temporarily so it expects:
app=front-endinstead of:
app=frontendTest communication.
Expected:
Frontend → BackendFailsInvestigation
Section titled “Investigation”Check:
kubectl get pods --show-labelsThen:
kubectl describe networkpolicy allow-frontend-to-backendCompare:
Policy Selector vsActual LabelsRestore Correct Configuration
Section titled “Restore Correct Configuration”Change it back to:
app=frontendValidate connectivity again.
Troubleshooting Milestone
Section titled “Troubleshooting Milestone”You followed:
Symptom ↓Identify Source ↓Identify Destination ↓Inspect Labels ↓Inspect Policy ↓Find Selector Mismatch ↓Repair ↓ValidatePart 46 — Security Finding Exercise
Section titled “Part 46 — Security Finding Exercise”Suppose the original application had no NetworkPolicies.
Document:
Finding:Kubernetes Application Lacks Network Segmentation
Affected Namespace:ghc-network-lab
Observation:Application workloads can communicatewith unrelated workloads without explicitnetwork restrictions.
Threat Scenario:If an application Pod is compromised,an attacker may be able to communicatewith additional internal servicesand attempt lateral movement.
Business Impact:Compromise of one workload could increaserisk to other application tiers.
Risk:High
Recommendation:Implement default-deny controlsand explicitly allow only requiredapplication communication paths.Part 47 — Finding: Frontend Can Reach Database
Section titled “Part 47 — Finding: Frontend Can Reach Database”Another example:
Finding:Frontend Workload Has UnnecessaryDirect Access to Database Tier
Expected Flow:Frontend → Backend → Database
Observed Flow:Frontend → Database
Risk:High
Threat Scenario:Compromise of the internet-facing frontendcould provide direct network reachabilityto the database tier.
Recommendation:Restrict database ingress so onlyauthorized backend workloads can connect.Part 48 — Network Security Finding Template
Section titled “Part 48 — Network Security Finding Template”Use:
Finding:
Affected Namespace:
Affected Source:
Affected Destination:
Observed Flow:
Expected Flow:
Port / Protocol:
Evidence:
Threat Scenario:
Business Impact:
Risk:
Recommendation:
Validation:Part 49 — Evidence Collection
Section titled “Part 49 — Evidence Collection”Capture:
Namespace
Pods and Labels
Services
Baseline Connectivity
NetworkPolicies
Default-Deny Results
Allowed Frontend-to-Backend Test
Blocked Frontend-to-Database Test
Allowed Backend-to-Database Test
Blocked Test-Client Traffic
Troubleshooting Evidence
Final Connectivity MatrixLab Evidence Template
Section titled “Lab Evidence Template”Lab:Kubernetes Network Policies
Date:
Cluster:
Namespace:
Baseline Connectivity:
Default-Deny Applied:
Required Flow 01:Frontend → Backend
Result:
Required Flow 02:Backend → Database
Result:
Blocked Flow 01:Frontend → Database
Result:
Blocked Flow 02:Test Client → Backend
Result:
Finding:
Remediation:
Validation:Part 50 — Attack Path Analysis
Section titled “Part 50 — Attack Path Analysis”Before segmentation:
Internet ↓Frontend ↓Backend ↓DatabaseBut potentially also:
Frontend ─────────→ Database │ └──────────────→ Other WorkloadsAfter segmentation:
Internet ↓Frontend ↓Backend ↓Databasewith unnecessary paths removed.
Security Outcome
Section titled “Security Outcome”You reduced:
Lateral Movement OpportunitiesPart 51 — NetworkPolicy and RBAC
Section titled “Part 51 — NetworkPolicy and RBAC”RBAC controls:
API PermissionsNetworkPolicy controls:
Network CommunicationA workload could have:
No Kubernetes API Permissionsbut still have:
Network Access to Sensitive ServicesTherefore both controls matter.
Part 52 — NetworkPolicy and Kyverno
Section titled “Part 52 — NetworkPolicy and Kyverno”Kyverno can enforce that application teams deploy required network controls.
For example, an organization may require:
Production Namespace ↓NetworkPolicy BaselineThis combines:
Policy Governance +Network EnforcementPart 53 — NetworkPolicy and Service Accounts
Section titled “Part 53 — NetworkPolicy and Service Accounts”Kubernetes network policies usually identify network entities primarily through workload and namespace selectors rather than service-account RBAC permissions.
But architecturally you should evaluate both:
Who Is the Workload?and:
Where Can the Workload Communicate?Security Model
Section titled “Security Model”Workload ↓Service Account ↓API Permissionplus:
Workload ↓NetworkPolicy ↓Network ReachabilityPart 54 — NetworkPolicy and Secrets
Section titled “Part 54 — NetworkPolicy and Secrets”Suppose a frontend cannot read a database Secret from Kubernetes.
That is good.
But if it can still directly reach the database and somehow obtains valid credentials through another path:
Frontend ↓Databasenetwork segmentation could have provided another defensive layer.
This is:
Defense in DepthPart 55 — NetworkPolicy and Runtime Security
Section titled “Part 55 — NetworkPolicy and Runtime Security”NetworkPolicy attempts to control:
What Network CommunicationShould Be PossibleRuntime monitoring helps identify:
What CommunicationActually OccursExample:
Unexpected External Connection ↓Runtime / Network AlertTogether:
Prevent +DetectPart 56 — Egress and Data Exfiltration
Section titled “Part 56 — Egress and Data Exfiltration”Suppose a compromised application reads sensitive data.
Without egress restrictions:
Compromised Pod ↓Internet ↓Attacker InfrastructureWith carefully designed egress:
Compromised Pod ↓Only Approved DestinationsThis can reduce some exfiltration opportunities.
Part 57 — Egress and Command-and-Control
Section titled “Part 57 — Egress and Command-and-Control”Malicious software may attempt:
External Connectionto obtain:
Commands
Payloads
UpdatesEgress controls can reduce unnecessary external connectivity.
Part 58 — Egress Design Questions
Section titled “Part 58 — Egress Design Questions”For each workload ask:
Does It Need Internet Access?
Which Domains / Destinations?
Which Ports?
Which Cloud APIs?
Which Internal Services?
Does It Need DNS?Part 59 — Production Communication Inventory
Section titled “Part 59 — Production Communication Inventory”A mature organization maintains application flow information.
Example:
| Application | Source | Destination | Port | Purpose |
|---|---|---|---|---|
| Storefront | Frontend | API | 443 | API requests |
| Storefront | API | Database | 5432 | Data access |
| Storefront | API | Payment API | 443 | Payment processing |
This becomes the basis for segmentation.
Part 60 — Least Connectivity
Section titled “Part 60 — Least Connectivity”Apply:
Only Required Sources
Only Required Destinations
Only Required PortsAvoid:
Any Source
Any Destination
Any Portunless genuinely required.
Part 61 — Network Security Review Workflow
Section titled “Part 61 — Network Security Review Workflow”Use:
01 Identify Workloads
02 Map Application Tiers
03 Identify Required Flows
04 Record Ports and Protocols
05 Identify External Dependencies
06 Review Existing Policies
07 Identify Unnecessary Reachability
08 Implement Default-Deny
09 Add Required Allows
10 Validate
11 MonitorPart 62 — Policy Review Questions
Section titled “Part 62 — Policy Review Questions”For every NetworkPolicy ask:
Which Pods Does It Select?
Is It Ingress or Egress?
Who Is Allowed?
Which Ports?
Which Namespaces?
Is the Rule Too Broad?
Is There Another Policy Adding Access?Part 63 — Common Mistake: Wrong podSelector
Section titled “Part 63 — Common Mistake: Wrong podSelector”Policy:
app=databasePod:
app=dbResult:
Policy Does Not Select DatabaseAlways validate labels.
Part 64 — Common Mistake: Forgetting DNS
Section titled “Part 64 — Common Mistake: Forgetting DNS”After default-deny egress:
Service Names Stop Resolvingbecause DNS was not allowed.
This is one of the most useful lessons from egress-policy testing.
Part 65 — Common Mistake: Assuming Service Controls Traffic
Section titled “Part 65 — Common Mistake: Assuming Service Controls Traffic”A Kubernetes Service provides routing and discovery.
It is not itself the same as:
Security SegmentationUse NetworkPolicy for supported workload-level communication controls.
Part 66 — Common Mistake: Only Controlling Ingress
Section titled “Part 66 — Common Mistake: Only Controlling Ingress”Ingress reduces inbound attack paths.
But egress may still allow:
External Command-and-Control
Data Exfiltration
Unnecessary Internal AccessAssess both directions.
Part 67 — Common Mistake: Overly Broad Namespace Access
Section titled “Part 67 — Common Mistake: Overly Broad Namespace Access”Allowing:
All Pods From Namespace Xmay be broader than necessary.
Consider whether:
Only Specific Podsactually need access.
Part 68 — Common Mistake: No Validation
Section titled “Part 68 — Common Mistake: No Validation”A YAML file existing does not prove security.
Always perform:
Allowed Traffic Test
Blocked Traffic TestPart 69 — Positive and Negative Testing
Section titled “Part 69 — Positive and Negative Testing”For each rule test:
Expected Allowed Flowand:
Expected Blocked FlowExample:
Frontend → BackendAllowedand:
Frontend → DatabaseDeniedPart 70 — Security Metrics
Section titled “Part 70 — Security Metrics”Organizations can track:
Namespaces With Default-Deny
Workloads Covered by Policies
Unrestricted Egress
Policy Violations
Approved ExceptionsThese help measure segmentation maturity.
Part 71 — Compliance Connection
Section titled “Part 71 — Compliance Connection”A control requirement may state:
Production workloads mustbe appropriately segmented.Evidence could include:
NetworkPolicy Configuration
Application Flow Matrix
Connectivity Validation
Change RecordsPart 72 — Production Rollout Strategy
Section titled “Part 72 — Production Rollout Strategy”Do not immediately apply aggressive default-deny policies everywhere.
Use:
Map ↓Observe ↓Test ↓Restrict ↓Validate ↓MonitorSuggested Progression
Section titled “Suggested Progression”01 Development
02 Testing
03 Selected Production Workload
04 Wider Production RolloutPart 73 — NetworkPolicy Troubleshooting Challenge
Section titled “Part 73 — NetworkPolicy Troubleshooting Challenge”Scenario:
Frontend cannot reach Backend.Use:
Is Frontend Running?
Can DNS Resolve Backend?
Does Service Have Endpoints?
Does Backend Ingress Allow Frontend?
Does Frontend Egress Allow Backend?
Do Labels Match?
Is Port 80 Allowed?Part 74 — Database Access Challenge
Section titled “Part 74 — Database Access Challenge”Scenario:
Test Client can still reach Databaseafter segmentation.Investigate:
Which Policies Select Database?
Does Another Policy Allow Test Client?
Is Database Actually Selected?
Are Labels Correct?
Is NetworkPolicy Being Enforced?Part 75 — DNS Challenge
Section titled “Part 75 — DNS Challenge”Scenario:
curl backend-servicefails after egress isolation.But using a direct IP behaves differently.
Likely investigation area:
DNS EgressPart 76 — Final Connectivity Validation
Section titled “Part 76 — Final Connectivity Validation”Your final desired matrix should resemble:
| Source | Frontend | Backend | Database |
|---|---|---|---|
| Frontend | As Required | Allow | Deny |
| Backend | Deny/As Required | As Required | Allow |
| Database | Deny | Deny/As Required | As Required |
| Test Client | Deny/As Required | Deny | Deny |
Exact requirements vary by application.
The key is:
Explicit Business Requirementrather than:
Default Broad ReachabilityPart 77 — Cleanup
Section titled “Part 77 — Cleanup”Capture your evidence first.
List policies:
kubectl get networkpoliciesThen delete the training namespace:
kubectl delete namespace ghc-network-labVerify:
kubectl get namespace ghc-network-labRestore Namespace Context
Section titled “Restore Namespace Context”If required:
kubectl config set-context --current --namespace=defaultVerify:
kubectl config view --minifyLab Completion Checklist
Section titled “Lab Completion Checklist”Environment
Section titled “Environment”- Verified Kubernetes context
- Confirmed NetworkPolicy API
- Created lab namespace
- Confirmed network policy enforcement behavior
Application
Section titled “Application”- Deployed frontend
- Deployed backend
- Deployed database simulation
- Deployed test client
- Created Services
Baseline
Section titled “Baseline”- Tested initial connectivity
- Recorded application flows
- Identified unnecessary communication
Ingress Security
Section titled “Ingress Security”- Created default-deny ingress
- Allowed frontend to backend
- Allowed backend to database
- Blocked test client to backend
- Blocked frontend to database
Egress Security
Section titled “Egress Security”- Understood default-deny egress
- Identified DNS requirement
- Allowed required application egress
- Considered external dependencies
- Understood exfiltration risk
Troubleshooting
Section titled “Troubleshooting”- Reviewed Pod labels
- Reviewed NetworkPolicies
- Checked Services
- Checked endpoints
- Investigated selector mismatch
- Validated corrected traffic
Security Assessment
Section titled “Security Assessment”- Created flow matrix
- Identified lateral movement risk
- Documented network-security finding
- Applied least connectivity
- Validated remediation
Skills You Practiced
Section titled “Skills You Practiced”You have now worked with:
Kubernetes Networking
NetworkPolicy
Ingress Controls
Egress Controls
Default-Deny
Pod Selectors
Namespace Selectors
Application Flow Mapping
Network Segmentation
Lateral Movement Reduction
Connectivity TroubleshootingCareer Connection
Section titled “Career Connection”These skills are highly relevant for:
Kubernetes Security Engineer
Cloud Security Engineer
Platform Security Engineer
DevSecOps Engineer
Cloud Network Security Engineer
Security Architect
Security ConsultantIn enterprise Kubernetes, network segmentation becomes particularly important because clusters may host:
Many Applications
Many Teams
Sensitive Workloads
Different Trust LevelsInterview Questions
Section titled “Interview Questions”- What is a Kubernetes NetworkPolicy?
- Why are NetworkPolicies important?
- What is ingress?
- What is egress?
- What does
podSelectordo? - What does an empty
podSelector: {}mean? - What is a default-deny policy?
- Why would you implement default-deny ingress?
- Why would you implement default-deny egress?
- What is lateral movement?
- How can NetworkPolicy reduce lateral movement?
- How do labels affect NetworkPolicy?
- What happens if a policy selector does not match a Pod?
- Can multiple NetworkPolicies apply to one Pod?
- How do multiple NetworkPolicies affect effective connectivity?
- What is a namespaceSelector?
- When would you use a namespaceSelector?
- Why can overly broad namespace selectors be risky?
- What is the purpose of egress filtering?
- How can egress controls reduce data-exfiltration risk?
- Why can default-deny egress break DNS?
- Which ports does DNS commonly use?
- Why should DNS be included in network-policy design?
- How would you troubleshoot a Service that becomes unreachable after NetworkPolicy changes?
- Why should you check Pod labels?
- Why should you check Service endpoints?
- What is the difference between a Service and a NetworkPolicy?
- Why should security teams map required application flows?
- What is least connectivity?
- Why should frontend workloads not necessarily communicate directly with database workloads?
- How would you isolate a database Pod?
- How would you allow only backend Pods to reach a database?
- How do ingress and egress policies work together?
- Why should policy behavior be tested instead of assumed?
- What does it mean if a NetworkPolicy exists but traffic is still unrestricted?
- How do RBAC and NetworkPolicy complement each other?
- How do Kyverno and NetworkPolicy complement each other?
- How does runtime monitoring complement NetworkPolicy?
- How would you document a Kubernetes network-security finding?
- How would you safely introduce network segmentation into production?
Practical Readiness Milestone
Section titled “Practical Readiness Milestone”You should now be able to receive an architecture:
Frontend ↓Backend ↓Databaseand derive:
Required Network Flows ↓Default-Deny ↓Frontend Allow Rule ↓Backend Allow Rule ↓DNS Requirements ↓ValidationThen prove:
Required Traffic = Allowed
Unnecessary Traffic = DeniedSecurity Readiness Milestone
Section titled “Security Readiness Milestone”You should also be able to investigate:
Compromised Frontend Podand ask:
Can It Reach Backend?
Can It Reach Database?
Can It Reach Other Namespaces?
Can It Reach the Internet?
Can It Reach Internal Services?This transforms Kubernetes security from:
Is the Pod Secure?into:
What Can the Pod ReachIf It Is Compromised?Final Lab Mental Model
Section titled “Final Lab Mental Model”Remember:
APPLICATION ARCHITECTURE ↓REQUIRED FLOWS ↓DEFAULT-DENY ↓EXPLICIT ALLOW ↓VALIDATE ↓MONITORFor every workload:
WHO CAN CONNECT TO IT?and:
WHERE CAN IT CONNECT?The security objective is:
Minimum NecessaryNetwork ReachabilityLab Outcome
Section titled “Lab Outcome”Before this lab:
Your Kubernetes workloadscould communicate based primarilyon the cluster's default networking behavior.After this lab:
You mapped application flows,
implemented default-deny controls,
allowed required communication,
blocked unnecessary paths,
restricted lateral movement,
investigated DNS dependencies,
troubleshot policy behavior,
and validated network segmentation.You have moved from:
Kubernetes Connectivityto:
Kubernetes Network Security.What’s Next?
Section titled “What’s Next?”➡️ Lab 05 — OPA Gatekeeper
In the next lab, you will return to Kubernetes policy enforcement and learn another major policy-as-code approach.
You will work with:
OPA
Gatekeeper
ConstraintTemplates
Constraints
Admission Control
Policy Enforcement
Security Standards
Compliance ValidationThe progression becomes:
Lab 01 — Kubernetes Fundamentals ↓Understand Resources
Lab 02 — Kubernetes RBAC ↓Control Identity
Lab 03 — Kyverno ↓Enforce Kubernetes-Native Policy
Lab 04 — Network Policies ↓Control Communication
Lab 05 — OPA Gatekeeper ↓Build Advanced Admission GuardrailsYou are now combining:
Identity Security
Configuration Security
Network Security
Policy Enforcementinto a layered Kubernetes security model.