一、名称空间规则
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的权限:
- 下面的案例中,ingress traffic允许那些服务帐户匹配
api-service
或auth-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"'
- 通过服务帐户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"'
- 使用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或网络规则
- 允许一个含有标签
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
- 在本案例中,使用
GlobalNetworkSet
和在GlobalNetworkPolicy
中引用它。
- 设置
GlobalNetworkset
的地址范围为192.0.2.55/32
和203.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
- 拒绝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
- 允许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
- 允许匹配协议类型和代码的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 流量
- 创建策略去限制主机流量
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
- 创建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的默认行为
- 获取要编辑的对象
calicoctl get felixconfiguration default --export -o yaml > default-felix-config.yaml
- 打开文件和添加参数,
defaultEndpointToHostAction
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
name: default
spec:
ipipEnabled: true
logSeverityScreen: Info
reportingInterval: 0s
defaultEndpointToHostAction: Accept
- 应用编辑的配置
calicoctl apply -f default-felix-config.yaml
六、限制k8s节点流量二
假设集群提供多种多样的服务,它们作为kubernetes NodePorts进行暴露。但管理员不想暴露那些NodePorts给外部。
在本案例中,我们将使用pre-DNAT策略应用于集群节点的外部接口。
-
禁止外部进入的流量。
-
然后允许流量到特定的节点端口上。
针对以下原因,我们使用pre-DNAT策略,替代正常的host endpoint策略:因为:
-
我们希望保护到任何对象的流量 --比如,到local hosted pod,或到其它节点的pod, 或本地主机的服务进程的。 在这些情况下,pre-DNAT策略都可以执行。但是使用正常的
host endpoint
是做不到的,因为没有办法限制到local pod的。 -
我们希望写这个策略是依据通告的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'
网友评论