Cluster information:
Kubernetes version:1.14.10
Cloud being used: (put bare-metal if not on a public cloud)
Installation method:kubeadm
Host OS: centos
CNI and version:calico 3.7
CRI and version: 18.06.3-ce
I am trying to isolate my pods in namespace from other namespaces. I have tried to create a NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: dev-ns
spec:
podSelector:
matchLabels:
ingress:
- from:
- podSelector: {}
This NetworkPolicy successfully isolating pods in my namespace from another namespace. But this policy, once applied, disables all external traffic to these pods.
For example when i request the service by its <EXTERNAL_IP>:<PORT>
, then the network policy will deny the ingress traffic from the service and the request will time out
Is there any method for only block traffic from other namespaces and allow all external traffic to the pods.
I think you have to use namespaceSelector instead of podSelector to block other namespaces traffic.
@tej-singh-rana ,Yes we can do this using namespace selector in ingress field ,and this block traffic from another namespace,which is fine . But the issue is both methods will block traffic from outside the cluster via NodePort
I think it’s blocked dns service too so not able to resolv. Open port for dns (53).
@tej-singh-rana . No port 53 is open and working fine without Network Policy …
Here’s an example Scenario: allow requests from ns2 to ns1 only, on port 80
create namespace ns1 and ns2
kubectl create ns ns1
kubectl create ns ns2
label namespace ns2
kubectl label ns ns2 ns=ns2
apply network policy on ns1
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: ns2
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
ns: ns1
ports:
- protocol: TCP
port: 80
Test this,
create busybox on ns2
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: bb
name: bb
spec:
containers:
- name: bb
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 3600;done"]
name: bb
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
create nginx on ns1
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
expose this service,
kubectl expose svc nginx --port=80 --type=NodePort -n ns1
Now try to do wget from ns2 to ns1
kubectl exec -it bb -n ns2 -- sh
wget http://nginx.ns1
You can try to deploy the busybox on default namespace and test it to see if it allows the request or not.
a perfect soluction if you can use Calico
- namespace have tag tianbao=“dev” , can not ping each other
- able ping public traffic
- public able to access pod
- nodePort is working fine.
- remember to add tag (tianbao=“dev”) to new namespace
kubectl label namespaces test1 tianbao="dev"
kubectl label namespaces test2 tianbao="dev"
cat <<EOF | kubectl apply -f -
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: deny-dev-namesapce-to-test
spec:
namespaceSelector: env == "test1"
ingress:
- action: Allow
egress:
- action: Allow
destination:
namespaceSelector: env == "test1"
- action: Deny
destination:
namespaceSelector: tianbao == "dev"
- action: Allow
EOF
cat <<EOF | kubectl apply -f -
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: deny-dev-namesapce-to-test
spec:
namespaceSelector: env == "test2"
ingress:
- action: Allow
egress:
- action: Allow
destination:
namespaceSelector: env == "test2"
- action: Deny
destination:
namespaceSelector: tianbao == "dev"
- action: Allow
EOF