k8s NetworkPolicy
demo 示例
---
# Source: tests/busybox.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: busybox
name: busybox
spec:
containers:
- name: busybox
# 确保使用 busybox:1.28 image(或更早版本)进行任何测试,最新版本有一个unpstream bug,影响nslookup的使用
#image: busybox:1.28
# 如下镜像含有 curl,git,telnet,nslookup 命令
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
执行
kubectl apply -f demo.yaml
kubectl apply -f demo.yaml -n test
kubectl apply -f demo.yaml -n kube-system
通过进入不同 namespace 的 busybox 的 pod 进行验证
[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.默认禁止任何客户端访问该 Namespace 中的所有 Pod
默认拒绝:当在spec.policyTypes
中指定规则类型,却在networkpolicy.spec
中没有定义任何ingress
或 egress
字段时,将拒绝相关方向上一切流量!
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {} # 匹配所有Pod
policyTypes:
- Ingress
2.默认允许任何客户端访问该 Namespace 中的所有 Pod
默认允许:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {} # 匹配所有Pod
ingress:
- {}
policyTypes:
- Ingress
3.默认禁止该 Namespace 中的所有 Pod 访问外部服务:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {} # 匹配所有Pod
policyTypes:
- Egress
4.默认允许该 Namespace 中的所有 Pod 访问外部服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {} # 匹配所有Pod
egress:
- {}
policyTypes:
- Egress
5.默认禁止任何客户端访问该 Namespace 中的所有 Pod ,同时禁止访问外部服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {} # 匹配所有Pod
policyTypes:
- Ingress
- Egress
6.隔离Namespace, 放行与kube-system名称空间中Pod的通信,以实现监控和名称解析等各种管理功能
需要先给 ns 打上类似这样的标签,kubectl label ns test name=test
# 一条命令给所有 namespace 打上标签
[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
修改文件
# 先禁出所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-deny-all
namespace: default
spec:
policyTypes: ["Ingress","Egress"]
podSelector: {}
---
# 放行对应 Namespace 的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-
namespace: default
spec:
policyTypes: ["Ingress","Egress"]
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchExpressions: # matchExpressions是标签选择器要求的列表。
- 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"]
注意:
matchExpressions
是标签选择器要求的列表。matchLabels
是{key,value}
对的映射。matchLabels映射中的单个{key,value}
等同于matchExpressions
的元素,其key
字段为key
,运算符为In
,而values
数组仅包含value
。
查看策略
[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.隔离 Namespace, 限制入方向
# 先禁止所有入方向的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-deny-all
namespace: test
spec:
policyTypes: ["Ingress"]
podSelector: {}
---
# 放行对应 Namespace 入方向的流量
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.示例
放行特定入站流量
仅定义from
将隐含允许本地Pod所有端口;仅定义ports
将隐含允许所有源端点;同时定义from
和ports
时,是逻辑与关系
多个from
之间是逻辑或关系
多个ports
之间是逻辑或关系
from
与ports
间是逻辑与关系
from
下 ipBlock
、namespaceSelector
、podSelector
同时使用多个时,为逻辑或关系
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
管控出站流量
# 默认出方向拒绝所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
policyTypes: ["Egress"]
# 放行特定的出站流量
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