【问题标题】:Google Kubernetes Engine: NetworkPolicy allowing egress to k8s-metadata-proxyGoogle Kubernetes Engine:允许出口到 k8s-metadata-proxy 的 NetworkPolicy
【发布时间】:2021-01-17 09:25:48
【问题描述】:

上下文

我有一个启用了Workload Identity 的 Google Kubernetes Engine (GKE) 集群。作为 Workload Identity 的一部分,k8s-metadata-proxy DaemonSet 在集群上运行。我有一个命名空间my-namespace,并且想要拒绝命名空间中除到 k8s-metadata-proxy DaemonSet 的出口之外的所有 pod 出口流量。因此,我有以下 NetworkPolicy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: my-namespace
spec:
  # Apply to all pods.
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - ports:
    # This is needed to whitelist k8s-metadata-proxy. See https://github.com/GoogleCloudPlatform/k8s-metadata-proxy
    - protocol: TCP
      port: 988

问题

NetworkPolicy 过于宽泛,因为它允许将 TCP 流量出口到端口 988 上的任何主机,而不仅仅是出口到 k8s-metadata-proxy DaemonSet,但我似乎找不到方法指定.spec.egress[0].to 来实现我想要的粒度。

我尝试了以下tos:

  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          namespace: kube-system
    ports:
    - protocol: TCP
      port: 988
  - to:
    - ipBlock:
        cidr: <cidr of pod IP range>
    - ipBlock:
        cidr: <cidr of services IP range>
    ports:
    - protocol: TCP
      port: 988

但是这些规则会导致到 k8s-metadata-proxy 的流量被阻止。

问题

如何在networking.k8s.io/v1/NetworkPolicy 的出口规则的to 部分选择k8s-metadata-proxy DaemonSet?

【问题讨论】:

标签: google-kubernetes-engine kubernetes-networkpolicy


【解决方案1】:

正如我在评论中所说:

你好。您可以将 podSelector.matchLabels 添加到 Egress 定义中,以允许您的 pod 仅连接到具有特定标签的 Pod。你可以在这里阅读更多信息:cloud.google.com/kubernetes-engine/docs/tutorials/…

此评论可能具有误导性,因为官方文档中描述了与 gke-metadata-server 的通信:

关注上述文档部分:

了解 GKE 元数据服务器

GKE 元数据服务器是一个新的metadata server,专为与 Kubernetes 一起使用而设计。它作为 daemonset 运行,每个集群节点上都有一个 Pod。元数据服务器拦截对 http://metadata.google.internal (169.254.169.254:80) 的 HTTP 请求,包括像 GET /computeMetadata/v1/instance/service-accounts/default/token 这样的请求,以检索 Pod 配置为充当的 Google 服务帐户的令牌。到元数据服务器的流量永远不会离开托管 Pod 的 VM 实例。

注意:如果您有一个严格的cluster network policy,您必须允许在端口 988 上到 127.0.0.1/32 的出口,这样您的 Pod 才能与 GKE 元数据服务器通信。

上面引用的最后一段描述了只允许到GKE Metadata server 的流量的规则。 YAML 定义应如下所示:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: egress-rule
  namespace: restricted-namespace # <- namespace your pod is in 
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: nginx # <- label used by pods trying to communicate with metadata server
  egress:
  - to:
    - ipBlock:
        cidr: 127.0.0.1/32 # <- allow communication with metadata server #1 
  - ports:
    - protocol: TCP
      port: 988 # <- allow communication with metadata server #2 

假设:

  • 您有一个 Kubernetes 集群:
    • Network Policy 已启用
    • Workload Identity 已启用
  • 您的 Pods 正在尝试从 restricted-namespace 命名空间进行通信

用于描述所需NetworkPolicy的输出:

  • $ kubectl describe networkpolicy -n restricted-namespace egress-rule
Name:         egress-rule
Namespace:    restricted-namespace
Created on:   2020-10-04 18:31:10 +0200 CEST
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"name":"egress-rule","namespace":"restricted-name...
Spec:
  PodSelector:     app=nginx
  Allowing ingress traffic:
    <none> (Selected pods are isolated for ingress connectivity)
  Allowing egress traffic:
    To Port: <any> (traffic allowed to all ports)
    To:
      IPBlock:
        CIDR: 127.0.0.1/32
        Except: 
    ----------
    To Port: 988/TCP
    To: <any> (traffic not restricted by source)
  Policy Types: Egress

免责声明!

应用这些规则将拒绝来自带有app=nginx 标签的 Pod 的所有流量,这些流量不是发往元数据服务器的!

您可以通过以下方式创建并exec 进入带有标签app=nginx 的pod:

kubectl run -it --rm nginx \
--image=nginx \
--labels="app=nginx" \
--namespace=restricted-namespace \
-- /bin/bash

提示!

使用图片nginx,因为它默认安装了curl!

通过本示例,您将无法与 DNS 服务器通信。您可以:

  • 允许您的 pod 与 DNS 服务器通信
  • 为元数据服务器 (169.254.169.254) 设置 env 变量

与GKE Metadata Server通信的例子:

  • $ curl 169.254.169.254/computeMetadata/v1/instance/ -H 'Metadata-Flavor: Google'
attributes/
hostname
id
service-accounts/
zone

其他资源:



要允许特定 pod 仅将流量发送到特定端口上的特定 pod,您可以使用以下策略:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: egress-rule
  namespace: restricted-namespace # <- namespace of "source" pod
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: ubuntu # <- label for "source" pod
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: nginx # <- label for "destination" pod
  - ports:
    - protocol: TCP
      port: 80 # <- allow only port 80

【讨论】:

  • 谢谢,根据您链接的文档将 127.0.0.1:988 列入白名单
  • 他们应该让它在官方文档中更加明显。
猜你喜欢
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 2020-03-04
  • 2022-01-13
  • 2022-06-28
  • 2020-09-26
  • 2021-05-31
相关资源
最近更新 更多