Integrating Network Policy with Helm for Enhanced Kubernetes Security
On this page
Learn how to enhance your Kubernetes cluster security by implementing Network Policies through Helm charts, including best practices and real-world examples.
Understanding Network Policies in Kubernetes
Network Policies are Kubernetes resources that control the flow of network traffic between pods, namespaces, and external endpoints. They act as a firewall, allowing you to:
- Isolate workloads
- Enforce zero-trust networking
- Implement microsegmentation
- Control ingress and egress traffic
- Define allowed communication paths
Why Use Helm for Network Policies?
Helm provides several advantages when managing Network Policies:
- Templating capabilities for dynamic policy generation
- Version control and rollback support
- Consistent policy deployment across environments
- Easy updates and modifications
- Reusable policy templates
Prerequisites
Before implementing Network Policies with Helm, ensure:
- Your cluster supports Network Policies (e.g., using Calico, Cilium, or other CNI with NetworkPolicy support)
- Helm 3.x is installed
- Proper RBAC permissions are configured
Basic Network Policy Template
Here’s a basic example of a Network Policy template in a Helm chart:
# templates/network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-policy
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app: {{ .Values.appName }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: {{ .Values.allowedNamespace }}
- podSelector:
matchLabels:
role: {{ .Values.allowedRole }}
ports:
- protocol: TCP
port: {{ .Values.servicePort }}
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53 # DNSImplementing Common Security Patterns
1. Default Deny All Traffic
# templates/default-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-default-deny
namespace: {{ .Release.Namespace }}
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress2. Allow Specific Microservices Communication
# templates/microservice-policy.yaml
{{- range .Values.microservices }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ $.Release.Name }}-{{ .name }}-policy
spec:
podSelector:
matchLabels:
app: {{ .name }}
ingress:
{{- range .allowedServices }}
- from:
- podSelector:
matchLabels:
app: {{ . }}
{{- end }}
{{- end }}3. Monitoring System Access
# templates/monitoring-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-monitoring
spec:
podSelector:
matchLabels:
app: {{ .Values.appName }}
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- port: {{ .Values.metricsPort }}
protocol: TCPValues File Configuration
# values.yaml
appName: myapp
servicePort: 8080
metricsPort: 9090
allowedNamespace: frontend
allowedRole: api
microservices:
- name: frontend
allowedServices:
- backend
- cache
- name: backend
allowedServices:
- database
- cache
- name: database
allowedServices: []Best Practices
1. Layer Your Policies
Create multiple policies that build upon each other:
# templates/layered-policy.yaml
{{- if .Values.security.layers.basic }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-basic
spec:
podSelector: {}
policyTypes:
- Ingress
---
{{- end }}
{{- if .Values.security.layers.advanced }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-advanced
spec:
# Additional restrictions
{{- end }}2. Use Conditional Policies
# templates/conditional-policy.yaml
{{- if .Values.environment.production }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-strict-policy
spec:
# Stricter rules for production
{{- else }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-dev-policy
spec:
# More permissive rules for development
{{- end }}3. Template Helper Functions
# templates/_helpers.tpl
{{- define "networkpolicy.common.labels" -}}
app: {{ .Values.appName }}
environment: {{ .Values.environment.name }}
managed-by: {{ .Release.Service }}
{{- end }}Testing and Validation
- Dry Run Installation:
helm install --dry-run --debug my-policies ./network-policies- Policy Validation:
kubectl auth can-i create networkpolicy
kubectl auth can-i update networkpolicy- Testing Connectivity:
# Test pod connectivity
kubectl run test-pod --image=busybox -n test-namespace -- wget -O- http://service-name:portTroubleshooting
Common issues and solutions:
Policy Not Applied
- Check CNI plugin supports Network Policies
- Verify label selectors match pods
- Check policy is in correct namespace
Unexpected Blocking
- Review egress rules for DNS access
- Check namespace labels
- Verify port specifications
Policy Conflicts
- Network Policies are additive
- More specific policies take precedence
- Review all policies in namespace
Monitoring and Logging
Enable policy monitoring:
# templates/policy-metrics.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
annotations:
metrics-enabled: "true"
policy-log-level: "info"Conclusion
Integrating Network Policies with Helm provides a powerful way to manage and enforce network security in Kubernetes clusters. Key takeaways:
- Use templates for consistent policy deployment
- Layer policies for defense in depth
- Implement environment-specific policies
- Regular testing and validation
- Monitor policy effectiveness
Remember to:
- Start with restrictive policies
- Test thoroughly before production
- Document policy intentions
- Monitor policy impacts
- Regularly review and update policies
For more information, refer to the Kubernetes Network Policy documentation and Helm documentation.