With Izuma Edge, gateways host application containers that are isolated from one another for security. This protects neighboring containers in the event of a compromised application. To securely separate containers, Izuma Edge includes a network plugin that implements the Kubernetes Network Policy. You can use the Kubernetes Network Policy to control traffic between Pods, as well as traffic between Pods and external networking entities at the IP address and port level.
Because Izuma Edge doesn't allow gateways to communicate with one another, the network policies are applied to Pods in each gateway separately.
Note: Network policies don’t apply to the Pods configured with hostNetwork: true
. If a Pod is configured with hostNetwork: true
, the Pod can use the host network namespace. The Pod can access loopback device, services listening in localhost and all traffic in the host network namespace.
An example network policy looks like this:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rule-engine-policy
spec:
podSelector:
matchLabels:
role: rule-engine
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 192.168.10.0/24
except:
- 192.168.10.1/24
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 80
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
The specification has four key fields:
podSelector
selects all the Pods. In the above example, the policy applies to all the Pods with role=rule-engine
.Ingress
, Egress
or both.podSelector
or an ipBlock
(IP CIDR range).podSelector
or an ipBlock
(IP CIDR range).In addition to podSelector
and ipBlock
rules, you can specify port
and protocol
to control traffic. Port ranges are not supported.
namespaceSelector
based ingress and egress rules are not supported in Izuma Edge.
By default, Pods allow all the traffic. After a network policy selects a Pod, all traffic is denied except the traffic explicitly allowed by the policy. The network policies are additive - when multiple policies affect a Pod, the Pod is restricted to what is allowed by the union of those policies' ingress and egress rules. See the Kubernetes network policy documentation for more details.
This section lists a few example scenarios to illustrate how to set up network policies. To set up a network policy for your gateway, you need to set up the appropriate labels to Pods and identify IP CIDR ranges for the various networks that Pods communicate with.
In this scenario, the gateway has one or more Pods that are allowed to connect to the Internet but aren't allowed to connect to any other Pods or destinations:
```
apiVersion: v1
kind: Pod
metadata:
name: pod-a
labels:
role: internet-pod
spec:
automountServiceAccountToken: false
hostname: pod-a
nodeName: 017729140448000000000001001d7ef9
containers:
- name: app-a
image: alpine:latest
```
```
apiVersion: v1
kind: Pod
metadata:
name: pod-b
labels:
role: internet-pod
spec:
automountServiceAccountToken: false
hostname: pod-b
nodeName: 017729140448000000000001001d7ef9
containers:
- name: app-b
image: alpine:latest
```
The policy below assumes the gateway is connected to a local network with IP CIDR range 192.168.20.0/24
:
```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: internet-pod-policy
spec:
podSelector:
matchLabels:
role: internet-pod
policyTypes :
- Ingress # Deny all ingress
- Egress # Deny all egress
egress:
- to
- ipBlock:
cidr: 0.0.0.0/0
except:
- 192.168.20.0/24 # Deny local network
```
In this scenario, the gateway has a central message broker Pod that other Pods publish and subscribe to. This example assumes that broker is listening on port 8181
:
```
apiVersion: v1 kind: Pod metadata: name: pod-broker labels: role: message-broker-pod spec: automountServiceAccountToken: false hostname: pod-broker nodeName: 017729140448000000000001001d7ef9 containers: - name: app-broker image: alpine:latest ```
```
apiVersion: v1 kind: Pod metadata: name: pod-publisher labels: role: message-client-pod spec: automountServiceAccountToken: false hostname: pod-publisher nodeName: 017729140448000000000001001d7ef9 containers: - name: app-publisher image: alpine:latest ```
```
apiVersion: v1 kind: Pod metadata: name: pod-subscriber labels: role: message-client-pod spec: automountServiceAccountToken: false hostname: pod-subscriber nodeName: 017729140448000000000001001d7ef9 containers: - name: app-subscriber image: alpine:latest ```
```
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: message-broker-pod-policy spec: podSelector: matchLabels: role: message-broker-pod policyTypes : - Ingress # Deny all ingress - Egress # Deny all egress ingress: - from - podSelector: matchLabels: role: message-client-pod ports: - protocol: TCP port: 8181
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: message-client-pod-policy spec: podSelector: matchLabels: role: message-client-pod policyTypes : - Ingress # Deny all ingress - Egress # Deny all egress egress: - to - podSelector: matchLabels: role: message-broker-pod ports: - protocol: TCP port: 8181 ```
In this scenario, the gateway has two Pods – one service Pod and one datastore Pod. The datastore allows a connection only from the service Pod. The service Pod connects only to the datastore, which allows connection from Pods with label the role=service-client-pod
. The Pods with label the role=service-client-pod
aren't shown in the example:
```
apiVersion: v1 kind: Pod metadata: name: pod-datastore labels: role: datastore-pod spec: automountServiceAccountToken: false hostname: pod-datastore nodeName: 017729140448000000000001001d7ef9 containers: - name: datastore image: alpine:latest ```
```
apiVersion: v1 kind: Pod metadata: name: pod-service labels: role: service-pod spec: automountServiceAccountToken: false hostname: pod-service nodeName: 017729140448000000000001001d7ef9 containers: - name: service image: alpine:latest ```
```
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: datastore-pod-policy spec: podSelector: matchLabels: role: datastore-pod policyTypes : - Ingress # Deny all ingress - Egress # Deny all egress ingress: - from - podSelector: matchLabels: role: pod-service ports: - protocol: TCP port: 3456
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: service-pod-policy spec: podSelector: matchLabels: role: service-pod policyTypes : - Ingress # Deny all ingress - Egress # Deny all egress ingress: - from - podSelector: matchLabels: role: service-client-pod ports: - protocol: TCP port: 9191 egress: - to - podSelector: matchLabels: role: datastore-pod ports: - protocol: TCP port: 3456 ```
In this scenario, the gateway has two Pods. Both can connect to a local privete network (identified by an IP CIDR range). One of the Pods is also a publisher as described in scenario 2:
```
kind: Pod metadata: name: pod-private labels: network-access: local spec: automountServiceAccountToken: false hostname: pod-private nodeName: 017729140448000000000001001d7ef9 containers: - name: app-private image: alpine:latest
kind: Pod metadata: name: pod-private-publisher labels: network-access: local role: message-client-pod spec: automountServiceAccountToken: false hostname: pod-private-publisher nodeName: 017729140448000000000001001d7ef9 containers: - name: app-private-publisher image: alpine:latest
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: private-pod-policy spec: podSelector: matchLabels: network-access: local policyTypes: - Ingress # Deny all ingress - Egress # Deny all egress egress: - to - ipBlock: cidr: 192.168.20.0/24 # Connection to local network ```
Because Pod pod-private-publisher
has the label role=message-client-pod
, the network policy message-client-pod-policy
from scenario 2 will also be applied to it.