k8s的service资源类型有ClusterIP、Nodeport、ExternalName、LoadBalancer、Headless(None)

2023-11-16

1. ClusterIP

是什么


ClusterIP 是在所有节点内生成一个虚拟IP,为一组pod提供统一的接入点,当service存在时,它的IP地址和端口不会发生改变,客户端通过service的ip和端口建立连接,由service将连接路由到该服务的任意一个后端pod上,通过这种方式,客户端不需要知道每个pod的具体ip,pod可以随时移除或创建,同时实现pod间的负载均衡。

Service通过使用标签选择器来指定哪些pod属于同一组。

创建service:

注意:

Port : 80 为Service 服务端口,  targetPort:8080 为POD中的容器内部端口, 一般情况下保持一致!

新的服务会分配一个集群内部IP,只能在集群内部访问,服务的主要目标是使集群内其他pod可以访问当前这种service 服务的pod,但通常也希望对外暴露服务,如何对外暴露,在文章后面有讲解

集群内部服务流转:

配置服务的会话亲和性


同一个客户端向一组pod的服务发起请求,服务每次将请求转发给不同的pod,如果希望特定的客户端产生的所有请求都指向同一个pod,可以设置服务的sessionAffinity属性为ClientIP(而不是None,None是默认值)

这种方式会将来自同一个clientIP的所有请求转发至同一个pod。

k8s仅支持None和ClinetIP两种会话亲和性配置,不支持基于cooki的会话亲和性选项,因为k8s的service不是在http层面工作,服务处理TCP和UDP包,cookie是HTTP协议的内容,所以service并不知道cookie。

同一个服务可以暴露多个端口,暴露多个端口必须为端口指定名字。

服务发现方式


客户端pod如何知道服务的IP和端口?有两种方式

1. 通过环境变量

当创建一个新pod时,k8s会初始化一系列环境变量给容器,其中包含当前存在的所有服务IP和端口,在任意一个pod容器中执行env命令,可以看到

 如上图所示,包含一个叫kubia的服务的地址和端口

2. 通过DNS发现服务(跨VPC 服务访问:coreDNS 解析

k8s的kube-system命名空间下有一个自带的dns服务组件kube-dns,集群中的所有pod都使用它作为dns,在每个容器的/etc/resolv.conf中有配置,所有pod中的进程dns查询都会被这个dns服务器响应,这个服务器知道集群中运行的所有服务。

(pod是否使用内部的dns服务器是根据pod中spec的dnsPolicy属性决定的)

客户端在知道服务名的前提下可以通过全限定域名(FQDN)来访问服务,格式为

{servicename}.{namespace}.svc.cluster.local

例如一个backend服务在default命名空间下,其域名为backend.default.svc,cluster.local,如果是在同一个命名空间下,可以省略命名空间及后面的部分

注意:直接ping service Ip是不通的,这是因为服务的集群IP是一个虚拟IP,并且只有与端口结合时才有意义。

DNS 解析文件/etc/resolv.conf 

配置domain域: 声明主机的域名,当查询不完全的域名时主机名将被使用(相当于search的默认值)

配置search域:调整/etc/resolv.conf配置文件,添加search,会顺序补全,直到有响应

 2. 就绪探针(readinessProbe)


我们已经知道pod的标签和服务选择器一样时,pod就会作为服务的后端,但是存在一种情况,pod刚启动时还没有加载好配置,或者需要执行预热防止第一个请求时间过长,这时不想让该pod接收请求。

方案是实用就绪探测器,k8s定期向pod执行探测,发现探测结果成功了才将服务转发过去。

就绪探针有三种类型

Exec探针 :在容器内执行进程,根据进程退出码决定

HTTP GET探针: 向容器发送http get请求,根据返回码决定

TCP socket探针 :向容器指定端口打开TCP连接,如果连接成功,判定为就绪

启动容器后会定期向容器执行探针操作,如果pod报告为尚未就绪,则会从对应的服务中剔除该pod,等下次探测成功后,再将pod添加到endpoints

3. headless (无头服务一般用户集群内部访问


创建服务时默认会生成一个集群IP,客户端无需知道后面有几个pod,但是如果需要具体每一个pod 的IP呢,只需要指定clusterIp为None即可,即headless,headless类型的区别就是不会为服务生成虚拟IP

 常规的服务通过DNS服务器获得servicename.namespace.svc.cluster.local的是集群IP,而headless服务获取该域名的实际IP是所有后台pod的IP列表。

从客户端角度来看headless与常规服务并无不同,但是对于headless服务,由于DNS返回了pod的IP,客户端直接连接到pod,而不是通过服务代理。

headless仍然提供跨pod负载均衡,但是是通过DNS轮询机制不是通过服务代理。

连接集群外部服务的方式:手动配置Endpoint、使用ExternalName 为外部服务创建别名。


1. Endpoint


服务service和pod并不是直接相连的,它们之间有个Endpoint资源,Endpoint资源就是一组pod的ip地址和端口的列表,和其他k8s资源一样,可以通过kubectl get endpoints 查看信息。

在Service的spec中定义的pod选择器,不是由服务直接使用,而是用于构建IP和端口列表,然后存储在Endpoint资源中。

如果创建服务时不指定选择器,将不会创建Endpoints(没有选择器不知道服务该包含哪些pod),这样可以分别手动配置它们。

为没有选择器的服务创建Endpoint资源,注意Endpoint是一个独立的资源,并不是Service的属性,由于Service没指定选择器,所以需要手动创建Endpoint

 Endpoint对象需要与服务同样的名称,并包含目标IP地址和端口列表,这样服务就可以和有选择器一样正常使用了。将IP配置为外部服务,就可以连接外部服务了

2. ExternalName (跨VPC 外部服务访问)


创建外部服务的别名,创建service时指定type字段为ExternalName,例如有一个外部服务域名为api.somecompany.com

服务创建后可以通过external-service.defaul.svc.cluster.local 连接外部服务,ExternaleName服务仅在DNS级别实施,为服务创建了简单的CNAME DNS记录,因此,连接到服务的客户端将直接连接到外部服务,完全绕过服务代理。出于这个原因,这些类型的服务不会有集群IP.

CNAME 记录指向完全限定的域名而不是数字IP地址。

暴露服务的几种方式:Nodeport、LoadBalancer、Ingress↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


4. Nodeport


创建Servcie时指定type为Nodeport,会在所有集群节点上开一个相同的端口,创建Nodeport时的同时会创建ClusterIP,指定端口不是强制的,如果忽略,集群会自动分配一个

 在集群内部可以通过clusterip访问,集群外部通过节点IP:nodeport 访问。到达任何一个节点的连接将会被重定向到一个随机的pod,该pod不一定是位于接收节点的Pod.

 如果集群外部的客户端总是指向某个指定节点,那么当这个节点故障时将无法访问,因此节点前面需要一个负载均衡器,以保证发送的请求传播到健康的节点。

5. loadbalancer


负载均衡器

负载均衡器拥有一个可公开访问的IP地址,并将连接重定向到服务。需要注意的是 ,loadbalancer需要额外的基础设施支持,如果环境不支持,则不会调负责均衡器,该服务就像一个Nodeport服务一样了。

防止不必要的网络跳数
当外部客户端通过节点端口(包括使用负载均衡的情况),随机选择的pod不一定和接收连接在同一个节点,需要额外的网络跳转,可以在服务的sepc中设置亲和性为local避免这种情况

 弊端是这样必须要保证节点都有Pod,如果节点没有pod,连接会被挂起。同时会出现pod负载不均衡,如下图

获取客户端IP
在集群内访问服务时,服务端可以获取客户端地址,但是通过节点端口访问时,由于发生了源网络地址转换(SNAT),因此数据包的源IP地址发生了更改。使用上述的Local策略可以保留源IP,因为接收连接的节点和pod节点没有额外的跳跃(不执行SNAT)。

6. Ingress


上文介绍的LoadBalancer需要自己的负载均衡器,以及独有的公网IP地址,而Ingress只需要一个公网IP就能为许多服务提供访问。当客户端向Ingress发送http请求时,Ingress会根据请求的主机名和路径决定要发送的服务。

 Ingress在应用层工作,可以提供基于cookie的会话亲和性功能。

Ingress必需要Ingress控制器才能运行,不同的k8s环境使用不同的控制器实现,首先要确保环境启用了Ingress控制器。

  

上图定义了一个单一规则的Ingress,Ingress控制器收到的请求主机kubia.example.com的请求会被发送到kubia-noport服务的80端口。

获取Ingress的IP地址:

 配置DNS服务器将kubia.example.com指向得到的IP,或者在客户端 /etc/hosts文件中配置。

将不同服务映射到同一主机名的不同路径下:

将不同服务映射到不同主机名下:

排除服务故障思路:


服务是k8s的重要概念,也是让许多开发感到困惑的根源。许多开发同学为了弄懂无法通过服务IP或FQDN连接到pod的原因花了大量时间。了解如何排序服务故障是有必要的,如果无法访问pod,排查如下:

首先, 确保从集群内连接到服务的集群IP,而不是从外部
不要通过ping服务IP 来判断服务是否可访问(请记住,服务的集群IP是虚拟IP, 是无法ping通的)。
如果已经定义了就绪探针, 请确保 它返回成功;否则该pod不会成为服务的一部分 。
要确认某个容器是服务的一部分, 请使用kubectl get endpoints来检查相应的端点对象。
如果尝试通过FQDN或其中一部分来访问服务(例如,myservice.mynamespace.svc.cluster.local或 myservice.mynamespace), 但
并不起作用, 请查看是否可以使用其集群IP而不是FQDN来访问服务 。
检查是否连接到服务公开的端口,而不是目标端口 。
尝试直接连接到podIP以确认pod正在接收正确端口上的 连接。
如果甚至无法通过pod的IP 访问应用, 请确保应用不是仅绑定 到本地主机。
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k8s的service资源类型有ClusterIP、Nodeport、ExternalName、LoadBalancer、Headless(None) 的相关文章

  • 如何打印整个字符串池?

    我想打印包含文字的整个字符串池String使用添加的对象intern 就在垃圾收集之前 JDK有没有隐式的方法来进行这样的操作 我们如何检查字符串池 EDIT The comment suggests that there may be a
  • 将链接对象转换为流或集合

    我想迭代堆栈跟踪 堆栈跟踪由可抛出对象组成 其 getCause 返回下一个可抛出对象 最后一次调用 getCause 返回 null 示例 a gt b gt null 我尝试使用 Stream iterable 这会导致 NullPoi
  • 由于连接超时,无法通过 ImageIO.read(url) 获取图像

    下面的代码似乎总是失败 URL url new URL http userserve ak last fm serve 126 8636005 jpg Image img ImageIO read url System out printl
  • MI设备中即使应用程序被杀死,如何运行后台服务

    您好 我正在使用 alaram 管理器运行后台服务 它工作正常 但对于某些 mi 设备 后台服务无法工作 我使用了服务 但它无法工作 如何在 mi 中运行我的后台服务 MI UI有自己的安全选项 所以你需要的不仅仅是上面提到的粘性服务 你需
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • Java 重写 hashCode() 得到 StackOverflowError

    所以我不太熟悉重写 hashCode 并且我似乎在 hashCode 方法中以某种方式进行了一些无限递归 这是我的场景 我有一个 DuplicateCache 类 它是一个缓存对象 用于检查系统中的重复对象 我有一个静态内部类 Duplic
  • Java:从元素创建 DOM 元素,而不是文档

    如您所知 在 Java 中创建 Dom 元素的正确方法是执行以下操作 import org w3c dom Document import org w3c dom Element Document d Element e e d creat
  • Spring Stomp over Websocket:流式传输大文件

    我的SockJs客户端在网页中 发送帧大小为16K的消息 消息大小限制决定了我可以传输的文件的最大大小 以下是我在文档中找到的内容 Configure the maximum size for an incoming sub protoco
  • 为什么我在 Mac 上看到“java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int)accessibl

    我已经在工作中愉快地构建代码好几天了 但突然我的一个项目 不是全部 失败并出现此错误消息 看看下面的答案吧 我是如何修复它的 起初我用谷歌搜索 看到很多有这个问题的人正在使用 Java 16 但我认为 错误 我正在使用 Java 11 因为
  • Install4j:如何在安装结束时执行命令行 java -jar filename.jar

    在 Intall4j 中 在安装结束时 我只想通过执行如下命令行来初始化某些内容 java jar filename jar 我怎样才能归档这个任务install4j Thanks 将 运行可执行文件或批处理文件 操作添加到 安装屏幕 并设
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • 不兼容的类型:在 java netbeans 中对象无法转换为 String

    我试图在我的项目中使用对象数组 但出现错误 incompatible types Object cannot be converted to String 在这一行 ST1 new String emt1 emt2 emt3 emt4 现在
  • 从 Stax XMLStreamReader 读取以解组部分

    我正在使用 Stax 游标 API 从大型 xml 文件中提取数据 当前 我转到特殊标签的开头并使用 JAXB 解组该标签 这对于格式良好的 xml 文件效果很好 但不久前我有一个文档 其中数十万个标签中有一个未关闭 JAXB 使用 XML
  • 如何在keycloak中动态编辑standalone.xml文件

    我正在尝试通过 docker 编辑standalone xml 并尝试添加 但 keycloak 正在使用它standalone xml 但我可以看到standalone xml 文件中的更改 我需要在standalone xml 文件中添
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一
  • 我想要一个 Java 阿拉伯语词干分析器

    我正在寻找阿拉伯语的 Java 词干分析器 我找到了一个名为 AraMorph 的库 但它的输出是无法控制的 并且它会形成不需要的单词 还有其他阿拉伯语词干分析器吗 这是新的阿拉伯语词干分析器 Assem 的阿拉伯语轻词干分析器 http
  • Spock模拟inputStream导致无限循环

    我有一个代码 gridFSFile inputStream bytes 当我尝试这样测试时 given def inputStream Mock InputStream def gridFSDBFile Mock GridFSDBFile
  • 从一个文本文件中获取数据并将其移动到新的文本文件

    我有一个文件 里面有数据 在我的主要方法中 我读入文件并关闭文件 我调用另一种方法 在原始文件的同一文件夹内创建一个新文件 所以现在我有两个文件 原始文件和通过我调用的方法生成的文件 我需要另一种方法 从原始文件中获取数据并将其写入创建的新
  • Java 推断泛型类型

    我正在寻找类似的推断捕获泛型类型的概念 类似于以下方法片段 但不是捕获泛型类型的类 public
  • java中如何找到class文件的包

    我正在编写一个使用 class 文件的 java 程序 我希望能够读取文件系统上的 class 文件 使用 InputStream 并确定它所在的包 该 class 文件可能不在一个好的包目录结构中 它可能位于某个随机位置 我怎样才能做到这

随机推荐

  • Redis下载部署并加入idea应用(详细笔记)

    文章目录 前言 一 下载Window版本的redis 1 打开网址 github上的redis安装包 https github com microsoftarchive redis 找到Redis on Windows 点击 release
  • java stream流常用方法

    Stream流用法 1 分组 2 过滤 3 List map互转 4 求和 极值 5 求最大 最小值的对象 6 去重 7 排序 8 拼接 9 统计 10 平均值 11 某个值的数量 12 分区 13 截断 14 跳过 15 查找与匹配 16
  • Unity Shader入门精要第四章:Unity Shader 的内置变量(数学篇)

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一 4 8 1 变换矩阵 二 4 8 2 摄像机和屏幕参数 4 9 答疑解惑 扩展阅读 参考 前言 使用Unity 写Shader 的一个好处在于 它提供了很多内置的参数 这使
  • typora+pandoc:markdown文本转换成word(也可把word转换成markdown哦)

    因为想把自己写的博客转换成word 博客是markdown格式 公式什么的又懒得在word里面敲第二遍 于是就找了个方法让 md文本与 doc文本转换 反之也可把word转换成markdown哦 教程附后 markdown文本转换成word
  • SyntaxError: Cannot use import statement outside a module

    SyntaxError Cannot use import statement outside a module 错误展示 问题 使用 vs code 调试js 代码 出现 SyntaxError Cannot use import sta
  • Maven的从入门到精通(完结篇)

    Maven的从入门到精通 完结篇 一 maven工程运行调试 1 1 端口占用处理 1 2 断点测试 二 总结 2 1 maven仓库 2 2 常用的maven命令 2 3 坐标定义 2 4 pom 基本配置 本文是Maven学习中的完结篇
  • (转载)Flutter、Weex、React Native和Android原生对比报告

    Flutter Weex React Native和Android原生对比报告 Zhang Jun的博客 CSDN博客
  • docker 通过中间镜像加速部署

    概要 实施 修改前的实施时间 制作编译用的镜像 测试修改后的实施时间 概要 使用 docker 打包镜像的时候 每次耗费时间最多的就是 docker build 的过程 特别是对于前端工程的打包 有时候下载依赖包的时间就要 10 几分钟 这
  • MySql数据库实验知识点:

    实验一 创建以下数据库和表 并查看是否成功创建 目的与要求 1 了解 mysql 数据库的存储引擎分类 2 了解表的结构特点 3 了解 mysql 的基本数据类型 4 了解空值概念 5 学会使用 sql 语句创建数据库和表 实验内容 1 实
  • nginx高性能原因

    epoll多路复用 BIO 堵塞式IO 缺点 client和server一旦建立连接 就可以建立通信套接字在这个通信套接字上进行读写操作 此时不能再接收其他客户端连接请求 只能等待同当前连接的客户端的操作执行完成 select模型 缺点 变
  • 第四章 神经网络知识扩展

    1 其他的神经网络学习算法 1 1介绍 梯度下降算法并不是神经网络的唯一算法 还有其他算法 我们喜欢称他们为优化器 Optimizer 优化器就是优化网络的机器 主要有以下几种 1 2SGD优化器 SGD优化器全称为随机梯度下降算法 可以简
  • Java Web 学习笔记 06 Servlet 案例(get、post,转发与重定向)

    Servlet 案例 get post 转发与重定向 案例一 初体验 Servlet web项目 案例二 get 和post 提交流程 编码 1 get和post的区别 乱码问题 2 实例 案例三 转发与重定向 案例一 初体验 Servle
  • Vision Transformer论文精读(2/2)

    目录 一 主题 3 1模型总览图 3 2 微调 二 实验部分 三 回顾总结 四 参考链接 一 主题 在模型的设计上 是尽可能的按照最原始的Transformer来做的 这样的一个好处是我们可以直接把NLP那边已经成功地Transformer
  • 博客园美化

    写在前面 前面的文章中提到过 自己开始在博客园上更新文章 说也奇怪 自己博客园账号注册了好久 都没在上面更新过博客 直到前段时间博客园的求助信息火了 才对博客园有了全新的认知 博客园一个最大的特点就是简洁 干净 广告少 但也有一个个人认为很
  • sqli-less-26-less26a

    less 26 单引号 GET型 这关就有点过滤的意思了 过滤了上一关的东西 并且把空格和 23给过滤了 如果是ubuntu的话 可以用 0a等绕过 方便一些 但我的是windows 所以就只能用 了 让后使用 来代替and 用 1来闭合
  • 树莓派显示器截图方法大全(适用于Linux-C,可扩展开发)

    树莓派显示器截图方法大全 适用于Linux C 可扩展开发 文章目录 树莓派显示器截图方法大全 适用于Linux C 可扩展开发 1 前言 2 shutter 3 scrot 4 raspi2png 5 fb2png 6 最后 1 前言 有
  • Oracle阻塞会话源头查找-单机和RAC环境

    在写 Oracle session相关数据字典 一 这篇文章时 提到使用v session视图的树形查询可以得到Oracle锁树 这样就便于我们找出阻塞会话的源头 但是仅仅可以在单机环境中使用 今天把单机和RAC的阻塞树都整理了一下 话不多
  • kotlin高阶函数开发一个程序,统计文本中字符串出现的个数

    一 高阶函数是Kotlin的核心部分 下面来使用下高阶函数写一个程序 注意 我这里的File使用的是 与src同级的文件 你可以根据自己的需要 修改文件地址 代码实例 package net println kotlin chapter5
  • 如何完整地掌握一个机器学习模型

    如何完整地掌握一个机器学习模型 要全面地学习 掌握一个机器学习模型 可以遵循以下步骤 基础理论学习 了解该模型的背后数学原理和推导过程 包括假设 损失函数 优化方法等 学习算法实现 通过查阅论文 教程或开源代码 了解算法的具体实现过程 尝试
  • k8s的service资源类型有ClusterIP、Nodeport、ExternalName、LoadBalancer、Headless(None)

    1 ClusterIP 是什么 ClusterIP 是在所有节点内生成一个虚拟IP 为一组pod提供统一的接入点 当service存在时 它的IP地址和端口不会发生改变 客户端通过service的ip和端口建立连接 由service将连接路