Kubernetes NetworkPolicy
[root@master ~]# kubectl create ns linux
namespace/linux created
[root@master ~]# kubectl create ns python
namespace/python created
[root@master ~]# kubectl label ns linux nsname=linux
namespace/linux labeled
[root@master ~]# kubectl label ns python nsname=python
namespace/python labeled
在linux namespace下面部署nginx和tomcat
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
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
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
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: 30008
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30443
selector:
app: linux-nginx-selector
[root@master linux-ns1]# cat tomcat.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
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
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
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: 30006
selector:
app: linux-tomcat-app1-selector
配置tomcat
[root@master linux-ns1]# kubectl exec -it linux-tomcat-app1-deployment-5646755db6-ww86j -n linux bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@linux-tomcat-app1-deployment-5646755db6-ww86j:/usr/local/tomcat# cd webapps
root@linux-tomcat-app1-deployment-5646755db6-ww86j:/usr/local/tomcat/webapps# ls
root@linux-tomcat-app1-deployment-5646755db6-ww86j:/usr/local/tomcat/webapps# mkdir app
root@linux-tomcat-app1-deployment-5646755db6-ww86j:/usr/local/tomcat/webapps# echo "<h1>linux app web page</h1>" > app/index.jsp
配置nginx
vi /etc/nginx/conf.d/default.conf
nginx -t
nginx -s reload
浏览器直接访问nginx就可以访问到tomcat了
在python namesapce下部署nginx和tomcat
[root@master python-ns2]# cat nginx.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
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
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
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: 30014
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30453
selector:
app: python-nginx-selector
project: python #一个或多个selector,至少能匹配目标pod的一个标签
[root@master python-ns2]# cat tomcat.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
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: node1 #把nginx和tomcat区分开
containers:
- name: python-tomcat-app1-container
image: tomcat:7.0.109-jdk8-openjdk
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
# resources:
# limits:
# cpu: 2
# memory: 2Gi
# requests:
# cpu: 500m
# memory: 1Gi
---
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: 30015
selector:
app: python-tomcat-app1-selector
给python namespace的tomcat加一个index.jsp
[root@master linux-ns1]# kubectl exec -it python-tomcat-app1-deployment-5f65d66fd9-4n8nb -n python bash
cd webapps
mkdir app
echo "<h1>python app web page</h1>" > app/index.jsp
修改linux namespace下的nginx location为python下的tomcat
[root@master linux-ns1]# kubectl exec -it linux-nginx-deployment-5d57fd55bb-xqkbf -n linux sh
/ # vi /etc/nginx/conf.d/default.conf
/ # nginx -t
/ # nginx -s reload
继续访问linux namespace下的svc可以访问到python下的tomcat,可以证明,不同namespace下的pod可以互相通信
创建NetworkPolicy规则标签app: python-tomcat-app1-selector的pod只允许project: python的访问,再次访问svc就不能访问了
[root@master python-ns2]# cat case1-ingress-podSelector.yaml
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 #如果存在多个matchLabel条件,如果存在多个matchLabel条件,是and的关系,即要同时满足条件A、条件B、条件X
project: "python"
[root@master python-ns2]# kubectl apply -f case1-ingress-podSelector.yaml
networkpolicy.networking.k8s.io/tomcat-access--networkpolicy created
修改python的nginx location为python下的tomcat
[root@master python-ns2]# kubectl exec -it python-nginx-deployment-748685f845-56m54 -n python sh
[root@master ~]# kubectl get svc -n python
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
python-nginx-service NodePort 10.96.232.151 <none> 80:30014/TCP,443:30453/TCP 133m
python-tomcat-app1-service NodePort 10.100.114.67 <none> 80:30015/TCP 136m
访问svc地址就可以访问了
把标签的值修改下,再次访问报错。
[root@master python-ns2]# kubectl apply -f case1-ingress-podSelector.yaml
networkpolicy.networking.k8s.io/tomcat-access--networkpolicy configured
[root@master python-ns2]# cat case1-ingress-podSelector.yaml
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 #如果存在多个matchLabel条件,如果存在多个matchLabel条件,是and的关系,即要同时满足条件A、条件B、条件X
project: "pythonxx"
端口限制和标签同时限制
[root@master python-ns2]# cat case2-ingress-podSelector-ns-SinglePort.yaml
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
[root@master python-ns2]# kubectl apply -f case2-ingress-podSelector-ns-SinglePort.yaml
networkpolicy.networking.k8s.io/tomcat-access--networkpolicy created
多个端口限制
[root@master python-ns2]# cat case3-ingress-podSelector-ns-MultiPort.yaml
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 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
相同namesapce可以访问
[root@master python-ns2]# cat case4-ingress-podSelector-ns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels: {} #匹配所有目标pod
ingress:
- from:
- podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels: {}
#ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
#- protocol: TCP
# port: {} #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
#- protocol: TCP
# port: 3306
#- protocol: TCP
# port: 6379
通过地址限制
[root@master python-ns2]# cat case5-ingress-ipBlock.yaml.bak
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.219.0/24 #在以上范围内禁止访问的源IP地址
- 10.200.229.0/24 #在以上范围内禁止访问的源IP地址
- 10.200.218.11/32 #在以上范围内禁止访问的源IP地址
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
基于namespace
[root@master python-ns2]# cat case6-ingress-namespaceSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tomcat-access--networkpolicy
namespace: python
spec:
policyTypes:
- Ingress
podSelector: #目标pod
matchLabels: {} #允许访问python namespace 中的所有pod
# app: python-tomcat-app1-selector #可以只允许访问python namespace中指定的pod
ingress:
- from:
# - podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
# matchLabels: {}
# - ipBlock:
# cidr: 10.200.0.0/16 #指定禁止访问的源网段
# except:
# - 10.200.218.0/24 #在以上范围内禁止访问的源IP地址
- namespaceSelector:
# matchLabels: {} #允许所有namespace访问python namespace指定的目标端口或指定的pod加指定端口
matchLabels:
nsname: linux #只允许指定的namespace访问
- namespaceSelector:
matchLabels:
nsname: python #只允许指定的namespace访问
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
- protocol: TCP
port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
#port: 80
- protocol: TCP
port: 3306
- protocol: TCP
port: 6379
限制指定Pod可以访问指定IP
[root@master python-ns2]# cat case7-Egress-ipBlock.yaml
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的解析
Pod出口方向目的Pod限制-只允许访问指定的pod及端口
[root@master python-ns2]# cat case8-Egress-PodSelector.yaml
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:
# - ipBlock:
# cidr: 10.200.0.0/16 #允许访问的目的CIDR地址范围
# - ipBlock:
# cidr: 172.31.7.106/32 #允许访问的目的主机地址
# - ipBlock:
# cidr: 10.200.218.4/32 #白名单,允许访问的目的主机地址
- podSelector: #匹配pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
matchLabels:
app: python-tomcat-app1-selector
ports:
- protocol: TCP
port: 8080 #允许80端口的访问
- protocol: TCP
port: 53 #允许DNS的解析
- protocol: UDP
port: 53
限制匹配成功的pod没有访问指定的namespace
[root@master python-ns2]# cat case9-Egress-namespaceSelector.yaml
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:
# - ipBlock:
# cidr: 10.200.0.0/16 #允许访问的目的CIDR地址范围
# - ipBlock:
# cidr: 172.31.7.106/32 #允许访问的目的主机地址
# - ipBlock:
# cidr: 10.200.218.4/32 #允许访问的目的主机地址
# - podSelector: #匹配pod,matchLabels: {}为不限制源pod即允许所有pod,写法等同于resources(不加就是不限制)
# matchLabels:
# app: python-tomcat-app1-selector
- 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
安装calicoctl
[root@master]# curl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.16.1/calicoctl
[root@master]# chmox +x calicoctl && mv calicoctl /usr/bin
[root@master]# mkdir /etc/calico
[root@master]# vim /etc/calico/calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/root/.kube/config"
查看networkpolicy详细信息
[root@master python-ns2]# calicoctl get networkpolicy -n python
NAMESPACE NAME
python knp.default.tomcat-access--networkpolicy
[root@master python-ns2]# calicoctl get networkpolicy -n python knp.default.tomcat-access--networkpolicy -o yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
creationTimestamp: "2022-10-28T09:59:07Z"
name: knp.default.tomcat-access--networkpolicy
namespace: python
resourceVersion: /1085433
uid: 61971561-433f-41f0-a766-298ba843b2e7
spec:
ingress:
- action: Allow
destination:
ports:
- 3306
- 6379
- 8080
protocol: TCP
source:
namespaceSelector: nsname == 'linux'
selector: projectcalico.org/orchestrator == 'k8s'
- action: Allow
destination:
ports:
- 3306
- 6379
- 8080
protocol: TCP
source:
namespaceSelector: nsname == 'python'
selector: projectcalico.org/orchestrator == 'k8s'
order: 1000
selector: projectcalico.org/orchestrator == 'k8s'
types:
- Ingress
启动三个测试容器
[root@master python-ns2]# kubectl run net-test-centos-pod1 --image=centos:7.9.2009 sleep 10000000 -n linux
pod/net-test-centos-pod1 created
[root@master python-ns2]# kubectl run net-test-centos-pod1 --image=centos:7.9.2009 sleep 10000000 -n python
pod/net-test-centos-pod1 created
[root@master python-ns2]# kubectl run net-test-centos-test1 --image=centos:7.9.2009 sleep 10000000
pod/net-test-centos-test1 created