Kubernetes(K8s)Service详解-07

news2025/2/22 9:07:08

Service详解

Service介绍
在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。

为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。

img

Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行着一个kube-proxy服务进程。当创建Service的时候会通过api-server向etcd写入创建的service的信息,而kube-proxy会基于监听的机制发现这种Service的变动,然后它会将最新的Service信息转换成对应的访问规则。

img

#10.97.97.97:80 是service提供的访问入口
#当访问这个入口的时候,可以发现后面有三个pod的服务在等待调用,
#kube-proxy会基于rr(轮询)的策略,将请求分发到其中一个pod上去
#这个规则会同时在集群内的所有节点上都生成,所以在任何一个节点,访问都可以。
[root@node1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.97.97.97:80 rr
  -> 10.244.1.39:80               Masq    1      0          0
  -> 10.244.1.40:80               Masq    1      0          0
  -> 10.244.2.33:80               Masq    1      0          0

kube-proxy目前支持三种工作模式:

userspace 模式
userspace模式下,kube-proxy会为每一个Service创建一个监听端口,发向Cluster IP的请求被Iptables规则重定向到kube-proxy监听的端口上,kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。 该模式下,kube-proxy充当了一个四层负责均衡器的角色。由于kube-proxy运行在userspace中,在进行转发处理时会增加内核和用户空间之间的数据拷贝,虽然比较稳定,但是效率比较低。

img

iptables 模式
iptables模式下,kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向Cluster IP的请求重定向到一个Pod IP。 该模式下kube-proxy不承担四层负责均衡器的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。

img

ipvs 模式
ipvs模式和iptables类似,kube-proxy监控Pod的变化并创建相应的ipvs规则。ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。

img

#此模式必须安装ipvs内核模块,否则会降级为iptables
#开启ipvs
[root@k8s-master01 ~]# kubectl edit cm kube-proxy -n kube-system
# 修改mode: "ipvs"
[root@k8s-master01 ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system
[root@node1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.97.97.97:80 rr
  -> 10.244.1.39:80               Masq    1      0          0
  -> 10.244.1.40:80               Masq    1      0          0
  -> 10.244.2.33:80               Masq    1      0          0

Service类型
Service的资源清单文件:

kind: Service  # 资源类型
apiVersion: v1  # 资源版本
metadata: # 元数据
  name: service # 资源名称
  namespace: dev # 命名空间
spec: # 描述
  selector: # 标签选择器,用于确定当前service代理哪些pod
    app: nginx
  type: # Service类型,指定service的访问方式
  clusterIP:  # 虚拟服务的ip地址
  sessionAffinity: # session亲和性,支持ClientIP、None两个选项
  ports: # 端口信息
    - protocol: TCP 
      port: 3017  # service端口
      targetPort: 5003 # pod端口
      nodePort: 31122 # 主机端口
ClusterIP:默认值,它是Kubernetes系统自动分配的虚拟IP,只能在集群内部访问
NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务
LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持
ExternalName: 把集群外部的服务引入集群内部,直接使用

Service使用
实验环境准备
在使用service之前,首先利用Deployment创建出3个pod,注意要为pod设置app=nginx-pod的标签

创建deployment.yaml,内容如下:

apiVersion: apps/v1
kind: Deployment      
metadata:
  name: pc-deployment
  namespace: dev
spec: 
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80
[root@k8s-master01 ~]# kubectl create -f deployment.yaml
deployment.apps/pc-deployment created

#查看pod详情
[root@k8s-master01 ~]# kubectl get pods -n dev -o wide --show-labels
NAME                             READY   STATUS     IP            NODE     LABELS
pc-deployment-66cb59b984-8p84h   1/1     Running    10.244.1.39   node1    app=nginx-pod
pc-deployment-66cb59b984-vx8vx   1/1     Running    10.244.2.33   node2    app=nginx-pod
pc-deployment-66cb59b984-wnncx   1/1     Running    10.244.1.40   node1    app=nginx-pod

#为了方便后面的测试,修改下三台nginx的index.html页面(三台修改的IP地址不一致)
#kubectl exec -it pc-deployment-66cb59b984-8p84h -n dev /bin/sh
#echo "10.244.1.39" > /usr/share/nginx/html/index.html

#修改完毕之后,访问测试
[root@k8s-master01 ~]# curl 10.244.1.39
10.244.1.39
[root@k8s-master01 ~]# curl 10.244.2.33
10.244.2.33
[root@k8s-master01 ~]# curl 10.244.1.40
10.244.1.40

ClusterIP类型的Service
创建service-clusterip.yaml文件

apiVersion: v1
kind: Service
metadata:
  name: service-clusterip
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: 10.97.97.97 # service的ip地址,如果不写,默认会生成一个
  type: ClusterIP
  ports:
  - port: 80  # Service端口       
    targetPort: 80 # pod端口
#创建service
[root@k8s-master01 ~]# kubectl create -f service-clusterip.yaml
service/service-clusterip created

#查看service
[root@k8s-master01 ~]# kubectl get svc -n dev -o wide
NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service-clusterip   ClusterIP   10.97.97.97   <none>        80/TCP    13s   app=nginx-pod

#查看service的详细信息
#在这里有一个Endpoints列表,里面就是当前service可以负载到的服务入口
[root@k8s-master01 ~]# kubectl describe svc service-clusterip -n dev
Name:              service-clusterip
Namespace:         dev
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP:                10.97.97.97
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.39:80,10.244.1.40:80,10.244.2.33:80
Session Affinity:  None
Events:            <none>

#查看ipvs的映射规则
[root@k8s-master01 ~]# ipvsadm -Ln
TCP  10.97.97.97:80 rr
  -> 10.244.1.39:80               Masq    1      0          0
  -> 10.244.1.40:80               Masq    1      0          0
  -> 10.244.2.33:80               Masq    1      0          0

#访问10.97.97.97:80观察效果
[root@k8s-master01 ~]# curl 10.97.97.97:80
10.244.2.33

Endpoint
Endpoint是kubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。

一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换句话说,service和pod之间的联系是通过endpoints实现的。

image-20200509191917069

负载分发策略

对Service的访问被分发到了后端的Pod上去,目前kubernetes提供了两种负载分发策略:

如果不定义,默认使用kube-proxy的策略,比如随机、轮询

基于客户端地址的会话保持模式,即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上

此模式可以使在spec中添加sessionAffinity:ClientIP选项

#查看ipvs的映射规则【rr 轮询】
[root@k8s-master01 ~]# ipvsadm -Ln
TCP  10.97.97.97:80 rr
  -> 10.244.1.39:80               Masq    1      0          0
  -> 10.244.1.40:80               Masq    1      0          0
  -> 10.244.2.33:80               Masq    1      0          0

#循环访问测试
[root@k8s-master01 ~]# while true;do curl 10.97.97.97:80; sleep 5; done;
10.244.1.40
10.244.1.39
10.244.2.33
10.244.1.40
10.244.1.39
10.244.2.33

#修改分发策略----sessionAffinity:ClientIP

#查看ipvs规则【persistent 代表持久】
[root@k8s-master01 ~]# ipvsadm -Ln
TCP  10.97.97.97:80 rr persistent 10800
  -> 10.244.1.39:80               Masq    1      0          0
  -> 10.244.1.40:80               Masq    1      0          0
  -> 10.244.2.33:80               Masq    1      0          0

#循环访问测试
[root@k8s-master01 ~]# while true;do curl 10.97.97.97; sleep 5; done;
10.244.2.33
10.244.2.33
10.244.2.33
  
#删除service
[root@k8s-master01 ~]# kubectl delete -f service-clusterip.yaml
service "service-clusterip" deleted

HeadLiness类型的Service
在某些场景中,开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况,kubernetes提供了HeadLiness Service,这类Service不会分配Cluster IP,如果想要访问service,只能通过service的域名进行查询。

创建service-headliness.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-headliness
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
  type: ClusterIP
  ports:
  - port: 80    
    targetPort: 80
#创建service
[root@k8s-master01 ~]# kubectl create -f service-headliness.yaml
service/service-headliness created

#获取service, 发现CLUSTER-IP未分配
[root@k8s-master01 ~]# kubectl get svc service-headliness -n dev -o wide
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service-headliness   ClusterIP   None         <none>        80/TCP    11s   app=nginx-pod

#查看service详情
[root@k8s-master01 ~]# kubectl describe svc service-headliness  -n dev
Name:              service-headliness
Namespace:         dev
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP:                None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.39:80,10.244.1.40:80,10.244.2.33:80
Session Affinity:  None
Events:            <none>

#查看域名的解析情况
[root@k8s-master01 ~]# kubectl exec -it pc-deployment-66cb59b984-8p84h -n dev /bin/sh
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search dev.svc.cluster.local svc.cluster.local cluster.local

[root@k8s-master01 ~]# dig @10.96.0.10 service-headliness.dev.svc.cluster.local
service-headliness.dev.svc.cluster.local. 30 IN A 10.244.1.40
service-headliness.dev.svc.cluster.local. 30 IN A 10.244.1.39
service-headliness.dev.svc.cluster.local. 30 IN A 10.244.2.33

NodePort类型的Service
在之前的样例中,创建的Service的ip地址只有集群内部才可以访问,如果希望将Service暴露给集群外部使用,那么就要使用到另外一种类型的Service,称为NodePort类型。NodePort的工作原理其实就是将service的端口映射到Node的一个端口上,然后就可以通过NodeIp:NodePort来访问service了。

img

创建service-nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-nodeport
  namespace: dev
spec:
  selector:
    app: nginx-pod
  type: NodePort # service类型
  ports:
  - port: 80
    nodePort: 30002 # 指定绑定的node的端口(默认的取值范围是:30000-32767), 如果不指定,会默认分配
    targetPort: 80
#创建service
[root@k8s-master01 ~]# kubectl create -f service-nodeport.yaml
service/service-nodeport created

#查看service
[root@k8s-master01 ~]# kubectl get svc -n dev -o wide
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)       SELECTOR
service-nodeport   NodePort   10.105.64.191   <none>        80:30002/TCP  app=nginx-pod

#接下来可以通过电脑主机的浏览器去访问集群中任意一个nodeip的30002端口,即可访问到pod

LoadBalancer类型的Service
LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。

img

ExternalName类型的Service
ExternalName类型的Service用于引入集群外部的服务,它通过externalName属性指定外部一个服务的地址,然后在集群内部访问此service就可以访问到外部的服务了。

img

apiVersion: v1
kind: Service
metadata:
  name: service-externalname
  namespace: dev
spec:
  type: ExternalName # service类型
  externalName: www.baidu.com  #改成ip地址也可以
#创建service
[root@k8s-master01 ~]# kubectl  create -f service-externalname.yaml
service/service-externalname created

#域名解析
[root@k8s-master01 ~]# dig @10.96.0.10 service-externalname.dev.svc.cluster.local
service-externalname.dev.svc.cluster.local. 30 IN CNAME www.baidu.com.
www.baidu.com.          30      IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       30      IN      A       39.156.66.18
www.a.shifen.com.       30      IN      A       39.156.66.14

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SL6015B降压恒流60V耐压1.5A高辉调光LED芯片 电路简单 元器件少

SL6015B是一款专为LED照明应用设计的降压恒流芯片&#xff0c;具有60V的耐压能力&#xff0c;最大输出电流可达1.5A。它采用高辉调光方式&#xff0c;通过改变输入电压或电流来调节LED的亮度。此外&#xff0c;SL6015B还具有电路简单和元器件数量少的特点&#xff0c;使其成为一…

C语言之程序的组成和元素格式

目录 关键字 运算符 标识符 姓名和标识符 分隔符 常量和字符串常量 自由的书写格式 书写限制 连接相邻的字符串常量 缩进 本节我们来学习程序的各组成元素&#xff08;关键字、运算符等&#xff09;和格式相关的内容。 关键字 在C语言中&#xff0c;相if和else这样的标识…

c++ 三目运算符在类中的使用

简介 在类比较方面&#xff0c;三目运算符可以用于重载比较运算符。 代码示例1 #include <iostream> #include <cstring>class Person { public:Person(const char* name, int age) : m_age(age) {m_name new char[strlen(name) 1];strcpy(m_name, name);}~Pe…

大模型上下文学习(ICL)训练和推理两个阶段31篇论文

大模型都火了这么久了&#xff0c;想必大家对LLM的上下文学习&#xff08;In-Context Learning&#xff09;能力都不陌生吧&#xff1f; 以防有的同学不太了解&#xff0c;今天我就来简单讲讲。 上下文学习&#xff08;ICL&#xff09;是一种依赖于大型语言模型的学习任务方式…

Python 数据清洗库详解

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 数据清洗是数据处理过程中至关重要的一部分。Python拥有许多强大的库&#xff0c;用于数据清洗和预处理&#xff0c;使得数据分析人员能够有效处理、转换和清洗数据。本文将介绍几个最常用的Python库&#xff0c…

火焰图的基本认识与绘制方法

火焰图的认识与使用-目录 火焰图的基本认识火焰图有以下特征(on-cpu)火焰图能做什么火焰图类型On-CPU 火焰图和Off-CPU火焰图的使用场景火焰图分析技巧 如何绘制火焰图生成火焰图的流程1.生成火焰图的三个步骤 安装火焰图必备工具1.安装火焰图FlameGraph脚本2.安装火焰图数据采…

第2章 知识抽取:概述、方法

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

创建数据库并使用索引查询学员考试成绩

5.1索引 索引提供指针以指向存储在表中指定列的数据值&#xff0c;然后根据指定的次序排列这些指针&#xff0c;再跟随 指针到达包含该值的行。 5.1.1什么是索引 数据库中的索引与书籍中的目录类似。在一本书中&#xff0c;无须阅读整本书&#xff0c;利用目录就可以快速查 找…

Leetcod面试经典150题刷题记录——数组 / 字符串篇

数组 / 字符串篇 1. 合并两个有序数组Python3排序法双指针法 2. 移除元素Python3 3. 删除有序数组中的重复元素Python3 7. 买卖股票的最佳时机Python3 8. 买卖股票的最佳时机ⅡPython3贪心法动态规划法 11. H 指数Python3排序法计数排序法二分查找 有个技巧&#xff0c;若想熟悉…

Vue项目图片预览v-viewer插件使用,图片预览,图片查看;antdesign+vue2+v-viewer实现图片查看器并可删除图片

Vue项目图片预览v-viewer插件使用 1. 安装 v-viewer 你可以使用 npm 或者 yarn 来安装 v-viewer&#xff1a; npm install v-viewer 或者 yarn add v-viewer 2. 导入和配置 v-viewer 在你的 Vue 项目中&#xff0c;你需要在入口文件&#xff08;通常是 main.js&#xff09…

通信标准化协会,信通院及量子信息网络产业联盟调研玻色量子,共绘实用化量子未来!

8月14日&#xff0c;中国通信标准化协会&#xff0c;信通院标准所及量子信息网络产业联盟等单位领导走访调研北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;&#xff0c;参观了玻色量子公司及自建的十万颗粒洁净度的光量子信息技术实验室&#x1f517;…

自己开发组件更新到npm网站上 通过npm install 安装 保姆级别教程

文章目的 在项目开发中&#xff0c;经常通过npm install安装使用各种各样的npn包。本文记录如何自己实现的一个npm包 1. 环境准备 开发环境安装好,没有准备好环境 需要先安装哦 2. 创建Vue项目 初始化Vue项目&#xff1a;vue create xwdm-test 选择手动选择功能 Manually selec…

mac shortcut keys cheat sheet【mac 快捷键清单】

文章目录 剪切、拷贝、粘贴和其他常用快捷键访达和系统快捷键 Mac 键盘快捷键 Command&#xff08;或 Cmd&#xff09;⌘ Shift ⇧ Option&#xff08;或 Alt&#xff09;⌥ Control&#xff08;或 Ctrl&#xff09;⌃ Caps Lock ⇪ Fn 剪切、拷贝、粘贴和其他常用快捷…

分享106个图片JS特效,总有一款适合您

分享106个图片JS特效&#xff0c;总有一款适合您 106个图片JS特效下载链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;6666 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知识付费甚欢喜&#xff0c…

4、类和对象、this指针、常对象和常函数

类和对象 类的一般形式 访问控制限定符 public 公有成员&#xff0c;谁都可以访问protected 保护成员&#xff0c;只有类自己和子类可以访问private 私有成员&#xff0c;只有类自己可以访问 类和结构的访问控制限定符区别 类的缺省访问控制限定为私有(private)结构的缺省访…

C++空类的那点事儿

什么是C的空类 顾名思义&#xff0c;空类就是指哪些不包含成员变量的类。例如以下这个就是一个空类&#xff1a; class EmptyBase {}; 既然如此&#xff0c;那么是不是说空类的内部一定不会其他代码呢&#xff1f;不是的&#xff0c;空类内部也可以包含其他东西&#xff0c;…

数字化车间|用可视化技术提升车间工作效率

数字化车间正在成为现代制造业的重要组成部分。随着科技的不断进步&#xff0c;传统的车间生产方式逐渐地被数字化和自动化取代。数字化车间将机器和软件进行整合&#xff0c;实现了生产过程的高效、精确和可追溯。在数字化车间中&#xff0c;机器之间可以进行无缝的通信和协作…

【云备份】客户端实现 及 项目整体总结

文章目录 客户端客户端实现思想客户端文件操作类的设计与拷贝Util.hpp的设计data.hpp的设计Storage —— 持久化存储Initload——数据初始化加载 cloud.hpp的设计GetFileIdentifier——创建文件唯一标识Upload—— 文件上传IsNeedupload —— 客户端文件是否需要上传判断RunMod…

正点原子linux应用编程——提高篇5

这篇笔记记一下网络应用编程以及CAN总线的应用编程。 网络基础知识 这个在学习lwIP的时候已经接触过了&#xff0c;这边再过一下&#xff0c;我自己觉得没什么意思的我就跳过了。 网络通信概述 网络通信本质上是一种进程间通信&#xff0c;是位于网络中不同主机上的进程之间…

麒麟linux将图片批量生成PDF的方法

笔者手里有一批国产linu系统&#xff0c;目前开始用在日常的工作生产环境中&#xff0c;我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux&#xff0c;统信UOS等&#xff0c;基本都是基于debian再开发的linux。 问题描述&#xff1a; wind…