如果您想在 IP 地址或端口级别(OSI 第 3 或 4 层)控制流量,那么您可以考虑将 Kubernetes NetworkPolicies 用于集群中的特定应用程序。 

     默认 Pod 是未隔离的,它们可以从任何的源接收请求。Pod 的使用网络策略后,Pod 就会变成隔离的。 一旦 Namespace 中配置的网络策略能够选择一个特定的 Pod,这个 Pod 将拒绝任何该网络策略不允许的连接。(Namespace 中其它未被网络策略选中的 Pod 将继续接收所有流量)        

    默认情况下,每个Pod之间是可以相互访问的。但在某些场景中,不同的Pod不应该互通,这个时候就需要进行访问控制 

    Pod 可以与之通信的实体通过以下 3 个标识符的组合来标识:

  • 允许的其他 pod(例外:pod 不能阻止对自身的访问)
  • 允许的命名空间
  • IP 块(例外:始终允许进出 Pod 运行的节点的流量,无论 Pod 或节点的 IP 地址如何)

    在定义基于 pod 或命名空间的 NetworkPolicy 时,您可以使用选择器来指定允许哪些流量进出与选择器匹配的 Pod。

    同时,当创建基于 IP 的 NetworkPolicies 时,我们定义基于 IP 块(CIDR 范围)的策略。

前提

     需要有一个支持网络策略的 Kubernetes 集群。支持 NetworkPolicy 的网络如下:

  • Calico
  • Romana
  • Weave 网络

网络策略资源对象定义

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
  • podSelector: 每个 NetworkPolicy 都包含一个 podSelector,用于选择策略适用的 pod 分组。 示例策略选择标签为“role=db”的 pod。 空的 podSelector 选择命名空间中的所有 pod。
  • policyTypes: 每个 NetworkPolicy 都包含一个 policyTypes 列表,其中可能包含 Ingress、Egress 或两者。 policyTypes 字段指示给定的策略是否适用于到选定 Pod 的入口流量、来自选定 Pod 的出口流量,或两者。 如果 NetworkPolicy 上未指定任何策略类型,则默认情况下将始终设置 Ingress,如果 NetworkPolicy 有任何出口规则,则将设置 Egress。
  • ingress: 每个 NetworkPolicy 可能包含一个允许的入口规则列表。 每个规则都允许匹配 from 和 ports 部分的流量。 示例策略包含一条规则,该规则匹配来自三个源之一的单个端口上的流量,第一个通过 ipBlock 指定,第二个通过命名空间选择器指定,第三个通过 podSelector 指定。
  • egress: 每个 NetworkPolicy 可能包含一个允许的出口规则列表。 每个规则都允许与 to 和 ports 部分匹配的流量。 示例策略包含单个规则,该规则将单个端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

1. 默认策略

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

   1.1 默认拒绝所有入口流量

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

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

    这确保即使是未被任何其他 NetworkPolicy 选择的 pod 仍将被隔离。 此策略不会更改默认的出口隔离行为。

   1.2 默认允许所有入口流量

    如果您希望允许所有流量流向命名空间中的所有 pod(即使添加的策略导致某些 pod 被视为“隔离”),您可以创建一个策略,明确允许该命名空间中的所有流量。

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

测试例子

  1. 创建nginx deployment并将服务暴露

kubectl run nginx --image=nginx --replicas=2

kubectl expose deployment nginx --port=80

  2. 测试服务能够被其它的 pod 访问

        与nginx的80通

    

    3. 添加networkpolicy限制访问 nginx 服务

          kubectl apply -f 

          拥有标签 access: true 的 pod 可以访问

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

  4. 当访问标签没有定义时测试访问服务

[root@httpserver-7777-845f5fd9c8-7tpw6 /]# curl nginx:80 
curl: (7) Failed connect to nginx:80; Connection timed out

参考:

   https://kubernetes.io/docs/concepts/services-networking/network-policies/

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐