# NetworkPolicy for my-app in app-dev namespace --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-default-deny-app-dev namespace: app-dev spec: podSelector: matchLabels: app: my-app policyTypes: - Ingress - Egress # By omitting ingress/egress rules, all traffic is denied by default.
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-allow-observability-egress-app-dev namespace: app-dev spec: podSelector: matchLabels: app: my-app policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: name: monitoring # Allow egress to the monitoring namespace podSelector: {} # Allow to all pods in monitoring namespace ports: - protocol: TCP port: 9090 # Example: Prometheus metrics port - protocol: TCP port: 24224 # Example: Fluentd log forwarding port - protocol: TCP port: 14268 # Example: Jaeger agent/collector port
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-allow-self-ingress-app-dev namespace: app-dev spec: podSelector: matchLabels: app: my-app policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: my-app # Allow ingress from other my-app pods in the same namespace ports: - protocol: TCP port: 8080 # Example: Internal application communication port
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-allow-db-egress-app-dev namespace: app-dev spec: podSelector: matchLabels: app: my-app policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: name: data # Allow egress to the data namespace podSelector: matchLabels: app: db-service # Allow egress to the db-service pods ports: - protocol: TCP port: 5432 # Example: PostgreSQL port
# NetworkPolicy for my-app in app-prod namespace --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-default-deny-app-prod namespace: app-prod spec: podSelector: matchLabels: app: my-app policyTypes: - Ingress - Egress
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-allow-observability-egress-app-prod namespace: app-prod spec: podSelector: matchLabels: app: my-app policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: name: monitoring podSelector: {} ports: - protocol: TCP port: 9090 - protocol: TCP port: 24224 - protocol: TCP port: 14268
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-allow-self-ingress-app-prod namespace: app-prod spec: podSelector: matchLabels: app: my-app policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: my-app ports: - protocol: TCP port: 8080
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-app-allow-db-egress-app-prod namespace: app-prod spec: podSelector: matchLabels: app: my-app policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: name: data podSelector: matchLabels: app: db-service ports: - protocol: TCP port: 5432
GitOps Integration Notes (Helm/Kustomize)
Helm: For Helm, these NetworkPolicy manifests can be placed directly into the templates/ directory of your application's Helm chart.
- Parameterization: Use Helm's templating capabilities to make
namespace and observability_namespace configurable via values.yaml. For example, namespace: {{ .Release.Namespace }} and name: {{ .Values.observabilityNamespace }}. - Conditional Deployment: You might include a
values.yaml flag (e.g., networkPolicies.enabled: true) to conditionally deploy these policies, allowing for environments where they might not be needed or are managed externally. - Dependencies: If observability or database services are managed by separate charts, ensure proper dependency management or coordinate deployments to avoid policy enforcement issues before target services are ready.
Kustomize: With Kustomize, these policies can be managed as base resources and then overlaid for specific environments.
- Base: Place all generated YAML files in a
base/network-policies/ directory. - Overlays: Create
overlays/app-dev/ and overlays/app-prod/ directories. In each overlay's kustomization.yaml, reference the base policies and apply namespace transformations if needed (though the policies are already namespaced here). - Common Labels: Use
commonLabels in kustomization.yaml to add environment-specific labels to the policies for easier identification. - Patches: If minor modifications are needed per environment (e.g., adding an extra port), use JSON or Strategic Merge Patches.
Rollout and Rollback Strategy
Rollout Strategy (Phased Approach):
- Audit Mode (Optional but Recommended): If your CNI supports it (e.g., Calico's
doNotTrack or allow-all with logging), deploy policies in a "log-only" or "audit" mode first. This allows you to observe what traffic *would* be blocked without actually enforcing it, helping identify missing rules. - Staging Environment Deployment: Apply the NetworkPolicies to a non-production staging environment first. Thoroughly test all application functionalities, internal communications, and especially observability integrations (metrics, logs, traces). Verify that all expected traffic flows are permitted and unexpected traffic is blocked.
- Gradual Production Deployment:
* Phase 1 (Observability First): Deploy only the my-app-allow-observability-egress-* policies to production. This ensures that even if subsequent policies cause issues, you retain visibility into your application's health. * Phase 2 (Internal & DB): Deploy my-app-allow-self-ingress-* and my-app-allow-db-egress-* policies. Monitor closely for any disruptions to application functionality or database connectivity. * Phase 3 (Default Deny): Finally, deploy the my-app-default-deny-ingress-egress-* policies. This is the most impactful step, as it will block all traffic not explicitly allowed by the previous policies. Monitor all application metrics, logs, and user-facing functionality immediately after deployment.
- Continuous Monitoring: After full deployment, maintain vigilant monitoring for any
NetworkPolicy related drops or unexpected application behavior.
Rollback Strategy:
- Immediate Reversal: If any critical issues arise during a deployment phase, the primary rollback strategy is to immediately delete the problematic NetworkPolicy resources. This can be done via
kubectl delete -f <policy-file.yaml> or by reverting the Git commit in your GitOps repository and letting the reconciler apply the change. - Gradual Removal (if needed): In complex scenarios, you might need to remove policies in reverse order of their deployment, starting with the
default-deny and then specific allow policies, to isolate the problematic rule. - Pre-computed Rollback Manifests: For critical applications, consider having pre-computed "rollback" manifests (e.g., an
allow-all policy for the application's namespace) ready to apply instantly if a policy causes a severe outage, providing a quick "circuit breaker." - Version Control: Ensure all NetworkPolicy changes are version-controlled. This allows for easy identification of the last working state and simplifies reverting to it.