k8s之网络策略

网络策略是控制Pod资源组间以及与其他网络端点间如何进行通信的规范,它使用标签来分组Pod,并在该组Pod之上定义规则来管控其流量,从而为Kubernetes提供更为精细的流量控制以及租户隔离机制

Kubernetes自身仅实现了NetworkPolicy API的规范,具体的策略实施要靠CNI网络插件完成,例如,Calico、Antrea、Canal和Weave等,Flannel不支持网络策略。

Calico的calico-kube-controllers是该项目中用于将用户定义的网络策略予以实现的组件,它主要依赖于在节点上构建iptables规则实现访问控制功能,默认情况下,kubernetes没有对pod做任何隔离限制

NetworkPolicy是名称空间级别的资源,允许用户使用标签选择器在筛选出的一组Pod对象上分别管理Ingress和Egress流量,一旦将Network Policy引入到名称空间中,则被标签选择器“选中”的Pod将默认拒绝所有流量,而仅放行由特定的NetworlPolicy资源明确“允许”的流量,未被任何NetworkPolicy资源的标签选择器选中的Pod对象的流量则不受影响。

官方提供的模板如下:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:                   #该策略适用于的pod为默认命名空间下标签为role:db的pod
    matchLabels:                 #如果为podSelector{}表示该策略作用于此命名空间下的所有pod
      role: db
  policyTypes:                   #设置策略类型,有入栈(Ingress)和出栈(Egress)类型,如果不设置默认为入栈(Ingress)
    - Ingress
    - Egress
  ingress:                       #配置入栈规则,通过from
    - from:
        - ipBlock:               #IP规则
            cidr: 172.17.0.0/16
            except:
              - 172.17.1.0/24
        - namespaceSelector:     #命名空间规则
            matchLabels:
              project: myproject
        - podSelector:           #Pod规则
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 6379
  egress:                        #出栈规则,通过to
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
      ports:
        - protocol: TCP
          port: 5978

上述网络策略说明:

  • 此策略作用于默认命名空间中标签为role:db的pod
  • 入站规则允许IP地址除了172.17.1.0/24 之外的所有172.17.0.0/16段、标签为project:myproject的命名空间、默认命名空间下标签为role:frontend的pod访问标签为role:db的pod的TCP 6379端口
  • 出站规则允许默认命名空间中标签为role:db的pod访问10.0.0.0/24的TCP 5978端口

1、在default命名空间中拒绝所有入站流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}        #表示针对默认命名空间下的所有pod
  policyTypes:
  - Ingress              #未配置ingress,表示拒绝所有

2、允许所有入站流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
spec:
  podSelector: {}        #表示针对默认命名空间下的所有pod
  ingress:               #配置了ingress{},表示允许所有
  - {}
  policyTypes:
  - Ingress

3、默认拒绝所有出站流量,对入站没有影响:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

4、允许所有出站流量,对入站没有影响,如下:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-egress
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

5、默认拒绝所有入站和所有出站流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

下面是一道cks考试真题,关于网络策略的

创建一个名为pod-restriction 的NetworkPolicy来限制对在namespace dev-team中运行的Pod products-service的访问,只允许以下的pod连接到products-service:

  • namespace qa中的Pod
  • 位于任何namespace,带有标签environment: testing的Pod

网络策略pod-restriction的清单文件如下:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pod-restriction
  namespace: dev-team
spec:
  podSelector:
    matchLabels:
      app: products                 #根据标签匹配,可自定义打标签
  policyTypes:
    - Ingress
  ingress:
    - from:                         #第一个from
        - namespaceSelector:
            matchLabels:
              app: qa               #给命名空间qa打上标签,可自定义标签名
    - from:
        - namespaceSelector: {}     #表示来自所有的命名空间
          podSelector:
            matchLabels:
              environment: testing  #任何命名空间中带有此标签的pod

标签