k8s Service服务详解

2023-10-26

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.yaml

apiVersion: apps/v1  #指定使用的API版本
kind: Deployment     #指定对象类型为Deployment
metadata:   #元数据部分,包含名称和命名空间等信息
  name: nginx-deployment  #定义deployment的名称为nginx-deployment
  namespace: default  #指定创建所在的命名空间
spec:    #指定 deployment 对象的配置信息
  selector:  #选择器,用于选择要部署的Pod
    matchLabels:  #匹配标签,选择具有指定标签的Pod
      app: nginx  
      release: stabel  
  replicas: 3   #指定要创建的Pod副本数量
  template:    #Pod的模板,定义了要创建的Pod的规范
    metadata:  #Pod元数据部分,包含标签等信息
      labels:  #Pod 标签
        app: nginx
        release: stabel
    spec:   #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-service
  namespace: default   #指定service创建所在的命名空间
spec:     #指定 service对象的配置信息
  type: ClusterIP  #指定Service类型为ClusterIP,即集群内部访问
  selector:    #选择器,用于选择要关联的Pod
    app: nginx   #匹配具有指定标签的Pod
    release: stabel  #匹配具有指定标签的Pod
  ports:  #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.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless-service
  namespace: default
spec:
  selector:
    app: nginx
    release: stabel
  clusterIP: "None"
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 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.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport-service
  namespace: default
spec:
  type: NodePort
  selector:
    app: nginx
    release: stabel
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 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.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-external-service
  namespace: default
spec:
  type: ExternalName
  externalName: 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层,而且不会进行代理或转发
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k8s Service服务详解 的相关文章

随机推荐

  • 20张程序员才懂的搞笑图!保准你笑出猪叫......

    温馨提示 请勿在以下场景食用本文 吃饭时 挤电梯时 路过精神病院时 HTML的4种黑法 扫地阿姨 HTML确实是一门编程语言啊 扫地阿姨 所以HTML程序员不能称自己是程序员 扫地阿姨 这个黑的太过分了吧 扫地阿姨 小姑娘我被你的外表欺骗的
  • Java基础之字符常量

    表示一个字符 一个字符常量要用一对英文半角格式的单引号 引起来 它可以是英文字母 数字 标点符号 以及由转义序列来表示的特殊字符 a 1 r u0000 u0000 表示一个空白字符 即在单引号之间没有任何字符 之所以能这样表示是因为 Ja
  • 线程安全集合类概述

    HashTable和Vector 遗留的线程安全实现 效率较低 HashTable map的实现 Vector list的实现 Collections中的带synchronized修饰实现类 如synchronizedMap synchro
  • 反爬机制之验证setcookie

    反爬表现 在使用python或rust进行爬虫的时候的有时会遇到请求返回一段含有只含有js代码的html页面如图 分析及优化文件 首先解决转义字符 x63 x73 x4b x48 x77 x71 x4d x49这种 转义字符可以通过prin
  • 新一配:区块链及其概念【转载】

    区块链是分布式数据存储 点对点传输 共识机制 加密算法等计算机技术的新型应用模式 区块链 Blockchain 是比特币的一个重要概念 它本质上是一个去中心化的数据库 同时作为比特币的底层技术 是一串使用密码学方法相关联产生的数据块 每一个
  • 考研数学-三角函数与反三角函数图像

    转载自 http math001 com inverse trigonometric functions 在三角函数的前面加上 arc 表示它们的反函数 f 1 x 即由一个三角函数值得出当时的角度 1 正弦函数 sin x 反正弦函数 a
  • 泰勒公式浅谈原理(转) ----- 深度好文, 一点是如何蕴含整个世界

    泰勒公式浅谈原理 转 上周写完了 三体 读后思考 泰勒展开 维度打击 黑暗森林 后收到一些邮件 进一步思考了关于泰勒展开的意义 也许我掌握的那些网络技术比如Linux Netfilter NAT之类 太过底层太过小众 所以大家几乎都是没有感
  • [论文阅读] (15)英文SCI论文审稿意见及应对策略学习笔记总结(letpub爬虫)

    娜璋带你读论文 系列主要是督促自己阅读优秀论文及听取学术讲座 并分享给大家 希望您喜欢 由于作者的英文水平和学术能力不高 需要不断提升 所以还请大家批评指正 非常欢迎大家给我留言评论 学术路上期待与您前行 加油 前一篇介绍英文论文实验评估
  • 在 .NET Core 中结合 HttpClientFactory 使用 Polly(下篇)

    译者 王亮作者 Polly 团队原文 http t cn EhZ90oq声明 我翻译技术文章不是逐句翻译的 而是根据我自己的理解来表述的 包括标题 其中可能会去除一些不影响理解但本人实在不知道如何组织的句子 译者序 这是 Polly and
  • c++11中auto&&是什么意思?

    为什么80 的码农都做不了架构师 gt gt gt By using auto var
  • Missing global shader FCopyVelocityGridCS‘s permutation 0, Please make sure cooking was successful.

    打包好的项目报了如下错误 如何解决这个bug呢 这个问题困扰了我很久 从2022年9月左右就无法打包到现在的2023年5月31号 没想到今天解决了 最近我花了一星期的时间来研究这个bug导致 当时以为是蓝图和材质代码导致 一个个查 吧资源的
  • Python快速入门多线程与多进程

    Python快速入门多线程与多进程 多线程 多线程的含义 进程我们可以理解为是一个可以独立运行的程序单位 比如打开一个浏览器 这就开启了一个浏览器进程 打开一个文本编辑器 这就开启了一个文本编辑器进程 但一个进程中是可以同时处理很多事情的
  • 链栈C++实现

    include
  • arcpy批量将excel一些列的点坐标制作成面

    使用Arcpy可以批量将Excel表格中的点坐标制作成面 并将对应组点的属性写入到对应面的属性中 import arcpy import xlrd 设置输入数据路径 excel file r C data points xlsx 包含点坐标
  • GCC编译过程,了解编译原理

    说明 这篇文件是在读 程序员的自我修养 链接 装载与库 的一点笔记 权当时学习的记录 1 GCC编译过程分解 以HelloWorld程序为例 2 预编译 规则 命令 gcc E XXX c o XXX i 3 编译 词法分析 语法分析 语义
  • Android九宫格控件-可在ListView和RecyclerView中使用

    需求场景 熟悉Android App开发的同学 肯定都清楚 如果要显示多张图片 类似九宫格 可以用GridView或者GridLayout来做 但是如果需求要求在ListView或者recyclerView 的每个item中都显示这样一个九
  • python期末考试试卷及解析

    一 单项选择题 每题 2 分 共 20 分 1 以下关于计算机和程序设计的说法错误的是 A 高级编程语言按照计算机执行方式可分为静态语言和脚本语言 B 编译是将源代码转换成目标代码的过程 C IPO 方法是一种按输入数据 处理数据和输出数据
  • 876. 链表的中间结点

    876 链表的中间结点 简单 给定一个头结点为 head 的非空单链表 返回链表的中间结点 如果有两个中间结点 则返回第二个中间结点 示例 1 输入 1 2 3 4 5 输出 此列表中的结点 3 序列化形式 3 4 5 返回的结点值为 3
  • python爬虫入门教程(非常详细),全网最细的Python爬虫教程

    一 基础入门 1 1什么是爬虫 爬虫 spider 又网络爬虫 是指向网站 网络发起请求 获取资源后分析并提取有用数据的程序 从技术层面来说就是 通过程序模拟浏览器请求站点的行为 把站点返回的HTML代码 JSON数据 二进制数据 图片 视
  • k8s Service服务详解

    1 Service 的概念 k8s中Service定义了这样一种抽象 一个pod的逻辑分组 一种可以访问他们的策略 通常称为微服务 这一组pod能够被Service访问到 通常是通过Label Selector Service能够提供负载均