Complete Guide to Kubernetes Network Policy: Controlling Service Communication with Zero Trust
As microservice architecture (MSA) has become the mainstream, application complexity has grown exponentially. Countless services communicate with each other to form a vast ecosystem, but this very “connectivity” can become the biggest security vulnerability. It is like an environment where an attacker who has entered the internal network can roam freely as if they were a legitimate employee.
In this environment, Kubernetes Network Policy is what answers the fundamental question: “Our service should only communicate with service A, so why is it also talking to service C?” This guide goes beyond simple conceptual explanations and provides concrete hands-on instructions on how to implement Zero Trust principles at the network level in real production environments.
🛡️ Why Are Network Policies Essential in Kubernetes Environments?
Traditional datacenter security models relied on “Perimeter Defense.” In other words, they assumed that if you only blocked inbound traffic from the outside, the inside would be safe. That assumption breaks down in MSA environments. Containers are isolated, but communication between Pods is often allowed by default.
This default behavior is convenient in the early stages of development, but from a security perspective it is a critical weakness. If one service (for example, an authentication module) is compromised, an attacker can exploit this policy gap to attempt lateral movement toward other sensitive services (for example, a payment module).
The core is “Never Trust.” Network policies discard the very concept of trust and act as a firewall that opens only explicitly permitted communication paths. This is the core of implementing Zero Trust architecture at the network layer.
⚙️ Understanding How Network Policies Work and Their Basic Structure
Network policies are a set of rules that control L3 (IP) and L4 (port/protocol) traffic at the Kubernetes Pod level. These policies are converted into actual networking rules and applied by the CNI (Container Network Interface) plugin deployed in the cluster (for example, Calico, Cilium).
The most basic policy targets a specific namespace or Pod Selector, and can control Ingress (incoming traffic) and Egress (outgoing traffic) separately.
💡 Basic YAML Example: Allowing Only a Specific Port
The following example restricts Ingress so that the api-server Pod in the frontend namespace can only be accessed from outside on port 8080.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-api-ingress
namespace: frontend
spec:
podSelector:
matchLabels:
app: api-server
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: ingress-controller # Ingress Controller에서 오는 트래픽만 허용
ports:
- protocol: TCP
port: 8080The key to understanding this code is the from field. Traffic from all sources not specified in from is blocked by default.
🧱 Deep Dive: Applying the Principle of Least Privilege
In network security, the Principle of Least Privilege is the rule that “each subject (service) should have access only to the minimum resources needed to do its job.” Implementing this with network policies means explicitly stating: “This service has permission to communicate only with this port and this service.”
🌐 Concrete Use Cases for Ingress and Egress Control
- Ingress control (restricting incoming traffic):
- Use Case: The user authentication service (
auth-svc) should only receive HTTPS traffic on port 443 from the load balancer (Ingress Controller). Direct access from other internal services must be blocked.
- Use Case: The user authentication service (
- Egress control (restricting outgoing traffic):
- Use Case: The payment service (
payment-svc) needs to communicate with an external payment gateway (PG) API server (a specific IP/domain). Arbitrary data transmission to other internal microservices must be blocked.
- Use Case: The payment service (
📊 Security Level Comparison: Default Allow vs. Default Deny
| Category | Before Policy (Default Allow) | After Policy (Default Deny) | Security Level |
|---|---|---|---|
| Allowed communication scope | All Pod-to-Pod communication in the cluster is allowed | Only explicitly permitted communication is allowed | Very low |
| Impact of an attack | Lateral movement is easy | The attack surface is isolated to the initial point of compromise | Very high |
| Guiding principle | Trust-based | Least Privilege | Zero Trust implementation |
🚨 Production Application and Advanced Considerations: The Default Deny Strategy
The strongest security strategy is “block everything by default and allow only what is needed (Default Deny).”
If no NetworkPolicy is applied to a namespace, all traffic is allowed by default. Therefore, the first thing you should do is apply a policy that blocks all Ingress/Egress by default for every Pod in that namespace.
⚠️ Debugging Guide for Policy Misconfiguration (Failure Cases)
The most common mistake is omitting a required communication path. For example, if user-service needs to connect to database-svc but you leave out the database-svc label selector in the policy, the service will appear as if communication is broken.
Debugging tips:
kubectl describe networkpolicy <policy-name>: Check which selectors and ports the policy actually targets.- Check CNI logs: Check the logs of the CNI in use (for example, Calico) to confirm whether the traffic was explicitly dropped by the policy. This is the most reliable approach.
[A practitioner’s hard-won advice] Early in a project I overlooked this and experienced an outage because logging traffic between services was blocked. When designing network policies, separately defining exception rules for monitoring/logging traffic in addition to business traffic is the key to stable operations.
🚀 Conclusion: Raising Architecture Maturity Through Network Security
Introducing network policies is more than a simple security patch; it is a process that raises architecture maturity by one level. It is equivalent to requiring development teams to “clearly document what communication you will do and prove it in code.”
Next-step roadmap:
- Audit: Map all current inter-service communication flows in the cluster.
- Define: Define the minimum ports, protocols, and source/destination Pods required for each communication path.
- Implement: Apply a Default Deny policy at the top level, then sequentially add exception policies for required communication.
Through this process, your Kubernetes cluster will evolve from a mere collection of containers into a strongly controlled system with clear security boundaries.
Frequently Asked Questions (FAQ)
Q1. Do all Pods need to be in the same namespace to apply NetworkPolicy?
A1. No. You can apply policies to groups of Pods with specific labels using podSelector, and you can also reference Pods in other namespaces using label selectors in the from field.
Q2. If communication fails after applying NetworkPolicy, what should I check first?
A2. The first things to check are whether the CNI plugin in use (Calico, Cilium, etc.) supports NetworkPolicy, and whether the policy was actually deployed in that namespace (kubectl get netpol -n <namespace>).
Q3. If I use a Service Mesh, do I still need NetworkPolicy? A3. Yes, you still need it. Service meshes (Istio, Linkerd, etc.) provide L7 (HTTP headers, methods) policy control that improves security, but NetworkPolicy acts as a last line of defense that blocks fundamental traffic flow at L3/L4. Using both together is the strongest security combination.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.