Kubernetes Service的过程

这篇具有很好参考价值的文章主要介绍了Kubernetes Service的过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Kubernetes Service的实现

基础内容

在了解Service之前,需要先了解一些额外的知识:

  1. 命令: ip route show table all
  2. DNAT
  3. IPVS和iptables
  4. 基础的网络知识(网关,网段或子网,转发)

1. 命令 ip route show table all

这条命令会列出主机内所有的路由.内容展示包含了对应的网段或者IP,要通过那个虚拟设备发送出去.示例:

root@debian:~/kubernetes# ip route show table all 
default via 10.0.0.2 dev ens33 onlink 
10.0.0.0/24 dev ens33 proto kernel scope link src 10.0.0.50 
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 
local 10.0.0.50 dev ens33 table local proto kernel scope host src 10.0.0.50 
broadcast 10.0.0.255 dev ens33 table local proto kernel scope link src 10.0.0.50 
local 10.96.0.1 dev kube-ipvs0 table local proto kernel scope host src 10.96.0.1 
......

摘取一条,比如:local 10.96.0.1 dev kube-ipvs0 table local proto kernel scope host src 10.96.0.1
local:这表示这是一个本地路由,用于指示目标地址是本地主机。
10.96.0.1:目标地址,即要匹配的 IP 地址.
dev kube-ipvs0:指定了数据包应该通过的网络接口,即 kube-ipvs0.
table local:指定了路由表名称,即 local 表.
proto kernel:表示该路由表项是内核生成的.
scope host:表示该路由的作用域仅限于本地主机.
src 10.96.0.1:源 IP 地址,即数据包的出站地址.

2. DNAT

在网络中发送数据包,都是要写明源IP地址及目标IP地址等信息的.可以参考OSI模型.
而DNAT就是,修改数据包中的目标IP为另一个IP,源IP不变.然后重新把这个数据包发送出去.实际上就是一个转发.
Kubernetes Service的过程,kubernetes,容器,云原生

3. IPVS和iptables

kube-proxy是k8s中的一个组件.主要负责网络相关的事情,或者说Service就是基于kube-proxy实现的.
而kube-proxy实际上是调用了系统的iptables和IPVS.所以Service也是基于他们两个实现的.
前者是防火墙,后者是一个性能更好的转发服务.两者在k8s集群中起到的作用都是转发数据包,也就是DNAT.

查看IPVS:

root@debian:~/kubernetes# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 10.0.0.50:6443               Masq    1      3          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.24:53               Masq    1      0          0         
  -> 10.244.0.25:53               Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.0.24:9153             Masq    1      0          0         
  -> 10.244.0.25:9153             Masq    1      0          0         
TCP  10.107.158.131:80 rr
  -> 10.244.0.30:80               Masq    1      0          0         
  -> 10.244.0.33:80               Masq    1      0          0         
  -> 10.244.0.34:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.0.24:53               Masq    1      0          0         
  -> 10.244.0.25:53               Masq    1      0          0 

rr表示轮询策略。

4. Service

Service 是一种抽象,用于定义一组 Pod 的逻辑网络端点。它是 Kubernetes 集群内部的一种资源对象,用于实现服务发现和负载均衡。
Service对应了一组endpoint。每个endpoint都是一个Pod的IP地址,他是基于IPVS实现的,所以你访问Service可以转发到对应的Pod上。
示例:

root@debian:~/kubernetes# kubectl get service
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   34d
nginx        ClusterIP   10.107.158.131   <none>        80/TCP    36m

现在,集群里有一个nginx的Service。

root@debian:~/kubernetes# kubectl get endpoints -o wide 
NAME         ENDPOINTS                                      AGE
kubernetes   10.0.0.50:6443                                 34d
nginx        10.244.0.30:80,10.244.0.33:80,10.244.0.34:80   36m

查看他们对应的endpoints,可以看到nginx对应了三个IP地址。

root@debian:~/kubernetes# kubectl get pod -o wide 
NAME                                READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-6595874d85-5hpvq   1/1     Running   0          4m9s   10.244.0.33   master   <none>           <none>
nginx-deployment-6595874d85-mm2m5   1/1     Running   0          4m9s   10.244.0.34   master   <none>           <none>
nginx-deployment-6595874d85-qtnwb   1/1     Running   0          41m    10.244.0.30   master   <none>           <none>

最后,我们看一下Pod的IP地址,和endpoint的是完全对应的。而endpoints和Service ClusterIP的地址,也是在上面ipvs表中可以找到对应关系的。

所以,当创建或者更新了一个Pod的时候,controller会去同步更新endpoint的地址。接下来endpoint通知kube-proxy,kube-proxy更新IPVS的规则。

Service的实现

Kubernetes Service的过程,kubernetes,容器,云原生

当Pod对一个Service发起请求后:

首先通过集群DNS解析到Service的IP地址。然后数据包源IP填写为当前Pod自己的IP,目标IP填写为对应的Service的IP,然后这个数据包通过虚拟设备来到宿主机。

对于虚拟设备和如何来到宿主机,可以参考docker 网络通信原理,kubernetes flannel 网络,flannel的host-gw与calico。或者参考 深入剖析 Kubernetes 张磊。

数据包来到宿主机后,这里就和Pod和Pod通信不同了。
通过命令可以看到,service的IP地址和Pod的IP地址完全不是一个网段:

root@debian:~/kubernetes# kubectl get pod -o wide 
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-6595874d85-5hpvq   1/1     Running   0          14m   10.244.0.33   master   <none>           <none>
nginx-deployment-6595874d85-mm2m5   1/1     Running   0          14m   10.244.0.34   master   <none>           <none>
nginx-deployment-6595874d85-qtnwb   1/1     Running   0          51m   10.244.0.30   master   <none>           <none>
root@debian:~/kubernetes# kubectl get service -o wide 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   34d   <none>
nginx        ClusterIP   10.107.158.131   <none>        80/TCP    50m   app=nginx

Pod的地址是10.244.0.30,而Service的地址是10.107.158.131
这就意味着,请求Service的数据包来到宿主机内核后,不能像其他到Pod的数据包一样直接通过CNI进行转发。

所以接下来查看下路由表:

root@debian:~/kubernetes# ip route show table all|grep "10.107.158.131"
local 10.107.158.131 dev kube-ipvs0 table local proto kernel scope host src 10.107.158.131

在这里可以看到。路由表中过滤了一下对应的IP地址,可以看到他要通过kube-ipvs0这个虚拟设备发出。
这个虚拟设备也是kube-proxy添加的了,这个虚拟设备就像一根网线,一端在宿主机上,一段对接到了IPVS。数据包接下来通过kube-ipvs0发送给了IPVS,IPVS根据自己的策略轮询选择一个endpoints:

# 这里只截取了重要部分
root@debian:~/kubernetes# ipvsadm -Ln
TCP  10.107.158.131:80 rr
  -> 10.244.0.30:80               Masq    1      0          0         
  -> 10.244.0.33:80               Masq    1      0          0         
  -> 10.244.0.34:80               Masq    1      0          0  

IPVS里有目标IP为10.107.158.131的这一条记录。然后从对应的这三个IP轮询获取一个,重新DNAT数据包,比如选择了10.244.0.30这个IP,那么DNAT后数据包的目标IP就改为了10.244.0.30

IPVS自己是发送不了数据包的。他只能把这个数据包重新发送到宿主机的网络栈里。但是这个时候经过IPVS加工处理过的数据包,和Pod请求Pod的数据包没什么区别了。源IP是发送数据包的Pod的IP,目标是nginx 的一个Pod的IP。
所以,主机内核就会根据路由表找到目标IP所在的主机节点发送出去。这里会根据使用的CNI和模式的不同,采取的策略也不同,同样参考上面的文档。但是数据包已经可以正常发送到对端Pod了。

简述

数据包从pod内发出后,在主机内核匹配路由表转发给了IPVS。IPVS虽然说是负载,但是实际上只做了一个DNAT的操作。然后操作结束后数据包的目标IP就不再是Service的,而是对端Pod的了。接下来数据包重新发送到主机网络栈,主机网络栈就可以根据CNI配置的规则进行下一步的转发了。

对于IPVS如何知道Pod的IP,是因为contaoller manage在创建Pod后,会更新endpoints,然后告知 kube-proxy。kube-proxy会去操作修改IPVS的规则表。这样,IPVS就可以轮流的使用多个IP转发数据包了。

所以kube-proxy实际上是操作的IPVS去工作。他们负责给每个节点的IPVS规则表里,加上整个集群的Service对应endpoints的规则。当集群Service较多的时候,iptables的性能就不如IPVS了。文章来源地址https://www.toymoban.com/news/detail-589365.html

到了这里,关于Kubernetes Service的过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【云原生】Kubernetes临时容器

    特性状态: Kubernetes v1.25 [stable] 本页面概述了临时容器:一种特殊的容器,该容器在现有 Pod 中临时运行,以便完成用户发起的操作,例如故障排查。 你会使用临时容器来检查服务,而不是用它来构建应用程序 Pod 是 Kubernetes 应用程序的基本构建块。 由于 Pod 是一次性且可替

    2024年02月15日
    浏览(30)
  • 【云原生】Kubernetes容器编排工具

    目录 1. K8S介绍 1.1 k8s的由来 下载地址 1.2 docker编排与k8s编排相比 1.3 传统后端部署与k8s 的对比 传统部署 k8s部署  ​2. k8s的集群架构与组件 (1) Kube-apiserver (2)Kube-controller-manager  (3)Kube-scheduler   2.2 k8s的配置存储中心 2.3  k8s的Node 组件   (1)Kubelet   (2)Kube-Proxy 

    2024年02月10日
    浏览(29)
  • 【云原生】容器编排工具Kubernetes

    目录 一、 K8S介绍 官网地址: 1.1docker编排与k8s编排相比 1.2特性 1.3功能 二、K8S重要组件 2.1核心组件 (1)Kube-apiserver (2)Kube-controller-manager (3)Kube-scheduler (4)Node ①kubelet ②kube-proxy ③docker (5)etcd 2.2Kubernetes工作原理 三、Pod 3.1 Pod控制器 (1)Deployment (2)ReplicaSet (3)

    2024年02月09日
    浏览(33)
  • 云原生、容器化、Kubernetes、微服务

    作者:禅与计算机程序设计艺术 云原生(Cloud Native)是一个开放且社区驱动的项目,它定义了一组架构原则、最佳实践和工具集,这些原则、实践和工具围绕业务需求和工程实践而设计,可用于开发人员在构建和运行分布式系统时更加顺畅地交付可靠的软件。云原生可以帮助

    2024年02月07日
    浏览(35)
  • 45了解容器编排工具 Kubernetes 的基本概念和应用,包括 Pod、Service

    Kubernetes 是一种用于自动部署、扩展和管理容器化应用程序的开源容器编排工具。它可以轻松地管理和编排应用程序容器,确保它们在大规模的云环境中高效、可靠地运行。本教程将介绍 Kubernetes 的基本概念和应用,包括 Pod 和 Service。 Pod 是 Kubernetes 中最小的可部署对象,是

    2024年02月08日
    浏览(28)
  • 【云原生】kubernetes中容器的资源限制

    目录 1 metrics-server 2 指定内存请求和限制 3 指定 CPU 请求和限制 资源限制 在k8s中对于容器资源限制主要分为以下两类: 内存资源限制: 内存 请求 (request)和内存 限制 (limit)分配给一个容器。 我们保障容器拥有它请求数量的内存,但不允许使用超过限制数量的内存。 官网参

    2024年02月14日
    浏览(34)
  • 云原生Kubernetes:CRI 容器运行时接口

    目录 一、理论 1.​CRI 2.容器运行时层级 3.容器运行时比较 二、总结 (1)概念       Kubernetes Node (kubelet) 的主要功能就是启动和停止容器的组件,我们 称之为容器运行时( Container Runtime) ,其中最知名的就是 Docker 。为了 更具扩展性, Kubernetes 1.5 版本开始就加入了容器运行

    2024年02月09日
    浏览(34)
  • 【Spring Cloud Kubernetes】使用k8s原生service实现服务注册和发现

    @TOC 现在微服务开发模式应用的越来越广泛,注册中心 Eureka 也逐渐被其它注册中心产品替代,比如阿里出品的 Nacos 。随着云原生相关技术的普及, k8s 迅猛发展,我们把 K8s 中的 Pod 暴露给外部访问,通过少了 Service ,这也是今天的主角。 有没有发现,其实 Service 已经解决了

    2024年02月12日
    浏览(39)
  • 【云原生 | 从零开始学Kubernetes】二十、Service代理kube-proxy组件详解

    该篇文章已经被专栏《从零开始学k8s》收录 上一篇文章:Kubernetes核心技术Service实战 点击跳转 Kubernetes service 只是把应用对外提供服务的方式做了抽象,真正的应用跑在 Pod 中的 container 里,我们的请求转到 kubernetes nodes 对应的 nodePort 上,那么 nodePort 上的请求是如何进一步转

    2024年02月03日
    浏览(31)
  • 【云原生|Kubernetes】08-Pod中的Init容器

    Init 容器是一种特殊容器,在 Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 你可以在 Pod 的spec中与用来描述应用容器的 containers 数组平行的位置指定 Init 容器。 Init 容器的状态在 status.initContainerStatuses 字段中以容器状态数组

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包