Question format
You have a Kubernetes cluster and running pods in multiple namespaces, The security team has mandated that the db pods on Project-a namespace only accessible from the service pods that are running in Project-b namespace.
Prerequisites
A Kubernetes cluster with a CNI plugin that supports Network Policies (e.g., Calico, Cilium, or Weave Net).
kubectl configured to interact with the cluster.
Existing namespaces project-a (for databases) and project-b (for services).
Step 1: Label the Namespaces
Add labels to the namespaces to simplify targeting in policies.
Label the project-b namespace:
kubectl label namespace project-b project=project-b
Verify labels:
kubectl get namespaces --show-labels
Step 2: Identify Pod Labels
Ensure your pods have labels for identification.
Database Pods in project-a:
Example label: app=db (e.g., add via kubectl label pod <db-pod> app=db -n project-a).
Service Pods in project-b:
Example label: app=service (e.g., add via kubectl label pod <service-pod> app=service -n project-b).
Step 3: Create a Network Policy
Create a policy to restrict traffic to the db pods in project-a only from project-b service pods.
Create a file named db-access-policy.yaml:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-project-b-to-db
namespace: project-a # Applies to the database pods in project-a
spec:
podSelector:
matchLabels:
app: db # Targets pods labeled "app=db"
policyTypes:
- Ingress # Controls incoming traffic
ingress:
- from:
- namespaceSelector: # Restrict to namespaces labeled "project=project-b"
matchLabels:
project: project-b
podSelector: # Restrict to pods labeled "app=service"
matchLabels:
app: service
ports: # Specify the database port (e.g., 3306 for MySQL)
- protocol: TCP
port: 3306
Replace port: 3306 with your database’s actual port.
Apply the policy:
kubectl apply -f db-access-policy.yaml
Step 4: Verify the Network Policy
Check the policy status:
kubectl -n project-a get networkpolicies
Test connectivity:
From project-b service pod (should succeed):
kubectl -n project-b exec -it <service-pod> -- curl http://db.project-a.svc.cluster.local:3306
From pods in other namespaces (should fail):
kubectl -n default exec -it <other-pod> -- curl http://db.project-a.svc.cluster.local:3306
How It Works
podSelector: Selects pods in project-a with the label app=db.
namespaceSelector: Restricts traffic to pods from namespaces labeled project=project-b.
podSelector (inside from): Further restricts traffic to pods labeled app=service in project-b.
Default Deny: All other ingress traffic to db pods is blocked.
Troubleshooting
Pods Can’t Communicate:
Ensure the CNI plugin supports Network Policies.
Verify pod and namespace labels match the policy.
Check for conflicting policies (kubectl get networkpolicies -A).
Port Mismatch:
Ensure the port in the policy matches the database pod’s listening port.