Kubernetes笔记(6) - Service和Ingress

2023-11-02

Service资源概述

Service是Kubernetes的核心资源类型之一,它通过规则定义出由多个Pod对象组合而成的逻辑集合,以及访问这组Pod的策略。
由Deployment等控制器管理的Pod对象在中断或扩缩容后,Pod组合的IP地址都会发生变化,而引入Service资源后,就可以基于标签选择器将一组Pod定义成一个逻辑组合,并通过自己的IP地址和端口调度代理请求至组内的Pod对象之上,它向客户端隐藏了真实的、处理用户请求的Pod资源,使得客户端的请求看上去就像是由Service直接处理并进行响应的一样。而且Service与Pod对象之间通过标签选择器以松耦合的方式关联,它可以先于Pod对象创建而不会发生错误。

创建Service资源

Service资源基本的配置清单:

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp  
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP

Service资源myapp-svc通过标签选择器关联至标签为“app=myapp”的各Pod对象,它会自动创建名为myapp-svc的Endpoints资源对象,并自动配置一个ClusterIP,暴露的端口由port字段进行指定,后端各Pod对象的端口则由targetPort给出。
分别查看service和endpoint的状态:

kubectl get svc myapp-svc
kubectl get endpoints myapp-svc

向Service对象请求服务

Service资源的默认类型为ClusterIP,它仅能接收来自于集群中的Pod对象中的客户端程序的访问请求。所以为了测试,会创建一个专用的Pod对象,利用其交互式接口来访问service资源。

kubectl run cirros-$RANDOM --rm -it --image=cirros -- sh

启动了一个运行CirrOS容器的Pod,CirrOS是设计用来进行云计算环境测试的Linux微型发行版,它自带HTTP客户端工具curl等。
在容器的交互式接口访问ClusterIP:Port

/ # curl http://10.105.246.145:80
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

Kubernetes集群默认的Service代理模式为iptables,而且使用随机调度算法,因此Service会将客户端请求随机调度至与其关联的某个后端Pod资源上。

Service会话粘性

Service资源还支持Session affinity(会话粘性)机制,它能够将来自同一个客户端的请求始终转发至同一个后端的Pod对象,适用于需要基于客户端身份保存某些私有信息,并根据这些私有信息追踪用户的活动等一类的需求。
Service资源通过spec.sessionAffinity和spec.sessionAffinityConfig两个字段配置粘性会话:

  • sessionAffinity字段用于定义要使用的粘性会话的类型,它仅支持使用“None”和“ClientIP”两种属性值。‰
    • None:不使用sessionAffinity,默认值。‰
    • ClientIP:基于客户端IP地址识别客户端身份,把来自同一个源IP地址的请求始终调度至同一个Pod对象。
  • sessionAffinityConfig用于配置其会话保持的时长,其可用的时长范围为“1~86400”,默认为10800秒

但是Service资源的Session affinity机制仅能基于客户端IP地址识别客户端身份,它会把经由同一个NAT服务器进行源地址转换的所有客户端识别为同一个客户端,调度粒度粗糙且效果不佳,因此实践中并不推荐使用此种方法实现粘性会话。

服务发现

Service为Pod中的服务类应用提供了一个稳定的访问入口,但Pod客户端中的应用如何得知某个特定Service资源的IP和端口呢,这就需要借助服务发现机制来进行。
服务发现机制的基本实现,一般是事先部署好一个网络位置较为稳定的服务注册中心(也称为服务总线),服务提供者(服务端)向注册中心注册自己的位置信息,并在变动后及时予以更新,服务消费者则周期性地从注册中心获取服务提供者的最新位置信息从而“发现”要访问的目标服务资源。
在K8S中可以基于CoreDNS进行服务发现,甚至也可以使用简单的环境变量方式。

服务暴露

Service的IP地址默认仅在集群内可达,集群外部想访问服务,需要首先进行服务的暴露。

Service的类型

Service有四种类似ClusterIP、NodePort、LoadBalancer和ExternalName

  1. ClusterIP:通过集群内部IP地址暴露服务,此地址仅在集群内部可达,而无法被集群外部的客户端访问;
  2. NodePort:建立在ClusterIP类型之上,其在每个Node的IP地址的某静态端口(NodePort)暴露服务,NodePort的路由目标为ClusterIP,简单来说,NodePort类型就是在工作节点的IP地址上选择一个端口用于将集群外部的用户请求转发至目标Service的ClusterIP和Port,这种类型的Service既可如ClusterIP一样受到集群内部客户端Pod的访问,也会受到集群外部客户端通过套接字NodeIP:NodePort进行的请求;
  3. LoadBalancer:建构在NodePort类型之上,其通过cloud provider提供的负载均衡器将服务暴露到集群外部,LoadBalancer类型的Service会指向关联至Kubernetes集群外部的某个负载均衡设备,该设备通过工作节点之上的NodePort向集群内部发送请求流量,这种Service的优势在于,能够把来自于集群外部客户端的请求调度至所有节点(或部分节点)的NodePort之上,而不是依赖于客户端自行决定连接至哪个节点,从而避免了因客户端指定的节点故障而导致的服务不可用;
  4. ExternalName:通过将Service映射至由externalName字段的内容指定的主机名来暴露服务,此主机名需要被DNS服务解析至CNAME类型的记录。这种类型并非定义由Kubernetes集群提供的服务,而是把集群外部的某服务以DNS CNAME记录的方式映射到集群内,从而让集群内的Pod资源能够访问外部的Service的一种实现方式,这种类型的Service没有ClusterIP和NodePort,也没有标签选择器用于选择Pod资源。
NodePort

NodePort型的Service资源,其配置清单与前面默认的ClusterIP类型类似,只是要显式地在spec下指定type: NodePort
此外还可以指定Node端口,但必须在30000-32767之间,而且推荐使用集群自动分配的端口以避免端口的冲突。

LoadBalancer

NodePort类型的Service资源虽然能够于集群外部访问得到,但外部客户端必须得事先得知NodePort和集群中至少一个节点的IP地址,且选定的节点发生故障时,客户端还得自行选择请求访问其他的节点,此外有时节点并不允许外界访问,LoadBalancer类型可将请求流量调度至各节点的NodePort之上。
创建LoadBalancer类型需要指定type: LoadBalancer

ExternalName

ExternalName类型的Service资源用于将集群外部的服务发布到集群中以供Pod中的应用程序访问。需要指定type: ExternalName和externalName,比如externalName: redis.ilinux.io,externalName属性定义了一个CNAME记录用于返回外部真正提供服务的主机的别名,而后通过CNAME记录值获取到相关主机的IP地址。

spec:
  type: ExternalName
  externalName: redis.ilinux.io

服务创建后通过serviceName访问相应的服务,ClusterDNS会将此名称以CNAME格式解析为spec.externalName字段中的名称,而后通过DNS服务将其解析为相应的主机的IP地址。

Ingress和Ingress Controller

在Kubernetes中,Service资源和Pod资源的IP地址仅能用于集群网络内部的通信,所有的网络流量都无法穿透边界路由器以实现集群内外通信。Kubernetes提供了两种内建的云端负载均衡机制(cloud loadbalancing)用于发布公共应用:

  • 一种是工作于传输层的Service资源,它实现的是“TCP负载均衡器”,无论是iptables还是ipvs模型的Service资源都配置于Linux内核中的Netfilter之上进行四层调度,是一种类型更为通用的调度器,支持调度HTTP、MySQL等应用层服务。
    但由于工作于传输层而功能有局限,比如不支持基于URL的请求调度机制,而且Kubernetes也不支持为其配置任何类型的健康检查。
  • 另一种便是Ingress资源,它实现的是“HTTP(S)负载均衡器”,属于应用层负载均衡机制的一种,它提供了诸如可自定义URL映射和TLS卸载等功能,并支持多种类型的后端服务器健康状态检查机制。

Ingress是Kubernetes API的标准资源类型之一,它其实就是一组基于DNS名称(host)或URL路径把请求转发至指定的Service资源的规则,用于将集群外部的请求流量转发至集群内部完成服务发布,它仅是一组路由规则的集合,Ingress控制器根据这些规则来匹配并路由请求流量。

Ingress资源

Ingress资源是基于HTTP虚拟主机或URL的转发规则。Ingress资源的定义方式举例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations: 
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: www.ilinux.io
    http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: myapp-svc
              port: 
                number: 80


spec字段下主要嵌套如下三个字段

  • rules,用于定义当前Ingress资源的转发规则列表;未由rules定义规则,或者没有匹配到任何规则时,所有流量都会转发到由backend定义的默认后端。‰
  • backend,默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,至少应该定义backend或rules两者之一;此字段用于让负载均衡器指定一个全局默认的后端。backend对象的定义由两个必选的内嵌字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源的名称和端口。‰
  • tls,TLS配置,目前仅支持通过默认端口443提供服务;如果要配置指定的列表成员指向了不同的主机,则必须通过SNI TLS扩展机制来支持此功能。
Ingress资源类型
单Service资源型Ingress

暴露单个Service的方法可以使用NodePort、LoadBalancer,也可以使用Ingress来暴露服务,只需要为Ingress指定“default backend”,这样Ingress控制器会为其分配一个IP地址接入请求流量,并将它们转至指定的后段service,如:

spec:
  backend:
    serviceName: my-svc
    servicePort: 80
基于URL路径进行流量分发

Ingress也支持基于URL路径进行流量分发,如:

spec:
  rules:
  - host: www.ilinux.io
    http:
      paths:
        - path: /web
          backend:
            service:
              name: myapp-svc-web
              port: 
                number: 80
        - path: /api
          backend:
            service:
              name: myapp-svc-api
              port: 
                number: 80

上面定义的规则会将对www.ilinux.io/web的请求转发到前端service myapp-svc-web,而将www.ilinux.io/api请求转发到后段service myapp-svc-api。

基于主机名称的虚拟主机

如果服务按照域名进行划分,可以将Ingress基于虚拟主机定义如下:

spec:
  rules:
  - host: web.ilinux.io
    ...
  - host: api.ilinux.io
TLS类型的Ingress资源

如果需要以HTTPS发布Service资源,也可以配置TLS协议的Ingress资源,但需要基于一个含有私钥和证书的Secret对象,这在后面的章节会涉及到,在Ingress资源中引用此Secret即可让Ingress控制器加载并配置为HTTPS服务:

spec:
  tls:
  - secretName: ilinuxSecret
  backend:
    ...

Ingress控制器

Ingress控制器自身是运行于Pod中的容器应用,一般是Nginx或Envoy一类的具有代理及负载均衡功能的守护进程,它监视着来自于API Server的Ingress对象状态,并以其规则生成相应的应用程序专有格式的配置文件并通过重载或重启守护进程而使新配置生效。例如,对于Nginx来说,Ingress规则需要转换为Nginx的配置信息。
既然Ingress控制器实际上也是Pod资源,那么也需要接入外部流量,这可以使用NodePort或LoadBalancer类型的Service对象为其接入集群外部的请求流量;或者借助于DaemonSet控制器,将Ingress控制器的Pod资源各自以单一实例的方式运行于集群的所有或部分工作节点之上,并配置这类Pod对象以hostPort或hostNetwork的方式在当前节点接入外部流量。
以部署ingress-nginx并通过专用的Service接入流量为例:
首先apply在线的mandatory.yaml来部署ingress-nginx所需的全部资源,它们的namespace:为ingress-nginx:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

然后定义专用的NodePort型Service资源,注意其selector要与nginx-ingress-controller的selector保持一致:

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: ingress-nginx
  ports:
  - port: 80
    name: http   
    nodePort: 30080
  - port: 443
    name: https   
    nodePort: 30443

然后就可以通过这个NodePort型Serviced的IP:30002访问了。或者也可以根据ingress指定的host名称配置etc/hosts,比如对于如下的ingress配置:

spec:
  rules:
  - host: tomcat.ilinux.io

sudo vim /etc/hosts,添加一行

127.0.0.1 tomcat.ilinux.io

然后也就可以通过tomcat.ilinux.io:30002访问了。

学习资料

《Kubernetes实战进阶》 马永亮著

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kubernetes笔记(6) - Service和Ingress 的相关文章

随机推荐

  • Win11:如何删除D盘中的WindowsApps文件夹

    问题描述 Win11 如何删除D盘中的WindowsApps文件夹 问题截图 问题原因 WindowsApps是微软应用商店使用的文件夹 是可以删除的 有些windows版本也没有微软应用商店 删除后对系统并不会有太大影响 解决方案 1 W
  • Selector的使用

    文章目录 Selector 的使用 1 直接使用 2 Scrapy Shell 3 XPath 选择器 4 CSS选择器 5 正则匹配 Selector 的使用 我们之前介绍了利用Beautiful Soup pyquery 以及正则表达式
  • Vue实例选项之【computed】

    目录 computed 显示效果 methods 和 computed 选项的区别 computed 的 setter 和 getter 属性 computed 计算属性在处理一些复杂逻辑时是很有用的 div p 原始字符串 message
  • 颠倒一个句子中的词的顺序。比如: I am a student颠倒后变成:student a am I.

    package com two public class ReverseWords 题目 颠倒一个句子中的词的顺序 比如 I am a student颠倒后变成 student a am I 词以空格分隔 要求 1 实现速度最快 移动最少
  • 单片机原理及应用 实验四 指示灯数码管的中断控制

    单片机原理及应用 C51 版 功能 开机后D1灭灯 LED1黑屏 随后单击K1 D1状态反转 单击K2 LED1从0开始循环显示0 F字符 实验目的及要求 1 掌握外部中断的工作原理 学会中断程序设计 2 按照实验报告要求图 绘制本实验电路
  • 全文检索Elasticsearch安装和配置

    一 ElasticSearch 介绍 1 1 为什么要用ElasticSearch 当我们访问购物网站的时候 我们可以根据我们随意所想的内容输入关键字就可以查询出相关的内容 这是怎么做到呢 这些随意的数据不可能是根据数据库的字段查询的 那是
  • 2021-08-12PHP面试笔试题记录

    1 编写函数function get duplicate num array in num 获取最大相同元素数组的返回结果数组 其中 in为输入数组 num为相同数组元素的重复上限数值 num gt 2 1 1 例如 in 1 20 20
  • dmmbus地址_www.dmmbus.us服务器iP

    2019 05 09 2020 12 15 69 171 237 26 2019 05 12 2020 12 15 31 13 82 1 2019 05 12 2020 12 15 74 86 142 55 2019 05 16 2020
  • flutter 对一个对象进行fromjson,tojson,encode和decode

    fromJson就是转成我们能app能用的数据 tojson就是转成服务器能用的数据 encode是列表 对象转json decode是json转列表 对象 存在下面的一个对象 RedEnvelopeModel redEnvelopeMod
  • EasyExcel详细教程

    目录 1 Excel导入导出的应用场景 2 EasyExcel特点 3 Excel进行写操作 4 Excel进行读操作 本篇文章为你详细介绍EasyExcel如何进行读取操作 1 Excel导入导出的应用场景 1 数据导入 减轻录入工作量
  • Linux_CGI_CGIC - 获取Get请求字符串

    获取Get请求字符串 Get请求就是我们在浏览器地址栏输入URL时发送请求的方式 或者我们在HTML中定义一个表单 form 时 把action属性设为 Get 时的工作方式 Get请求字符串就是跟在URL后面以问号 开始的字符串 但不包括
  • 知识蒸馏的说明

    本文参考 ChatGPT 温度系数t与top p 超参怎么设置最优 知乎 知识蒸馏系列 一 三类基础蒸馏算法 OpenMMLab的博客 CSDN博客 知识蒸馏算法汇总 知乎 知识蒸馏 Old Summer的博客 CSDN博客 目录 1 Ch
  • IDEA批量替换文件换行符、分隔符CRLF、LF、CR

    全局设置 只对新文件有效 file gt setting gt code style gt Line separator 选中需要替换的分隔符类型 注意 Line separator下面有行小字 applied to new files 意
  • 各种邮箱服务软件对比

    1 宝塔邮局管理器 特点 简单易用 可视化操作 小白也能搞 还有备份功能 一般足够用了 缺点 稳定性真是差 隔三差五的不能收发 没有接口 不能任意修改邮箱密码 只能管理员修改 注意要点 一定要开启ssl 否则有些邮箱给你发邮件你收不到 建议
  • python 学习笔记07: set(集合)类型的操作

    coding UTF 8 version Python2 7 15 set gt 集合学习笔记 Help on class set in module builtin class set object set gt new empty se
  • windows-x86安装qemu-arm虚拟机及文件互传

    一 规划安装目录及环境准备 a 这里是在D盘创建 vm arm64文件夹 然后再里面部署 正在上传 重新上传取消 b 在D盘创建一个存放镜像的目录 image并把镜像放到里面 c 下载qemu 并将软件安装在D vm arm64下qemu下
  • 【解决方案】5G时代浪潮来袭,EasyNVR助力5G厂区视频监控安防采集可视化展示

    智慧工厂被认为是5G技术的重要应用场景之一 利用5G网络将生产设备无缝连接 并进一步打通设计 采购 仓储 物流等环节 满足工业环境下设备互联和远程交互应用需求 TSINGSEE青犀视频面向工厂智能化升级需求 推出5G 智慧工厂方案 构建连接
  • Java-Final关键字

    Java Final关键字 1 概念 final 最终的 final可以修饰的结构 类 最终的类 此类不能被其他类继承 比如String类 StringBuffer类 方法 最终的方法 此方法不能被重写 比如Object 类中的getCla
  • JVM小册(1)------jstat和Parallel GC日志

    JVM小册 1 jstat和Parallel GC日志 一 背景 在生产环境中 有时候会遇到OOM的情况 抛开Arthas 等比较成熟的工具以外 我们可以使用java 提供的jatat和jps jmap等工具来帮助我们排查问题和定位原因 本
  • Kubernetes笔记(6) - Service和Ingress

    Service资源概述 创建Service资源 向Service对象请求服务 Service会话粘性 服务发现 服务暴露 Ingress和Ingress Controller Ingress资源 Ingress控制器 Service资源概述