目录

一、定义Service

  1.1 type=ClusterIP

   1.2 type=NodePort

   1.3 type=LoadBalancer

   1.4 type=ExternalName

   1.5 无标签选择器的Service

   1.6 Headless Service

二、Kubernetes的服务发现

   2.1 环境变量方式

   2.2 DNS方式


        Kubernetes 中 Service 是 将运行在一个或一组 Pod 上的应用程序对外暴露出去的方法。这样多个相同功能容器可以对外提供统一的访问入口。

       Service解决了:

  • 避免直接访问Pod,因为Pod的数量和IP都可能发生变化。而通过Service可以提供稳定的统一入口。
  • 提供了负载均衡机制(包括后端Pod自动注册和发现)

一、定义Service

    定义Service的yaml常见字段含义说明如下:

apiVersion: v1
kind: Service
metadata:name: namespace:labels: []anotations: []
spec:selector: []             # 标签选择器,选择满足条件的后端Podtype:                    # Service的公开暴露类型,type可取值(首字母大写):ClusterIP默认、NodePort、LoadBalancer、ExternalNameclusterIP:               # 分配给该Service的IP地址列表。type=ClusterIP或NodePort时,若不手动指定IP则自动分配(在kubeadm init指定的网段范围内);若填值None则为Headless服务sessionAffinity:        # 可取值:ClientIP、None默认。若配置为ClientIP表示对收到同个客户端IP的访问请求每次都转发到同个后端Pod上。ports:                   # 端口列表,列表多个须分别指定端口的name- name:                  # 端口名。若仅有一个port,可不设置此字段protocol:              # 协议。可取值: TCP默认、UDP、SCTPport:                  # Service在clusterIP上的监听端口nodePort:              # 当type=NodePort或LoadBalancer时,在每个节点机器上的分配端口(端口允许范围30000-32767)。targetPort:            # 转发至后端Pod上的端口,若未指定则等于port
status:                    # 当type=LoadBalancer时设置外部负载均衡器地址,比如公有云环境loadBalancer:            # 外部负载均衡器ingress:               # 外部负载均衡器ip:                  # 外部负载均衡器的IP地址hostname:            # 外部负载均衡器的主机名

  1.1 type=ClusterIP

在前文【Kubernetes(三):Workload工作负载-CSDN博客】已经创建Deployment的基础上(Pod的标签是app=nginx, Pod内容器端口为80)。然后通过以下nginx-service.yaml文件,创建一个Service:

apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:                # 标签选择器,选择满足条件的后端Podapp: nginxtype: ClusterIPports:- port: 55580            # Service在clusterIP上的监听端口targetPort: 80         # 转发至后端Pod上的端口,若未指定则等于port
kubectl apply -f nginx-service.yaml# 以下service可简写svc
kubectl get service -o widekubectl describe service/nginx-service

注:kube-apiserver本身也是一个Service,名字为kubernetes。 该service的ClusterIP是地址池中第一个IP,端口是HTTPS的443。如上图。

Service中的Endpoints是后端Pod的地址列表。如果Pod发生变化,Kubernetes会自动维护Service的EndPoints地址列表,自动保持最新。

Kubernetes集群内(包括集群节点机器、Pod容器内)可通过命令访问Service的虚拟IP和端口来访问后端的Pod:curl http://172.16.242.61:55580

默认情况,访问请求会被Service均衡分发给后端Pod之一。

   1.2 type=NodePort

     在上文type=ClusterIP的例子中,因为值在服务虚拟IP(clusterIP)上监听,所以只能在Kubernetes集群内(包括集群节点机器及容器内)才能访问到该Service。

    若希望从Kubernetes集群外也可以访问Service,则需把改type=NodePort。NodePort是建立在type=ClusterIP的基础上,并在每个节点机器上分配一个nodePort端口。通过该nodePort端口访问的请求,Service也可以分发到与后端Pod的Endpoints。

apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:                # 必选。标签选择器,选择满足条件的后端Podapp: nginxtype: NodePortports:- port: 55580            # Service在clusterIP上的监听端口nodePort: 32000        # 当type=NodePort或LoadBalancer时,在每个节点机器上的分配端口(端口允许范围默认30000-32767)。targetPort: 80         # 转发至后端Pod上的端口,若未指定则等于port
kubectl apply -f nginx-service.yaml# 以下service可简写svc
kubectl get service -o widekubectl describe service/nginx-service

不仅可以从Kubernetes集群内(包括集群节点机器、Pod容器内)可通过命令访问Service的虚拟IP和端口来访问后端的Pod:curl http://172.16.167.197:55580

并且还可以从Kubernetes集群外访问,访问地址为:任意一个节点机器IP:nodePort   如下图:

虽然可以通过节点机器IP访问,但在节点机器操作系统上通过netstat命令是无法看到nodePort侦听端口。这是因为没有采用通常的直接监听方式,而是kube-proxy利用操作系统的代理模式来转发。

kube-proxy的--proxy-mode选项指定转发的代理模式,当节点机器是Linux则可为ipvs或iptables模式(不手工指定时,若Linux操作系统加载启用了IPVS内核,kube-proxy会自动优先选择IPVS模式,否则切换iptables模式);当节点机器是Windows则为kernelspace模式。

   1.3 type=LoadBalancer

     type=LoadBalancer是基于NodePort的基础上构建并创建一个外部负载均衡器,通过该外部负载均衡器路由到与 clusterIP 相同的 Endpoints。

    type=LoadBalancer主要用于云平台环境。Service使用云平台负载均衡器,Kubernetes不直接提供负载均衡。这要求云平台能够监控Kubernetes的Service资源对象创建过程,云平台负载均衡器中upstream值自动配置为Service的Endpoints列表,同时云平台还能对Kubernetes的Service的Status信息补充配置好的负载均衡器的IP地址。这样外部客户端就可以通过云平台负载均衡器IP及Service端口进行访问后端Pod服务了。

    默认情况:对于type=LoadBalancer的Service会默认开启节点机器NodePort,这是为了让负载均衡器能够通过Node节点IP来访问内部Pod。 从v1.24版开始,Service配置中提供了一个布尔类型字段allocateLoadBalancerNodePorts来指定是否分配NodePort(默认为true)。仅当云平台负载均衡器能够直接将流量路由到 Pod 而无需使用节点机器端口的情况才设置为false。

   1.4 type=ExternalName

     type=ExternalName是将 Service 映射到指定的目标域名或IP。相当于对目标域名或IP设置别名。

  下面externalname-service.yaml

apiVersion: v1
kind: Service
metadata:name: externalname-service
spec:type: ExternalNameexternalName: www.baidu.com
kubectl apply -f externalname-service.yaml# 以下service可简写svc
kubectl get service -o widekubectl describe service/externalname-service

注:type=ExternalName的Service没有Endpoints,也没有为服务分配ClusterIP。

Kubernetes对服务自动生成的域名格式为:<ServiceName>.<namespace>.svc.<clusterDomain> 

Kubernetes集群内(包括集群节点机器、Pod容器内)可通过该服务域名访问,既自动访问externalName指定的目标域名。本例中访问 curl http://externalname-service.default.svc.cluster.local  相当于访问www.baidu.com

   1.5 无标签选择器的Service

    上文type=ExternalName的Service没有Endpoints,也没有为服务分配ClusterIP。 除上文外,还可以通过基于type=ClusterIP类型来将外部服务定义为Service,这种将外部服务定义为Service也称为没有标签选择器的Service (Services without selectors)。

     普通type=ClusterIP的Service通过selector标签选择器对后端Pod的Endpoints列表进行了抽象封装,如果后端的Endpoints不是由Pod提供,而是在Kubernetes之外的其他服务提供。在Kubernetes里的一些应用也需要访问这些外部服务,典型场景为:

  • 非Kubernetes管理的服务。例如单独部署的数据库、Redis、或者其他服务。
  • 从一个Kubernetes集群访问另一个Kubernetes集群。

本场景中,在创建Service时不设置selector标签选择器(也无后端Pod可选)。由于此 Service 没有选择器,因此不会自动创建对应的 EndpointSlice 对象。需要手工在EndpointSlice定义外部服务的IP地址和端口号。

注意:从v1.33版开始,Endpoints已被标记为deprecated。所以低版本Kubernetes可使用Endpoints,高版本Kubernetes应当使用EndpointSlice。

为演示,先通过python启动简易Web,模拟已存在的外部服务

# 若python版本为2.x
python -m SimpleHTTPServer 9999# 若python版本为3.x
python -m http.server 9999

下面outside-service.yaml

---
apiVersion: v1
kind: Service
metadata:name: outside-service
spec:ports:- port: 21212            # Service在clusterIP上的监听端口targetPort: 1111       # 此情况因为不使用targetPort,所以配成什么端口都无所谓
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:name: outside-service    # 习惯上,将Service名称作为EndpointSlice名称前缀labels:# 须设置 "kubernetes.io/service-name" 标签,以选择匹配Servicekubernetes.io/service-name: outside-service
addressType: IPv4          # 取值范围:IPv4、IPv6、FQDN
ports:                     # 若列表多个须分别指定端口name(且name值须与Service中spec.ports.name字段值匹配一致)- port: 9999
endpoints:  # 此列表中的 IP 地址可以按任何顺序显示- addresses:- "192.168.43.49"
kubectl apply -f outside-service.yaml# 以下service可简写svc
kubectl get service -o widekubectl describe service/outside-servicekubectl get endpointslices

可以在Kubernetes集群内(包括集群节点机器、Pod容器内)可通过命令访问Service的虚拟IP和端口来访问外部服务。curl http://172.16.155.209:21212

   1.6 Headless Service

    在某些场景场景中,不需要Service提供负载均衡功能,也不需要Service的ClusterIP。而是直接对后端Pod进行指定访问,因此只需要Service为后端每个Pod生成一个子域名。这是可以创建一个与普通Service不同的Headless Service。Headless Service既是没有入口访问地址(服务无ClusterIP),kube-proxy不会为其创建负载转发规则。

    有标签选择器的Headless Service

    如果Headless Service配置了标签选择器,则Kubernetes根据匹配选择的后端Pod,自动创建Endpoints列表。此Headless Service会将DNS解析机制设为:①服务域名可得到后端所有Pod的IP列表(而不是单独的一个ClusterIP);②还会为每个Pod都创建一个子域名,便于对特定某个Pod进行指定访问或识别。

   示例可以参考:https://blog.csdn.net/zyplanke/article/details/150985065 中StatefulSet章节。

    无标签选择器的Headless Service

    如果Headless Service没有配置标签选择器,则Kubernetes不会自动创建对应的Endpoints列表。Kubernetes的DNS会根据如下条件尝试对该Service设置DNS解析:

  • 对于 type=ExternalName,将配置的externalName尝试作为对应的 CNAME 记录。
  • 对所有其他类型的 Service,对Service后端处于Ready状态的Endpoints既Endpointslices创建DNS记录。对于 IPv4 端点,DNS 系统创建 A 记录; 对于 IPv6 端点,DNS 系统创建 AAAA 记录。

二、Kubernetes的服务发现

    对于在集群内运行的客户端,Kubernetes 支持两种Service发现模式:环境变量和DNS。

   2.1 环境变量方式

    当 Pod 运行时,kubelet 会自动为其注入以“KUBERNETES_”开头的环境变量。

     除此环境变量外,根据当前已经存在且活跃 Service,kubelet还会对新创建的Pod自动为已存在的Service生成一组环境变量添加到Pod容器中。 kubelet添加的环境变量包括:

  • {SVCNAME}_SERVICE_HOST
  • {SVCNAME}_SERVICE_PORT
  • {SVCNAME}_PORT

这里 Service 名称被转为大写字母,横线被转换成下划线。

在新创建Pod容器中,可以从环境变量获取需要访问的目的Service的地址了。

   2.2 DNS方式

    对于环境变量方式,要求Service必须先于Pod创建好。这实际上对部署顺序提出了较为苛刻的要求,而使用DNS方式就不存在此问题。  对于客户端而言,DNS域名方式提供了一种稳定的、不变的访问方式,可以简化客户端配置,是Kubernetes推荐的方式

   Service遵从DNS命名规范:

Service的DNS域名命名规则:<ServiceName>.<namespace>.svc.<clusterDomain> 

   如果Service中的port端口号指定了名称name,则该端口号也拥有DNS域名:

Service端口的DNS域名命名规则:_<PortName>._<Protocal>.<ServiceName>.<namespace>.svc.<clusterDomain> 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921805.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921805.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921805.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 Python 中实现观察者模式的具体步骤是什么?

在 Python 中实现观察者模式可以遵循以下具体步骤&#xff0c;这些步骤清晰地划分了角色和交互流程&#xff1a; 步骤 1&#xff1a;定义主题&#xff08;Subject&#xff09;基类 主题是被观察的对象&#xff0c;负责管理观察者和发送通知。需实现以下核心方法&#xff1a; 存…

分布式方案 一 分布式锁的四大实现方式

Java分布式锁实现方式详解 什么是分布式锁 基于数据库的分布式锁基于Redis的分布式锁基于ZooKeeper的分布式锁基于Etcd的分布式锁 各种实现方式对比最佳实践建议多节点/线程调用结果展示 基于数据库的分布式锁 - 多线程测试基于Redis的分布式锁 - 多节点测试基于ZooKeeper的分…

基于Room+RESTful的双权限Android开机时间监控方案

概述 以下是使用Kotlin实现的商业级Android开机时间记录功能&#xff0c;包含现代Android开发最佳实践。 系统架构 组件设计 // BootReceiver - 接收开机广播 class BootReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent?) {if (int…

水库大坝安全监测系统的作用

水库大坝作为重要的水利基础设施&#xff0c;承担着防洪、供水、发电、灌溉等多重功能&#xff0c;其安全性直接关系到人民生命财产安全和社会经济发展。然而&#xff0c;由于自然环境变化、材料老化、荷载作用以及人为因素的影响&#xff0c;大坝在长期运行过程中可能出现裂缝…

《Kubernetes 构建 MySQL MGR 集群实战教程》

#### 一、前言 MySQL Group Replication (MGR) 是 MySQL 官方提供的高可用集群方案&#xff0c;基于 Paxos 协议实现多节点数据强一致性。本教程将指导如何在 Kubernetes 上部署 MySQL MGR 集群&#xff0c;适用于生产级高可用场景。---#### 二、环境准备 1. **Kubernetes 集…

影视APP源码 SK影视 安卓+苹果双端APP 反编译详细视频教程+源码

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 影视APP源码 SK影视 安卓苹果双端APP 反编译详细视频教程源码 自带对接优效SDK广告&#xff08;已失效&#xff09;。域名和IP都可以搭建。 自带一起看和短剧页面功能&#xff0c;三种…

pyqt+python之二进制生肖占卜

目录 一、引言 二、GUI界面设计 1.效果演示 2.相关提示 3.界面设计.py 三、主要程序详解 1.导入相关模块 2.初始化设置 3.组内判断 4.猜测过程 四、总程序代码 一、引言 在数字时代&#xff0c;传统文化与编程语言的碰撞总能迸发奇妙火花。本项目以PyQtPython为技术…

人工智能-python-深度学习-经典网络模型-LeNets5

文章目录LeNet-5&#xff08;详解&#xff09;—— 从原理到 PyTorch 实现&#xff08;含训练示例&#xff09;简介LeNet-5 的核心思想LeNet-5 逐层结构详解逐层计算举例&#x1f4cc; 输入层&#x1f4cc; C1 卷积层&#x1f4cc; S2 池化层&#x1f4cc; C3 卷积层&#x1f4…

机器视觉的手机柔性屏贴合应用

在智能手机制造领域&#xff0c;柔性屏逐渐成为智能手机的主流选择&#xff0c;柔性屏因其轻便、易于弯曲的特性&#xff0c;已成为现代电子设备的重要组成部分&#xff0c;但同时也带来了前所未有的制造挑战。柔性屏与传统刚性玻璃屏有本质区别&#xff0c;它容易形变&#xf…

贪心算法应用:数字孪生同步问题详解

Java中的贪心算法应用&#xff1a;数字孪生同步问题详解 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。下面我将全面详细地讲解贪心算法在数字孪生同步问题中的应用。…

UOS20系统安装与 SSH/XRDP 远程访问功能配置指南

UOS20系统安装与 SSH/XRDP 远程访问功能配置指南 一、UOS 20 系统安装​ ​1. 下载系统镜像​ 访问统信官网下载 UOS 20 专业版镜像&#xff08;推荐适配当前硬件的版本&#xff09;&#xff1a; https://www.chinauos.com/resource/download-professional 2. 系统安装与硬件配…

【Python】S1 基础篇 P5 字典模块指南

目录字典的本质与底层实现基础语法结构使用字典访问字典中的值添加键值对修改字典中的值删除键值对使用 get() 来访问值遍历字典遍历所有键值对遍历字典中的所有键遍历字典中的所有值嵌套字典列表在字典中存储列表字典&#xff08;Dictionary&#xff09;是Python中灵活且强大的…

计算机视觉之多模板匹配

简介 计算机视觉第一课opencv&#xff08;四&#xff09;保姆级教学 之前说过模糊匹配只是对于单个目标进行匹配&#xff0c;今天我们就来学习一下如何对多个目标进行匹配 一、多目标匹配 对于这个图片我们要匹配下面那个箭头&#xff0c;我们可以发现图中是有两个位置相同的…

封装日期选择器组件,带有上周,下周按钮

ui图组件代码如下&#xff1a; <template><div><el-date-pickerv-model"dateRange"type"daterange"align"right"size"mini":editable"false"unlink-panelsrange-separator"至"start-placeholder&q…

基于SpringBoot+MYSQL开发的AI智能大数据医疗诊断平台

角色&#xff1a; 管理员、医生、居民 技术&#xff1a; SpringBoot、MyBatis、MySQL、Shiro、Beetl、Swagger、jQuery、Bootstrap 核心功能&#xff1a; 这是一个基于SpringBoot的社区医疗管理平台&#xff0c;旨在为管理员提供用户、角色、部门、菜单、日志等系统管理功能&am…

【MFC 小白日记】对话框编辑器里“原型图像”到底要不要勾?3 分钟看懂!

摘要&#xff1a;本文解析了MFC中Picture Control的"原型图像(Prototype Image)"属性的真实作用。该属性仅在设计时提供可视化的占位图预览&#xff0c;方便UI布局&#xff0c;运行时不会影响程序表现。文章通过对比实验验证&#xff0c;勾选后会在对话框编辑器中显示…

微信开放平台第三方平台,可以管理多个微信小程序

大家好&#xff0c;我是小悟。 这个系统可以帮助服务商更好地管理多个商家小程序&#xff0c;无需管理多个商家小程序的账号密码或者appId和secret&#xff0c;大大提升效率。 不需要频繁登录小程序后台就能完成上传代码、认证、备案、提交代码审核、发布小程序等操作。 这里录…

Java全栈学习笔记32

-- drop table t_stu;-- unique 唯一约束的列允许为null-- 如果在之后的操作中。需要某列必须为key&#xff0c;才能做一些操作的情况下。也可以使用唯一约束代替主键约束-- create table t_stu(-- studId int,-- tel varchar(11) unique,-- sex varchar(1),-- addr va…

linux升级系统,重启出现Minimal BASH-like line editingis supported

文章目录一.问题背景二.解决步骤2.1确认系统分区2.2手动引导2.3 重建grub引导2.4 还原软件包 一.问题背景 闲来无事&#xff0c;把ubuntu25.04通过sudo do-release-upgrade命令升级到了ubuntu25.10.在升级的过程会出现以下问题 1.自动替换flatpak程序为snap2.请求是否清除旧依赖…

type(类型别名)和 interface的区别和最佳实践

核心结论在大多数情况下&#xff0c;它们可以互换使用&#xff0c;都能描述对象的结构。它们的区别更多在于设计和扩展能力上。主要区别总结表特性interface (接口)type (类型别名)扩展方式使用 extends 继承interface A extends B {}使用 & 交叉类型type A B & C合并…