热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Kubernetes最佳实践:映射外部服务

文开发技术推广工程师SandeepDinesh大多数Kubernetes用户都有可能用到集群外部的服务。例如,您可能使用TwillioAPI发送短信,或使用Google

文 / 开发技术推广工程师 Sandeep Dinesh

 

大多数 Kubernetes 用户都有可能用到集群外部的服务。例如,您可能使用 Twillio API 发送短信,或使用 Google Cloud Vision API 进行图像分析。

 

如果位于不同环境中的应用连接相同的外部端点,并且您不打算将外部服务引入 Kubernetes 集群,那么在代码中直接使用外部服务端点是完全可以的。然而,很多时候情况并非如此。

 

数据库就是一个很好的例子。虽然一些云原生数据库(如 Cloud Firestore 或 Cloud Spanner)对所有访问均使用一个端点,但大多数数据库对不同实例都有单独的端点。

 

说到这里,您可能会认为,就查找端点而言,ConfigMap 是个不错的解决方案。只需将端点地址存储在 ConfigMap 中,并将其作为环境变量用于代码中。此解决方案的确有效,但也存在一些缺点。您需要修改部署以包含 ConfigMap 并编写额外的代码以从环境变量中读取。但最重要的是,如果端点地址发生变化,您可能需要重启所有正在运行的容器以获取更新后的端点地址。

 

在本集的 “Kubernetes 最佳实践” 中,我们会学习如何将 Kubernetes 内置服务发现机制运用于集群外部运行的服务,像使用集群内的服务一样使用外部服务!通过这种方式,您可以在开发环境和生产环境中实现相同的功能,如果您最终将服务移入集群内,则不需要更改任何代码。

 

640?wx_fmt=png

 

 

场景 1:具有 IP 地址的集群外数据库

其中一个常见场景是在集群外部托管自己的数据库,例如在 Google 计算引擎实例中。如果您在 Kubernetes 内部和外部分别运行一些服务,或者需要在 Kubernetes 允许的基础上获得更多定制或控制,通常可采用上述这种方式。

 

希望未来某个时候您可以将所有服务都移入集群内,但在此之前将是“内外混用”的状态。幸运的是,您可以使用静态 Kubernetes 服务来缓解上述痛点。

 

在本例中,我使用 Cloud Launcher 创建了一个 MongoDB 服务器。由于此服务器在与 Kubernetes 集群相同的网络(或 VPC)中创建,因此可以使用高性能的内部 IP 地址访问。在 Google Cloud 中,这是默认设置,因此无需进行任何特殊配置。

 

640?wx_fmt=png

 

现在我们有了 IP 地址,那么第一步就是创建服务:

 

kind: Service

apiVersion: v1

metadata:

?name: mongo

Spec:

?type: ClusterIP

?ports:

?- port: 27017

? ?targetPort:?27017

 

您可能会注意到此服务没有 Pod 选择器。此操作将创建一个服务,但它不知道往哪里发送流量。这样一来,您可以手动创建一个将从此服务接收流量的 Endpoints 对象。

 

kind: Endpoints

apiVersion: v1

metadata:

?name: mongo

subsets:

?- addresses:

? ? ?- ip: 10.240.0.4

? ?ports:

? ? ?- port: 27017

 

您可以看到 Endpoints 手动定义了数据库的 IP 地址,并且使用的名称与服务名称相同。Kubernetes 将 Endpoints 中定义的所有 IP 地址视为与常规 Kubernetes Pod 一样。现在您可以用一个简单的连接字符串访问数据库:

 

mongodb://mongo

> 根本不需要在代码中使用 IP 地址!如果以后 IP 地址发生变化,您可以为端点更新 IP 地址,而应用无需进行任何更改。

 

 

场景 2:具有 URI 的远程托管数据库

如果您使用的是来自第三方的托管数据库服务,它们可能会为您提供可用于连接的统一资源标识符 (URI)。如果它们为您提供 IP 地址,则可以使用场景 1 中的方法。

 

在本例中,我在 mLab 上托管了两个 MongoDB 数据库。一个是我的开发数据库,另一个是生产数据库。

 

640?wx_fmt=png

 

这些数据库的连接字符串如下所示:

 

mongodb://:@ds149763.mlab.com:49763/devmongodb://:@ds145868.mlab.com:45868/prodmLab?

 

为您提供了动态 URI 和动态端口,您可以看到两者都不同。我们来使用 Kubernetes 基于这些差异创建一个抽象层。在本例中,我们将连接开发数据库。

 

您可以创建一个 “ExternalName” Kubernetes 服务,此服务为您提供将流量重定向到外部服务的静态 Kubernetes 服务。此服务在内核级别执行简单的 CNAME 重定向,因此对性能的影响非常小。

 

服务的 YAML 如下所示:

kind: Service

apiVersion: v1

metadata:

?name: mongo

spec:

?type: ExternalName

?externalName: ds149763.mlab.com

 

现在,您可以使用更简化的连接字符串:

mongodb://:@mongo:/dev

 

由于 “ExternalName” 使用 CNAME 重定向,因此无法执行端口重映射。对于使用静态端口的服务来说,这可能不成问题,然而本例中使用的是动态端口。mLab 免费版为您提供了动态端口号,并且不允许更改。这意味着您需要对开发和生产数据库使用其他连接字符串。

 

但如果您可以获取 IP 地址,就可以执行端口重映射,关于此内容,我将在下一部分进行介绍。

 

场景 3:具有 URI 和端口重映射功能的远程托管数据库

CNAME 重定向对于每个环境均使用相同端口的服务非常有效,但如果每个环境的不同端点使用不同的端口,CNAME 重定向就略显不足。幸运的是我们可以使用一些基本工具来解决这个问题。

 

第一步是从 URI 获取 IP 地址。

 

对 URI 运行 nslookup、hostname 或 ping 命令即可获取数据库的 IP 地址。

 

640?wx_fmt=png

 

您现在可以创建一个重新映射 mLab 端口的服务,并为此 IP 地址创建端点。

 

kind: Service

apiVersion: v1

metadata:

?name: mongo

spec:

?ports:

?- port: 27017

? ?targetPort: 49763

---

kind: Endpoints

apiVersion: v1

metadata:

?name: mongo

subsets:

?- addresses:

? ? ?- ip: 35.188.8.12

? ?ports:

? ? ?- port: 49763

 

注:URI 可以使用 DNS 在多个 IP 地址之间进行负载平衡,因此,如果 IP 地址发生变化,这个方法可能会有风险!如果您通过上述命令获取多个 IP 地址,则可以将所有这些地址都包含在 Endpoints YAML 中,并且 Kubernetes 会在所有 IP 地址之间进行流量的负载平衡。

 

通过这种方式,您无需指定端口即可连接到远程数据库。Kubernetes 老年服饰服务重映射端口的过程完全透明!

mongodb://:@mongo/dev

 

结论

将外部服务映射到内部服务可让您未来灵活地将这些服务纳入集群,同时最大限度地减少重构工作。即使您今天不打算将服务加入集群,以后可能也会这样做!而且,这样一来,您可以更轻松地管理和了解组织所使用的外部服务。

 

如果外部服务具有有效域名,并且您不需要重新映射端口,那么使用 “ExternalName” 服务类型将外部服务映射到内部服务十分简便、快捷。如果您没有域名或需要执行端口重映射,只需将 IP 地址添加到端点并使用即可。

 

更多 AI 相关阅读:

·?通过安全浏览保护 WebView

·?通过视频着色进行自监督跟踪

·?通过机器学习让医疗数据更好用

 

 

 


文章来源:https://blog.csdn.net/jILRvRTrc/article/details/81117261


推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Hive常用命令及其用途,包括列出数据表、显示表字段信息、进入数据库、执行select操作、导出数据到csv文件等。同时还涉及了在AndroidManifest.xml中获取meta-data的value值的方法。 ... [详细]
  • JAVA调用存储过程CallableStatement对象的方法及使用示例
    本文介绍了使用JAVA调用存储过程CallableStatement对象的方法,包括创建CallableStatement对象、传入IN参数、注册OUT参数、传入INOUT参数、检索结果和OUT参数、处理NULL值等。通过示例代码演示了具体的调用过程。 ... [详细]
  • PatchODAX8: ... [详细]
  • 我上个月有幸参加了在西雅图召开的PASS(ProfessionalAssociationforSQLServer)峰会。我的同事MattMasson做了 ... [详细]
  • 这篇文章主要讲解了“怎么用Python写一个电信客户流失预测模型”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入, ... [详细]
  • 基于halcon的特征匹配实例
    特征匹配原图模板识别图代码结果原图模板识别图代码*这个例子在图片数据库中查找文章的页面。*第一步是训练不同的页面并创建模型。*然后搜索未知图像并检测出正确的文章页面。*请注意& ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 初始化_SQL Server 2017 AlwaysOn AG 自动初始化
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了SQLServer2017AlwaysOnAG自动初始化相关的知识,希望对你有一定的参考价值。 ... [详细]
  • q3.whichstatementistrueregardingexternaltablesa.thedefaultrejectlimitforext ... [详细]
  • 使用R包提供的数据是学习数据科学工具的好方法,但是在某个时候,您希望停止学习,开始使用自己的数据。在本章中,您将学习如何将纯文本矩形文件读入r。在这里,我们只讨论数据导入的皮毛,但 ... [详细]
  • 本文整理了Java中org.osgi.service.blueprint.reflect.BeanMetadata.getDependsOn()方法的一些代码示例,展示 ... [详细]
  • 一条数据的漫游 XEngine SIGMOD Paper Introduction
    大多数人追寻永恒的家园(归宿),少数人追寻永恒的航向。----瓦尔特.本雅明背景X-Engine是阿里数据库产品事业部自研的OLTP数据库存储引擎, ... [详细]
  • 一.元祖类型 (tuple)1.什么是元祖?用途:用于存放多个值,当存放的多个值只有读的需求没有改变的需求时,用元祖最合适.定义方式:在()内用逗号分隔开的多个任意类型的值t(1, ... [详细]
author-avatar
权利阳成_278
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有