访问Kubernetes集群中托管的服务的两种最常见方法是通过Ingress或Load Balancer。对于公有云用户来说,这些是访问服务的简单有效方法。云托管的控制器可以完成分配公共IP,设置负载平衡和管理SSL的繁重工作。
在本地运行私有托管的Kubernetes集群的运营商将很快意识到,将服务公开提供比在公有云上更为复杂。服务将在公共互联网上还是仅对本地用户公开?应该如何设置Ingress,负载平衡,IP分配和SSL管理?在维护安全性的同时将服务公开发布的最有效方法是什么?
Calico项目通过其服务IP发布功能为某些问题提供了答案,该功能与现有的机架(ToR)基础架构集成在一起,可以提供Kubernetes服务IP或Kubernetes外部服务IP的路由。在以下情况下,服务IP发布是一个很好的解决方案:
- 您的ToR解决方案能够运行边界网关协议(BGP)
- 您希望将服务从群集共享到网络基础结构的其余部分
- 您想利用网络负载均衡
为了启用服务IP发布功能,Calico需要与BGP路由器建立对等关系,该路由器在Calico的内部路由器之外,但在网络本地。BGP是网络中使用的最基本的路由协议之一。在较高级别,BGP通过在信任对等方之间共享路由来工作。与ToR对等时,Calico共享Kubernetes服务的路由,这使它们可用于整个网络。
为了帮助讨论此功能,假定我们安装以下方式配置了网络和群集:
- 托管Kubernetes节点的服务器机架通过顶部机架式路由器连接到物理网络
- Calico作为CNI和网络策略插件运行
- Calico和Rack顶部路由器配置为使用BGP对等
在此设置中,我们具有以下网络配置:
- 机架顶部路由器的IP地址是192.168.1.1,服务器的IP地址是从192.168.1.0/24分配的
- Kubernetes Pod网络配置了CIDR 10.48.0.0/16
- Kubernetes服务集群IP范围配置为10.49.0.0/16
- 外部服务IP范围配置为192.168.3.0/24
您的ToR BGP路由器的确切配置超出了本文的范围,并且会因您使用的供应商或软件包而异。如果您没有可用的服务器机架,但仍然想尝试该功能,那么在单独的服务器上运行的Bird Internet Routing Daemon(BIRD)是尝试进行操作的不错选择。
第一步是启用ToR和Calico网络之间的对等连接。其工作方式将根据您的ToR实现而有所不同,但是要牢记一些关键事项:
- 必须将ToR路由器配置为与在每个节点上运行的Calico对等
- ToR需要接受来自外部网络,外部服务网络和Pod服务网络的路由和流量
- 如果可以选择,ToR应该启用正常重启,以防止网络服务中断
将ToR配置为接受路由后,下一步是在Calico端启用对等。首先通过以下清单告诉Calico有关外部BGP路由器的信息:
1 | calicoctl apply -f - << EOF |
启用对等功能后,Calico可以使Pod成为网络中的头等公民,而无需覆盖网络,并使他们可以直接在群集外部访问。
尽管启用了对等连接,但是Calico仍需要进一步配置以公开Kubernetes服务IP范围。这可以通过创建新的Calico BGPConfiguration资源来完成:
1 | calicoctl create -f - <<EOF |
启用服务群集IP范围的发布后,ToR上的路由表将如下所示:
1 | ip r |
注意到10.49.0.0/16网络的路由如何在节点之间实现ECMP负载平衡。您公开的所有服务将由ToR在所有节点上进行负载平衡。为了说明这一点,我们可以创建一个基本的Nginx服务。
1 | control:~$ kubectl apply -f - <<EOF |
现在,您可以从外部网络通过其内部群集IP地址访问Kubernetes托管服务。
1 | external:~$ curl 10.49.62.131 |
这里有两个阶段的负载平衡。首先,ToR通过将其路由到节点来对与群集IP的连接进行负载平衡。然后,使用NAT(网络地址转换)在该节点上运行的kube-proxy负载均衡到特定的Pod,以将目标IP从群集IP更改为后备Pod之一的IP地址。后备Pod可能在本地节点上,也可能在其他节点之一上,从而导致了另一个网络跃点。
如果我们想避免额外的潜在网络跳数,可以通过将服务上的外部流量策略设置为本地来实现。
1 | control:~$ kubectl patch service nginx \ |
现在,在ToR上,您将看到路由表的新增内容,包括Nginx服务到正在运行Nginx的特定节点的ECMP负载平衡:
1 | ip r |
这是公开Kubernetes网络服务的简便方法,但是在操作上,它具有将Kubernetes群集中该IP范围内的每个服务都暴露给网络其余部分的缺点。如果您想更精细地控制提供哪些服务,或者想要分配真正面向公众的IP地址,Calico可以通过发布外部服务IP来解决这个问题。该方法类似,主要区别在于外部IP不由Kubernetes集群管理,必须手动分配给服务。
下一个示例将说明这一点。首先重新配置BGPConfiguration,以发布外部IP而不是内部IP(值得注意的是,您可以一次公开这两个集合,但是在此示例中,我们要关闭对内部网络的公共访问,同时仍提供对应用程序的访问)。
1 | control :~$calicoctl create -f - <<EOF |
检查路由时,请注意已删除到群集IP范围的路由,并已添加到外部服务网络的路由。
1 | ip r |
该服务的群集IP不再公开可见。
1 | external :~$ curl -m 10 10.49.62.131 |
我们现在在发布外部IP范围,但我们还需要为服务分配一个外部IP:
1 | control:~$ kubectl patch svc nginx \ |
检查连接性:
1 | external:~$ curl 192.168.3.180 |
到此为止,我们快速完成了Calico如何在Kuberentes群集之外发布服务和外部服务IP的快速浏览。对于具有启用BGP路由的本地云,这是一种简单的解决方案,无需提供安装和维护自定义Kubernetes负载均衡器或Ingress控制器的额外工作即可访问Kubernetes服务。如果您想了解更多有关此功能的信息,请查阅官方的Calico项目”Advertise Kubernetes Service IPs“。