对Kurbernetes中服务暴露方法的一些理解和说明(201001)

标签: 微服务架构 | 发表时间:2020-10-01 09:05 | 作者:人月神话
出处:http://blog.sina.com.cn/cmmi



由于最近在进一步整理和学习云原生解决方案的相关材料,原来一直没太理解清楚的就是kurbernetes中的网络和服务暴露方式。最近又查找资料进一步学习了下。

业务场景说明

在前面谈DevOps解决方案的时候就谈到,一个完整的DevOps持续集成和交付过程,需要和容器云集成,来实现自动化部署,动态弹性伸缩,环境迁移等能力。

对Kurbernetes中服务暴露方法的一些理解和说明

 

一个DevOps支撑平台离不开和容器化PaaS平台的集成,即最终的编译构建完成的内容形成镜像并放到镜像仓库,后续部署,环境迁移,资源扩展基于镜像仓库进行快速的拷贝和复制。对于Docker容器一般会和K8S结合来实现资源的动态调度,集群管理能力。

在原来谈的时候仅仅谈到通过K8s来完成部署和资源动态扩展的时候会从此一个VIP虚拟地址提供给应用模块访问使用,而这里没有进行展开,今天主要是结合场景进一步展开说明。

场景说明:

我们以整个应用实际有两个微服务模块来举例,一个是UserMgr微服务,一个是OrderMgr订单管理微服务,这个两个微服务都通过k8s自动化部署到容器云环境。同时我们假设,每个微服务都动态扩展了2个副本Pod,即形成了三个Pod节点。

在这种情况下,我们不可能直接去访问Pod IP,一个是Pod IP本身就会动态变化,一个是集群扩展后本身同一个微服务已经存在多个副本Pod IP。

因此我们需要通过Service来访问。

Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector实现的。比如上面的UserMgr微服务,我们可以给它打一个UserMgr的标签,然后相同的标签自动聚合到一个Service逻辑分组上面。

内部模块间服务访问-ClusterIP

刚才我们谈到,整个业务场景里面有UserMgr和OrderMgr两个微服务,那么这两个微服务之间的访问属于Kurbernetes集群内部的访问。

在这种集群内部访问场景下,即通过Service的ClusterIP即可。

对Kurbernetes中服务暴露方法的一些理解和说明

 

注意ClusterIP本身是一个虚拟IP,无法Ping通,对于该IP的访问请求实际是基于IPTables路由表和KubeProxy最终路由到具体的Pod实例节点上面。即:

Request-》ClusterIP-》IPTables+KubeProxy-》Pod Instance

如下图:

对Kurbernetes中服务暴露方法的一些理解和说明

 

在iptables代理模式下,对每个Service,它会安装iptables规则,从而捕获到达该Service的clusterIP(虚拟IP)和端口的请求,进而将请求重定向到Service的一组backend中某个上面。对于每个Endpoints对象,它也会安装iptables规则,这个规则会选择一个backend Pod。默认的策略是,随机选择一个backend。

对外提供服务-NodePort方式

如果需要对外提供服务,实际上有NodePort,LoadBalancer和Ingress多种方式。下面分别来对这几种方式做下说明。

对Kurbernetes中服务暴露方法的一些理解和说明

 

NodePort方式主要通过每个节点IP加端口的形式暴露端口,访问任意一个node ip都可以访问到(前提没有指定node调度策略),其中端口可以通过apiserver的配置文件可以看到端口暴露范围。

比如还是上面的两个微服务模块部署下去后,对于8001端口可以配置为访问UserMgr这个微服务模块。即:10.0.0.1:8001, 10.0.0.1:8002,10.0.0.1:8003。

对于NodePort这种模式,实际上仍然是将请求转发到Service上面,再通过Service路由到具体的Pod实例节点上面。唯一差异在于NodeIP是可以访问到的IP地址。

这三个地址都可以访问到用户管理这个微服务。注意一个port端口映射到一个微服务上面,比如8001映射到UserMgr微服务,8002映射到8002微服务。上面三个地址都可以外部访问到,如果客户端要统一访问,统一接入到类似Ngnix反向代理就可以了。

但是这种方式存在问题即如果新增加了Node节点,我们需要在集群或负载均衡上新增加配置信息,其次就是Node本身是附属在虚拟机上面,如果整个IaaS环境的虚拟机重启后IP地址可能发生变化,那么这个时候又需要手工进行配置。

对外提供服务-LoadBalancer方式

对Kurbernetes中服务暴露方法的一些理解和说明

 

这种方式主要是利用其他第三方的LB暴露服务的,阿里云或者亚马逊的LB等等。在这种方式下注意对于每一个微服务都会消耗一个IP,因此可能带来公有云费用的问题。其次,也不容易形成了要给统一的服务访问出口。

在这种方式下,来自外部负载均衡器的流量将直接达到 backend Pod 上,不过实际它们是如何工作的,这要依赖于云提供商。 在这些情况下,将根据用户设置的 loadBalancerIP 来创建负载均衡器。

对外提供服务-Ingress方式

对Kurbernetes中服务暴露方法的一些理解和说明

 

Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。Kubernetes使用一个Ingress策略定义和一个具体的Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器。

Ingress Controller将基于Ingress规则将客户请求直接转发到Service对应的后端Endpoint上,这样会跳过kube-proxy的转发功能,kube-proxy 不再起作用。

对于Ingress完全可以理解为整个Kurbernetes集群对外的一个网关或代理出口。把它理解为一个对外的API网关也没有问题。通过Ingress可以接入和注册各个微服务,微服务的IP访问地址意义,通过后面不同的路径和url来区分具体路由到哪个微服务上面。

对于Ingress网关的选型

可以参考:https://www.cnblogs.com/upyun/p/12372107.html

该篇文章给出了一个对比图如下:

对Kurbernetes中服务暴露方法的一些理解和说明

 

可以看到,当前Kong API网关本身也有了Kurbernetes插件后,形成了Kong Ingress,即既满足了集群节点的对外暴露,同时又包括了Kong网关的一些核心能力,包括服务注册发现,限流熔断,安全等能力都可以满足日常对API管理的需要。

简单来说,如果你是将内部微服务的API接口暴露出去给前端APP用,那么采用Kong Ingress应该是一个不错的选择。同时Kong ingress 还有一个非常大的优点,他提供了一些 API、服务的定义,去抽象成 K8S 的 CRD,所以可以很方便地通过 K8S ingress 配置,同步到 Kong 的集群。

参考:https://github.com/Kong/kubernetes-ingress-controller/tree/main/docs

在DevOps集成中能做什么?

对Kurbernetes中服务暴露方法的一些理解和说明

 

对于API网关和DevOps的协同,我在前面做过思考和整理如下。

我们首先看下什么时候需要涉及到API网关,在我们最初的概念里面是当一个业务应用需要对外发布API接口服务能力,这个对外发布可能是外部其它合作伙伴使用,也可能是我们自己的APP前端使用,只要存在这种场景往往就涉及到API网关的使用。

在一个大型项目的多团队协同下可以看到,如果都采用微服务架构,我们实际建议的是每个团队都是自己独立的微服务注册中心,负责团队内部多个微服务模块之间的API接口调用,这些API接口调用走注册中心即可。但是涉及到跨团队协同的API接口服务,那么就需要注册到API网关进行统一管理。

简单来说就是,对外发布API或者跨团队API接口调用都需要涉及将API注册接入到网关管理。

对于一个微服务模块和API网关的协同,包括了提供API接口服务注册和接入到网关,也包括了从网关调用API接口服务消费。因此需要从API注册接入和API消费调用两个方面来谈协同。

API注册接入

对于整个DevOps过程可以看到,底层是Docker容器+K8s资源调度,在我们编排流水线的时候涉及到编译构建和打包,部署等各个动作。实际上可以看到在完成自动部署后接口服务会暴露一个k8s提供出来的动态ip访问地址。而我们需要做的是将这个ip地址提供出来的访问接口,注册和接入到网关。

在整个过程搞清楚后,实际上我可以有两种方式来处理API注册接入。

  1. 在部署节点,增加自定义脚本编写,通过自定义运行的脚本来完成API接口服务的注册。
  2. 增加接口注册流水线编排节点,在部署节点完成后,编排注册节点,在API注册节点定义接口注册内容。

由于整个DevOps流水线设计和执行偏开发人员使用,可以看到,采用第一种方式往往更加灵活。唯一的就是在定义某一个流水线的时候,需要预先规划好需要接入和注册的接口内容。

而在DevOps支撑平台虽然不需要完整的API网关管控功能,但是最好还是增加一个功能,就是能够在DevOps支撑平台查询到当前已经注册和接入了哪些接口服务,注册接入后提供的代理服务地址是什么,是哪个微服务模块注册接入的该服务等基本服务目录信息。

基于前面思考,后续我们考虑就是实现Kong Ingress和K8s集群的集成,对于需要要注册的接口服务先写入配置文件,然后在K8s进行微服务部署或动态节点扩展的时候,通过API调用,将接口服务自动注册到API网关上面,实现对外访问。

API消费调用

注意在采用了API网关后带来的一个好处就是,API网关本身提供出来的API访问地址的IP是固定的,不会随着每次微服务模块的自动构建和部署动态变化。对于API网关我们会提前先部署到测试环境和生产环境,在网关部署完成后再开始进行各个微服务模块的持续集成和部署操作。

因此一个微服务模块需要访问其它微服务模块哪些接口,一个方法是每次都调用服务注册中心去查询具体的服务访问地址,一个方法就是本身要将访问地址存在在本地配置文件。更好的方法是:

  1. 首先调用先访问服务注册中心,获取服务访问地址,并存在到本地配置文件
  2. 在发现本地配置文件已经有服务访问地址后,不再从服务注册中心调用,除非得到地址变更消息通知

在这个确定后,微服务模块本身的构建打包和部署,实际上和原来没有和API网关协同是完全一样的,只是配置文件访问地址固定为了API网关提供的地址而已。如何知道API网关提供了哪些地址,即我们谈到的可以在API网关的管控平台查询,也可以在DevOps平台提供的服务目录查询功能上进行查询。


 

相关 [kurbernetes 服务 方法] 推荐:

对Kurbernetes中服务暴露方法的一些理解和说明(201001)

- - 人月神话的BLOG
由于最近在进一步整理和学习云原生解决方案的相关材料,原来一直没太理解清楚的就是kurbernetes中的网络和服务暴露方式. 在前面谈DevOps解决方案的时候就谈到,一个完整的DevOps持续集成和交付过程,需要和容器云集成,来实现自动化部署,动态弹性伸缩,环境迁移等能力. 一个DevOps支撑平台离不开和容器化PaaS平台的集成,即最终的编译构建完成的内容形成镜像并放到镜像仓库,后续部署,环境迁移,资源扩展基于镜像仓库进行快速的拷贝和复制.

(总结)NFS服务常见故障排查和解决方法

- - 服务器运维与网站架构|Linux运维|互联网研究
NFS,全名叫Network File System,中文叫网络文件系统,是Linux、UNIX系统的分布式文件系统的一个组成部分,可实现在不同网络上共享远程文件系统. NFS由Sun公司开发,目前已经成为文件服务的一种标准之一(RFC1904,RFC1813). 其最大的功能就是可以通过网络,让不同操作系统的计算机可以共享数据,所以可以把NFS看做是一个文件服务器.

Erlang服务器内存吃紧的优化解决方法

- - CSDN博客系统运维推荐文章
问题提出:服务器100万人在线,16G内存快被吃光. 查看进程数目是否正常,是否超过了erlang虚拟机的最大进程数. 查看节点的内存瓶颈所在地方. 显示内存大部分消耗在进程上,由此确定是进程占用了大量内存. (以输出text方式启动etop,其间隔为1秒,输出行数为20行,按照内存排序. 这里spawn一个新进程,目的是输出etop数据时不影响erlang shell 输入.).

linux服务器出现大量TIME_WAIT的解决方法

- - 操作系统 - ITeye博客
今天突然发现系统的访问速度变得缓慢,反复查找原因,发现服务器存在大量的TIME_WAIT连接. 通过netstat -an | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’命令进行查询,反馈结果为:. 显然TIME_WAIT 的数量过于异常.

使用Zabbix监控MySQL服务器方法

- - 行业应用 - ITeye博客
      从Zabbix 2.2开始,Zabbix官方已经支持了MySQL监控,但是MySQL监控默认是不可用的,需要经过额外的设置才可以使用. Kaijia将Zabbix换到了新的服务器时候性能绰绰有余,于是决定充分发挥剩余的内存和SSD性能,把MySQL、Apache、PHP-FPM等的监控也开起来.

squid 服务器读取出现104 connection reset by peer 解决方法 (转)

- - 开心平淡对待每一天。热爱生活
      在CDN 系统中squid 充当着举足轻重的作用,要保证cdn 网站加速系统,就要保护squid 的正常工作,下对squid 服务器读取出现104 connection reset by peer 这个原因是由什么引起的呢. 经过在百度、google中查到说是开启了防火墙,或者说是查看访问日志.

加固 WordPress 安全性的几个简单方法(服务器篇)

- - DiggLife
WordPress的安全性其实不错,但是如果服务器上不做一些基本的安全措施,Wordpress再安全也是白搭. 现在的VPS相比几年前便宜很多,很多人都买了自己的独立主机,如果不注意安全,面对满世界全天候的自动攻击脚本,网站被挂马,主机变毒瘤都是分分钟的事. 等中招之后再排查就异常困难了,因为可能有问题的点太多,逐一排查也不见得不会有漏网之鱼.

用“逐步排除”的方法定位Java服务线上“系统性”故障

- - 有道技术沙龙博客
李斯宁(高级测试开发工程师). 由于硬件问题、系统资源紧缺或者程序本身的BUG,Java服务在线上不可避免地会出现一些“系统性”故障,比如:服务性能明显下降、部分(或所有)接口超时或卡死等. 其中部分故障隐藏颇深,对运维和开发造成长期困扰. 笔者根据自己的学习和实践,总结出一套行之有效的“逐步排除”的方法,来快速定位Java服务线上“系统性”故障.

服务禁语

- tiancaicai - 白板报
前几天在一个公交汽车站拍到了一张规定,里面规定了服务禁语和礼貌用语,看了大乐. 3、乘车高峰车厢内拥挤时,禁语:“快往里走,站在前面又没有钞票检. ”文明语:“请尽量往里走,照顾没有上车的乘客”. 4、车子抛锚,禁语:“车子抛锚没有办法,人都要生毛病的,车子坏了也正常. ”文明语:“对不起,车子出现故障修一下,请大家理解.

服务熔断

- - CSDN博客推荐文章
服务熔断也称服务隔离,来自于Michael Nygard 的《Release It》中的CircuitBreaker应用模式,Martin Fowler在博文 CircuitBreaker中对此设计进行了比较详细说明. 本文认为服务熔断是服务降级的措施. 服务熔断对服务提供了proxy,防止服务不可能时,出现串联故障(cascading failure),导致雪崩效应.