Question:
Create a namespace named g04 with labels app=orion
Set up three Pods to demonstrate the unrestricted Pod-to-Pod network communication. Define the Pods named backend which will use image gcr.io/kuar-demo/kuard-amd64:blue with container port 8080 and frontend with image alpine with command sleep 1d in the namespace g04. Define the other Pod with busybox image with command sleep 1d that lives in the default namespace.
Determine the virtual IP addresses assigned to the Pods.
Try to communicate between The frontend and the backend using wget
Try to communicate from other Pod residing in the default namespace with the backend Pod using wget
Apply deny-all ingress network policy from Kubernetes documentation.
Try again procedure with wget.
Allow ingress traffic to the backend Pod only from the frontend Pod that lives in the same namespace. Ingress traffic from all other Pods should be denied independently of the namespace they are running in.
Adjust network policy that allows the frontend Pod to talk to the backend Pod only on port 8080. No other communication should be allowed.
Test again with wget
Answer:
Create the namespace. First - generate a manifest:
k create ns g04 --dry-run=client -o yaml > ns.yaml
Edit the ns.yaml to match like this:
apiVersion: v1
kind: Namespace
metadata:
name: g04
labels:
app: orion
Apply to create the namespace:
k apply -f ns.yaml
Create backend Pod in the g04 namespace:
k -n g04 run backend --image=gcr.io/kuar-demo/kuard-amd64:blue --port=8080
Create frontend Pod in the g04 namespace:
k -n g04 run frontend --image=alpine --command -- /bin/sh -c "sleep 1d"
Create other Pod in the default namespace:
k run other --image=busybox --command -- /bin/sh -c "sleep 1d"
Determine the IPs of new-created Pods:
k -n g04 get po -o wide
k get po -o wide
The output should be something like:
$ k -n g04 get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
backend 1/1 Running 0 19s 192.168.1.3 node01 <none> <none>
frontend 1/1 Running 0 3m58s 192.168.1.5 node01 <none> <none>
$ k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
other 1/1 Running 0 3m34s 192.168.1.6 node01 <none> <none>
Try to communicate between frontend and backend:
k -n g04 exec frontend -it -- wget --spider --timeout=1 192.168.1.3:8080
Output will be:
Connecting to 192.168.1.3:8080 (192.168.1.3:8080)
remote file exists
Try the same communication from other Pod to backend:
k exec other -it -- wget --spider --timeout=1 192.168.1.3:8080
Response is the same:
Connecting to 192.168.1.3:8080 (192.168.1.3:8080)
remote file exists
So, the frontend Pod can talk to the backend Pod and the other Pod residing in the default namespace can communicate with the backend Pod without problems.https://kubernetes.io/docs/concepts/services-networking/network-policies/#default-policies
provides a couple of helpful YAML manifest examples. The below one shows a network policy deny-all-ingress-network-policy.yaml that denies ingress traffic to all Pods in the namespace g04:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: g04
spec:
podSelector: {}
policyTypes:
- Ingress
Apply deny-all-ingress-network-policy.yaml above NetPol:
kubectl apply -f deny-all-ingress-network-policy.yaml
Let’s see how this changed the runtime behavior for Pod-to-Pod network communication. Try again the communication between frontend and backend:
k -n g04 exec frontend -it -- wget --spider --timeout=1 192.168.1.3:8080
The frontend Pod cannot talk to the backend Pod anymore:
Connecting to 192.168.1.3:8080 (192.168.1.3:8080)
wget: download timed out
command terminated with exit code 1
Try to make a call from the other Pod running in the default namespace to the IP address of the backend Pod:
k exec other -it -- wget --spider --timeout=1 192.168.1.3:8080
Furthermore, Pods running in a different namespace cannot connect to the backend Pod anymore either:
Connecting to 192.168.1.3:8080 (192.168.1.3:8080)
wget: download timed out
command terminated with exit code 1
Network policies are additive. To grant more permissions for network communication, simply create another network policy with more fine-grained rules.kubectl get ns g04 --show-labels
We will need those when creating a Network Policy. Output:
NAME STATUS AGE LABELS
g04 Active 17m app=orion,kubernetes.io/metadata.name=g0
Get the pod labels in the g04 namespace:
k -n g04 get po --show-labels
Output:
NAME READY STATUS RESTARTS AGE LABELS
backend 1/1 Running 0 20m run=backend
frontend 1/1 Running 0 20m run=frontend
Create a new network policy backend-ingress-network-policy.yaml that allows the frontend Pod to talk to the backend Pod only on port 8080. No other communication should be allowed:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-ingress
namespace: g04
spec:
podSelector:
matchLabels:
run: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
app: orion
podSelector:
matchLabels:
run: frontend
ports:
- protocol: TCP
port: 8080
Apply backend-ingress-network-policy.yaml:
k apply -f backend-ingress-network-policy.yaml
Test again with wget from frontend Pod:
k -n g04 exec frontend -it -- wget --spider --timeout=1 192.168.1.3:8080
And it works:
Connecting to 192.168.1.3:8080 (192.168.1.3:8080)
remote file exists
Test from other pod in default namespace:
k exec other -it -- wget --spider --timeout=1 192.168.1.3:8080
Pods running outside of the g04 namespace still can’t connect to the backend Pod:
Connecting to 192.168.1.3:8080 (192.168.1.3:8080)
wget: download timed out
command terminated with exit code 1