k8s network policy

k8s NetworkPolicy

demo example

---
# Source: tests/busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox
  name: busybox
spec:
  containers:
  - name: busybox
    # Make sure to use busybox:1.28 image (or earlier version) for any test. The latest version has an unpstream bug that affects the use of nslookup
    #image: busybox:1.28
    # The following image contains curl, GIT, telnet and NSLOOKUP commands
    image: radial/busyboxplus
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
---
# Source: tests/myapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        resources: {}
        ports:
        - name: http
          containerPort: 80
      dnsPolicy: ClusterFirst
      restartPolicy: Always
---
# Source: tests/myapp-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: myapp
  name: myapp
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp
---
# Source: tests/myapp-ingress.yaml
#apiVersion: extensions/v1beta1
#kind: Ingress
#metadata:
#  name: ingress-myapp
#  labels:
#    app: myapp
#  annotations:
#    kubernetes.io/ingress.class: "nginx"
#spec:
#  rules:
#  - host: myapp.5179.top
#    http:
#      paths:
#      - path: /
#        backend:
#          serviceName: myapp
#          servicePort: 80

implement

kubectl apply -f demo.yaml
kubectl apply -f demo.yaml -n test
kubectl apply -f demo.yaml -n kube-system

Verify by entering the pod of busybox in different namespace s

[root@centos7-nginx ~]# kubectl exec -it busybox -- sh
/ # nslookup myapp
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      myapp
Address 1: 10.103.12.181 myapp.default.svc.cluster.local
/ # curl myapp/hostname.html
myapp-5cbd66595b-sgqpg
/ #

1. by default, any client is forbidden to access all pods in the Namespace

Default reject: when a rule type is specified in spec.policyTypes, it is rejected in networkpolicy No ingress or egress field, all traffic in the relevant direction will be rejected!

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

2. by default, any client is allowed to access all pods in the Namespace

Default allowed:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}  # Match all pods
  ingress:
  - {}
  policyTypes:
  - Ingress

3. by default, all pods in the Namespace are prohibited from accessing external services:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}  # Match all pods
  policyTypes:
  - Egress

4. by default, all pods in the Namespace are allowed to access external services

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}  # Match all pods
  egress:
  - {}
  policyTypes:
  - Egress

5. by default, any client is prohibited from accessing all pods in the Namespace and from accessing external services

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}  # Match all pods
  policyTypes:
  - Ingress
  - Egress

6. isolate the Namespace and release the communication with Pod in Kube system Namespace to realize various management functions such as monitoring and name resolution

You need to label ns with a label like kubectl label ns test name=test

# One command to label all namespace s
[root@centos7-nginx ~]# kubectl get ns --show-labels |grep -v NAME |awk '{print $1}' |xargs -I {} kubectl label namespace {} name={}

[root@centos7-nginx ~]# kubectl get ns --show-labels
NAME              STATUS   AGE     LABELS
default           Active   3d17h   name=default
ingress-nginx     Active   22h     app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx,name=ingress-nginx
kube-node-lease   Active   3d17h   name=kube-node-lease
kube-public       Active   3d17h   name=kube-public
kube-system       Active   3d17h   name=kube-system
test              Active   23h     name=test

Modify file

# Ban all
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-deny-all
  namespace: default
spec:
  policyTypes: ["Ingress","Egress"]
  podSelector: {}
---
# Release the traffic of the corresponding Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-
  namespace: default
spec:
  policyTypes: ["Ingress","Egress"]
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:  # matchExpressions is the list required by the tag selector.
        - key: name
          operator: In
          values: ["default","kube-system","ingress-nginx","monitoring"]
  egress:
  - to:
    - namespaceSelector:
        matchExpressions:
        - key: name
          operator: In
          values: ["default","kube-system","ingress-nginx","monitoring"]

Note:

  • matchExpressions is the list required by the tag selector.
  • matchLabels is the mapping of {key, value} pairs. A single {key, value} In the matchLabels map is equivalent to the element of matchExpressions. The key field is key, the operator is In, and the values array only contains value.

View policy

[root@centos7-nginx policy]# kubectl describe netpol namespace-deny-all -n test
Name:         namespace-deny-all
Namespace:    test
Created on:   2020-07-06 17:09:06 +0800 CST
Labels:       <none>
Annotations:  Spec:
  PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
  Allowing ingress traffic:
    <none> (Selected pods are isolated for ingress connectivity)
  Allowing egress traffic:
    <none> (Selected pods are isolated for egress connectivity)
  Policy Types: Ingress, Egress

[root@centos7-nginx policy]# kubectl describe netpol namespace-allow-some-ns -n test
Name:         namespace-allow-some-ns
Namespace:    test
Created on:   2020-07-06 17:09:06 +0800 CST
Labels:       <none>
Annotations:  Spec:
  PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
  Allowing ingress traffic:
    To Port: <any> (traffic allowed to all ports)
    From:
      NamespaceSelector: name in (ingress-nginx,kube-system,monitoring,test)
  Allowing egress traffic:
    To Port: <any> (traffic allowed to all ports)
    To:
      NamespaceSelector: name in (ingress-nginx,kube-system,monitoring,test)
  Policy Types: Ingress, Egress

7. isolate the Namespace and restrict the entry direction

# Prohibit the flow in all directions first
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-deny-all
  namespace: test
spec:
  policyTypes: ["Ingress"]
  podSelector: {}
---
# Release the flow in the corresponding Namespace direction
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-allow-some-ns
  namespace: test
spec:
  policyTypes: ["Ingress"]
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:
        - key: name
          operator: In
          values: ["test","kube-system","ingress-nginx","monitoring"]

8. examples

Release specific inbound traffic

Defining only from will implicitly allow all ports of the local Pod; Defining only ports will implicitly allow all source endpoints; When defining from and ports at the same time, it is logic and relation
Multiple from are logical or relational
Multiple ports are logical or related
The relationship between from and ports is logic and
When multiple ipblocks, namespaceSelector, and podSelector are used at the same time under from, it is a logic or relationship

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-myapp-ingress
  name: default
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes: ["Ingress"]
  ingress:
  - from:
    - ipBlock:
        cidr: 10.244.0.0/16
        except:
        - 10.244.3.0/24
    - podSelector:
        matchLabels:
          app: myapp
    ports:
    - protocol: TCP
      port: 80

Control outbound flow

# Default outgoing direction reject all
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {}
  policyTypes: ["Egress"]
# Release specific outbound flow
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-tomcat-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: tomcat
  policyTypes: ["Egress"]
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: nginx
  - ports:
    - protocol: TCP
      port: 80
  - to:
    - podSelector:
        matchLabels:
          app: mysql
    ports:
    - protocol: TCP
      port: 3306

Tags: Kubernetes network

Posted by scottybwoy on Wed, 01 Jun 2022 10:37:55 +0530