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

 

posted @ 2022-10-28 18:34  Maniana  阅读(38)  评论(0编辑  收藏  举报