问题描述
由于Kubernetes中Service的会话保持是根据ClientIP来配置,属于4层配置。当SLB监听是7层时,会话保持只能实现客户端到SLB后端ECS之间的会话保持,而ECS到Pod这个链路是无法进行会话保持。本文主要介绍该链路如何进行会话保持。
解决方案
本文以使用负载均衡的Service为例进行配置会话保持的介绍。本文中涉及的镜像地址与IP地址均为测试环境配置,正确的配置以实际情况为准。
测试会话保持是否正常
- 为了方便看到结果,本文使用两个返回结果不同的Pod来做区分,且两个Deployment有相关的label,以便于一个Service能关联到这两个Pod,如下所示。测试方式是请求资源路径,其中一个pod的安装了Nginx应用,请求时会返回Nginx界面,另一个pod请求时会返回404。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: nginx
spec:
affinity: {}
containers:
- env:
- name: aliyun_logs_catalina
image: 'nginx:latest'
imagePullPolicy: Always
name: nginx
resources:
requests:
cpu: 250m
memory: 512Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: web
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: 'registry-XXX/go-web:latest'
imagePullPolicy: Always
name: web
resources:
requests:
cpu: 250m
memory: 512Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {} - 然后参考以下配置,创建Service。
apiVersion: v1
kind: Service
metadata:
name: session1
namespace: default
spec:
clusterIP: 10.XX.XX.217
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: ClusterIP - 连接Kubernetes集群,详情请参见连接Kubernetes集群,在同一个客户端多次执行如下命令,确认返回结果不同,说明没有会话保持。
curl http://[$Cluster_IP]
说明:[$Cluster_IP]为上一步Service资源配置清单中的clusterIP值。
系统显示类似如下。
配置会话保持
- 如果要实现负载均衡的Service会话保持,必须要添加Service资源配置清单,如下所示。
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small #注解里面不能让SLB监听http或者https协议,必须是TCP(默认不修改就是TCP)
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-persistence-timeout: '1800' #这里必须开启SLB的TCP会话保持
name: session1
namespace: default
spec:
clusterIP: 10.68.121.217
externalTrafficPolicy: Local #这里必须是Local
healthCheckNodePort: 30595
ports:
- nodePort: 30389
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: ClientIP #这里必须配置成ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
type: ClusterIP - 参考测试会话保持是否正常第三步步骤,确认返回结果相同,如下图所示。
适用于
- 容器服务Kubernetes专有版
- 容器服务Kubernetes托管版