美文网首页
一文学会Calico高级网络策略

一文学会Calico高级网络策略

作者: sknfie | 来源:发表于2021-07-17 23:36 被阅读0次

一、名称空间规则

kubernetes 名称空间让你组成/分离 资源以符合各种情况。 比如,你可以使用名称空间去把development,production,QA environments进行分隔,或允许不同的团队使用相同的集群。在Calico network policies使用名称空间选择器去允许或拒绝流量 。

1. 在名称空间中控制traffic to/from endpoints.

案例1:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-tcp-6379
  namespace: production
spec:
  selector: color == 'red'
  ingress:
  - action: Allow
    protocol: TCP
    source:
      selector: color == 'blue'
    destination:
      ports:
        - 6379

案例2:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-tcp-6379
  namespace: production
spec:
  selector: color == 'red'
  ingress:
  - action: Allow
    protocol: TCP
    source:
      selector: color == 'blue'
      namespaceSelector: shape == 'circle'
    destination:
      ports:
      - 6379

2. 使用kubernetes RBAC 去控制名称空间的分配

通过应用基于端点的名称空间的选择器,你可以kubernetes RBAC去控制哪个用户可以分配标签到名称空间。

在下面的案例中,在开发环境的用户仅可以和名称空间有标签environment=="development的通信。

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: restrict-development-access
spec:
  namespaceSelector: 'environment == "development"'
  ingress:
    - action: Allow
      source:
        namespaceSelector: 'environment == "development"'
  egress:
    - action: Allow
      destination:
        namespaceSelector: 'environment == "development"'

二、服务帐户规则

使用calico network policy,你可以利用kubernetes服务帐户来灵活的控制策略如何应用到一个集群中。 比如,案例团队可以有RBAC的权限:

  1. 下面的案例中,ingress traffic允许那些服务帐户匹配api-serviceauth-service的workload。
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: demo-calico
  namespace: prod-engineering
spec:
  ingress:
    - action: Allow
      source:
        serviceAccounts:
          names:
            - api-service
            - user-auth-service
  selector: 'app == "db"'
  1. 通过服务帐户label限制ingress流量。

在下面的例子中,任何工作负载只要其服务帐户与标签选择器app == web-frontend匹配,就允许进入流量

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-web-frontend
  namespace: prod-engineering
spec:
  ingress:
    - action: Allow
      source:
        serviceAccounts:
          selector: 'app == "web-frontend"'
  selector: 'app == "db"'
  1. 使用kubernetes RBAC去控制服务帐户的分配

案例如下所示:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: restrict-intern-access
  namespace: prod-engineering
spec:
  serviceAccountSelector: 'role == "intern"'
  ingress:
    - action: Allow
      source:
        serviceAccounts:
          selector: 'role == "intern"'
  egress:
    - action: Allow
      destination:
        serviceAccounts:
          selector: 'role == "intern"'

三、外部IPs或网络规则

  1. 允许一个含有标签color:red的pod访问到目的114.114.114.114/32`的网络。
kubectl run --namespace=production access --rm -ti --image busybox /bin/sh
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: production
spec:
  selector: all()
  types:
  - Egress
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-egress-external
  namespace: production
spec:
  selector:
    run == 'access'
  types:
    - Egress
  egress:    
    - action: Allow
      destination:
        nets:
        - 114.114.114.114/32
  1. 在本案例中,使用GlobalNetworkSet和在GlobalNetworkPolicy中引用它。
  • 设置GlobalNetworkset的地址范围为192.0.2.55/32203.0.113.0/24
apiVersion: projectcalico.org/v3
kind: GlobalNetworkSet
metadata:
  name: ip-protect
  labels:
    IP-blacklist: true
spec:
  nets:
  - 10.1.0.2/32
  • 然后创建策略

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: forward-default-allow
spec:
  selector: run == 'nginx'
  order: 1000
  types:
  - Ingress
  ingress:
  - action: Allow
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: ip-protect
spec:
  selector: run == 'nginx'
  order: 1
  types:
  - Ingress
  ingress:
  - action: Deny
    source:
      selector: IP-blacklist == 'true' && !has(projectcalico.org/namespace)

四、在网络规则中使用icmp

  1. 拒绝ICMP, 所有workloads和host endpoints.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: block-icmp
spec:
  order: 200
  selector: all()
  types:
  - Ingress
  - Egress
  ingress:
  - action: Deny
    protocol: ICMP
  - action: Deny
    protocol: ICMPv6
  egress:
  - action: Deny
    protocol: ICMP
  - action: Deny
    protocol: ICMPv6    
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: forward-default-allow
spec:
  selector: all()
  order: 1000
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
  egress:
  - action: Allow
  1. 允许IMCP ping, all workloads和host endpoints.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-ping-in-cluster
spec:
  selector: all()
  order: 100
  types:
  - Egress
  egress:
  - action: Allow
    protocol: ICMP
    source:
      selector: all()
    icmp:
      type: 8 # Ping request
  - action: Allow
    protocol: ICMPv6
    source:
      selector: all()
    icmp:
      type: 128 # Ping request
  1. 允许匹配协议类型和代码的ICMP,所有的Kubernetes pods.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-host-unreachable
spec:
  selector: projectcalico.org/orchestrator == 'kubernetes'
  types:
  - Ingress
  ingress:
  - action: Allow
    protocol: ICMP
    icmp:
      type: 3 # Destination unreachable
      code: 1 # Host unreachable

icmp 类型和代码: https://blog.csdn.net/noooooorth/article/details/51636482

五、限制k8s节点流量一

默认的,calico为了防止我们配置错误,把一些关键性的端口是采取放行的。

以下表列出了放行的端口,当然你可以更改默认的值。

Port Protocol Direction Purpose
22 TCP Inbound SSH access
53 UDP Outbound DNS queries
67 UDP Outbound DHCP access
68 UDP Inbound DHCP access
179 TCP Inbound & Outbound BGP access (Calico networking)
2379 TCP Inbound & Outbound etcd access
2380 TCP Inbound & Outbound etcd access
6666 TCP Inbound & Outbound etcd self-hosted service access
6667 TCP Inbound & Outbound etcd self-hosted service access

1. 使用策略去限制host 流量

  1. 创建策略去限制主机流量
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
 name: drop-ingress
spec:
 order: 20
 preDNAT: true
 applyOnForward: true
 ingress:
 - action: Deny
 selector: role == 'k8s-worker'
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: forward-default-allow
spec:
  selector: all()
  order: 1000
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
  egress:
  - action: Allow
  1. 创建host endpoints.
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: my-host-eth0
  labels:
    role: k8s-worker
    environment: production
spec:
  interfaceName: eth0
  node: c720111.xiodi.cn

2. 控制workload endpoints到 host的默认行为

  1. 获取要编辑的对象
calicoctl get felixconfiguration default --export -o yaml > default-felix-config.yaml
  1. 打开文件和添加参数,defaultEndpointToHostAction
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
  name: default
spec:
  ipipEnabled: true
  logSeverityScreen: Info
  reportingInterval: 0s
  defaultEndpointToHostAction: Accept
  1. 应用编辑的配置
calicoctl apply -f default-felix-config.yaml

六、限制k8s节点流量二

假设集群提供多种多样的服务,它们作为kubernetes NodePorts进行暴露。但管理员不想暴露那些NodePorts给外部。

在本案例中,我们将使用pre-DNAT策略应用于集群节点的外部接口。

  • 禁止外部进入的流量。

  • 然后允许流量到特定的节点端口上。

针对以下原因,我们使用pre-DNAT策略,替代正常的host endpoint策略:因为:

  1. 我们希望保护到任何对象的流量 --比如,到local hosted pod,或到其它节点的pod, 或本地主机的服务进程的。 在这些情况下,pre-DNAT策略都可以执行。但是使用正常的host endpoint是做不到的,因为没有办法限制到local pod的。

  2. 我们希望写这个策略是依据通告的NodePorts,而不是依据它想转换的内部端口。在ingress node ,kube-proxy使用DNAT去改变Nodeport的端口号和IP地址到Pods与之相关的服务。因此我们的策略需要放在DNAT之前才能生效。这也意味着它必须是一个pre-DNAT的策略。

这里是一个pre-DNAT策略,我们需要拒绝外部流量。

calicoctl apply -f - <<EOF
- apiVersion: projectcalico.org/v3
  kind: GlobalNetworkPolicy
  metadata:
    name: allow-cluster-internal-ingress
  spec:
    order: 10
    preDNAT: true
    applyOnForward: true
    ingress:
      - action: Allow
        source:
          nets: [10.240.0.0/16, 192.168.0.0/16]
    selector: has(host-endpoint)
- apiVersion: projectcalico.org/v3
  kind: GlobalNetworkPolicy
  metadata:
    name: drop-other-ingress
  spec:
    order: 20
    preDNAT: true
    applyOnForward: true
    ingress:
      - action: Deny
    selector: has(host-endpoint)
EOF

上面就是允许集群内部的IP,在这里假设10.240.0.0/16是节点它自己的IP地址, 192.168.0.0/16是kubernetes分配给pod的地址。然后拒绝其它流量 。

接下来,还需要定义一个egress的流量策略,因为如果不定义的话,就是egress放行所有了。

calicoctl apply -f - <<EOF
- apiVersion: projectcalico.org/v3
  kind: GlobalNetworkPolicy
  metadata:
    name: allow-outbound-external
  spec:
    order: 10
    egress:
      - action: Allow
    selector: has(host-endpoint)
EOF

为每个节点定义host-endpoint:

calicoctl apply -f - <<EOF
- apiVersion: projectcalico.org/v3
  kind: HostEndpoint
  metadata:
    name: node1-eth0
    labels:
      host-endpoint: ingress
  spec:
    interfaceName: eth0
    node: node1
EOF

在完成上面定义后,你会发现集群内部的通信是正常的,但是从外部连接到集群是拒绝的。如果想要允许一个外部的主机来访问K8S集群内部,比如NodePort 31852端口。那么需要配置如下:

$ calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-nodeport
spec:
  preDNAT: true
  applyOnForward: true
  order: 10
  ingress:
    - action: Allow
      protocol: TCP
      destination:
        selector: has(host-endpoint)
        ports: [30091]
  selector: has(host-endpoint)
EOF

  • 定义一个策略,针对特定的外部可以访问特定的节点端口
host-endpoint: <special-value>

七、链接追踪的旁路

当一个节点上的连接数超过Linux conntrack可以跟踪的连接数时,可以拒绝或删除连接。可以使用Calico网络策略有选择地绕过Linux conntrack来获得这些类型的工作负载之间的流量。

1. 概念

1.1 Linux conntrack

接跟踪(“conntrack”)是Linux内核网络堆栈的一个核心特性。它允许内核跟踪所有的逻辑网络连接或流,从而识别组成每个流的所有数据包,以便能够一致地处理它们。Conntrack是主线Linux网络处理管道的重要组成部分,通常可以提高性能,并支持NAT和有状态访问控制。

1.2 高连接的工作流

一些小范围的工作负载处理非常多的并发连接,或非常高的短生存连接率,可能会超过Linux conntrack能够跟踪的最大连接数。这种工作负载的一个真实示例是每秒处理50k+连接的超大规模memcached服务器。

1.3 Calico doNotTrack network policy

Calico全局网络策略选项doNotTrack指示在连接跟踪之前应用策略中的规则,并且不应该跟踪这些规则所允许的数据包。该策略在Linux包处理管道的早期应用,先于任何常规的网络策略规则,并且独立于策略顺序字段。与普通的网络策略规则不同,doNotTrack网络策略规则是无状态的,这意味着您必须显式地指定规则来允许conntrack通常自动允许的返回流量。例如,对于端口999上的服务器,策略必须包含一个允许入站流量到端口999的入口规则,以及一个允许从端口999发出流量的出口规则。

在doNotTrack策略:

  • 入口规则适用于通过主机端点的所有传入流量,而不管流量流向何处
  • 出口规则只适用于从主机端点(而不是本地工作负载)发送的流量。

2. 针对高连接服务器的连接旁路

apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: memcached-node-1-eth0
  labels:
    memcached: server
spec:
  interfaceName: eth0  
  node: memcached-node-1  
  expectedIPs:
    - 10.128.0.162  
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: memcached-server
spec:
  selector: memcached == 'server'
  applyOnForward: true
  doNotTrack: true
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: memcached == 'client'
      destination:
        ports:
          - 12211
  egress:
    - action: Allow
      protocol: TCP
      source:
        ports:
          - 12211
      destination:
        selector: memcached == 'client'

相关文章

网友评论

      本文标题:一文学会Calico高级网络策略

      本文链接:https://www.haomeiwen.com/subject/pcvgpltx.html