【 Kubernetes 风云录 】- Istio的一致性哈希机制
文章目录
- `ConsistentHashLB` 说明
- 配置示例:
- 基于HTTP头
- 验证
- 实例
- 结果
⚡️: 根据请求的标识符(如
header
)将流量固定路由到特定的 pod 实例,从而实现 “粘性会话”。
ConsistentHashLB
说明
一致的基于哈希的负载平衡可用于提供基于HTTP头、cookie或其他属性的软会话关联。当从目标服务中添加/删除一个或多个主机时,与特定目标主机的关联将丢失。
- 一致性哈希和 Pod 绑定
- 不再与其他 Pod 实例联系
- 子集与实例
配置示例:
基于HTTP头
---
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: username
minimumRingSize: 1024
验证
这里我通过一个小服务,通过请求这个服务来确认请求到哪个实例(服务部署在我们的kuberneters
集群)
package main
import (
"fmt"
"log"
"net"
"net/http"
)
// 获取本地机器的 IP 地址
func getLocalIP() (string, error) {
// 获取本地机器的 IP 地址
addrs, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
// 遍历所有的网络接口,返回第一个有效的非回环接口的 IP 地址
for _, addr := range addrs {
if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
return ipNet.IP.String(), nil
}
}
return "", fmt.Errorf("no valid IP address found")
}
// 处理 HTTP 请求并返回本地 IP 地址
func handler(w http.ResponseWriter, r *http.Request) {
ip, err := getLocalIP()
if err != nil {
http.Error(w, fmt.Sprintf("Error getting local IP: %v", err), http.StatusInternalServerError)
return
}
// 返回本地 IP 地址
fmt.Fprintf(w, "Local IP: %s", ip)
}
func main() {
// 定义 HTTP 请求路由
http.HandleFunc("/ip", handler)
// 启动服务
log.Println("Starting server on :80")
if err := http.ListenAndServe(":80", nil); err != nil {
log.Fatalf("Error starting server: %v", err)
}
}
实例
启动三个服务实例
- Pod1
- Pod2
- Pod3
当我们正常请求时,集群会通过轮询的方式降请求均衡打到三个实例上
⚡️: 由图可以看出三个实例个均衡收到五次请求
通过istio-proxy去请求服务
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
subsets:
- labels:
app.kubernetes.io/instance: httpbin
name: httpbin
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: username
minimumRingSize: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
gateways:
- httpbin
http:
- match:
- uri:
prefix: /local/
- uri:
prefix: /local
rewrite:
uri: /
route:
- destination:
host: httpbin
port:
number: 80
subset: httpbin
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- gsair.gstrain.qa.17usoft.com
- 10.189.200.59
port:
name: http
number: 80
protocol: HTTP
如果请求中携带 username: user1
被哈希到 Pod1
,那么所有后续带有 username: user1
的请求都会被路由到 Pod1
,直到某种情况导致哈希环或 Pod 配置发生变化。
结果
所有相同 username
的请求都被路由到相同的 Pod。当然这只是其中的一种负载方式,工作中能够用到的,istio还支持其他类型的负载,有兴趣可以查看官方文档