![OpenShift高效运维:SRE视角的集群和分布式系统管理](https://wfqqreader-1252317822.image.myqcloud.com/cover/859/49070859/b_49070859.jpg)
3.3 公开服务
到目前为止,你已经了解了如何使用给定服务的主机名或集群内部DNS名称从集群内访问服务。要从本地计算机访问服务进行调试,可以使用端口转发。然而,在大多数情况下,你希望用户通过网络(例如使用We b浏览器)访问We b服务,或者至少访问其中的一部分。为此,你需要公开你的服务。OpenShift提供了易于使用的工具来创建公共DNS名称作为集群域的子域,可以从集群外部访问该子域。要使用它,你可以为希望公开到内网或公网的服务创建路由资源。
3.3.1 按自动生成的DNS名称路由
首先要公开的服务是街机游戏平台的主要入口,即platform服务。为此,只需再次运行oc expose,这一次指定要向外部世界公开的服务:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/43_01.jpg?sign=1738834533-Bt4Lk1WIfbblYTpY4ELr4FfTf3hvajZn-0-219a6e63e30136724794b2cf458414c8)
运行此命令后,我们在“arcade”命名空间中创建了一个路由资源。使用以下命令查看已生成的路由:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/43_02.jpg?sign=1738834533-JHVKzwuLELTrJXCBLjjgpy90YGYS8v2u-0-b7cfb417daf3d57b3ca3947de2981ffd)
接下来,公开game服务。再次运行oc expose,检查OpenShift在命名空间中创建的路由:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/43_03.jpg?sign=1738834533-Ddzzq8zgRJuK4u3N7eRtt7PdSuZCYFRL-0-77bb90daeedf2724ae084f798febe86e)
现在可以看到,对于服务的不同路由,每个路由都分配了一个唯一的DNS名称。打开浏览器验证两个网页是否可以到达。
图3-2展示了街机游戏平台页面的外观。如果你运行OpenShift Local,这些将是http://platform-arcade.apps-crc.testing和http://game-arcade.apps-crc.testing/s3e。记住,游戏服务只服务于/s3e路径。
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/44_01.jpg?sign=1738834533-P21SQBwfTFdtlhEbz5ZUyIZbgwTlMUws-0-2d03cc3173eaa154fa5f03ee5574b6bf)
图3-2:示例应用程序:街机游戏平台前端
3.3.2 按路径路由
在平台页面上,你会注意到到记分页面的链接和游戏按钮目前都无法工作。这是因为highscore服务尚未公开,并且game服务目前以不同的域名公开。默认情况下,OpenShift为每个公开的服务创建唯一的子域,由命名空间和服务名称组成。你可以在前面的oc get routes命令的输出中看到它们。但是,你可以告诉OpenShift基于URL中的路径路由请求,而不是为每个服务生成唯一的名称。回头看看图3-1中示例应用程序的架构,使用相同域名的路径路由是应用程序运行所需要的。
你可以重用为平台服务生成的域名——platform-arcade.apps-crc.testing(整个应用程序),指定应该路由到不同服务的路径。由于platform服务是应用程序的主要入口点,并且在/处接收请求,因此你不需要更改此路由。使用以下命令在/highscore处公开highscore服务:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/44_02.jpg?sign=1738834533-SqOtC9cXSzY724HMpN6sEoSpCfre052d-0-be6385bf73df6a321d61b59dd40194e9)
要更改游戏服务的主机名,可以使用以下命令编辑生成的路由。它打开一个编辑器,你可以将生成的主机名调整为platform-arcade.apps-crc.testing并设置路径为/s3e:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/44_03.jpg?sign=1738834533-Cfg92u96zw4ePbwPweDSlF1Id4iQV2Zc-0-68b51956d8b4a45494fcacd3095906c3)
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/45_01.jpg?sign=1738834533-6NQTmE5kYRWI6WcO8WEY0CBPrHKAntK8-0-f5e3ae2490717db17b26bda5f9b718de)
❶将此路由的路径设置为/s3e,以便所有到此路径的请求将被转发到game服务。
保存更改并退出编辑器后,你可以再次获得路由列表。
所有三个路由现在应该被分配到相同的主机名:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/45_02.jpg?sign=1738834533-MNRElvCdiUdfgoDggMfp6XhZJFpy20st-0-5aa0dfb1809e6a83a0e9d5fac05308ff)
当你在浏览器中重新访问主页http://platform-arcade.apps-crc.testing时,游戏按钮应该可以工作。到记分页面的链接也应该可以正常工作,在完成一些游戏后,它看起来类似于图3-3。
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/45_03.jpg?sign=1738834533-moWUPSz5xrWCcMC9UBonvpdUzZljZ0j8-0-83f6b0feefcbf32719121b48d481a12c)
图3-3:示例应用程序:街机游戏平台记分
3.3.3 外部负载均衡器
你可以使用基础设施提供的负载均衡器,而不是使用OpenShift路由器来公开和访问你的服务。例如,如果你已经将OpenShift集群部署到谷歌云平台(GCP),你可以创建GCP负载均衡器,将请求分发到OpenShift节点上的服务。
在集群的所有节点上都将打开一个端口,用于侦听定向到特定服务的流量。负载均衡器将请求分发到这个特定端口上的节点。对负载均衡器IP的请求将被转发到正确的pod。这个概念在OpenShift中称为NodePort。
OpenShift将负责在基础设施中配置负载均衡器。你需要做的就是在公开部署时指定LoadBalancer类型。
为了遵循本节的示例,你将需要一个部署在提供负载均衡器的基础设施上的OpenShift集群,如GCP或Amazon Web Services(AWS)。虽然你可以在OpenShift Local上执行所有命令并创建LoadBalancer类型的服务,但它与NodePort类型的服务没有什么不同。
使用以下命令创建一个名为game-lb的新服务,以使用LoadBalancer类型的服务公开game部署。之后,用oc describe检查创建的服务:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/46_02.jpg?sign=1738834533-PwRRnn2FrioMfcqMg0DWEEpf7lq3FylD-0-1ff6256d8c59b3a5b4151cddb3c5fb82)
你可以将此服务与原始game服务进行比较。
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/46_03.jpg?sign=1738834533-GgFzyIuBvFOcjOzc2Wbvl9looC9K5Egu-0-b5422d049f4cbad5653f40fa36e6e0dd)
你可以看到OpenShift创建了一个LoadBalancer服务,而不是ClusterIP。此外,已经为该服务分配了一个NodePort,现在可以用来访问该服务。你应该能够查询该端口上的任何节点并到达game-lb服务,该服务将在与game服务相同的端点上分发请求。
通过oc get nodes -o wide或oc describe nodes获取任意节点的IP地址。如果你的节点可以从外部访问并且端口是公开的,那么你可以使用外部IP直接从你的计算机查询服务。在大多数情况下,节点不直接公开于互联网,或者端口位于防火墙后面,因此无法从互联网访问它们。但是,你仍然可以在集群内部署pod并查询内部IP以观察服务行为。
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/47_01.jpg?sign=1738834533-E1p5wPtzUI93t9mYoTvJ41eAHuqgN67E-0-7fa12a72750bca0325c1f60240ab6a67)
❶如果curl pod已经在前面的例子中运行,这个命令可能会返回一个错误。你可以删除pod,也可以重用现有的pod。
❷与上面相同的命令,它会一直运行。要退出,请按Ctrl+C。
在上述命令中,使用该服务分配的端口查询一个节点。从标题中,你可以看到请求被分配到与之前指向game服务的请求相同的端点。
除了NodePort之外,OpenShift还使用部署集群的基础设施中的负载均衡器公开了该服务。
对于本例,已经在GCP上创建了OpenShift集群。在GCP控制台中,通过比较与负载均衡器关联的公共IP,可以找到与此服务关联的负载均衡器。图3-4是OpenShift创建的一个负载均衡器配置示例。
就像你之前查询NodePort一样,你可以在本地机器上应用curl使用外部IP访问负载均衡器后面的服务:
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/47_02.jpg?sign=1738834533-E3K5DCZ4jrJPAiIM0gykNli2tbeGLsfq-0-504c33ba367d6872f5be6c0be8d96b9d)
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/48_01.jpg?sign=1738834533-Cqn9wkzKsI4XBhjHH2D6nJitbgQMrp0T-0-9dafc81f2f146f5dd3a4a4f4036e2f28)
![](https://epubservercos.yuewen.com/EB4D27/28831576607915606/epubprivate/OEBPS/Images/48_02.jpg?sign=1738834533-ck51FtZN8WDygEGNpvk3fp7Xqlk42E9g-0-4c1e5fc78cd7a7bb34c781bc4add4f1d)
图3-4:GCP控制台中负载均衡器的详细信息
再次按Ctrl+C停止Curl循环。
请注意,为你的服务使用基础设施提供的负载均衡器会给你的项目带来额外的成本。我们建议使用OpenShift路由器作为默认值(也是为了便于使用)。只有当它不能提供你所需的性能,或者出于其他原因需要外部负载均衡器时,你才应该考虑为服务创建一个。