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