NetworkPolicy网络策略可以在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量。 NetworkPolicy 是一种以应用为中心的结构,允许你设置如何允许 Pod 与网络上的各类网络“实体”通信。 NetworkPolicies 适用于一端或两端与 Pod 的连接,与其他连接无关。
Pod 可以通信的 Pod 是通过如下三个标识符的组合来辩识的:
创建两个命名空间,每个空间运行多个pod,多个pod运行在不同的节点。
kubectl create ns linux
kubectl create ns python
kubectl label ns linux nsname=linux
kubectl label ns python nsname=python
命名空间linux与python均部署nginx与tomcat。
tomcat镜像构建:
FROM tomcat:7.0.109-jdk8-openjdk
# 自定义tomcat app路径首页
RUN mkdir /usr/local/tomcat/webapps/app/
ADD index.jsp /usr/local/tomcat/webapps/app/
nginx镜像构建:
FROM nginx:1.20.2-alpine
# 自定义首页,配置nginx
ADD default.conf /etc/nginx/conf.d/
ADD index.html /usr/share/nginx/html/
nginx配置,将访问app路径转发给tomcat。
vim /etc/nginx/conf.d/default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /app {
proxy_pass http://10.68.4.22:80;
}
测试容器,前台卡住一天时间,用于测试网络策略效果:
kubectl run net-test-centos-pod1 --image=centos:7.9.2009 sleep 86400 -n linux
kubectl run net-test-centos-pod1 --image=centos:7.9.2009 sleep 86400 -n python
kubectl run centos-net-test1 --image=centos:7.9.2009 sleep 86400
部署linux-tomcat:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: linux-tomcat-app1-deployment-label
name: linux-tomcat-app1-deployment
namespace: linux
spec:
replicas: 1
selector:
matchLabels:
app: linux-tomcat-app1-selector
template:
metadata:
labels:
app: linux-tomcat-app1-selector
spec:
containers:
- name: linux-tomcat-app1-container
image: tomcat:7.0.109-jdk8-openjdk
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
name: http
---
kind: Service
apiVersion: v1
metadata:
labels:
app: linux-tomcat-app1-service-label
name: linux-tomcat-app1-service
namespace: linux
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 38080
selector:
app: linux-tomcat-app1-selector
部署linux-nginx:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: linux-nginx-deployment-label
name: linux-nginx-deployment
namespace: linux
spec:
replicas: 1
selector:
matchLabels:
app: linux-nginx-selector
template:
metadata:
labels:
app: linux-nginx-selector
spec:
containers:
- name: linux-nginx-container
image: nginx:1.20.2-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
---
kind: Service
apiVersion: v1
metadata:
labels:
app: linux-nginx-service-label
name: linux-nginx-service
namespace: linux
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30080
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30443
selector:
app: linux-nginx-selector
部署python-tomcat:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: python-tomcat-app1-deployment-label
name: python-tomcat-app1-deployment
namespace: python
spec:
replicas: 1
selector:
matchLabels:
app: python-tomcat-app1-selector
template:
metadata:
labels:
app: python-tomcat-app1-selector
spec:
nodeName: 192.168.100.164
containers:
- name: python-tomcat-app1-container
image: tomcat:7.0.109-jdk8-openjdk
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
name: http
---
kind: Service
apiVersion: v1
metadata:
labels:
app: python-tomcat-app1-service-label
name: python-tomcat-app1-service
namespace: python
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 38081
selector:
app: python-tomcat-app1-selector
部署python-tomcat:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: python-nginx-deployment-label
name: python-nginx-deployment
namespace: python
spec:
replicas: 1
selector:
matchLabels:
app: python-nginx-selector
template:
metadata:
labels:
app: python-nginx-selector
project: python
spec:
containers:
- name: python-nginx-container
image: nginx:1.20.2-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
---
kind: Service
apiVersion: v1
metadata:
labels:
app: python-nginx-service-label
name: python-nginx-service
namespace: python
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30081
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30444
selector:
app: python-nginx-selector
project: python #一个或多个selector,至少能匹配目标pod的一个标签
Pod 有两种隔离: 出口的隔离和入口的隔离。入口隔离(Ingress)策略较为常用。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector:
matchLabels:
app: python-tomcat-app1-selector #对匹配到的目的Pod应用以下规则
ingress: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- from:
- podSelector:
matchLabels:
#app: python-nginx-selector #and关系
project: "python"
在project=linux的pod进行测试:
# NetworkPolicy前
curl http://172.20.153.199:8080/app/
tomcat app python 456
# NetworkPolicy后
curl http://172.20.153.199:8080/app/
curl: (7) Failed connect to 172.20.153.199:8080; Connection timed out
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector:
matchLabels:
app: python-tomcat-app1-selector
ingress:
- from:
- podSelector:
matchLabels:
#app: python-nginx-selector #指定访问源的匹配条件,如果存在多个matchLabel条件,是and的关系,即要同时满足条件A、条件B、条件X
project: "python"
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access-networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels:
app: python-tomcat-app1-selector
ingress:
- from:
- podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels: {}
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080
endPort: 8090
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels:
app: python-tomcat-app1-selector
ingress:
- from:
# - podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
# matchLabels: {}
- ipBlock:
cidr: 10.200.0.0/16 #白名单,允许访问的地址范围,没有允许的将禁止访问目标pod
except:
- 10.200.100.0/24 #在以上范围内禁止访问的源IP地址
- 10.200.200.0/24 #在以上范围内禁止访问的源IP地址
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels: {} #允许访问python namespace 中的所有pod
ingress:
- from:
- namespaceSelector:
matchLabels:
nsname: linux #只允许指定的namespace访问
- namespaceSelector:
matchLabels:
nsname: python #只允许指定的namespace访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-access-networkpolicy
namespace: python
spec:
policyTypes:
- Egress
podSelector: #目标pod选择器
matchLabels: #基于label匹配目标pod
app: python-tomcat-app1-selector #匹配python namespace中app的值为python-tomcat-app1-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
egress:
- to:
- ipBlock:
cidr: 10.200.0.0/16 #允许匹配到的pod出口访问的目的CIDR地址范围
- ipBlock:
cidr: 172.31.7.106/32 #允许匹配到的pod出口访问的目的主机
ports:
- protocol: TCP
port: 80 #允许匹配到的pod访问目的端口为80的访问
- protocol: TCP
port: 53 #允许匹配到的pod访问目的端口为53 即DNS的解析
- protocol: UDP
port: 53 #允许匹配到的pod访问目的端口为53 即DNS的解析
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-access-networkpolicy
namespace: python
spec:
policyTypes:
- Egress
podSelector: #目标pod选择器
matchLabels: #基于label匹配目标pod
app: python-nginx-selector #匹配python namespace中app的值为python-tomcat-app1-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
egress:
- to:
- podSelector: #匹配pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels:
app: python-tomcat-app1-selector
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-access-networkpolicy
namespace: python
spec:
policyTypes:
- Egress
podSelector: #目标pod选择器
matchLabels: #基于label匹配目标pod
app: python-nginx-selector #匹配python namespace中app的值为python-tomcat-app1-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
egress:
- to:
- namespaceSelector:
matchLabels:
nsname: python #指定允许访问的目的namespace
- namespaceSelector:
matchLabels:
nsname: linux #指定允许访问的目的namespace
ports:
- protocol: TCP
port: 8080 #允许80端口的访问
- protocol: TCP
port: 53 #允许DNS的解析
- protocol: UDP
port: 53