通过 *** 从 GKE Pod 传出的流量

Posted

技术标签:

【中文标题】通过 *** 从 GKE Pod 传出的流量【英文标题】:Egress traffic from GKE Pod through *** 【发布时间】:2020-03-31 02:11:34 【问题描述】:

我有一个 VPC 网络,其子网范围为 10.100.0.0/16,节点位于其中。有一个路由和防火墙规则应用于 10.180.102.0/23 范围,这些规则路由并允许进出 *** 隧道的流量。

如果我在 10.100.0.0/16 范围内部署一个节点,我可以 ping 我在 10.180.102.0/23 范围内的设备。但是,在该节点内运行的 pod 无法 ping 10.180.102.0/23 范围内的设备。我认为这与 Pod 位于不同的 IP 范围(10.12.0.0/14)有关。

如何配置我的网络以便我可以与 10.180.102.0/23 范围内的设备 ping/通信?

【问题讨论】:

你的集群配置是什么?您是否激活了选项--enable-ip-alias?你的--cluster-ipv4-cidr 参数是什么?您是否已激活辅助 IP 范围?如果是这样,使用哪些值? @guillaumeblaquiere 我已经通过 GCP 控制台配置了集群和节点池,不是通过 gcloud,而是运行 gcloud container clusters describe <cluster>,给了我 clusterIpv4Cidr: 10.12.0.0/14ipAllocationPolicy: clusterIpv4Cidr: 10.12.0.0/14 clusterIpv4CidrBlock: 10.12.0.0/14 clusterSecondaryRangeName: gke-XXX-stack-cluster-pods-f28f6de4 servicesIpv4Cidr: 10.142.0.0/20 servicesIpv4CidrBlock: 10.142.0.0/20 servicesSecondaryRangeName: gke-XXX-stack-cluster-services-f28f6de4 useIpAliases: true 【参考方案1】:

我想从 GKE 中的一些 IP 地址术语开始。

网络命名空间:基于MAN page,网络命名空间在逻辑上是网络堆栈的另一个副本,具有自己的路由、防火墙规则和网络设备。此网络命名空间将节点的物理网络接口与 Pod 连接起来。此网络命名空间还连接到 Linux 桥接器,允许同一节点上的 pod 之间进行通信以及外部通信。

Pod IP: 分配给 Pod 的 IP 地址,可在 Pod 地址范围 选项内创建集群期间进行配置。 GKE 将此 IP 分配给 Pod 的网络命名空间中的虚拟网络接口,并路由到节点的物理网络接口,例如 eth0。

节点 IP: 分配给节点物理网络接口的 IP 地址为eth0。此节点 IP 配置在网络命名空间上以与 pod 通信。

集群 IP: 分配的 IP 地址并在服务的生命周期内保持稳定。使用网络命名空间允许节点和外部网络之间的通信。

这是我的信息来源; GKE Network Overview 我还在这里找到了这个注释:

警告:请勿手动更改节点,因为它们已被 GKE 覆盖,您的集群可能无法正常运行。直接访问节点的唯一原因是调试配置问题。


如果您希望在 GKE 集群和另一个网络之间建立通信,我建议您使用不同的服务:

外部负载平衡器管理来自集群外部和 Google Cloud Virtual Private Cloud (VPC) 网络之外的流量。他们使用与 Google Cloud 网络关联的转发规则将流量路由到 Kubernetes 节点。

内部负载均衡器管理来自同一 VPC 网络的流量。与外部负载平衡器一样,它们使用与 Google Cloud 网络关联的转发规则将流量路由到 Kubernetes 节点。

HTTP(S) 负载平衡器是用于 HTTP(S) 流量的专用外部负载平衡器。他们使用 Ingress 资源而不是转发规则将流量路由到 Kubernetes 节点。

您可以在此documentation 中找到有关不同服务的更多详细信息。

从整体上看,Pod 无法直接与外部资源通信。 您应该使用服务并将 pod 公开给服务。

【讨论】:

“在大图中,Pod 不能直接与外部资源通信。你应该使用服务并将 Pod 暴露给服务。”,但问题是我不想将流量路由到一个吊舱,已经解决了。问题是将流量从 pod 路由到另一个网络中的另一台计算机。希望我说得更清楚。感谢您帮助我,但我似乎无法用语言来解释我的问题。 我需要更多背景信息才能正确地为您提供建议。我知道您有一个 GKE 集群,并且您正在尝试访问另一个网络。告诉我更多关于这个网络的信息,这是 GCP 上的另一个 VPC?现场?互联网上的随机设备? 我有一个使用 Google Cloud *** 的 *** 隧道,它将我拥有的一些设备连接到 Google Cloud VPC 网络。这些设备可以从我在此 VPC 网络上的 GCP 上部署的节点通过此隧道访问。但是在这些节点内运行的 pod,由于某种原因无法访问这些设备,即从 pod 到设备的通量(可通过 *** 隧道到达)。 现在有了这个新词汇,我想我找到了与我的问题类似的东西? github.com/kubernetes/kubernetes/issues/6545 作为参考,pdecat 似乎找到了解决方案:link 1 正如他所提到的,这里有一些关于 IP 伪装的更多信息:link 2【参考方案2】:

我不太记得如何解决,但我发布了我必须帮助@tdensmore 的内容。

您必须编辑 ip-masq-agent(它是在 GKE 上运行的代理,伪装 IP),此配置负责让节点内的 pod 到达 GCP VPC 网络的其他部分,更具体地说***。因此,它允许 pod 与可通过 *** 访问的设备进行通信。

首先,我们将在 kube-system 命名空间内工作,我们将把配置我们的 ip-masq-agent 的 configmap 放入 config 文件中:

nonMasqueradeCIDRs:
  - 10.12.0.0/14  # The IPv4 CIDR the cluster is using for Pods (required)
  - 10.100.0.0/16 # The IPv4 CIDR of the subnetwork the cluster is using for Nodes (optional, works without but I guess its better with it)
masqLinkLocal: false
resyncInterval: 60s

然后运行kubectl create configmap ip-masq-agent --from-file config --namespace kube-system

然后,配置 ip-masq-agent,将其放入 ip-masq-agent.yml 文件中:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: ip-masq-agent
  namespace: kube-system
spec:
  template:
    metadata:
      labels:
        k8s-app: ip-masq-agent
    spec:
      hostNetwork: true
      containers:
      - name: ip-masq-agent
        image: gcr.io/google-containers/ip-masq-agent-amd64:v2.4.1
        args:
            - --masq-chain=IP-MASQ
            # To non-masquerade reserved IP ranges by default, uncomment the line below.
            # - --nomasq-all-reserved-ranges
        securityContext:
          privileged: true
        volumeMounts:
          - name: config
            mountPath: /etc/config
      volumes:
        - name: config
          configMap:
            # Note this ConfigMap must be created in the same namespace as the daemon pods - this spec uses kube-system
            name: ip-masq-agent
            optional: true
            items:
              # The daemon looks for its config in a YAML file at /etc/config/ip-masq-agent
              - key: config
                path: ip-masq-agent
      tolerations:
      - effect: NoSchedule
        operator: Exists
      - effect: NoExecute
        operator: Exists
      - key: "CriticalAddonsOnly"
        operator: "Exists"

然后运行kubectl -n kube-system apply -f ip-masq-agent.yml

注意:我已经很久没有这样做了,这个链接中有更多信息:https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent

【讨论】:

非常感谢您花时间写这篇文章@henke。我现在就去试试。 我刚刚确认了这项工作。 @Henke 非常感谢您花时间编写此解决方案。它解决了我的问题,我希望它也能解决其他人的问题。 很高兴听到这个消息! 谢谢,这正是我所需要的。现在如何从本地连接到服务 IP 范围:)?静态路由似乎还不够。 @VincentGerris 我在静态内部 IP 地址中设置了内部负载平衡器。通过这种方式,我在 *** 上配置设备,以访问此静态 IP 负载平衡器,以平衡您的服务之间的负载。不知道能不能解决你的问题

以上是关于通过 *** 从 GKE Pod 传出的流量的主要内容,如果未能解决你的问题,请参考以下文章

代理 kubernetes 通过代理 (CNTLM) 的传出流量

为公共 GKE 集群设置 Cloud NAT

如何使用网络策略停止所有外部流量并仅允许命名空间内的 Pod 间网络调用?

如何在不使用 PCap 的情况下嗅探 .NET 中的本地传出网络流量?

拦截**传出** HTTP(S) 流量

传出流量 AWS 的公共 IP 地址