基本介绍

SVC的ip到后端Pod负载均衡机制,是由每个Node上的Kube-proxy负责实现的。下面讲述kube-proxy的代理模式、会话保持机制和基于拓扑感知的服务路由机制说明;

①:kube-proxy的代理模式

一:userspace模式:效率低
二:iptables模式:kube-proxy通过Linux kernel的iptables规则,实现对svc到后端EP的负载分发规则。
##这里当某服务可能正在处于启动过程中,而因转发失败则得到失败的响应。(不可靠,因此,通过readinessprobe来保证只有ready状态的EP才会被设置到svc后端的EP)
三:ipvs模式:通过linux Kernel的netlink接口设置IPVS规则,转发效率和支持的吞吐率都是最高的。
IPVS支持:轮询、最小连接数、目的地址哈希、源地址哈希、最短期望延时、用不排队等。
四:kernelspace模式:windows Server上的代理模式。

②:会话保持机制

svc通过sessionAffinity实现基于客户端IP的会话保持机制(保证会话不中断!)yaml部分配置如下:
在这里插入图片描述

③:SVC多端口类型

服务暴露:

将外部服务定义为SVC
图例:
在这里插入图片描述

将SVC暴露到集群外部

主要有如下几种方式:
ClusterIP:默认设置的svc的虚拟IP地址,仅可被集群内部的客户端应用访问。也可以通过yaml里面定义ClusterIP;
NodePort:将svc的端口号映射到每个Node的端口上;
LoadBalancer:将SVC映射到一个已存在的负载均衡器的IP地址上;
ExternalName:将SVC映射为一个外部域名地址,通过externalName字段设置;

下面为Nodeport的SVC的yaml文件:
(可以应用在多网卡的情况下,在kube-proxy文件内配置启动参数 “–nodeport-addresses= A/16,B/8…………”)

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 8081
    #####注意这里的配置####
### 这里的port指节点开的端口 ####
### targetPort指的是pod的端口 ###
### nodePort 指的是SVC对外暴露的端口 ###**

loadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - port: <Port>
    targetPort: <Target Port>
  clusterIP: 10.0.0.8
###  公有云厂商后续完成负载分发机制  ###
status:
  loadBalancer:
    ingress:
    - ip: …………

ExternalName:(这个因为是外部的服务,因此集群内没有后端服务,也不需要selector了)
在这里插入图片描述

SVC支持的网络协议

在这里插入图片描述
注意:
这里放入要修改的文字要使用AppProtocol,需要设置kube-apiserver的启动参数
–feature-gates=ServiceAppProtocol=true开启;
在这里插入图片描述

K8s的服务发现机制:

两种方式:环境变量方式和DNS方式(这两种方式同时存在)

一:其中环境变量方式:

当 Pod 在节点上运行时,kubelet 会为每个活动的服务添加一组环境变量。
它添加{SVCNAME}_SERVICE_HOST和{SVCNAME}_SERVICE_PORT变量,其中服务名称是大写的,破折号被转换为下划线

可以进容器env| grep -i <name>查看相应配置
##Kubernetes 可以将 Pod 所在的 Service 的 IP 和端口信息作为环境变量注入到 Pod 内部
root@webapp-6d4bb56b96-7pk5x:/usr/local/tomcat# env |grep -i webapp
WEBAPP_PORT_8080_TCP_ADDR=10.4.182.209
HOSTNAME=webapp-6d4bb56b96-7pk5x
WEBAPP_PORT=tcp://10.4.182.209:8080
WEBAPP_SERVICE_HOST=10.4.182.209
WEBAPP_PORT_8080_TCP_PROTO=tcp
WEBAPP_PORT_8080_TCP_PORT=8080
WEBAPP_SERVICE_PORT=8080
WEBAPP_PORT_8080_TCP=tcp://10.4.182.209:8080

二:DNS方式

对于客户端应用来说,DNS域名格式的SVC名称提供的是稳定、不变的访问地址;
SVC以DNS域名的方式进行访问时,这就需要k8s里面有一个DNS服务器来完成域名到ClusterIP地址的解析工作;
目前主要以CoreDNS来负责提供解析。
在这里插入图片描述
在这里插入图片描述

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  selector:
    app: webapp
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
    name: http
### 起了这么个svc ###
可以在客户端上nslookup -q=srv _http._tcp.webapp.default.svc.cluster.local 解析出对应的端口号!!!

又或者采取Headless的SVC

在某些应用场景中,客户端应用不需要通过k8s内置的SVC实现的负载均衡功能,而是自行完成对服务后端各实例的服务发现机制,或者自行实现负载均衡转发。

总结:

在 Kubernetes 中,服务发现和服务暴露是两个不同的概念。
服务发现是指容器间如何相互发现彼此并建立连接的过程。Kubernetes 提供了内置的服务发现机制,使得容器可以使用 Kubernetes DNS 或者环境变量等方式来发现彼此的地址。
服务暴露是指将容器中的服务暴露给外部网络的过程。Kubernetes 提供了多种服务暴露的方式,例如 ClusterIP、NodePort、LoadBalancer、Ingress 等。
可以这样理解,服务发现是容器间互相发现的过程,服务暴露是将容器暴露给外部网络的过程。服务发现是服务暴露的基础,没有服务发现就无法实现服务暴露。

参考:《K8s权威指南第五版》、k8s官网

Logo

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

更多推荐