Kubernetes 网络策略 networkpolicy
网络策略
在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量,为集群中特定应用使用 Kubernetes 网络策略(NetworkPolicy);
Pod 可以通信的 Pod 是通过如下三个标识符的组合来辩识的:
- 其他被允许的 Pods(例外:Pod 无法阻塞对自身的访问)
- 被允许的命名空间
- IP 组块(例外:与 Pod 运行所在的节点的通信总是被允许的, 无论 Pod 或节点的 IP 地址
在定义基于 Pod 或命名空间的 NetworkPolicy 时,你会使用 选择算符 来设定哪些流量 可以进入或离开与该算符匹配的 Pod。
同时,当基于 IP 的 NetworkPolicy 被创建时,我们基于 IP 组块(CIDR 范围) 来定义策略。
网络策略是相加的,所以不会产生冲突。如果策略适用于 Pod 某一特定方向的流量, Pod 在对应方向所允许的连接是适用的网络策略所允许的集合。
前置条件
网络策略通过网络插件 来实现。要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。 创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。
Pod 隔离的两种类型
Pod 有两种隔离: 出口的隔离和入口的隔离。它们涉及到可以建立哪些连接。 这里的“隔离”不是绝对的,而是意味着“有一些限制”。 另外的,“非隔离方向”意味着在所述方向上没有限制。这两种隔离(或不隔离)是独立声明的, 并且都与从一个 Pod 到另一个 Pod 的连接有关。
默认策略
默认情况下,如果命名空间中不存在任何策略,则所有进出该名字空间中 Pod 的流量都被允许。 以下示例使你可以更改该命名空间中的默认行为。
默认拒绝所有入站流量
你可以通过创建选择所有容器但不允许任何进入这些容器的入站流量的 NetworkPolicy 来为名字空间创建 “default” 隔离策略。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress
这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。 此策略不会更改默认的出口隔离行为。
其实简单的理解就是{} 代表了所有;
默认允许所有入站流量
如果要允许所有流量进入某个命名空间中的所有 Pod(即使添加了导致某些 Pod 被视为 “隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-ingress spec: podSelector: {} ingress: - {} policyTypes: - Ingress
默认拒绝所有出站流量
通过创建选择所有容器但不允许来自这些容器的任何出站流量的 NetworkPolicy 来为命名空间创建 “default” 隔离策略。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress spec: podSelector: {} policyTypes: - Egress
此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许流出流量。 此策略不会更改默认的入站流量隔离行为;
默认允许所有出站流量
如果要允许来自命名空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略), 则可以创建一个策略,该策略明确允许该命名空间中的所有出站流量。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-egress spec: podSelector: {} egress: - {} policyTypes: - Egress
默认拒绝所有入口和所有出站流量
为命名空间创建“默认”策略,以通过在该命名空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all spec: podSelector: {} policyTypes: - Ingress - Egress
此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被 允许入站或出站流量。
针对某个端口范围
在编写 NetworkPolicy 时,你可以针对一个端口范围而不是某个固定端口。
这一目的可以通过使用 endPort
字段来实现,如下例所示;
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: multi-port-egress namespace: default spec: podSelector: matchLabels: role: db policyTypes: - Egress egress: - to: - ipBlock: cidr: 10.0.0.0/24 ports: - protocol: TCP port: 32000 endPort: 32768
上面的规则允许名字空间 default
中所有带有标签 role=db
的 Pod 使用 TCP 协议 与 10.0.0.0/24
范围内的 IP 通信,只要目标端口介于 32000 和 32768 之间就可以。