概念
会话保持可以确保用户在访问应用时的连续性和一致性。如果在客户端和服务器之间部署了负载均衡设备,很有可能这多个连接会被转发至不同的服务器进行处理。开启会话保持后,负载均衡会把来自同一客户端的访问请求持续分发到同一台后端云服务器上进行处理。
例如在大多数需要用户身份认证的在线系统中,一个用户需要与服务器实现多次交互才能完成一次会话。由于多次交互过程中存在连续性,如果不配置会话保持,负载均衡可能会将部分请求分配至另一个后端服务器,但由于其他后端服务器并未经过用户身份认证,则会出现用户登录失效等交互异常。
因此,在实际的部署环境中,需要根据应用环境的特点,选择适当的会话保持机制。
表1 会话保持类型
类型 |
说明 |
支持的会话保持类型 |
会话保持失效的场景 |
四层会话保持 |
当创建Service时,使用的协议为TCP或UDP,默认为四层会话保持。 |
源IP地址:基于源IP地址的简单会话保持,将请求的源IP地址作为散列键(HashKey),从静态分配的散列表中找出对应的服务器。即来自同一IP地址的访问请求会被转发到同一台后端服务器上进行处理。 |
- 客户端的源IP地址发生变化。
- 客户端访问请求超过会话保持时间。
|
七层会话保持 |
当创建Ingress时,使用的协议为HTTP或HTTPS,默认为七层会话保持。 |
- 负载均衡器cookie:负载均衡器会根据客户端第一个请求生成一个cookie,后续所有包含这个cookie值的请求都会由同一个后端服务器处理。
- 应用程序cookie:该选项依赖于后端应用。后端应用生成一个cookie值,后续所有包含这个cookie值的请求都会由同一个后端服务器处理。
|
- 如果客户端发送请求未附带cookie,则会话保持无法生效。
- 客户端访问请求超过会话保持时间。
|
在创建负载均衡时,分配策略选择“加权轮询算法”(即kubernetes.io/elb.lb-algorithm参数为ROUND_ROBIN)或“加权最少连接”(即kubernetes.io/elb.lb-algorithm参数为LEAST_CONNECTIONS)可配置会话保持;选择“源IP算法”(即kubernetes.io/elb.lb-algorithm参数为SOURCE_IP)时已支持基于源IP地址的会话保持,无需重复配置会话保持。
四层会话保持(Service)
四层的模式下可以开启基于源IP的会话保持(基于客户端的IP进行hash路由)。
在CCE Standard集群中开启四层会话保持
在CCE Standard集群中,Service开启基于源IP的会话保持需要满足以下条件:
- Service的服务亲和级别选择“节点级别”(即Service的externalTrafficPolicy字段为Local)。
- Service后端的应用开启反亲和,避免所有Pod均部署在同一节点。
操作步骤
- 创建nginx工作负载。
实例数设置为3,通过工作负载反亲和设置Pod与自身反亲和。
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: container-0
image: 'nginx:perl'
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 250m
memory: 512Mi
imagePullSecrets:
- name: default-secret
affinity:
podAntiAffinity: # Pod与自身反亲和
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname
- 创建Service的负载均衡,以使用已有的ELB为例,配置源IP地址会话保持的YAML示例如下。
apiVersion: v1
kind: Service
metadata:
name: svc-example
namespace: default
annotations:
kubernetes.io/elb.class: union
kubernetes.io/elb.id: *****
kubernetes.io/elb.lb-algorithm: ROUND_ROBIN # 加权轮询分配策略
kubernetes.io/elb.session-affinity-mode: SOURCE_IP # 开启源IP会话保持
spec:
selector:
app: nginx
externalTrafficPolicy: Local # 服务亲和级别为“节点级别”
ports:
- name: cce-service-0
targetPort: 80
nodePort: 32633
port: 80
protocol: TCP
type: LoadBalancer
- 验证四层会话保持是否开启。
- 登录ELB控制台找到对应的ELB,并在ELB所在行中单击的对应监听器名称。
- 查看后端服务器组中,会话保持配置是否开启。
图1 开启四层会话保持
在CCE Turbo集群中开启四层会话保持
在CCE Turbo集群中,Service开启基于源IP的会话保持与ELB类型相关。
- 使用独享型ELB时,ELB可以直通Pod(即Pod直接作为ELB的后端服务器组),因此Service开启基于源IP的会话保持无需配置服务亲和及应用反亲和。
- 使用共享型ELB时,不支持开启会话保持。
操作步骤
- 独享型ELB场景
以使用已有的ELB为例,Service的负载均衡配置源IP地址会话保持的YAML示例如下。
apiVersion: v1
kind: Service
metadata:
name: svc-example
namespace: default
annotations:
kubernetes.io/elb.class: performance
kubernetes.io/elb.id: *****
kubernetes.io/elb.lb-algorithm: ROUND_ROBIN # 加权轮询分配策略
kubernetes.io/elb.session-affinity-mode: SOURCE_IP # 开启源IP会话保持
spec:
selector:
app: nginx
externalTrafficPolicy: Cluster # CCE Turbo集群中,使用独享型ELB对服务亲和策略无要求
ports:
- name: cce-service-0
targetPort: 80
nodePort: 32633
port: 80
protocol: TCP
type: LoadBalancer
验证四层会话保持是否开启。
- 登录ELB控制台找到对应的ELB,并在ELB所在行中单击的对应监听器名称。
- 查看后端服务器组中,会话保持配置是否开启。
图2 开启四层会话保持
七层会话保持(Ingress)
七层的模式下可以开启基于http cookie和app cookie的会话保持 。
在CCE Standard集群中开启七层会话保持
在Ingress上开启基于cookie的会话保持需要满足以下条件:
- Ingress对应的Service服务亲和级别选择“节点级别”(即Service的externalTrafficPolicy字段为Local)。
- Ingress对应的应用(工作负载)应该开启与自身反亲和,避免所有Pod均部署在同一节点。
操作步骤
- 创建nginx工作负载。
实例数设置为3,通过工作负载反亲和设置Pod与自身反亲和。
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: container-0
image: 'nginx:perl'
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 250m
memory: 512Mi
imagePullSecrets:
- name: default-secret
affinity:
podAntiAffinity: # Pod与自身反亲和
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname
- 为工作负载创建Service。本文以NodePort类型Service为例。
会话保持的配置需在Service的配置中进行设置,由于Ingress可以对接多个Service,因此每个Service可以有不同的会话保持配置。
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
kubernetes.io/elb.lb-algorithm: ROUND_ROBIN # 加权轮询分配策略
kubernetes.io/elb.session-affinity-mode: HTTP_COOKIE # HTTP Cookie类型
kubernetes.io/elb.session-affinity-option: '{"persistence_timeout":"1440"}' # 会话保持时间,单位为分钟,取值范围为1-1440
spec:
selector:
app: nginx
ports:
- name: cce-service-0
protocol: TCP
port: 80
targetPort: 80
nodePort: 32633 # 自定义节点端口
type: NodePort
externalTrafficPolicy: Local # 服务亲和级别为“节点级别”
还可以选择应用程序Cookie,如下所示。
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
kubernetes.io/elb.lb-algorithm: ROUND_ROBIN # 加权轮询分配策略
kubernetes.io/elb.session-affinity-mode: APP_COOKIE # 选择应用程序Cookie
kubernetes.io/elb.session-affinity-option: '{"app_cookie_name":"test"}' # 应用程序Cookie名称
spec:
selector:
app: nginx
ports:
- name: cce-service-0
protocol: TCP
port: 80
targetPort: 80
nodePort: 32633 # 自定义节点端口
type: NodePort
externalTrafficPolicy: Local # 服务亲和级别为“节点级别”
- 创建Ingress,关联Service。以下示例以使用已有的ELB为例,如需使用自动创建ELB的方式,请参考通过Kubectl命令行添加ELB Ingress。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
namespace: default
annotations:
kubernetes.io/elb.class: union
kubernetes.io/elb.port: '80'
kubernetes.io/elb.id: *****
spec:
rules:
- host: 'www.example.com'
http:
paths:
- path: '/'
backend:
service:
name: nginx # Service的名称
port:
number: 80
property:
ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
pathType: ImplementationSpecific
ingressClassName: cce
- 验证七层会话保持是否开启。
- 登录ELB控制台找到对应的ELB,并在ELB所在行中单击的对应监听器名称。
- 切换至“转发策略”页签,单击后端服务器组名称,查看会话保持配置是否开启。
图3 开启七层会话保持
在CCE Turbo集群中开启七层会话保持
在Ingress上开启基于cookie的会话保持:
- 使用独享型ELB时,ELB可以直通Pod(即Pod直接作为ELB的后端服务器组),因此Ingress开启基于cookie的会话保持无需配置服务亲和及应用反亲和。
- 使用共享型ELB时,不支持开启会话保持。
操作步骤
- 独享型ELB场景
- 为工作负载创建Service。CCE Turbo集群中,使用独享型ELB的Ingress需对接CLusterIP类型的Service。
会话保持的配置需在Service的配置中进行设置,由于Ingress可以对接多个Service,因此每个Service可以有不同的会话保持配置。
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
kubernetes.io/elb.lb-algorithm: ROUND_ROBIN # 加权轮询分配策略
kubernetes.io/elb.session-affinity-mode: HTTP_COOKIE # HTTP Cookie类型
kubernetes.io/elb.session-affinity-option: '{"persistence_timeout":"1440"}' # 会话保持时间,单位为分钟,取值范围为1-1440
spec:
selector:
app: nginx
ports:
- name: cce-service-0
protocol: TCP
port: 80
targetPort: 80
nodePort: 0
type: ClusterIP
- 创建Ingress,关联Service。以下示例以使用已有的ELB为例,如需使用自动创建ELB的方式,详情请参考通过Kubectl命令行添加ELB Ingress。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
namespace: default
annotations:
kubernetes.io/elb.class: performance
kubernetes.io/elb.port: '80'
kubernetes.io/elb.id: *****
spec:
rules:
- host: 'www.example.com'
http:
paths:
- path: '/'
backend:
service:
name: nginx # Service的名称
port:
number: 80
property:
ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
pathType: ImplementationSpecific
ingressClassName: cce
- 验证七层会话保持是否开启。
- 登录ELB控制台找到对应的ELB,并在ELB所在行中单击的对应监听器名称。
- 切换至“转发策略”页签,单击后端服务器组名称,查看会话保持配置是否开启。
图4 开启七层会话保持