Network Traffic Is Though Of From Where The Request Starts

In a traditional http data-transfer, each request has 2 parts: a request and a response. One unit makes a request to another unit, and the other unit fullfills the request and the http data-transfer "comes back" to the initial requester.

Unsupported markdown: list
Unsupported markdown: list

I Want Something

I Have What You Need

Kubernetes default allow-all policy

Kubernetes applies an "allow-all" networking policy between objects.
Network policies are used to restrict network activity to & from k8s objects.

A 3-Pod Networking Example

3 Servers. Example Ports. What happens when the users wants to use a page that gets data from a db through an api:

DB_ServerAPI_ServerFrontendServeruserDB_ServerAPI_ServerFrontendServeruserReq. on port 80Req. on port 3001Req on port 27017ResponseResponseResponse

Another View

Here, actors and request ports.
Requests, ingress traffic, are solid lines with port labels.
Responses are dotted lines.

:80 Frontend Ingress

:5000 Frontend Egress API Ingress

:27017 API Egress DB Ingress

End-User

Frontend

API

DB

Ingress and Inbound traffic

Ingress and Egress notes specifically about where dataflow starts.
Ingress referrs to inbound traffic, like how ...

  • the frontend server recieves ingress traffic from the user
  • the api server recieves ingress traffic from the frontend server
    • the db recieves ingress traffic from the api server

Egress and Outbound Traffic

Egress represents an object making an outbound request, like how...

  • the frontend server creates egress traffic to the api
  • the api server creates egress traffic to the db

Ingress and Egress as Rules

Here, ingress and egress traffic are describes by each object in this 3-object diagram in 6 bullet points.
These rules will translate to the K8s world.
Also notice - indirectly, the frontend does not "need" to talk to the db server.

Frontend Server

  • allow ingress on port 80 from the world
  • allow egress on port 5000 to the api pod

API Server

  • allow ingress on port 5000 from the frontend server
  • allow egress on port 27017 to the db

DB

  • allow ingress on port 27017 from the api server

Ingress, Pods, and Services Through Network Policies

Here, a look at the db networking policy details:

policyTypes:
  - Ingress
ingress:
  - from:
      - podSelector:
          matchLabels:
            name: api-pod
    ports:
      - protocol: TCP
        port: 27017

in context of a more complete network policy def file: the db is being "protected" and assured that only traffic on a specific port from a specific pod is allowed

# db-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-network-policy
spec:
  # the pod(s) this will apply to, via matched labels
  podSelector:
    matchLabels:
      role: db
  policyTypes:
    # only incoming data
    - Ingress
  # the ingress description
  ingress:
    # where data can come from
    - from:
        # traffic source pod by "name" label
        - podSelector:
            matchLabels:
              name: api-pod
          # only pods from the "prod" namespace
          namespaceSelector:
            matchLabels:
              name: prod
      # traffic source port(s)
      # ...DONT FORGET PORTS CONFIG in a network policy
      # a "default" could be protocol:tcp port:80
      ports:
        - protocol: TCP
          port: 27017

kubectl create -f db-policy.yaml

Allow Traffic from non-pod I.P addresses

Perhaps network traffic is desired to this example db pod from a machine that is not managed by kubernetes.
Perhaps a backup server will talk to the db and create backups.
This will be an ingress connection on for the db network policy:

# db-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-network-policy
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
    - Ingress
  ingress:
    - from:
        # api traffic
        #  matching pod label AND namespace label
        - podSelector:
            matchLabels:
              name: api-pod
          namespaceSelector:
            matchLabels:
              name: prod
        # db backup machine
        # matching pi address block
        - ipBlock:
            cidr: 192.168.99.10/32
      ports:
        - protocol: TCP
          port: 27017

Network Policies are Enforced by the networking solutions

K8s Has more docs on the details:
| SUPPORTING network policies | NOT supporting network policies | |:--|:--| |Kube-router|Flannel| |Calico|| |Romana|| |weave-net|| |Antrea|| |Cilium||

Egress Definitions

A trivial egress-only example:

# db-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-network-policy
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 192.168.99.10/32
      ports:
        - protocol: TCP
          port: 80

A Deny-All Ingress Policy

This can be one way to lock-down network traffic, and require all network traffic between pods to be explicity: egress and ingress.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
    - Ingress

Some Takeaways

  • Network Policies are enforced by the networking tool (see above)
  • Networking Policies are to prevent unwanted network activity - not to enable
  • Networking policies consider pods, not replicasets or deployments: this is interesting!

Things to do

Create a network policy that...

  • allows traffic from an "internal" app
  • to the "payroll-service" and the "db-service"
    • payroll on port 8080
    • db-service on 3306

Something like this...

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              name: payroll
      ports:
        - protocol: TCP
          port: 8080
    - to:
        - podSelector:
            matchLabels:
              name: mysql
      ports:
        - protocol: TCP
          port: 3306

Open-Source Netowrk Policy Recipes

Here!:

  • Deny
    • via whitelise
    • from other namespaces
  • Limit
  • Allow
    • to
      • apps in a namespace
      • certain ports
    • from
      • a namespace
      • external clients