
 
 
一、Networkpolicy简介
 
 
- 网络策略(
NetworkPolicy) 是一种关于Pod间及Pod于其他网络端点间所允许的通信规则的规范,主要功能是对Pod间的网络通信进行限制和准入控制; - 简单理解,NetworkPolicy就是对pod进行网络策略控制。用于为Kubernetes实现更为精细的流量控制,实现租户隔离机制。Kubernetes使用标准的资源对象NetworkPolicy供管理员按需定义网络访问控制策略。
 - 设置方式为将Pod的Label作为查询条件,设置允许访问或禁止访问的客户端Pod列表。查询条件可以作用于Pod和Namespace级别。
 
 
二、NetworkPolicy策略模型
 

 
三、网络策略配置说明
 
网络策略的设置主要用于对目标Pod的网络访问进行限制,在默认情况下对所有Pod都是允许访问的,在设置了指向Pod的NetworkPolicy网络策略之后,到Pod的访问才会被限制。 需要注意的是网络策略是基于Pod的; 
  - NetWorkPolicy基于命名空间进行限制,即只作用当前命名空间,分为两种: 
    
ingress : 定义允许访问目标Pod的入站白名单规则;egress : 定义目标Pod允许访问的“出站”白名单规则;
  - 具体的规则限制方式分为三种(需要注意的是,多个限制之间是或的逻辑关系,如果希望变成与的关系,yaml文件需要配置为数组): 
     
 
 
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector: #用于定义该网络策略作用的Pod范围
    matchLabels:
      role: db
  policyTypes: #网络策略的类型,包括ingress和egress两种
  - Ingress
  - Egress
  ingress: #定义允许访问目标Pod的入站白名单规则
  - from: #满足from 条件的客户端才能访问ports定义的目标Pod端口号。
    - ipBlock: # IP限制
        cidr: 172.17.0.0/16
        except:  #排除那些IP
        - 172.17.1.0/24
    - namespaceSelector:  #命名空间限制
        matchLabels:
          project: myproject
    - podSelector:  # pod选择器限制
        matchLabels:
          role: frontend
    ports: #允许访问的目标Pod监听的端口号。
    - protocol: TCP
      port: 6379
  egress: #定义目标Pod允许访问的“出站”白名单规则
  - to: #目标Pod仅允许访问满足to条件的服务端IP范围和ports定义的端口号
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:  #允许访问的服务端的端口号。
    - protocol: TCP
      port: 5978
 
metadata : 描述信息。podSelector : pod选择器,选定的$ pod$ 所有的出入站流量要遵循本$ networkpolicy$ 的约束。policyTypes : 策略类型。包括了Ingress$ 和$ Egress,默认情况下一个policyTypes的值一定会包含Ingress,当有egress 规则时,policyTypes的值中会包含Egress 。ingress入站 : 即由其他网络端点发往特定$ Pod$ 组的流量 ,通常由流量发出的源站点$ from$ 和流量的目标端口所定义 。egress出站 : 即由特定的Pod组发往其他网络端点的流量 ,通常由流量的目标网络端点to和端口ports来进行定义 。port端口 : TCP或UDP的端口号。to,from端点 : 流量目标和流量源相关的组件, 它可以是CIDR格式的IP地址块 ipBlock、网络名称空间选择器namespaceSelector匹配的名称空间, 或Pod选择器podSelector匹配的Pod组。
 
四、NetworkPolicy默认策略
 
- 默认情况下,如果名称空间中不存在任何策略,则所有进出该名称空间中的Pod的流量都被允许。以下示例用于更改该名称空间中的默认行为。
 
 
4.1、默认拒绝所有入口流量
 
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
 
4.2、默认允许所有入口流量
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress
 
 
4.3、默认拒绝所有出口流量
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Egress
 
 
4.4、默认允许所有出口流量
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress
 
 
4.5、默认拒绝所有入口和所有出口流量
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
 
 
4.6、实战 :仅允许流量出向 ingress
 
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-only-igress
  namespace: test
spec:
  podSelector: {}   # 匹配 test ns下的所有Pod
  policyTypes:
  - Ingress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          app.kubernetes.io/name: ingress-nginx-main
      podSelector:
        matchLabels:
         "app.kubernetes.io/name": ingress-nginx-main
    ports:
    - protocol: TCP
      port: 8080
 
4.7、实战 : redis 流量限制示例
 
 
# apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: tcp
      port: 6379
 
4.8、实战 :允许带有access=true的Pod访问nginx的网络策略
 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      run: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"
 
4.9、实战 :禁止访问指定服务
 
# kubectl run web --image=nginx --labels app=web,env=prod --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-deny-all
spec:
  podSelector:
    matchLabels:
      app: web
      env: prod
 
4.10、实战 :只允许指定pod访问服务
 
# kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: api-allow
spec:
  podSelector:
    matchLabels:
      app: bookstore
      role: api
  ingress:
  - from:
      - podSelector:
          matchLabels:
            app: bookstore
 
4.11、实战 :禁止 namespace 中所有 Pod 之间的相互访问
 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: default
spec:
  podSelector: {}
 
4.12、实战 :禁止其他 namespace 访问服务
 
# kubectl create namespace secondary
# kubectl run web --namespace secondary --image=nginx --labels=app=web --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  namespace: secondary
  name: web-deny-other-namespaces
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}
 
4.13、实战 :只允许指定namespace访问服务
 
# kubectl run web --image=nginx --labels=app=web --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-prod
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          purpose: production
 
4.14、实战 :允许外网访问服务
 
# kubectl run web --image=nginx --labels=app=web --port 80
# kubectl expose deployment/web --type=LoadBalancer
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
  - ports:
    - port: 80
    from: []
 
五、使用flannel+canal实现k8s的NetworkPolicy
 
- $ Flannel$ 是解决容器网络方案最为普遍和简单的方案,$ Canal$ 代表了针对云原生应用程序的最佳网络策略解决方案,旨在让用户轻松的将$ Calico$ 和$ Flannel$ 网络部署在一起作为统一的网络解决方案,将$ Calico$ 的网络策略执行和$ Flannel$ 的叠加及非叠加网络连接选项的丰富功能相结合。 在$ Calico$ 的官方文档的相应部分中描述到此种方案是:用于策略的$ Calico$ 和用于网络的$ Flannel$ 相组合。
 - 官方文档见:Installing Calico for policy and flannel for networking -> https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/flannel