公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。

对k8s有点了解技术人员,应该都只知道k8s是有服务注册发现的,今天就分析下这个原理,看看怎么实现的。

什么是服务注册与发现

服务注册与发现是一种机制,用于在集群中动态地发现和连接不同的服务,比如我们在开发微服务时,经常使用的EurekaNacos



Service B 把自己注册到 Service Registry 叫做 服务注册

Service A 从 Service Registry 发现 Service B 的节点信息叫做 服务发现

K8s 中为什么需要服务发现

动态性

在K8s集群中,Pod和服务的数量和位置都是动态变化的,Pod有可能伸缩、重新部署或迁移,在这样的环境下,如果硬编码的服务地址是不可行的,所以服务注册与发现使得我们的系统能够自动感知到这种变化。

透明性

服务注册与发现使得我们的系统可以使用服务名称来访问其他服务,而不需要关心具体的IP地址和端口号。

负载均衡

通过服务注册与发现可以实现负载均衡,将请求均匀地分发到多个后端服务实例。

容错性

当服务实例发生故障或不可用时,服务注册与发现可以自动检测并从服务发现机制中移除不可用的实例。这样,请求将被自动路由到可用的实例上,提高应用程序的容错性和可用性。

k8s 服务注册发现原理

基于上面的介绍,我们了解到K8s中的Pod的生命周期是短暂的,他们的IP地址会不断变化,如果让服务消费方去管理这些Pod IP在做负载均衡调用Pod,那么会很复杂,为了对外提供统一的入口来提供服务,所以k8s创建了Service,不管是内部还是外部统一调用 Service,然后再由 Service 转发到后端Pod

Endpoints

Pod 的地址管理则由Endpoints管理,根据Service名称可以查询Endpoints信息,当通过API创建/修改service对象时,endpoints控制器的监听到Service对象,然后根据Service的配置的选择器创建一个endpoints对象,此对象将pod的IP、容器端口信息存储到etcd中。

他们之间关系如下:

同时Endpoints控制器会监听与Pod相关的事件,包括上下线事件,一旦Endpoints控制器接收到这些事件,它会相应地更新Endpoints资源,将不可用的Pod从Endpoints列表中移除。

域名解析

由于Service的 IP有可能会变,如果在代码里面写死Service IP后期维护起来也是比较麻烦的事情,所以通过在创建一个Service时,CoreDNS会为该Service添加一个域名解析记录,将Service的名称解析为相应的Cluster IP地址。这样其他Pod或服务可以通过使用Service名称来访问该Service。

kube-proxy

kube-proxy 是集群中每个节点上运行的网络代理,它负责将集群内部的Service暴露给其他Pod或外部网络。它通过在Node节点上设置网络规则和转发规则,将Service的请求转发到正确的目标Pod

同时kube-proxy实现负载均衡算法,将进入Service的请求均匀地分发到后端的Pod实例。这确保了在多个副本的情况下,Service能够平衡地处理请求,提高可用性和性能。

kube-proxy 通过监听知道了Service、endpoints对象的创建,然后把ServiceCLUSTER-IP 和端口信息拿出来,创建iptables NAT规则做转发或通过ipvs模块创建VS服务器,这样经过CLUSTER-IP的流量都被转发到后端pod。



当Service的目标Pod位于同一节点上时,kube-proxy会将请求直接转发到该节点上的Pod,而不会跨节点转发。这种情况下,请求不会被发送到其他节点上。

然而,如果Service的目标Pod分布在多个节点上,kube-proxy可以通过负载均衡算法将请求转发到其他节点上的Pod。

示例演示

下面我们基于两个配置文件,验证下上面的结论

nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: mirrorgooglecontainers/serve_hostname
ports:
- containerPort: 80

serve_hostname是k8s官方提供的debug镜像,返回hostname的web server,访问pod时会返回hostname。

nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- name: service-port
port: 80
protocol: TCP
targetPort: 9376
selector:
app: nginx
type: ClusterIP

可以看到service 的selector属性指定了app: nginx,这样就能匹配 deplyment 中定义的 nginx pod

我们依次执行以上两个文件,最后获取到信息如下

Service地址查看

kubectl get svc nginx-service

Pod信息查看

 kubectl get pods -l app=nginx -o wide

Endpoints信息查看

根据service名称查询

kubectl get ep nginx-service

CoreDNS信息验证

登录任意Pod,执行ping命令,可以看到根据Service 名称解析到了Service cluster ip

负载均衡验证

登录任意 pod,执行curl nginx-service,请求 service的 80 端口,会返回目标 pod名称

以上我们讲了什么是服务发现,以及 k8s 的服务发现是怎么实现的,希望对你有所帮助。

Kubernetes 中的服务注册与发现原理分析的更多相关文章

  1. Zookeeper服务注册与发现原理浅析

    了解Zookeeper的我们都知道,Zookeeper是一种分布式协调服务,在分布式应用中,主要用来实现分布式服务的注册与发现以及分布式锁,本文我们简单介绍一下Zookeeper是如何实现服务的注册与 ...

  2. nacos服务注册与发现原理解析

    前言:nacos 玩过微服务的想必不会陌生,它是阿里对于springcloud孵化出来的产品,用来完成服务之间的注册发现和配置中心,其核心作用我就不废话了 大致流程:每个服务都会有一个nacos cl ...

  3. 【Consul】 分布式环境中的服务注册和发现利器

    参考资料: http://www.cnblogs.com/shanyou/p/4695131.html http://blog.csdn.net/viewcode/article/details/45 ...

  4. Spring Cloud 入门教程 - Eureka服务注册与发现

    简介 在微服务中,服务注册与发现对管理各个微服务子系统起着关键作用.随着系统水平扩展的越来越多,系统拆分为微服务的数量也会相应增加,那么管理和获取这些微服务的URL就会变得十分棘手,如果我们每新加一个 ...

  5. 微服务注册与发现 —— eureka

    基础概念 在微服务系统中,服务的注册和发现是第一步,常用的有: Eureka:https://github.com/Netflix/eureka Zookeeper:https://zookeeper ...

  6. Spring Cloud Alibaba 实战 之 Nacos 服务注册和发现

    服务注册与发现,服务发现主要用于实现各个微服务实例的自动化注册与发现,是微服务治理的核心,学习 Spring Cloud Alibaba,首先要了解框架中的服务注册和发现组件——Nacos. 一.Sp ...

  7. 从零开始入门 | Kubernetes 中的服务发现与负载均衡

    作者 | 阿里巴巴技术专家  溪恒 一.需求来源 为什么需要服务发现 在 K8s 集群里面会通过 pod 去部署应用,与传统的应用部署不同,传统应用部署在给定的机器上面去部署,我们知道怎么去调用别的机 ...

  8. Kubernetes 中的服务发现与负载均衡

    原文:https://www.infoq.cn/article/rEzx9X598W60svbli9aK (本文转载自阿里巴巴云原生微信公众号(ID:Alicloudnative)) 一.需求来源 为 ...

  9. 🏆【Alibaba中间件技术系列】「Nacos技术专题」服务注册与发现相关的原理分析

    背景介绍 前几篇文章介绍了Nacos配置中心服务的能力机制,接下来,我们来介绍Nacos另一个非常重要的特性就是服务注册与发现,说到服务的注册与发现相信大家应该都不陌生,在微服务盛行的今天,服务是非常 ...

  10. 024.微服务架构之服务注册与发现(kubernetes / SpringCloud)

    微服务 微服务是一种架构模式,一种分布式的架构风格. 顾名思义,micro service,将一个庞大的单体应用拆分成若干个“微小”的服务,服务间通过进程通讯完成原本在单体应用中的调用. 其中必要的六 ...

随机推荐

  1. 需求太多处理不过来?MoSCoW模型帮你

    一.MoSCoW模型是什么 MoSCoW模型是在项目管理.软件开发中使用的一种排序优先级的方法,以便开发人员.产品经理.客户对每个需求交付的重要性达成共识. MoSCoW是一个首字母缩略词,代表: M ...

  2. 从read 系统调用到 C10M 问题

    一.前言 从上个世纪到现在,工程师们在优化服务器性能的过程中,提出了各种不同的io模型,比如非阻塞io,io复用,信号驱动式io,异步io.具体io模型在不同平台上的实现也不一样,比如io复用在bsd ...

  3. redis数据持久化之RDB和AOF

    前言 redis虽然是内存缓存程序,但是可以将内存中的数据保存到硬盘上,从而实现数据保存.目前有两种redis数据持久化方式,分别是RDB和AOF. RDB模式 RDB之简介 RDB(redis da ...

  4. 不重启Docker能添加自签SSL证书镜像仓库吗?

    应用背景 在企业应用Docker规划初期配置非安全镜像仓库时,有时会遗漏一些仓库没配置,但此时应用程序已经在Docker平台上部署起来了,体量越大就越不会让人去直接重启Docker. 那么,不重启Do ...

  5. pytest-xdist分布式测试原理浅析

    pytest-xdist执行流程: 解析命令行参数:pytest-xdist 会解析命令行参数,获取用户指定的分发模式.进程数.主机列表等信息. 加载测试用例:pytest-xdist 会加载所有的 ...

  6. 2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为 n - 1 的二维整数数组 edges , 其中 edges[i] =

    2023-09-03:用go语言编写.给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为 n - 1 的二维整数数组 edges , 其中 edges[i] ...

  7. Mybatis plus配置MetaObjectHandler无效

    项目环境 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-b ...

  8. js获取当前月的天数

    //取得本月天数(实际代码:) var now=new Date(); var d = new Date(now.getFullYear(),now.getMonth()+1,0); var days ...

  9. 关于MySQL获取自增ID的几种方法

    1. Select Max(id) From Table; 通过取表字段最大值的方式来获取最近一次自增id 缺点: 这种方法在多人操作数据库的软件上不可靠, 举个例子, 你刚插入一条记录. 当你在查询 ...

  10. 在线问诊 Python、FastAPI、Neo4j — 创建症状节点

    目录 症状数据 创建节点 附学习 电子病历中,患者主诉对应的相关检查,得出的诊断以及最后的用药情况.症状一般可以从主诉中提取. 症状数据 symptom_data.csv CSV 中,没有直接一行一个 ...