k8s SVC负载均衡机制、服务暴露、服务发现
k8s SVC负载均衡机制、服务暴露、服务发现
SVC负载均衡机制、服务暴露、服务发现
基本介绍
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官网
更多推荐
所有评论(0)