01 引言

至此,service的相关知识已经讲解完了,下面是相关文章的详情总结:

02 内容整理

先贴上整理的脑图:
在这里插入图片描述

2.1 资源定义

详情参考: 《k8s教程(service篇)-资源定义详解》

ServiceKubernetes实现微服务架构的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上,下面对Service的资源定义进行详细说明。

Service的YAML格式的定义文件的完整内容如下:

apiVersion: v1 
kind: Service  
metadata:     
	name: string   
	namespace: string   
	labels:
		- name: string
	annotations:
		- name: string
spec:          
	selector:[]     
	type: string
	clusterIP: string
	sessionAffinity:string 
	ports:
	- name: string
	  protocol: string
	  port: int
	  targetPort: int
	  nodePort: int
	status:
	  loadBalancer:
		ingress:
			ip: string
			hostname: string

属性说明:

属性名称取值类型必选取值说明
versionStringV1
kindStringService
metadataObject元数据
metadata.nameStringService名称,需符合RFC 1035规范
metadata.namespaceString命名空间,不指定系统时将使用名称为default的命名空间
metadata.labels[]list自定义标签属性列表
metadata.annotation[]list自定义注解属性列表
specObject详细描述
spec.selector[]listLabel Selector配置,将选择具有指定Label标签的Pod作为管理范围
spec.typeStringService的类型,指定Service的访问方式,默认值为ClusterIP。 ClusterIP:虚拟服务IP地址,该地址用于Kubernetes 集群内部的Pod访问,在Node上kube-proxy通过设置的 iptables规则进行转发. NodePort:使用宿主机的端口,使能够访问各Node的外 部客户端通过Node的P地址和端口号就能访问服务. LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均 衡器的P地址,同时定义nodePort和clusterIP,用于公有 云环境
spec.clusterIPString虚拟服务的P地址,当type=ClusterIP时,如果不指定,则系统进行自动分配,也可以手工指定;当type=LoadBalancer 时,需要指定
spec.sessionAffinityString是否支持Session,可选值为ClientIP,默认值为None。 ClientIP:表示将同一个客户端(根据客户端的IP地址决定) 的访问请求都转发到同一个后端Pod
spec.ports[]listService端口列表
spec.ports[].nameString端口名称
spec.ports[].protocolString端口协议,支持TCP和UDP,默认值为TCP
spec.ports[].portint服务监听的端口号
spec.ports[].targetPortint需要转发到后端Pod的端口号
spec.ports[].nodePortint当spec.type=NodePort时,指定映射到宿主机的端口号
StatusObject当spec.type=LoadBalancer时,设置外部负载均衡器的地址,用于公有云环境
status.loadBalancerObject外部负载均衡器
status.loadBalancer.ingressObject外部负载均衡器
status.loadBalancer.ingress.ipString外部负载均衡器的IP地址
status.loadBalancer.ingress.hostnameString外部负载均衡器的主机名

2.2 概念和原理

详情参考:《k8s教程(service篇)-概念和原理》

Service实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、 服务负载均衡等

2.2.1 创建service的方式

① 使用kubectl expose命令创建:

kubectl expose deployment webapp 
service/webapp exposed

查看新创建的Service,可以看到系统为它分配了一个虚拟IP地址(ClusterIP 地址),Service的端口号则从Pod中的containerPort复制而来:
在这里插入图片描述
通过curl 169.169.140.242:8080 也是可以访问的。访问时,会被自动负载分发到了后端两个Pod之一:10.0.95.22:8080或10.0.95.23:8080


② 资源文件的方式创建:
除了使用命令,还可以使用yaml资源文件的方式来创建:

apiVersion: v1
kind: Service
metadata:
	name: webapp
spec:
	ports:
	- protocol: TCP
	  port: 8080
	  targetPort: 8080
	selector:
	  app: webapp

Service定义中的关键字段是ports和selector

  • ports:定义部分指定了Service本身的端口号为8080;
  • targetPort:指定后端Pod的容器端口号;
  • selector:定义部分设置的是后端Pod所拥有的 label:app=webapp

使用kubectl create命令创建后,能看到和使用kubectl expose命令创建Service的效果一样。

2.2.2 endpoint

一个Service对应的 “后端” 由Pod的IP和容器端口号组成,这在k8s系统中称为Endpoint

可以通过kubectl descirbe svc 命令查看Endpoint列表,如:

在这里插入图片描述

2.2.3 负载均衡机制

从服务IP到后端Pod的负载均衡机制,则是由每个Node上的kube-proxy负责实现的

通过Service的负载均衡机制,Kubernetes实现了一种分布式应用的统一入口,免去了客户端应用获知后端服务实例列表和变化的复杂度。

2.2.3.1 kube-proxy的代理模式

目前kube-proxy提供了以下代理模式(通过启动参数--proxy-mode设置):

模式描述
userspace模式用户空间模式,由kube-proxy完成代理的实现,效率最低,不再推荐使用
iptables模式kube-proxy通过设置Linux Kernel的iptablesi规则,实现从Service到后端Endpoint列表的负载分发规则,效率很高。
——————————
但是,如果某个后端Endpoint在转发时不可用,此次客户端请求就会得到失败的响应,相对于 userspace模式来说更不可靠,此时应该通过为Pod设置readinessprobe(服务可用性健康检查)来保证只有达到ready状态的Endpoint才会被设置为Service的后端Endpoint。
ipvs模式在Kubernetes1.11版本中达到Stable阶段,kube-proxy通过设置Linux Kernel的netlink接口设置IPVS规则,转发效率和支持的吞吐率都是最高的。

ipvs模式要求Linux Kernel启用IPVS模块,如果操作系统未启用IPVS内核模块,kube-proxy则会自动切换至iptables模式。同时ipvs模式支持更多的负载均衡策略,如下所述:
——————————
rr(round-robin):轮询;
lc(least connection):最小连接数;
dh(destination hashing):目的地址哈希;
sh(source hashing):源地址哈希;
sed(shortest expected delay):最短期望延时;
nq(never queue):永不排队。
kernelspace模式Windows Server上的代理模式
2.2.3.2 会话保持模式

Service支持通过设置sessionAffinity实现基于客户端IP的会话保持机制,即:首次将某个客户端来源IP发起的请求转发到后端的某个Pod上,之后从相同的客户端 IP发起的请求都将被转发到相同的后端Pod上

配置参数为 service.spec.sessionAffinity,也可以设置会话保持的最长时间(service.spec.sessionAffinityConfig.clientIP.timeoutSeconds),例如下面的服务将会话保持时间设置为10800s(3h):

apiVersion: v1
kind: Service
metadata:
	name: webapp
spec:
	sessionAffinity: ClientIP 
	sessionAffinityConfig:
		clientIP:
		  timeoutSecondes: 10080
	ports:
	- protocol: TCP
	  port: 8080
	  targetPort: 8080
	selector:
	  app: webapp

2.2.4 多端口设置

在下面的例子中,Service设置了两个端口号来分别提供不同的服务,如web服务management服务(下面为每个端口号都进行了命名,以便区分):

apiversion: v1
kind: Service
metadata:
	name: webapp
spec:
ports:
- port: 8080
  targetPort: 8080
  name: web
- port: 8005
  targetPort: 8005 
  name: management
selector:
app: webapp

2.2.5 外部服务定义为service

普通的Service通过Label Selector对后端Endpoint列表进行了一次抽象,如果后端的Endpoint不是由Pod副本集提供的,则Service还可以抽象定义任意其他服务,将一个Kubernetes集群外部的已知服务定义为Kubernetes内的一个Service, 供集群内的其他应用访问

在这里插入图片描述

举例:(用户在创建Service资源对象时不设置Label Selector(后端Pod也不存在),同时再定义一个与Service关联的Endpoint资源对象,在Endpoint中设置外部服务的IP地址和端口号):

apiVersion: v1
kind: Service
metadata:
	name: my-service
spec:
	ports:
	- protocol: TCP
	  port: 80
	  targetPort: 80

-----------
apiversion: v1
kind: Endpoints
metadata:
	name: my-service
subsets:
- addresses:
  - IP: 1.2.3.4
  ports:
  - port: 80

2.2.6 service暴露给外部集群

可以通过Service资源对象的类型字段“type”进行设置。

目前Service的类型如下:

类型描述
ClusterIPKubernetes默认会自动设置Service的虚拟IP地址,仅可被集群内部的客户端应用访问。当然,用户也可手工指定一个ClusterIP地址,不过需要确保该IP在Kubernetes集群设置的ClusterIP地址范围内(通过kube-apiserver 服务的启动参数-service-cluster–ip-range设置),并且没有被其他Service使用
NodePort 将Service的端口号映射到每个Node的一个端口号上,这样集群中的任意Node都可以作为Service的访问入口地址,即NodeIP:NodePort
LoadBalancer将Service映射到一个已存在的负载均衡器的IP地址上, 通常在公有云环境中使用
ExternalName将Service映射为一个外部域名地址,通过externalName字段进行设置
2.2.6.1 NodePort类型
apiVersion: v1
kind: Service
metadata:
	name: webapp
spec:
type: NodePort
ports:
- port: 8080
  targetPort: 8080
  nodePort: 8081
selector:
  app: webapp

使用kubectl create创建了Service之后,就可以通过任意一个Node的IP地址+ NodePort 8081端口号 访问服务了。

2.2.6.2 LoadBalancer类型

通常在公有云环境中设置Service的类型为 “LoadBalancer‘” ,可以将Service映射到公有云提供的某个负载均衡器的IP地址上,客户端通过负载均衡器的IPService的端口号就可以访问到具体的服务,无须再通过kube-proxy提供的负载均衡机制进行流量转发。公有云提供的LoadBalancer可以直接将流量转发到后端Pod上,而负载分发机制依赖于公有云服务商的具体实现。

举例:

apiVersion: v1
kind: Service
metadata:
	name: my-service
spec:
type: LoadBalancer
	selector:
		app: MyApp
	ports:
	- protocol: TCP
	  port: 80
	  targetPort: 9376
	clusterIP: 10.0.171.239

在服务创建成功之后,云服务商会在Service的定义中补充LoadBalancerIP 地址(status字段):

status:
	loadBalancer:
	  ingress:
		- ip:192.0.2.127
2.2.6.3 ExternalName类型

ExternalName类型的服务用于将集群外的服务定义为Kubernetes的集群的Service,并且通过externalName字段指定外部服务的地址,可以使用域名或IP格式,集群内的客户端应用通过访问这个Service就能访问外部服务了

这种类型的Service没有后端Pod,所以无须设置Label Selector。例如:

apiVersion: v1
kind: Service
metadata:
	name: my-service
	namespace: prod
spec:
	type: ExternalName
	externalName: my.database.example.com

在本例中设置的服务名为my-service,所在namespace为prod,客户端访问服务地址my-service.prod.svc.cluster.local时,系统将自动指向外部域名my.database.example.com

2.2.7 Service支持的网络协议

目前Service支持的网络协议如下.

类型描述
TCPService的默认网络协议,可用于所有类型的Service
UDP可用于大多数类型的Service,LoadBalancer类型取决于云服务商对UDP的支持
HTTP取决于云服务商是否支持HTTP和实现机制
PROXY取决于云服务商是否支持HTTP和实现机制
SCTP从Kubernetes1.12版本引入,到1.19版本时达到Beta阶段,默认启用,如需关闭该特性,则需要设置kube-apiserver的启动参数–feature- gates=-SCTPSupport=-false进行关闭

2.2.8 k8s的服务发现机制

2.2.8.1 环境变量的方式

在一个Pod运行起来的时候,系统会自动为其容器运行环境注入所有集群中有效Service的信息。

Service的相关信息包括服务IP、服务端口号、各端口号相关的协议等,通过{SVCNAME_SERVICE_HOST}{SVCNAME_SERVICE_PORT}格式进行设置

webapp服务为例:

apiVersion: v1
kind: Service
metadata:
	name: webapp
spec: 
	ports:
	- protocol: TCP
	  port: 8080
	  targetPort: 8080
	selector:
	  app: webapp

在一个新创建的Pod(客户端应用)中,可以看到系统自动设置的环境变量如下:

WEBAPP_SERVICE_HOST=169.169.81.175
WEBAPP_SERVICE_PORT=8080
WEBAPP_P0RT=tcp://169.169.81.175:8080
WEBAPP_P0RT_8080_TCP=tcp://169.169.81.175:8080
WEBAPP_PORT_8080_TCP_PROTO=tcp
WEBAPP_PORT_8080_TCP_PORT=8080
WEBAPP_PORT_8080_TCP_ADDR=169.169.81.175

然后,客户端应用就能够根据Service相关环境变量的命名规则,从环境变量中获取需要访问的目标服务的地址了,例如:

curl http://${WEBAPP_SERVICE_HOST}:${WEBAPP_SERVICE_HOST}
2.2.8.2 DNS的方式

Service在Kubernetes系统中遵循DNS命名规范,Service的DNS域名表示方法为<servicename>.<namespace>.svc.<clusterdomain>,其中:

字段解析
servicename服务的名称
namespace所在namespace的名称
clusterdomainKubernetes集群设置的域名后缀(例如cluster.local),服务名称的命名规则遵循RFC 1123规范的要求

webapp服务为例,将其端口号命名为“http”:

apiversion: v1
kind: Service
metadata:
	name: webapp
spec:
	ports:
	- protocol: TCP
	  port: 8080
	  targetPort: 8080
	  name: http
	selector:
	  app: webapp

解析名为 “http” 端口的DNS SRV记录
_http._tcp.webapp.default.svc.cluster.local'”,可以查询到其端口号的值为8080
在这里插入图片描述

2.2.9 headless service

在某些应用场景中,客户端应用不需要通过Kubernetes内置Service实现的负载均衡功能,需要自行完成对服务后端各实例的服务发现机制,或者需要自行实现负载均衡功能,此时可以通过创建一种特殊的名为 Headless‘”的服务来实现。

服务名(DNS域名)的解析机制取决于该Headless Service是否设置了Label Selector

2.2.9.1 已设置Label Selector

如果Headless Service设置了Label Selector,Kubernetes则将根据Label Selector查询后端Pod列表,自动创建Endpoint列表,将服务名(DNS域名)的解析机制设置为:当客户端访问该服务名时,得到的是全部Endpoint列表(而不是一个确定的IP地址)。

以下面的Headless Service为例,其设置了Label Selector:

apiversion: v1
kind: Service
metadata:
	name: nginx
	labels:
		app: nginx
spec:
	ports:
	- port: 80
	clusterIP: None
	selector:
	  app: nginx

使用kubectl create命令创建完之后,可以查看该Headless Service的详细信息,可以看到后端的Endpoint列表:
在这里插入图片描述

当客户端通过DNS服务名 “nginx"和服务端口号访问该Headless服务(URL=nginx:80)时,将得到Service后端Endpoint列表"10.0.95.12:80,10.0.9513:80,10.0.95.14:80”,然后由客户端程序自行决定如何操作,例如:通过轮询机制访问各个Endpoint

2.2.9.2 未设置Label Selector

如果headless Service没有设置Label Selector,则Kubernetes将不会自动创建对应的Endpoint列表。

DNS系统会根据下列条件尝试对该服务名设置DNS记录:

  • 如果Service的类型为ExternalName,则对服务名的访问将直接被DNS系统转换为Service设置的外部名称(externalName);
  • 如果系统中存在与Service同名的Endpoint定义,则服务名将被解析为Endpoint定义中的列表,适用于非ExternalName类型的Service

2.2.10 端点分片和服务拓扑

2.2.10.1 端点分片

EndpointSlice通过对Endpoint进行分片管理来实现降低Master和各Node之间的网络传输数据量及提高整体性能的目标。对于Deployment的滚动升级,可以实现仅更新部分Node上的Endpoint信息,Master与Node之间的数据传输量可以减少100倍左右,能够大大提高管理效率。


EndpointSlice根据Endpoint 所在Node的拓扑信息进行分片管理,如图所示

在这里插入图片描述
Endpoint Slices要实现的第2个目标是为基于Node拓扑的服务路由提供支持,这需要与服务拓扑(Service Topology)机制共同实现

2.2.10.2 服务拓扑

在默认情况下,发送到一个Service的流量会被均匀转发到每个后端Endpoint,但无法根据更复杂的拓扑信息设置复杂的路由策略。服务拓扑机制的引入就是为了实现基于Node拓扑的服务路由,允许Service创建者根据来源Node和目标Node的标签来定义流量路由策略


通过对来源Node和目标Node标签的匹配,用户可以根据业务需求对Node进行分组,设置有意义的指标值来标识 “较近” 或者 “较远” 的属性:

例如:对于公有云环境来说,通常有区域(Zone或Region)的划分,云平台倾向于把服务流量限制在同一个区域内,这通常是因为跨区域网络流量会收取额外的费用。另一个例子是把流量路由到由DaemonSet管理的当前Node的Pod 上。又如希望把流量保持在相同机架内的Node上,以获得更低的网络延时。

2.3 dns服务搭建和配置

详情参考: 《k8s教程(service篇)-DNS服务搭建和配置》

2.3.1 dns在k8s服务的发展

发展:SkyDNS => KubeDNS =>CoreDNS

CoreDNS架构图如下:
在这里插入图片描述
描述:

  • 它是由go语言实现的一套高性能、插件式,易于扩展的DNS服务端;
  • 解决了KubeDNS的一些问题, 例如dnsmasq的安全漏洞、externalName不能使用stubDomains进行设置等等;
  • 支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS;
  • 它没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。

2.3.2 coredns搭建

① 修改每个Node上kubelet的启动参数,在其中加上以下两个参数:

  • --cluster-dns=169.169.0.100:为DNS服务的ClusterIP地址。
  • --cluster-domain=cluster.local:为在DNS服务中设置的域名。

② 重启kubelet服务


③ 部署:需要创建3个资源对象:1个ConfigMap、1个Deployment和1个Service

apiVersion: v1
kind: ConfigMap
metadata:
	name: coredns
	namespace: kube-system 
	labels: 
		addonmanager.kubernetes.io/mode: EnsureExists
data:
	Corefile: | 
		cluster.local{
			errors
			health{
				lameduck 5s 
			}
			ready
			kubernetes cluster.local 169.169.0.0/16{ 
				fallthrough in-addr.arpa ip6.arpa
			}
			prometheus: 9153
			forward	./etc/resolv.conf 
			cache 30 
			loop
			reload
			loadbalance
		}
		. {
			cache 30 
			loadbalance
			forward /etc/resolv.conf
		}

---
apiversion: apps/v1
kind: Deployment
metadata:
	name: coredns
	namespace: kube-system 
	labels:
		k8s-app: kube-dns
		kubernetes.io/name: "CoreDNS"
spec:
	replicas: 1
	strategy:
		type: RollingUpdate
		rollingUpdate:
			maxUnavailable: 1
	selector:
		matchLabels: 
			k8s-app: kube-dns
	template:
		metadata:
			labels:
				k8s-app: kube-dns
		spec:
		priorityClassName: system-cluster-critical 
		tolerations:
			- key: "CriticalAddonsonly"
			  operator: "Exists"
		nodeSelector:
			kubernetes.io/os: linux 
		affinity:
			podAntiAffinity:
			preferredDuringSchedulingIgnoredDuringExecution: 
			- weight: 100
			  podAffinityTerm:
			  	labelSelector:
					matchExpressions:
					- key: k8s-app
			          operator: In
			          values: ["kube-dns"]
			    topologyKey: kubernetes.io/hostname
		containers:
		- name: coredns
		  image: coredns/coredns:1.7.0 
		  imagePullPolicy: IfNotPresent
		  resources:
		    limits:
		      memory: 170Mi
		    requests:
		      cpu: 100m
		      memory: 70Mi
		  args: ["-conf","/etc/coredns/Corefile" ]
		volumeMounts:
		- name: config-volume 
		  mountPath: /etc/coredns 
		  readOnly: true
		ports:
		- containerPort: 53
		  name: dns
		  protocol: UDP
		- containerPort: 53
		  name: dns-tcp
		  protocol: TCP
		- containerPort: 9153
		  name: metrics
		  protocol: TCP
		securityContext:
		  allowPrivilegeEscalation: false
		  capabilities:
		    add:
		    - NET_BIND_SERVICE
		    drop:
		    - a11
		  readOnlyRootFilesystem: true 
		livenessProbe:
		  httpGet:
		    path: /health
		    port: 8080
		    scheme: HTTP
		  initialDelaySeconds: 60 
		  timeoutSeconds: 5
		  successThreshold: 1
		  failureThreshold: 5
		readinessProbe:
		  httpGet:
		    path: /ready
		    port: 8181
		    scheme: HTTP
		dnsPolicy: Default
		volumes:
		- name: config-volume
		  configMap:
		    name: coredns
		    items:
		    - key: Corefile
		      path: Corefile

---
apiVersion: v1
kind: Service
metadata:
	name: kube-dns
	namespace: kube-system 
	annotations:
		prometheus.io/port: "9153" 
		prometheus.io/scrape: "true" 
	labels:
		k8s-app: kube-dns
		kubernetes.io/cluster-service: "true" 
		kubernetes.io/name: "CoreDNS" 
spec:
	selector:
		k8s-app: kube-dns
	clusterIP: 169.169.0.100 
	ports:
	- name: dns
	  port: 53
	  protocol: UDP
	- name: dns-tcp
	  port: 53
	  protocol: TCP
	- name: metrics
	  port: 9153
	  protocol: TCP		

使用kubectl create命令依次把资源对象创建,然后可以看到创建成功:
在这里插入图片描述

2.3.3 配置解析

CoreDNS的主要功能是通过插件系统实现的,CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。常用的插件如下:

插件描述
loadbalance提供基于DNS的负载均衡功能
loop检测在DNS解析过程中出现的简单循环问题
cache提供前端缓存功能
health对Endpoint进行健康检查
kubernetes从Kubernetes中读取zone数据
etcd从etcd中读取zone数据,可用于自定义域名记录
file从RFC 1035格式文件中读取zone数据
hosts使用/etc/hosts文件或者其他文件读取zone数据,可用于自定义域名记录
auto从磁盘中自动加载区域文件
reload定时自动重新加载Corefile配置文件的内容
forward转发域名查询到上游DNS服务器上
prometheus为Prometheus系统提供采集性能指标数据的URL
pprof在URL路径/debug/pprof下提供运行时的性能数据
log对DNS查询进行日志记录
errors对错误信息进行日志记录

2.3.4 举例(自定义域名)

etcd和hosts插件都可以用于用户自定义域名记录

下面是使用etcd插件的配置示例,将以“.com”结尾的域名记录配置为从etcd中获取,并将域名记录保存在/skydns路径下:

{
	etcd com{
		path /skydns
		endpoint http://192.168.18.3:2379 
		upstream /etc/resolv.conf 
	}
	cache 160 com 
	loadbalance
	proxy /etc/resolv.conf
}

如果用户在etcd中插入一条“10.1.1.1 mycompany” DNS记录:

$ ETCDCTL_API=3 etcdctl put "/skydns/com/mycompany" '["host":"10.1.1.","ttl":60]'

客户端应用就能访问域名"mycompany.com"了:

$ nslookup mycompany.com
Server:				169.169.0.100
Address:			169.169.0.100#53

Name:				mycompany.com
Address:			10.1.1.1

2.4 node本地dns缓存

详情参考: 《k8s教程(service篇)-Node本地DNS缓存》

Node本地DNS缓存(NodeLocal DNSCache)的工作流程如图所示,客户端Pod首先会通过本地DNS缓存进行域名解析,当缓存中不存在域名时,会将请求转发到集群DS服务进行解析
在这里插入图片描述
部署Node本地DNS缓存工具,主要包括 ServiceAccount、Daemonset、ConfigMap和Service 几个资源对象,详情看原文。

2.5 pod的dns域名

详情参考: 《k8s教程(service篇)-pod的dns域名》

对Pod来说,Kubernetes会为其设置一个<pod-ip>.<namespace>.pod.<cluster-domain>格式的DNS域名,其中Pod IP部分需要用 “-” 替换 “.” 符号,例如下面Pod的IP地址为10.0.95.63

在这里插入图片描述


系统为这个Pod设置的DNS域名为10-0-95-63.default.pod.cluster.local,用 nslookup进行验证,便可以成功解析该域名的IP地址为10.0.95.63
在这里插入图片描述
其它与Service差不多,详情参考原文。

2.6 ingress 7层路由机制

详情参考: 《k8s教程(service篇)-ingress 7层路由机制》

Kubernetes 使用了一个Ingress策略定义一个具体提供转发服务的Ingress Controller,两者结合,实现了基于灵活Ingress策略定义的服务路由功能。

如果是对Kubernetes集群外部的客户端提供服务,那么Ingress Controller实现的是类似于边缘路由器(Edge Router)的功能。

需要注意的是,Ingress只能以HTTPHTTPS提供服务,对于使用其他网络协议的服务,可以通过设置Service的类型 typeNodePortLoadBalancer对集群外部的客户端提供服务


举例:使用Ingress进行服务路由时,Ingress Controller基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint(Pod)上,这样会跳过kube-proxy设置的路由转发规则,以提高网络转发效率,下图是一个典型的HTTP层路由的例子:
在这里插入图片描述
其中:

  • 对http:/mywebsite.com/api的访问将被路由到后端名为api的Service上;
  • 对http:/mywebsite.com/web的访问将被路由到后端名为web的Service上;
  • 对http:/mywebsite.com/docs的访问将被路由到后端名为docs的Service上。

主要流程:部署ingress controller -> 创建ingress策略 -> 客户端通过ingress controller访问后端web-app服务。


关系图大致如下:(图片来自:https://www.cnblogs.com/rancherlabs/p/12034075.html
在这里插入图片描述

03 疑问

如果还是对service的一些概念不清晰,比如:kube-proxy与ingress的关系,可以参考阅读:《Using a Network Load Balancer (NLB) to Expose an Application Outside the Kubernetes Cluster》

暴露k8s的服务的三种方式:

  • NodePort
  • Network Load Balancer (NLB)
  • Ingress (application load balancer, ALB)

原理图如下,以便于理解:
在这里插入图片描述

04 文末

本文主要总结k8s关于Service的一些学习笔记,以便后续的回顾,谢谢大家的阅读,本文完!

Logo

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

更多推荐