Kubernetes 网络策略,允许命名空间内的通信

Kubernetes Network Policy, allow communication within namespace

在启用了 Calico 网络策略插件的 Azure AKS 集群上,我想:

  1. 默认情况下阻止所有传入流量。
  2. 允许命名空间内的所有流量(从命名空间中的一个 pod 到 相同 命名空间中的另一个 pod。

我试过类似的方法:

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

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

但似乎阻止了同一命名空间中两个 deployments/pods 之间的流量。我做错了什么,我是不是看错文档了?

也许值得一提的是,上述设置似乎适用于基于 AWS EKS 的 Kubernetes 集群。

你可以先给Namespace打上标签

kubectl label ns <Namespace name> env: test

并像

一样应用政策
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-labled-namespace
spec:
  podSelector: {} 
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          env: test
    ports:
    - protocol: TCP
      port: 80

因此此网络策略将仅允许来自具有特定标签 test.

的命名空间的流量

如果您使用的是 Calico,则可以应用一个 GlobalNetworkPolicy 来拒绝对所有现有和未来命名空间有效的 Ingress:

apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
  name: default-global-deny-all-ingress
spec:
  namespaceSelector: has(projectcalico.org/name) && projectcalico.org/name not in {"kube-system", "calico-system", "tigera-operator"}
  order: 3000 # normal NPs (order: 1000) should have higher order
  types:
    - Ingress
  ingress:
    # allow collect metrics from Kubernetes Metrics Server
    - action: Allow
      protocol: TCP
      destination:
        selector: 'k8s-app == "metrics-server"'
        ports:
          - 443
    # Deny all ingress
    - action: Deny
      source:
        nets:
          - 0.0.0.0/0

重要的是顺序高于 1000,因为这是 NetworkPolicies 的默认顺序。现在您可以为每个命名空间的策略使用 Kuberentes 1.21 默认命名空间标签(ingress-nginx 示例):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ingress-allow-ingress-nginx
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
          podSelector: {}

经过调查发现:

  1. 我使用 terraform 创建了一个带有两个节点池的 k8s 集群。系统,和工人。 (注意:这在 GUI 中(尚不)可能)。
  2. 两个节点池位于不同的子网(系统子网和工作器子网)。
  3. AKS 配置 kubeproxy 以伪装进入系统子网之外的流量。
  4. Pods部署在工作节点上,因此使用工作子网。他们在 运行 所在的节点之外发送的所有流量都被伪装了。
  5. Calico 管理的 iptables 丢弃伪装的流量。我没有在这里查看更多细节。
  6. 但是,如果我将 kubeproxy 伪装设置更改为更大的 CIDR 范围,或者将其全部删除,它就会起作用。然而,Azure 会在一段时间后重置此设置。

总之。我尝试使用 Azure 尚不支持的东西。我现在为两个节点池使用一个(更大的)子网。