Kubernetes Service与服务发现

news/2024/9/20 2:54:01/文章来源:https://www.cnblogs.com/Dxj01/p/18411752

1. Service资源基础概念

1.1 Service资源

Service是Kubernetes标准的API资源类型之一

  • 为动态的Pod资源提供近似静态的流量入口
    • 服务发现:通过标签选择器筛选同一名称空间下的Pod资源的标签,完成Pod筛选
      • 实际上是由与Service同名的Endpoint或EndpointSlice资源及控制器完成
    • 流量调度:由运行各工作节点的kube-proxy根据配置的模式生成相应的流量调度规则
      • iptables
      • ipvs
  • 持续监视着相关Pod资源的变动,并实时反映至相应的流量调度规则之上

image

1.2 动态可配置负载均衡

从Service的视角来看,Kubernetes集群的每个工作节点都是动态可配置的负载均衡器

  • 对于隶属某Service的一组Pod资源,该Service资源能够将集群中的每个工作节点配置为该组Pod的负载均衡器
  • 客户端可以是来自集群之上的Pod,也可以是集群外部的其它端点
  • 对于一个特定的工作节点上的某Service来说,其客户端通常有两类
    • ◆ 该节点之上的进程,可通过该Service的Cluster IP进入
      • Service_IP:Service_Port
    • ◆ 该节点之外的端点,可经由该Service的NodePort进入
      • Node_IP:Node_Port

显然,若客户端进入的节点,并非目标Pod所在的节点时,报文转发的路径中必然存在跃点

image

1.3 Service类型

Service根据其所支持的客户端接入的方式,可以分为4种类型

  • ClusterIP:在集群内部进行通信,。

    • 功能:它为 Service 分配一个集群内的虚拟 IP 地址(Cluster IP),只能在 Kubernetes 集群内部使用,无法从外部直接访问。
    • 场景:当需要集群内服务之间的通信时(例如,前端应用和后端数据库之间的通信)。
    • 访问过程: Client --> Service_IP:Service_Port --> Pod_IP:Pod_Port
  • NodePort:从外部访问集群中的 Service,支持ClusterIP

    • 功能:在每个节点上开放一个静态端口(30000-32767 之间的端口范围),外部流量通过这个端口可以访问集群内的 Service。虽然这种方式允许外部访问,但它没有提供负载均衡的功能。
    • 场景:需要从外部直接访问集群内的应用,但不需要外部负载均衡器时使用。
    • 访问过程: Client --> Node_IP:NodePort --> Pod_IP:Pod_Port
  • LoadBalancer:为外部流量提供负载均衡器。

    • 功能:向云服务提供商(如 AWS, GCP, Azure)请求外部负载均衡器。该负载均衡器会分配一个外部 IP 地址,并将外部流量通过该 IP 地址分发到后端的 Pods。通常适用于需要暴露给互联网的服务。
    • 场景:当你在云环境中运行 Kubernetes,并且需要将服务通过负载均衡器暴露给外部世界时
    • 访问过程:Client --> LB_IP:LB_PORT --> Node_IP:NodePort --> Pod_IP:Pod_Port
  • ExternalName:将 Service 映射到外部的 DNS 名称。

    • 功能:将 Kubernetes 集群内的 Service 请求重定向到外部的 DNS 名称。它不会创建 Kubernetes 集群内部的代理,而是直接将 DNS 查询映射到外部服务。
    • 场景:当你需要从 Kubernetes 内部访问外部服务,并通过 Kubernetes 的 Service 进行管理时(例如访问外部的数据库或 API)。
    • 访问过程: ServiceName --> external Service DNS Name
      • 负责将集群外部的服务引入到集群中
      • 需要借助于ClusterDNS上的CNAME资源记录完成
      • 特殊类型,无需ClusterIP和NodePort
      • 无须定义标签选择器发现Pod对象

image

1.4 Endpoint 资源

Endpoint
概念:Endpoint 是 Kubernetes 的一个 API 资源,存储了 Service 的实际后端地址,即符合 Service 标签选择器的 Pod 的 IP 和端口。
作用:当 Service 被创建时,Kubernetes 的控制器会根据 Service 的选择器动态生成或更新相应的 Endpoint 资源,确保流量正确路由到实际的 Pod。每次 Pod 状态或 IP 地址发生变化,Endpoint 也会更新,保证 Service 始终指向有效的后端。

注意:创建 Service时会自动创建Endpoint资源。集群外部服务引入到集群内部使用时,除了使用Service的ExternalName类型外,可以先创建Endpoint指定后端服务器,最后创建同名Service的方法。

EndpointSlice
概念:EndpointSlice 是对传统 Endpoint 资源的扩展,设计用于提高可扩展性和性能。在大型集群中,Endpoint 资源的单一结构可能导致性能瓶颈,因为每个 Service 可能有成百上千的 Pod。EndpointSlice 引入了分片机制,将后端 Pod 分为多个较小的“切片”。
作用:每个 EndpointSlice 只包含一部分后端 Pod 的地址信息,多个 EndpointSlice 可以一起提供完整的 Pod 列表。这样,当集群规模较大时,可以减少对单个资源的压力,提高网络性能和稳定性。

示例
image

image

image

image

Readiness Probe 的结果直接影响着 Kubernetes 中 Endpoint 的注册。当 Readiness Probe 检查通过时,Kubernetes 会将该 Pod 添加到对应的 Endpoint 中,表示这个 Pod 可以接收流量。反之,如果 Pod 的 Readiness Probe 失败,Kubernetes 会从 Endpoint 中移除这个 Pod,从而避免将流量发送给不健康或未准备好的 Pod。

2. Service及流量转发

2.1 创建Service资源

由Service表示的负载均衡器,主要定义如下内容

  • 负载均衡器入口:ClusterIP及相关的Service Port、NodePort(每个节点的Node IP都可用)
    • 根据通信需求,确定选择的类型
  • 标签选择器:用于筛选Pod,并基于筛选出的Pod的IP生成后端端点列表(被调度的上游端点)
  • Service类型的专有配置

image

2.2 标签和标签选择器

标签:附加在资源对象上的键值型元数据

  • 键标识:由“键前缀(可选)”和“键名”组成,格式为“key_prefix/key_name”
    • 键前缀必须使用DNS域名格式
    • 键名的命名格式:支持字母、数字、连接号、下划线和点号,且只能以字母或数字开头;最长63个字符;
  • “kubectl label”命令可管理对象的标签

标签选择器:基于标签筛选对象的过滤条件,支持两种类型

  • 基于等值关系的选择器
    • 操作符:=或==、!=
  • 基于集合关系的选择器
    • 操作符:in、notin和exists
    • 使用格式:KEY in (VALUE1, VALUE2, …)、 KEY notin (VALUE1, VALUE2, …)、KEY 和 !KEY

示例:
添加标签,标签已存在,使用--overwrite覆盖
image

使用-号删除标签
image

添加Annotations注解示例
image

基于等值关系的选择器,1.过滤app=redis的pod 2.过滤app不等于redis的pod,同样会列出没有app标签的pod
image

基于集合关系的选择器,in表示app里面也有等于mysql wordpress demoapp的都符合条件。notin表示app不匹配mysql wordpress demoapp的以及没有app标签的都符合条件
image

存在性判定,匹配有app标签和没有app标签的pod
image

2.3 Service资源规范

Kubernetes上标准的API资源类型
image

apiVersion: v1 
kind: Service 
metadata: name: … namespace: … 
spec: type <string> # Service类型,默认为ClusterIP selector <map[string]string> # 等值类型的标签选择器,内含“与”逻辑 ports: # Service的端口对象列表 - name <string> # 端口名称 protocol <string> # 协议,目前仅支持TCP、UDP和SCTP,默认为TCP port <integer> # Service的端口号 targetPort  <interger> # 后端目标进程的端口号或名称,名称需由Pod规范定义 nodePort <integer> # 节点端口号,仅适用于NodePort和LoadBalancer类型 clusterIP <string> # Service的集群IP,建议由系统自动分配 externalTrafficPolicy <string> # 外部流量策略处理方式,Local表示由当前节点处理,Cluster表示向集群范围调度 loadBalancerIP <string> # 外部负载均衡器使用的IP地址,仅适用于LoadBlancer externalName  <string> # 外部服务名称,该名称将作为Service的DNS CNAME值

2.4 Service资源示例

2.4.1 ClusterIP Service示例

---
kind: Service
apiVersion: v1
metadata:name: demoapp-svcnamespace: demo
spec:selector:app: demoappports:- name: httpprotocol: TCPport: 80targetPort: 80                       

image

image

image

internalTrafficPolicy: Cluster: 决定流量的路由策略,Cluster 意味着允许集群内的流量,sessionAffinity: None: 不使用会话亲和性(Session Affinity),意味着同一个客户端的请求不一定会总是被路由到同一个 Pod。

image

创建临时pod,使用curl命令测试访问serviceIP和名称,使用名称访问需要加名称空间,默认解析为default名称空间。pod使用的DNS为cluster dns,该dns为service网络的第十个地址

image


### 2.4.2 NodePort Service示例
---
kind: Service
apiVersion: v1
metadata:name: demoapp-nodeport-svcnamespace: demo
spec:type: NodePortselector:app: demoappports:- name: httpprotocol: TCPport: 80targetPort: 80# nodePort: 31398# externalTrafficPolicy: Local

集群内部访问测试

image

使用nodeport集群外部访问测试

image

2.4.3 LoadBalancer Service示例

kind: Service
apiVersion: v1
metadata:name: demoapp-loadbalancer-svcnamespace: demo
spec:type: LoadBalancerselector:app: demoappports:- name: httpprotocol: TCPport: 80targetPort: 80#loadBalancerIP: 1.2.3.4externalTrafficPolicy: Local

访问测试

image

2.5 NodePort Service流量策略

流量策略一:Cluster,表示在整个Kubernetes集群范围内调度;

  • 该流量策略下,请求报文从某个节点上的NodePort进入,该节点上的Service会将其调度至任何一个可用后端Pod之上,而不关心Pod运行于哪个节点;

image

流量策略二:Local,表示仅将请求调度至当前节点上运行的可用后端端点;

  • 该流量策略下,请求报文从某节点NodePort进入后,该节点上的Service仅会将请求调度至当前节点上适配到该Service的后端端点
  • 仅应该从运行有目标Service对象后端Pod对象的节点的NodePort 发起访问
  • 需要在上层做一个loadbalancer

image

LoadBalancer类型的Service
在接入外部流量方面,NodePort存在着几个方面的问题

  • 非知名端口、私网IP地址、节点故障转移、节点间负载均衡、识别能适配到某Service的Local流量策略的节点等
  • 外置的Cloud Load Balancer可以解决以上诸问题

image

Service的externalTrafficPolicy字段用于控制集群外部流量进入集群时的路由和流量处理方式。它有两个可选值:Cluster和Local

  • Cluster
    • 行为:流量进入集群后,会通过 kube-proxy 负载均衡,可能会将流量转发到任意可用的 Pod,无论该 Pod 是否在接收流量的节点上运行。
    • 作用:这种模式提供了跨集群节点的均衡负载,因此,所有节点都可以接收外部流量。
    • 缺点:由于可能涉及跨节点的流量转发,源 IP 地址会被 kube-proxy 隐藏,外部客户端的真实 IP 无法传递给应用。
  • Local
    • 行为:流量只会路由到当前节点上正在运行相应 Service 的 Pod,不会进行跨节点的流量转发。
    • 作用:这种模式可以保留客户端的源 IP,因为没有跨节点的流量转发。
    • 缺点:如果某个节点上没有对应的 Pod,则该节点不会处理外部流量,负载均衡需要更精确。

3. Service名称解析

3.1 Service和Cluster DNS

Cluster DNS(CoreDNS)是Kubernetes集群的必备附件,负责为Kubernetes提供名称解析和服务发现

  • 每个Service资源对象,在CoreDNS上都会自动生成一个遵循“<service>.<ns>.svc.<zone>”格式的名称
    • <service>:当前Service对象的名称
    • <ns>:当前Service对象所属的名称空间
    • <zone>:当前Kubernetes集群使用的域名后缀,默认为“cluster.local”
  • 围绕该名称会生成一些DNS格式的资源记录

CoreDNS会持续监视API Server上的Service资源对象的变动,并实时反映到相关的DNS资源记录中

Pod中各容器默认会在/etc/resolv.conf中,将nameserver指向CoreDNS相关的Service的ClusterIP

  • 由kubelet创建Pod时根据指定的配置自动注入

示例:
进入容器内部解析service相关记录
image

3.2 Service在Cluster DNS上的资源记录

每个Service,在CoreDNS上都会有A/AAAA、SRV和PTR资源记录

  • A/AAAA资源记录
    • <service>.<ns>.svc.<zone>. <ttl> IN A <cluster-ip>
    • <service>.<ns>.svc.<zone>. <ttl> IN AAAA <cluster-ip>
  • 为每个定义了名称的端口生成一个SRV记录,以支持服务发现
    • _<port>._<proto>.<service>.<ns>.svc.<zone>. <ttl> IN SRV <weight> <priority> <port-number> <service>.<ns>.svc.<zone>.
  • 为每个A记录(例如a.b.c.d)或AAAA记录生成对应的PTR记录,例如
    • <d>.<c>.<b>.<a>.in-addr.arpa. <ttl> IN PTR <service>.<ns>.svc.<zone>.
    • h4.h3.h2.h1.g4.g3.g2.g1.f4.f3.f2.f1.e4.e3.e2.e1.d4.d3.d2.d1.c4.c3.c2.c1.b4.b3.b2.b1.a4.a3.a2.a1.ip6.arpa <ttl> IN PTR <service>.<ns>.svc.<zone>.

Pod可基于Service的DNS名称向其发起服务访问请求

3.3 Pod上的DNS解析策略

  • Kubernetes支持在单个Pod资源规范上自定义DNS解析策略和配置,并组合生效
    • spec.dnsPolicy:解析策略
    • spec.dnsConfig:名称解析机制
  • DNS解析策略
    • Default:从运行在的节点继承DNS名称解析相关的配置
    • ClusterFirst:于集群DNS服务上解析集群域内的名称,其他域名的解析则交由从节点继承而来的上游名称服务器
    • ClusterFirstWithHostNet:专用于在设置了hostNetwork的Pod对象上使用的ClusterFirst策略
    • None:用于忽略Kubernetes集群的默认设定,而仅使用由dnsConfig自定义的配置
  • DNS解析机制
    • nameservers <[]string>:DNS名称服务器列表,附加于由dnsPolicy生成的DNS名称服务器之后
    • searches <[]string>:DNS名称解析时的搜索域,附加由于dnsPolicy生成的搜索域之后
    • options <[]Object>:DNS解析选项列表,同dnsPolicy生成的解析选项合并成最终生效的定义

示例:

apiVersion: v1
kind: Pod
metadata:name: pod-with-dnspolicynamespace: default
spec:containers:- name: demoimage: ikubernetes/demoapp:v1.0imagePullPolicy: IfNotPresentdnsPolicy: None  #忽略集群默认设定使用dnsConfig自定义配置dnsConfig:nameservers:  - 10.96.0.10- 223.5.5.5- 223.6.6.6searches:  #搜索域- svc.cluster.local- cluster.local- ilinux.iooptions:  #搜索域中间点号不能超过5个- name: ndotsvalue: "5"

3.4 Headless Service

Service的各类型中,ClusterIP、NodePort和LoadBalancer都为其Service配置一个ClusterIP,CoreDNS上,这些Service对象的A记录也解析为它的ClusterIP;
广义上,那些没有ClusterIP的Service则称为Headless Service,它们又可以为分两种情形

  • 有标签选择器,或者没有标签选择器,但有着与Service对象同名的Endpoint资源
    • Service的DNS名称直接解析为后端各就绪状态的Pod的IP地址
    • 调度功能也将由DNS完成
    • 各Pod IP相关PTR记录将解析至Pod自身的名称,假设Pod IP为a.b.c.d,则其名称为a-b-c-d.<service>.<ns>.svc.<zone>
    • 这种类型也就是狭义上的Headless Service
  • 无标签选择器且也没有与Service对象同名的Endpoint资源
    • Service的DNS名称将会生成一条CNAME记录,对应值由Service对象上的spec.externalName字段指定

示例:
externalname示例

[root@k8s-master01 services]#vim externalname-redis-svc.yaml 
kind: Service
apiVersion: v1
metadata:name: externalname-redis-svcnamespace: default
spec:type: ExternalNameexternalName: redis.ik8s.ioports:- protocol: TCPport: 6379targetPort: 6379nodePort: 0selector: {}

image

解析该externalname服务会解析为redis.ik8s.io的ip地址

image

Headless Service示例

[root@k8s-master01 services]#vim demoapp-headless-svc.yaml 
---
kind: Service
apiVersion: v1
metadata:name: demoapp-headless-svc
spec:clusterIP: Noneselector:app: demoappports:- port: 80targetPort: 80name: http
~                             

image

解析该无头服务时,解析为后端pod对应的ip地址,使用ptr反解pod的ip,解析为pod自己的主机名。

image

endpoints示例

[root@k8s-master01 services]#cat mysql-endpoints-demo.yaml 
apiVersion: v1
kind: Endpoints
metadata:name: mysql-externalnamespace: default
subsets:
- addresses:- ip: 172.29.9.51- ip: 172.29.9.52ports:- name: mysqlport: 3306protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: mysql-externalnamespace: default
spec:type: ClusterIPports:- name: mysqlport: 3306targetPort: 3306protocol: TCP

手动创建endpoints和service
image

image

4. CoreDNS配置方式简介

4.1 CoreDNS的默认配置

CoreDNS的配置都存储在名为coredns的ConfigMap对象中,该对象位于kube-system名称空间中

[root@k8s-master01 coredns]# kubectl get cm coredns -o yaml -n kube-system
apiVersion: v1
data:Corefile: |.:53 {errorshealth {lameduck 5s}readykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30loopreloadloadbalance}
kind: ConfigMap
metadata:creationTimestamp: "2024-08-08T10:14:01Z"name: corednsnamespace: kube-systemresourceVersion: "215"uid: 8ca29b2a-96c6-4fdf-b61a-8dfe633b71e8#服务器配置段 (Server Blocks),用于定义负责解析的权威区域,配置段放置于其后的花括号{}中;
#服务器配置段也可以指定要监听的端口号 (端口号之前需要使用一个冒号),默认为53;
#若在同一端口上配置了多个区域CoreDNS将使用最长匹配机制来评估并挑出最适配的服务器配置段;
#随后,请求将由该服务器配置段中的插件链按特定顺序 (在构建CoreDNS程序时由plugin.cfg文件指定) 进行路由;
#针对一个DNS查询,相应配置段插件链中的每个插件都会检查并确定是否应该对其进行处理#每个服务器配置段都需要配置一些要使用的插件 (这些插件也可称为该服务器的插件链),用来为该服务器提供更加丰富的功能与配置,例如配置中的errors、health、ready、kubernetes、prometheus .forward等CoreDNS的插件可大致分为两类#负责处理请求的常规插件,这些插件才是插件链中的有效组成部分,例如errors、kubernetes和forward等;#不处理请求的特殊插件,它们仅用来修改Server或Server Block中的配置,例如health、tls、startup、shutdown和root等插件;这些用于处理请求的插件又大体可以分为两类:#负责执行请求的插件#后端插件: 用于配置区域数据的来源例如etcd、file和kubernetes等

4.2 CoreDNS上常用的插件简介

image
image

4.3 CoreDNS查询路由概述

CoreDNS处理DNS查询的方式:

  • 针对每个套接字,CoreDNS会生成一个服务器(dnsserver.Server)
  • 一个套接字上存在多个配置段(Server Block)时,CoreDNS将组合这些配置段生成单个服务器上的多个独立配置段,并将发往该套接字的DNS查询请求路由到最佳匹配的目标配置段
  • 若不存在匹配的服务器配置段,则返回SERVERFAIL

CoreDNS的插件可大致分为两类:

  • 负责处理请求的常规插件(Normal Plugin),这些插件才是插件链中的有效组成部分,例如errors、kubernetes和forward等
  • 不处理请求的特殊插件,它们仅用来修改Server或Server Block中的配置,例如health、tls、startup、shutdown和root等插件,这类插件不会作为服务器配置段的插件链中的有效组成部署

常规插件可再次划分为两种类型:

  • 负责以某种方式处理请求的插件
    • 这类插件不是区域数据源,它们的运行方式是在自身处理完成后,会将查询传递给下一个插件
  • 后端插件
    • 用于配置区域数据的来源,例如etcd、file和kubernetes等
    • 这类插件通常要为其负责的区域生成最终结果,它要么能正常响应查询,要么返回NXDOMAIN
    • 但也可以使用fallthrough改变这种响应行为:未发现查询的目标资源记录时,将DNS查询请求转交给插件链中的下一个插件,随后终结于另一个后端插件,或再次由fallthrought改变这种行为

4.3.1 CoreDNS查询路由示例

配置示例

image

路由处理办法及相应的插件链

image

4.3.2 CoreDNS的kubernetes插件

插件的配置参数简介

  • endpoint:指定kubernetes API Server的URL,默认为CoreDNS Pod所使用的ServiceAccount可接入的自身所在集群的API Server
  • tls:用于建立远程k8s连接时要使用的tls证书、私钥和CA证书
  • kubeconfig:用于谁到远程k8s时使用的kubeconfig文件
  • namespaces:仅对外暴露(提供Service名称解析)的k8s名称空间的列表,默认为所有名称空间
  • labels:namespace资源对象的标签选择器,匹配到的namespace中的Service才会对外暴露
  • pods:为Pod生成基于IP的资源记录时的处理模式
    • disabled:不处理Pod级别的名称解析请求,默认配置
    • insecure:不检查k8s,而直接返回一个带有IP地址的A记录
    • verified:若同一namespace中存在具有匹配的IP地址的Pod,则返回A记录
  • noendpoints:禁止endpoint相关的资源记录,所有endpoint查询和headless查询都将生成NXDOMAIN
  • fallthrough:若当前插件解析失败,则仅将针对指定zone列表中的查询请求继续交由插件链中后续的插件进行处理
  • ignore empty_service:为没有任何就绪的Service返回NXDOMAIN

image

4.3.3 CoreDNS的rewrite插件

在CoreDNS内部对查询及响应进行重写,重写过程对客户端透明
语法:rewrite [continue|stop] FIELD [TYPE] [(FROM TO)|TTL] [OPTIONS]

  • FIELD:用于指定请求或响应中的哪部分内容被重写
    • type:请求的类型字段被重写,此时FROM/TO必须是DNS记录类型,如A、MX等
    • name:重写查询请求中要查询的名称,默认情况下,其将执行名称的完全匹配
    • class:消息的类别被重写,此时FROM/TO必须是DNS class的类型,如IN、CH或HS等
    • edns0:将EDNS0选项附加到请求中
    • ttl:重写响应报文中的TTL值
  • TYPE:FILE字段为name时,用于指定匹配name值的方式
    • exact(默认):精确匹配,与查询请求中的名称完全匹配
    • substring:匹配查询请求中的名称的子串
    • prefix:匹配查询请求中的名称的前缀
    • suffix:匹配查询请求中的名称的后缀
    • regex:使用正则表达式模式匹配查询请求中的名称
  • FROM:要匹配的名称或类型
  • TO:要重写成的目标名称或类型
  • TTL:在响应报文中要设定的ttl值,仅适用于ttl FIELD

image

语法

  • OPTIONS:name FIELD还支持对响应报文进行隐式重写
    • answer auto:尽力完成响应报文中名称部分的重写
    • answer name FROM TO:将响应报文中的匹配FROM的查询名称重写为TO
    • answer value FROM TO:将响应报文中的匹配FROM的用于(例如CNAME或SRV资源记录中)响应的名称重写为TO
  • continue:继续由后面的rule进行处理
  • stop:将当前rule视作最后一条,即当前rule处理完成后即返回响应;此为默认行为

一般来说,重写查询的name比较常见

  • 语法:rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING [OPTIONS]
  • 例如:rewrite name regex (jenkins.*)\.magedu\.com {1}.jenkins.svc.cluster.local
    image

响应报文rewrite

  • 隐式的响应重写,可以定义在rewrite name规则的OPTIONS中

    • 例如: rewrite name regex (jenkins.*)\.magedu\.com {1}.jenkins.svc.cluster.local answer auto
      image
  • 显式报文重写,要使用明确定义的answer规则进行

    • 例如
      image

示例1:

#导出coredns的配置并添加rewrite配置,应用生效
[root@k8s-master01 ~]#kubectl get cm coredns -n kube-system -o yaml >> /tmp/coredns.yaml
[root@k8s-master01 ~]#cat /tmp/coredns.yaml 
apiVersion: v1
data:Corefile: |.:53 {errorshealth {lameduck 5s}readyrewrite name demoapp-svc.magedu.com demoapp-svc.demo.svc.cluster.localkubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30loopreloadloadbalance}
kind: ConfigMap
metadata:name: corednsnamespace: kube-system[root@k8s-master01 ~]#kubectl apply -f /tmp/coredns.yaml

测试解析demoapp-svc.magedu.com重写成了demoapp-svc.demo.svc.cluster.local的ip地址

image

image

image

示例2:

[root@k8s-master01 ~]#cat /tmp/coredns.yaml 
apiVersion: v1
data:Corefile: |.:53 {errorshealth {lameduck 5s}readyrewrite name regex (demoapp.*).magedu.com {1}.demo.svc.cluster.local answer auto #响应自动重写#answer name (demoapp.*).demo.svc.cluster.local {1}.magedu.com #显示报文重写kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30loopreloadloadbalance}
kind: ConfigMap
metadata:name: corednsnamespace: kube-system
[root@k8s-master01 ~]#kubectl apply -f /tmp/coredns.yaml
configmap/coredns configured

默认使用正regex正则,响应结果为非透明的,客户端看到的响应域名与查询域名不一致。

image

image

配置answer auto测试发现响应解析域名与查询一致。
image

显示重写配置
image

CoreDNS配置示例

prefer_udp:使用udp协议查询解析
forward:可以配置多个解析不同区域,多个forward时需要添加fallthrough,避免一个forward解析不了无法传递给下一个进行解析
image

[root@k8s-master01 ~]#cat /tmp/coredns.yaml 
apiVersion: v1
data:Corefile: |.:53 {errorshealth {lameduck 5s}readyrewrite { name regex (demoapp.*).magedu.com {1}.demo.svc.cluster.local answer name (demoapp.*).demo.svc.cluster.local {1}.magedu.com }hosts {         #使用hosts解析节点名称10.0.0.101 k8s-master01.magedu.com10.0.0.102 k8s-node01.magedu.com10.0.0.103 k8s-node02.magedu.comfallthrough      #该配置避免hosts无法解析其他域名时转发给下一配置进行解析}kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {   #将根区域转发给节点DNS服务器进行解析max_concurrent 1000}cache 30loopreloadloadbalance}
kind: ConfigMap
metadata:name: corednsnamespace: kube-system

测试效果
image

5. Service流量转发小结

5.1 Service流量转发机制

  • ClusterIP类型
    • 源自Pod
      • 没启动masquerade-all(全地址转换):请求报文的目标IP和目标端口由Service转为挑选出的后端Pod的IP和端口,并由后端Pod直接响应给客户端Pod
        •  发夹问题:Pod访问自身所属的Service后,由Service又调度回该Pod
        •  存在发夹问题(haripin)的场景中,需要启用源IP地址转换
      • 启用masquerade-all:请求报文的源IP和目标IP都将由Service进行转换,原IP将转为客户端Pod所在节点在Pod网络中的IP地址
    • 源自非Pod网络中的请求流量
      • 接入流量的节点充当NAT网关,请求报文的源IP和目标IP都将由Service进行转换
  • NodePort和LoadBalancer类型
    • 流量来自集群外部,节点扮演网关的角色,请求报文的源IP和目标IP都将由Service进行转换,原IP将转为客户端Pod所在节点的IP地址,以确保响应报文能正确送达

流量转发示意图:请求报文,目标地址转换都会进行,未启用masquerade-all时,源地址转换将视情况进行

  • Pod网络是虚拟网络,最终还是要通过节点网络完成报文传送,因此,SNAT通常会使用节点网络中的地址
    image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/799457.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt::BlockingQueuedConnection 与 QMetaCallEvent

Qt 创建连接类型如果是 Qt::BlockingQueuedConnection,即sender thread 与 receiver thread 不同, 但是要求 sender signal 与 receiver slot 执行是 不同线程间的同步行为。也即:在sender signal 发出后 sender线程 要 等待 receiver 线程的 slot 执行完后才能继续 向后执行…

设备地址

设备地址 BLE的设备地址可以使用公共地址(Public Device Adress)或者随机地址(Random Device Address),一个BLE至少使用一种地址类型,当然也可以同时使用两种地址类型。 公共地址和随机地址一样,都是48位(6字节),BLE设备地址关系如下:公共地址:从IEEE申请(购买),I…

扫码详见阳子公众号

https://mp.weixin.qq.com/mp/qrcode?scene=10000004&size=102&__biz=MzkwNzc0MjQ1MA==&mid=2247484006&idx=1&sn=43425e98c08a3887b090c927d89cbe40&send_time= 或直接扫码:

使用Addressables+SpriteAtlas打包产生冗余

1)使用Addressables+SpriteAtlas打包产生冗余2)使用SBP打AssetBundle脚本引用丢失3)Unity构建后处理(IPostprocessBuildWithReport等接口)抛出异常后,构建不会停止4)Unity 2022.3.0版本使用Occlusion,PC运行良好但是安卓手机无效这是第400篇UWA技术知识分享的推送,精选…

如何编制一份数据分析报表?这篇文章告诉你重点

在当今数据驱动的时代,数据分析报表成为了企业决策中不可或缺的工具。它不仅可以帮助我们清晰地展现数据,还能揭示数据背后的趋势与问题,为管理者提供有力的支持。那么,如何编制一份高效、准确的数据分析报表呢?本文将从数据分析报表的分类、制作原则以及具体步骤来为你详…

centos7下安装Python3.7

centos7默认安装的是python2.7,然而python2基本上要淘汰了,所以有必要安装最新的python3 python,g++这些工具一般安装在/usr/bin目录里 通过指令ll python*可以看到python指向的是python2.7我们要安装python3,使python指向python3 下面开始具体步骤(参考其他大佬的方法,也…

wpf简单自定义控件

用户控件(User Control)和自定义控件(Custom Control)的区别: UserControl: 将多个WPF控件(例如:TextBox,TextBlock,Button)进行组合成一个可复用的控件组; 由XAML和Code Behind代码组成; 不支持样式/模板重写; CustomControl 自定义控件,扩展自一个已经存在的控件,并…

应用AI技术的销售进化论

该文章聚焦AI技术在销售行业中的实际应用,解读销售人员如何利用先进技术及工具突破传统限制,增强业务能力帮助销售人员保持竞争优势,提升工作效率与业绩。 1、AI如何重塑销售规则 1.1 AI在销售领域的应用:不只是数字游戏 在销售领域,AI技术的引入正在重塑传统的销售模式,…

yum报错

参考这篇文章:https://www.cnblogs.com/kohler21/p/18331060Loading mirror speeds from cached hostfile Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was 14: curl#6 - "Could not re…

STM32H723+DMA+ADC多通道 问题记录

出现的问题1: ADC当开启扫描模式、DMA开始连续模式的时候,依然只能读出第一个通道的ADC的值,后面通道的AD值不更新。 尝试过将buf 固定在RAM_D3中也没有用。 实际最后问题在于,用STM32CubeMX配置工具生成代码的时候,ADC初始化的函数放在了DMA初始化的前面导致的问题。 出现…

改变您的HTTP服务器的缺省banner

原文链接:https://www.cnblogs.com/zmbhfly/p/10510594.html改变您的HTTP服务器的缺省banner 针对 IIS Asp.net,改变您的HTTP服务器的缺省banner引自:https://www.cnblogs.com/felixnet/p/6344613.html测试可以用,但仅仅是修改的应用程序,http://localhost不起作用 https:…

Paper Reading: Deep forest auto-Encoder for resource-Centric attributes graph embedding

本文设计了一种基于深度森林的embedding 学习方法 GraphDF,该方法可以实现以资源为中心的加权属性图的属性和拓扑信息的嵌入。提出的图预处理器包括基于自注意机制的潜在隐含特征挖掘、基于相似性和模块化相关转换对潜在隐含关系特征的深度一般信息挖掘。使编码器所提取的原始…