k8s Service服务详解

news/2024/11/24 13:23:40/

1. Service 的概念:

  • k8s中Service定义了这样一种抽象:一个pod的逻辑分组,一种可以访问他们的策略—通常称为微服务。这一组pod能够被Service访问到,通常是通过Label Selector

在这里插入图片描述

  • Service能够提供负载均衡的能力,但是在使用上有以下限制:

    • 只提供4层负载均衡能力,而没有7层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡不支持的。

2. Service的类型:

  • Service在k8s中有以下四种类型:

    • ClusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP。
    • NodePort:在ClusterIp基础上为Service在每台机器上绑定一个端口,这样就可以通过 NodeIP:NodePort来访问该服务。
    • LoadBalancer:在NodePort的基础上,借助Cluster Provider创建一个外部负载均衡器,并将请求转发到NodeIP:NodePort
    • ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理被创建,这里只有k8s1.7或更高版本的kube-dns才支持。

在这里插入图片描述

3. Vip和Service代理

  • 在k8s集群中,每个Node运行一个kube-proxy进程。kube-proxy负责为service实现一种VIP(虚拟IP)的形式,而不是ExternalName的形式。在k8s V1.0版本,代理完全在userspace。在k8s V1.1版本,新增了Iptables代理 ,但不是默认的运行模式。从k8s V1.2版本起,默认就是Iptables代理,在k8s V1.8.0-beta.0中,添加了ipvs代理。在k8s V1.14版本开始模式使用ipvs代理。
  • 在k8s v1.0版本,Service是“4层”(TCP/UDP over IP)概念。在K8s v1.1版本,新增了Ingress API(beta版),用来表示“7层”(HTTP)服务

4. 代理模式的分类:

4.1. userspace代理模式:

在这里插入图片描述

4.2. iptables代理模式:

在这里插入图片描述

4.3. Ipvs代理模式

  • 这种模式,kube-proxy会监视k8s service对象和Endpoints,调用netlink接口以相应的创建ipvs规则并定期与k8s service对象和Endpoints对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将重定向到后端pod。

  • 与iptables类似,ipvs与netfilter的hook功能,但使用哈希表作为底层数据结构并在内核空间工作。这意味着ipvs可以更快的重定向流量,并且在同步代理规则时具有更好的性能。此外ipvs为负载均衡算法提供了更多选项,例如:

    • rr:轮询调度
    • lc:最小连接数
    • dh:目标哈希
    • sh:源哈希
    • sed:最短期望延迟
    • nq:不排队调度
  • 注意:ipvs模式假定在运行kube-proxy之前在节点上都已经安装了ipvs内核模块。当kube-proxy以ipvs代理模式启动时,kube-proxy将验证节点是否安装ipvs模块,如果未安装,则kube-proxy 将退到iptables代理模式。
    在这里插入图片描述

5. ClusterlP

  • clusterlP主要在每个node节点使用iptables,将发向clusterlP对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod的地址和端口

在这里插入图片描述

  • 为了实现图上的功能,主要需要以下几个组件的协同工作:

    • apiserver用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到情求后将数据存储到etcd中
    • kube-proxy kubernetesl的每个节点中都有一个叫做kube-porxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables规则中
    • iptables使用NAT等技术将virtuallP的流量转至endpoint中

    5.1. 实例:

vim  nginx.yamlapiVersion: apps/v1  #指定使用的API版本
kind: Deployment     #指定对象类型为Deployment
metadata:   #元数据部分,包含名称和命名空间等信息name: nginx-deployment  #定义deployment的名称为nginx-deploymentnamespace: default  #指定创建所在的命名空间
spec:    #指定 deployment 对象的配置信息selector:  #选择器,用于选择要部署的PodmatchLabels:  #匹配标签,选择具有指定标签的Podapp: nginx  release: stabel  replicas: 3   #指定要创建的Pod副本数量template:    #Pod的模板,定义了要创建的Pod的规范metadata:  #Pod元数据部分,包含标签等信息labels:  #Pod 标签app: nginxrelease: stabelspec:   #Pod 配置信息containers:  #容器列表信息- name: nginx  #容器名称image: nginx:latest  #指定容器的镜像imagePullPolicy: IfNotPresent #指定容器拉取镜像策略,本地不存在镜像时才尝试拉取新镜像ports: #容器暴露的端口列表- name: http  #端口名称containerPort: 80  #容器的端口号---apiVersion: v1    #指定使用的API版本 
kind: Service     #指定对象类型为Service
metadata:         #元数据部分,包含名称和命名空间等信息name: nginx-service  #定义service的名称为nginx-servicenamespace: default   #指定service创建所在的命名空间
spec:     #指定 service对象的配置信息type: ClusterIP  #指定Service类型为ClusterIP,即集群内部访问selector:    #选择器,用于选择要关联的Podapp: nginx   #匹配具有指定标签的Podrelease: stabel  #匹配具有指定标签的Podports:  #Service暴露的端口列表- name: http  #端口名称protocol: TCP  #端口协议port: 80    #Service的端口号targetPort: 80  #将流量转发到Pod的端口号
  • 这个示例中,Deployment创建了3个副本的nginx Pod,并将它们的标签设置为app: nginx和release: stabel。Service使用相同的标签选择与这些Pod关联,并在集群内部暴露端口80,以便其他Pod可以通过nginx-service:80的方式访问这些Pod。

5.2. 创建

[root@master1 yaml]# kubectl apply -f nginx.yaml[root@master1 yaml]# kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.10.0.1       <none>        443/TCP   8h
nginx-service   ClusterIP   10.10.156.191   <none>        80/TCP    12s[root@master1 yaml]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-77fd88977b-2rlkk   1/1     Running   0          3m3s
nginx-deployment-77fd88977b-979tp   1/1     Running   0          3m3s
nginx-deployment-77fd88977b-g57b5   1/1     Running   0          3m3s[root@master1 yaml]# curl 10.10.156.191
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>

6. Headless Service

  • 有时不需要或不想要负载均衡,以及单独的Service IP。遇到这种情况,可以通过指定ClusterIP(spec.clusterlP)的值为"None"来创建Headless Service。这类Service并不会分配ClusterIP,kube-proxy不会处理它们,而且平台也不会为它们进行负载均衡和路由
vim  nginx-service-headless.yamlapiVersion: v1
kind: Service
metadata:name: nginx-headless-servicenamespace: default
spec:selector:app: nginxrelease: stabelclusterIP: "None"ports:- name: httpprotocol: TCPport: 80targetPort: 80

6.1. 创建

      targetPort: 80
[root@master1 yaml]# kubectl apply -f nginx-service-headless.yaml
service/nginx-headless-service created
[root@master1 yaml]# kubectl get svc
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes               ClusterIP   10.10.0.1       <none>        443/TCP   29h
nginx-headless-service   ClusterIP   None            <none>        80/TCP    8s    ---可以看的出来clusterIP是空的
nginx-service            ClusterIP   10.10.196.214   <none>        80/TCP    42m

6.2. 验证:

[root@master1 yaml]# yum -y install bind-utils.x86_64
用dns服务解析nginx-headless-service.default.svc.cluster.local.这个域名下是不是有三个pod的IP地址
[root@master1 yaml]# dig -t A nginx-headless-service.default.svc.cluster.local. @10.244.0.6

在这里插入图片描述

7. NodePort

  • nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步到给对应的pod
vim  nginx-service-nodeport.yamlapiVersion: v1
kind: Service
metadata:name: nginx-nodeport-servicenamespace: default
spec:type: NodePortselector:app: nginxrelease: stabelports:- name: httpprotocol: TCPport: 80targetPort: 80nodePort: 30080

7.1. 创建:

[root@master1 yaml]# kubectl apply -f nginx-service-nodeport.yaml
service/nginx-nodeport-service created
[root@master1 yaml]# kubectl get svc
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   10.10.0.1       <none>        443/TCP        30h
nginx-headless-service   ClusterIP   None            <none>        80/TCP         26m
nginx-nodeport-service   NodePort    10.10.113.141   <none>        80:30080/TCP   7s
nginx-service            ClusterIP   10.10.196.214   <none>        80/TCP         68m

7.2. 验证:

在这里插入图片描述

8. LoadBalancer

  • loadBalancer和nodePort其实是同一种方式。区别在于loadBalancer比nodePor片多了一步,就是可以调用cloud provider去创建LB来向节点导流

在这里插入图片描述

9. ExternalName

  • 这种类型的Service通过返回CNAME和它的值,可以将服务映射到externalName字段的内容(例如:hub.atguigu.com)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务
vim  externalname-service.yamlapiVersion: v1
kind: Service
metadata:name: my-external-servicenamespace: default
spec:type: ExternalNameexternalName: example.com

9.1. 创建:

[root@master1 yaml]# kubectl apply -f externalname-service.yaml
service/my-external-service created
[root@master1 yaml]# kubectl get svc
NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP      10.10.0.1       <none>        443/TCP        31h
my-external-service      ExternalName   <none>          example.com   <none>         4s
nginx-headless-service   ClusterIP      None            <none>        80/TCP         86m
nginx-nodeport-service   NodePort       10.10.113.141   <none>        80:30080/TCP   60m
nginx-service            ClusterIP      10.10.196.214   <none>        80/TCP         129m

9.2. 验证:

[root@master1 yaml]# dig -t A my-external-service.default.svc.cluster.local. @10.244.0.6

在这里插入图片描述

  • 当查询主机my-external-service.default.svc.cluster.local(SVC_NAME.NAMESPACE.svc.cluster.local)时,集群的DNS服务将返回一个值my.database.example.com的CNAME记录。访问这个服务的工作方式和其他的相同,唯一不同的是重定向发生在DNS层,而且不会进行代理或转发

http://www.ppmy.cn/news/457470.html

相关文章

2小时掌握Allegro PCB 布局专题

🏡《总目录》   🏡《宝典目录》 目录 1,概述2,大纲Cadence Allegro 通孔PAD制作方法Cadence Allegro 摆放关键元件关键模块方法Cadence Allegro 对齐元件交换元件方法Cadence Allegro 等距离对齐元件方法Cadence Allegro 板框内缩创建布线区域和放置元件区域方法Cadenc…

51 最佳实践-安全最佳实践-qemu-ga

文章目录 51 最佳实践-安全最佳实践-qemu-ga51.1 概述51.2 操作方法 51 最佳实践-安全最佳实践-qemu-ga 51.1 概述 qemu-ga&#xff08;Qemu Guest Agent&#xff09;它是运行在虚拟机内部的守护进程&#xff0c;它允许用户在host OS上通过QEMU提供带外通道实现对guest OS的多…

初识 Linux 进程

问题 strace 输出中的 execve(...) 究竟是什么&#xff1f; 进程生命周期 操作系统内部定义了进程的不同状态 Linux 进程基本概念 进程是 Linux 任务的执行单元&#xff0c;也是 Linux 系统资源的分配单元 每个 Linux 应用程序运行后由一个或多个进程构成 每个 Linux 进程可…

OpenCV项目开发实战-- 将一个三角形变形为另一个三角形 ( C++ / Python )代码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:左图中蓝色三角形内的所有像素都已转换为右图中的蓝色三角形。 在本教程中,我们将看到如何将图像中的单个三角形变形为不同图像中的另一个三角形。 在计算机图形学中,人们一直在处理扭曲三角形,因为任何 3D 表…

如何解压bz2后缀的压缩文件

.bz2 解压1&#xff1a;bzip2 -d FileName.bz2 解压2&#xff1a;bunzip2 FileName.bz2 压缩&#xff1a; bzip2 -z FileName .tar.bz2 解压&#xff1a;tar jxvf FileName.tar.bz2 #显示解压详细过程 或tar --bzip xvf FileName.tar.bz2 #不显示解压详细过程 压缩&#xff1a;…

解压后缀zip的压缩包

仅作参考 unzip jim.zip#jim.zip为需要解压的文件&#xff0c;解压到当前文件夹下

Windows11系统下解压文件后缀为.tar(.gz)的压缩文件

第一步&#xff1a;进入解压文件所在的当前文件夹内右键点击在终端打开 第二步&#xff1a;在终端内输入tar -zxvf xxx.tar.gz&#xff08;如果是.tar.gz文件就输入该行指令&#xff0c;如果是.tar文件就输入tar -zxvf xxx.tar指令&#xff0c;其中xxx为文件名&#xff09; 第三…

压缩文件的格式

任何一个文件存储在电脑上都有它的格式&#xff0c;例如文本格式像.txt .doc&#xff0c;图像格式 .jpg .tif .bmp等。 所有压缩文件也有压缩的格式&#xff0c;一般我们看到的压缩格式有 .rar .zip&#xff0c;但主要压缩的作用就是让某一个文件占用空间小点。比如原来的文件是…