【云原生】K8S 相关知识点整理 -- Service

【1】Service 的作用

在 K8S 中,Pod 存在生命周期,如果 Pod 重启则其 IP 可能会发生变化,若服务将 Pod 的 IP 地址写死,当 Pod 挂掉或者重启后,和刚重启的 Pod 相关联的服务将会找不到其所关联的 Pod,为了解决这个问题,在 K8S 中定义了 Service 资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,Service 是一组 Pod 的逻辑集合,这一组 Pod 能够被 Service 访问到 (通常是通过 Label Selector 实现的);

  • 1、Pod IP 经常变化,Service 是 Pod 的代理,客户端只需要访问 Service 就会把请求代理到 Pod
  • 2、Pod IP 在 K8S 集群之外无法访问,所以需要创建 Service,该 Service 可以在 K8S 集群外访问

【2】Service 简介
Service 是一个固定接入层,客户端可以通过访问 Service 的 IP 和端口访问到 Service 关联的后端 Pod;

Service 工作依赖于在 K8S 集群之上部署的 DNS 服务 (不同版本的 K8S 默认使用的 DNS 是不一样的,1.11 之前的版本使用的是 kubeDNs,较新的版本使用的是 coredns);

Service 的名称解析依赖于 DNS 服务,因此在部署完 K8S 之后需要再部署 DNS 服务,K8S 需要依赖第三方的网络插件 (flannel,calico 等) 给客户端提供网络功能;

每个 K8S 节点上都有一个 kube-proxy 组件,该组件将监视 apiserver 中有关 Service 资源的变动信息,与 master 之上的 apiserver 交互,随时获取与 Service 相关的资源的变动状态 (通过 K8S 中 Watch (监视) 方法实现),一旦有 Service 资源的内容发生变动 (如创建,删除),kube-proxy 都会将其转化成当前节点之上能够实现的 Service 资源调度,把请求调度到后端特定的 Pod 资源之上的规则 (该规则可能是 iptables,也可能是 ipvs,取决于 Service 的实现方式);

【3】Service 工作原理
K8S 在创建 Service 时,会根据标签选择器 (lable selector) 查找 Pod,据此创建与 Service 同名的 endpoint 对象,当 Pod 地址发生变化时,endpoint 也会随之发生变化,Service 接收前端 client 请求的时候,就会通过 endpoint,找到 Pod 的地址进行访问 (至于转发到哪个节点的 Pod,由负载均衡 kube-proxy 决定);

【4】K8S 集群中有三类 IP 地址

  • 1. Node Network (节点网络) : 物理节点或者虚拟节点的网络
    • 查询命令,ip addr
  • 2. Pod network (Pod 网络),创建的 Pod 具有的 IP 地址
    • 查询命令,kubectl get pods -o wide
  • 3. Cluster Network (集群地址,也称为 Service Network)
    • 查询命令,kubectl get svc

说明

  • Node Network 和 Pod Network 这两种网络地址是实实在在配置的,其中节点网络地址是配置在节点接口之上,而 Pod 网络地址是配置在 Pod 资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的
  • Cluster Network 是虚拟地址(virtual ip),没有配置在某个接口上,只是出现在 Service 的规则当中

【5】Service 服务代理 -- kube-proxy 组件简介

【5.1】kube-proxy 组件介绍
K8S Service 只是抽象了应用对外提供服务的方式,真正的应用跑在 Pod 中的 Container 里,客户的请求转到 K8S Nodes 对应的 NodePort 上,NodePort 上的请求通过 kube-proxy 进一步转到提供后台服务的 Pod;
kube-proxy 部署在 K8S 的每一个 Node 节点上,是 K8S 的核心组件,当创建一个 Service 的时候,kube-proxy 会在 iptables 中追加一些规则,以实现路由与负载均衡的功能;

  • 在 K8S1.8 之前,kube-proxy 默认使用的是 iptables 模式,通过各个 Node 节点上的 iptables 规则来实现 Service 的负载均衡,但是随着 Service 数量的增大,iptables 模式由于线性查找匹配、全量更新等特点,其性能会显著下降;
  • 从 K8S1.8 开始,kube-proxy 引入了 IPVS 模式,IPVS 模式与 iptables 同样基于 Netfilter,但是采用了 hash 表,因此当 Service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 Service 的服务性能;

Service 是一组 Pod 的服务抽象,相当于一组 Pod 的 LB (负载均衡),负责将请求分发给对应的 Pod,Service 会为这个 LB (负载均衡) 提供一个 IP,一般称为 Cluster IP,kube-proxy 的作用主要是负责 Service 的实现,具体来说,就是实现内部 -> 从 Pod 到 Service 和外部 -> 从 Node Port 向 Service 的访问

  • 1. kube-proxy 是管理 Service 的访问入口,包括集群内 Pod 到 Service 的访问和集群外访问 Service
  • 2. kube-proxy 管理 Sevice 的 Endpoints,该 Service 对外暴露一个 Virtual IP,也可以称为是 Cluster IP, 集群内通过访问这个 Cluster IP:Port 就能访问到集群内对应 Serivce 下的 Pod

【5.2】kube-proxy 的工作模式
【5.2.1】userspace 模式


Client Pod 访问 Server Pod 时,请求会先发给内核空间中的 service iptables 规则,再将请求转给监听在指定套接字上的 kube-proxy 的端口,kube-proxy 处理完请求,并确定请求待分发的 Server Pod 后,再将请求转发给内核空间中的 service iptables,由 service iptables 将请求转给各个节点中的 Server Pod;
该模式存在的主要问题是客户端请求先进入内核空间,再进入用户空间访问 kube-proxy,由 kube-proxy 封装完成后再进去内核空间的 iptables,再根据 iptables 的规则分发给各节点用户空间的 Pod,由于其需要来回在用户空间和内核空间交互通信,效率很差;
userspace 模式,在 K8S 1.1 版本之前,userspace 是默认的代理模型;
【5.2.2】iptables 模式

客户端发起请求时,直接请求本地内核 Service iptables,根据 iptables 的规则直接将请求转发到到各 Pod 上,因为使用 iptable NAT 来完成转发,仍然存在性能损耗;另外,如果集群中存在上万的 Service/Endpoint,那么 Node 上的 iptables rules 将会非常庞大,性能还会再打折;
iptables 代理模式由 K8S 1.1 版本引入,自 1.2 版本开始成为默认类型;
【5.2.3】ipvs 模式

客户端请求到达内核空间时,根据 ipvs 的规则直接分发到各 Pod 上,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 模式由 K8S1.9-alpha 版本引入,自 1.11 版本开始成为默认类型;

【6】Service 服务发现 -- coredns 组件简介

【6.1】DNS 与 CoreDNS 简介
域名系统 (Domain Name System,DNS),是整个互联网的电话簿,它能够将可被人理解的域名翻译成可被机器理解 IP 地址,域名系统在现在的互联网中非常重要,因为服务器的 IP 地址可能会经常变动,如果没有了 DNS,那么 IP 地址一旦发生了更改,当前服务器的客户端就没有办法连接到目标的服务器了,如果为 IP 地址提供一个 "别名" 并在其发生变动时修改别名和 IP 地址的关系,那么就可以保证集群对外提供的服务能够相对稳定地被其他客户端访问;DNS 其实就是一个分布式的树状命名系统,它就像一个去中心化的分布式数据库,存储着从域名到 IP 地址的映射;
CoreDNS 其实就是一个 DNS 服务,Kubernetes 在集群中使用 CoreDNS 解决服务发现的问题;

参考与致谢
本博客为博主学习笔记,同时参考了网上众博主的博文以及相关专业书籍,在此表示感谢,本文若存在不足之处,请批评指正。

【1】kubernetes核心组件kube-proxy

【2】kube-proxy支持的三种工作模式

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容