k8s networkpolicy网络策略详解

转载自博客:https://www.dtmao.cc/news_show_164887.shtml

当前位置: 首页 > 学习教程  > 编程语言

k8s networkpolicy网络策略详解

2020/9/5 19:21:41 0人评论 10次 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除
 

1. 简介

网络策略(NetworkPolicy)是一种关于 Pod 间及与其他网络端点间所允许的通信规则的规范。

NetworkPolicy 资源使用 标签 选择 Pod,并定义选定 Pod 所允许的通信规则。

2. 语法

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
 - Ingress
 - Egress
  ingress:
 - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
 - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

说明:

  • spec: NetworkPolicy 规约 中包含了在一个命名空间中定义特定网络策略所需的所有信息。
  • podSelector: 每个 NetworkPolicy 都包括一个 podSelector ,它对该策略所应用的一组 Pod进行选择。示例中的策略选择带有"role=db" 标签的 Pod空的 podSelector 选择命名空间下的所有 Pod
  • policyTypes: 每个 NetworkPolicy 都包含一个 policyTypes 列表,其中包含 Ingress 或 Egress 或两者兼具。policyTypes 字段表示给定的策略是否应用于进入所选 Pod 的入口流量或者来自所选 Pod的出口流量,或两者兼有。如果 NetworkPolicy 未指定 policyTypes 则默认情况下始终设置 Ingress,如果NetworkPolicy 有任何出口规则的话则设置 Egress。
  • ingress: 每个 NetworkPolicy 可包含一个 ingress 规则的白名单列表。每个规则都允许同时匹配from 和ports部分的流量。示例策略中包含一条简单的规则: 它匹配一个单一的端口,来自三个来源中的一个, 第一个通过 ipBlock指定,第二个通过namespaceSelector 指定,第三个通过 podSelector 指定。
  • egress: 每个 NetworkPolicy 可包含一个 egress 规则的白名单列表。每个规则都允许匹配to 和 port部分的流量。该示例策略包含一条规则,该规则将单个端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

所以,该网络策略示例:

  1. 隔离 “default” 命名空间下 “role=db” 的 Pod (如果它们不是已经被隔离的话)。
  2. (Ingress 规则)允许以下 Pod 连接到 “default” 命名空间下的带有 “role=db” 标签的所有 Pod 的6379 TCP端口:
"default" 命名空间下任意带有 "role=frontend" 标签的 Pod
带有 "project=myproject" 标签的任意命名空间中的 Pod
IP 地址范围为 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255(即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16)
  1. (Egress 规则)允许从带有 “role=db” 标签的命名空间下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978TCP 端口的连接。

3. 选择器 to 和 from 的行为

可以在 ingress from 部分或 egress to 部分中指定四种选择器:

  • podSelector: 这将在与 NetworkPolicy 相同的命名空间中选择特定的 Pod,应将其允许作为入口源或出口目的地。
  • namespaceSelector: 这将选择特定的命名空间,应将所有 Pod 用作其输入源或输出目的地。
  • namespaceSelector 和 podSelector: 一个指定 namespaceSelector 和 podSelector
    的 to/from 条目选择特定命名空间中的特定 Pod。注意使用正确的 YAML 语法;这项策略:
 ...
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          user: alice
      podSelector:
        matchLabels:
          role: client
  ...

在 from 数组中仅包含一个元素,只允许来自标有role=client的 Pod 且该 Pod 所在的命名空间中标有user=alice的连接。但是 这项 策略:

 ...
  ingress:
 - from:
    - namespaceSelector:
        matchLabels:
          user: alice
    - podSelector:
        matchLabels:
          role: client
  ...

在 from 数组中包含两个元素,允许来自本地命名空间中标有role=client的 Pod 的连接,或 来自任何命名空间中标有user = alice的任何 Pod 的连接。

  • ipBlock: 这将选择特定的IP CIDR范围以用作入口源或出口目的地。 这些应该是群集外部 IP,因为 Pod IP 存在时间短暂的且随机产生。
    群集的入口和出口机制通常需要重写数据包的源 IP 或目标 IP。在发生这种情况的情况下,不确定在 NetworkPolicy 处理之前还是之后发生,并且对于网络插件,云提供商,Service 实现等的不同组合,其行为可能会有所不同。

在进入的情况下,这意味着在某些情况下,您可以根据实际的原始源 IP 过滤传入的数据包,而在其他情况下,NetworkPolicy 所作用的 源IP 则可能是 LoadBalancer 或 Pod 的节点等。

对于出口,这意味着从 Pod 到被重写为集群外部 IP 的 Service IP 的连接可能会或可能不会受到基于 ipBlock 的策略的约束

4. 默认策略

默认情况下,如果命名空间中不存在任何策略,则所有进出该命名空间中的 Pod 的流量都被允许。以下示例使您可以更改该命名空间中的默认行为。

4.1 默认拒绝所有入口流量

您可以通过创建选择所有容器但不允许任何进入这些容器的入口流量的 NetworkPolicy 来为命名空间创建 “default” 隔离策略。

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

这样可以确保即使容器没有选择其他任何NetworkPolicy,也仍然可以被隔离。此策略不会更改默认的出口隔离行为。

4.2 默认允许所有入口流量

如果要允许所有流量进入某个命名空间中的所有 Pod(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。

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

4.3 默认拒绝所有出口流量

您可以通过创建选择所有容器但不允许来自这些容器的任何出口流量的 NetworkPolicy 来为命名空间创建 “default” egress 隔离策略。

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

4.4 默认允许所有出口流量

如果要允许来自命名空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。

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

4.5 默认拒绝所有入口和所有出口流量

您可以为命名空间创建 “default” 策略,以通过在该命名空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量。

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

5. 声明网络策略

5.1 创建一个nginx Deployment 并且通过服务将其暴露

$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80   #此 Deployment 以名为 nginx 的 Service 暴露出来
$ kubectl get svc,pod

$ kubectl run busybox --rm -ti --image=busybox /bin/sh  # 创建测试工具的pod
$ wget --spider --timeout=1 nginx
Connecting to nginx (10.100.0.16:80)
remote file exists

5.2 限制 nginx 服务的访问

如果想限制对 nginx 服务的访问,只让那些拥有标签access: true的 Pod 访问它, 那么可以创建一个如下所示的 NetworkPolicy 对象:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"

注意: NetworkPolicy 中包含选择策略所适用的 Pods 集合的podSelector。 你可以看到上面的策略选择的是带有标签 app=nginx 的 Pods。 此标签是被自动添加到 nginx Deployment 中的 Pod 上的。 如果 podSelector 为空,则意味着选择的是名字空间中的所有 Pods。

$ kubectl apply -f https://k8s.io/examples/service/networking/nginx-policy.yaml

$ kubectl run busybox --rm -ti --image=busybox -- /bin/sh  #创建测试工具的pod

$ wget --spider --timeout=1 nginx
Connecting to nginx (10.100.0.16:80)
wget: download timed out

定义访问标签后再次测试
创建一个拥有正确标签的 Pod,你将看到请求是被允许的:

$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox -- /bin/sh
在 Shell 中运行命令:

$ wget --spider --timeout=1 nginx
Connecting to nginx (10.100.0.16:80)
remote file exists

参考连接:
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/

posted on 2021-08-15 17:57  luzhouxiaoshuai  阅读(532)  评论(0编辑  收藏  举报

导航