Kubernetes中的静态出站IP

41

我在谷歌云 (GKE) 上运行 k8s 集群,MySQL 服务器在亚马逊云 (RDS) 上。Pod 需要连接到只允许来自特定 IP 的 RDS,如何配置出站流量以具有静态 IP?


1
我将添加一个具有全局IP的NAT服务器,并配置其他服务器(例如Web服务器)通过NAT连接到互联网。 - Shouichi
也许直接转到安全组设置,允许来自任何地方的连接到 RDS 会更简单。而不仅限于一个IP。 - iamnat
关于在集群中将所有节点IP列入白名单,这是一种方法,但似乎并不是最优的,因为节点会动态变化。关于安全组,k8s集群运行在GCP上,MySQL运行在AWS上,所以我不确定它是否可行。 - Shouichi
嗯..所以,您必须拥有一个不变的特定IP,通过该IP进行连接。然后,除了通过在该IP上运行的服务代理所有请求之外,没有其他选择。这意味着您可以创建一个代理服务,使用k8s中的nodeSelectors将其绑定到特定节点,然后将该节点的IP列入白名单。您可以保留该节点的外部IP,以确保即使销毁该节点,也可以使用相同的IP启动新节点。实际上,您可以将此想法扩展到多个节点。预留一组IP,分配这些公共IP等等。 - iamnat
这样,我们必须确保其中一个节点具有特定的IP,这似乎很困难(当节点大小减小并且拥有该IP的节点被杀死时,我们应该怎么办?)。在k8s集群外部拥有代理服务器可能更简单。 - Shouichi
显示剩余4条评论
4个回答

18

我遇到了同样的问题,无法从Pod连接到SFTP服务器。 要解决这个问题,首先需要创建一个外部IP地址:

gcloud compute addresses create {{ EXT_ADDRESS_NAME }} --region {{ REGION }}

那么,我假设您的Pod被分配给了默认节点池。 提取您的默认节点池节点名称:

gcloud compute instances list | awk '{ print $1 }' | grep default-pool

删除虚拟机实例的默认外部IP地址:

gcloud compute instances delete-access-config {{ VM_DEFAULT-POOL_INSTANCE }} --access-config-name external-nat

添加之前创建的外部静态 IP 地址:

gcloud compute instances add-access-config {{ VM_DEFAULT-POOL_INSTANCE }} --access-config-name external-nat --address {{ EXT_ADDRESS_IP }}

如果您的Pod没有附加到default-pool节点,请不要忘记使用nodeSelector选择它:

nodeSelector:
    cloud.google.com/gke-nodepool: {{ NODE_NAME }} 

1
由于某些原因,“add-access-config”命令需要“zone”和“network-interface”参数。除此之外,它表现得非常好。 - defectus
嗨,谢谢你的回答!有一件事对我来说不是很清楚。使用这种方法,Pod 是否总是在一个节点上运行? - Shouichi
这是一个基本配置,使用默认池。在这种情况下,它仅在一个节点上运行一个Pod。 - Luc Charpentier
我们想要实现的是在多个节点上运行多个Pod。我们使用NAT网关和GCP的路由规则来实现这一目标。 - Shouichi
@Shouichi 这里是否涉及到其他的传输开销成本? - Damien Roche

8

我做了一些研究,找到了一些资料。

我们需要寻找的是“egress IPs”或NAT-as-a-Service,但它们目前在GKE中都不可用。

无论如何,我们有两个不同的选择:

  1. 创建一个NAT网关虚拟机,作为出口代理。这里有一篇很好的文章介绍了这个过程(google cloud NAT gateway
  2. 将静态IP分配给容器集群VM实例

希望对您有所帮助!


确认一下,这个(https://kubernetes.io/docs/tutorials/services/source-ip/)不是已经满足了所描述的需求吗? - Zed_Blade
嗯,我不这么认为。@Zed_Blade:服务始终是来自外部的请求,并从Pod提供服务。另一方面,这里的问题是外部流量的NAT。 - Michele Orsi
2
这里有同样的讨论链接。目前看来,NAT网关似乎是可行的解决方案。 - Carlos
更新的谷歌指南 GCE/K8s: https://cloud.google.com/solutions/using-a-nat-gateway-with-kubernetes-engine - rprasad

5
我知道这个问题很老了,但我的解决方案是在Google Cloud中创建一个私有Kubernetes集群。如果集群是私有的,那么节点将没有任何外部IP。如果节点没有外部IP并且我们拥有云NAT,则所有出站流量都将具有与云NAT IP相同的IP。所有这些都可以通过Google Cloud控制台完成。
我发现这篇文章对创建私有集群非常有帮助。 https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters 如果集群是私有的,并且您需要从某个远程区域访问它,请使用以下命令:
gcloud container clusters update {cluster_name} --enable-master-authorized-networks --master-authorized-networks {CIDR notation of your ip}
注意:在与Kubernetes集群相同的区域中创建Cloud NAT。此外,在创建Cloud NAT时,请确保选择“手动”选项以获得NAT IP地址,然后选择一个静态IP。除非您知道自己在做什么,否则请将其余配置保留为默认值。
设置好一切之后,使用kubectl执行任何运行在任何节点上的pod。使用dig命令检查您的出站IP。
dig +short myip.opendns.com @resolver1.opendns.com
它应该与云NAT IP相同。

1
您可以使用kubeip,这是一个用于每个新节点从预定义的池中分配IP地址的Pod。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接