当流量请求到后端ECS,我们可以通过nginx这类的http服务器来实现会话保持,但是在k8s集群中真正提供服务的是Pod,那么如何实现ECS到Pod这条链路的会话保持呢。
service sessionAffinity
通过在service配置文件中加入 sessionAffinity: ClientIP 实现会话保持。
测试例子
该deployment会有2个nginx pod副本,在容器中有postStart钩子函数会将pod名称写入到nginx的index.html中,用来使我们看到会话保持的效果。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 2 progressDeadlineSeconds: 600 revisionHistoryLimit: 10 strategy: type: RollingUpdate rollingUpdate: maxSurge: 25% maxUnavailable: 25% selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: affinity: {} containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name lifecycle: postStart: exec: command: - "/bin/sh" - "-c" - "echo $POD_NAME > /usr/share/nginx/html/index.html" 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: nginx spec: type: ClusterIP sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 10800 selector: app: nginx ports: - port: 80 targetPort: 80
|
通过不同客户端使用curl访问service地址可以看到会话保持的效果
ingress-nginx
ingress-nginx提供了大量的注释配置来配置会话保持的策略。列举常用的配置如下:
属性名称 |
描述 |
值 |
nginx.ingress.kubernetes.io/affinity |
会话保持类型,设置为cookie为启用会话保持 |
nginx仅支持cookie |
nginx.ingress.kubernetes.io/affinity-mode |
定义会话的粘性。balanced在扩展pod时重新分配一些会话;persistent则是保证用户永远访问同一个pod |
balanced(默认) or persistent |
nginx.ingress.kubernetes.io/session-cookie-name |
cookie的名称 |
INGRESSCOOKIE(默认) |
nginx.ingress.kubernetes.io/session-cookie-max-age |
cookie过期时间 |
秒数 |
nginx.ingress.kubernetes.io/session-cookie-expires |
与旧浏览器兼容的旧注释版本。Expires通过将秒数添加到当前日期生成cookie指令 |
秒数 |
测试例子
pod与上面使用的一样,修改之前的service
apiVersion: v1 kind: Service metadata: name: nginx spec: type: ClusterIP selector: app: nginx ports: - port: 80 targetPort: 80
|
创建ingress
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/affinity-mode: "balanced" nginx.ingress.kubernetes.io/session-cookie-name: "route" nginx.ingress.kubernetes.io/session-cookie-expires: "172800" nginx.ingress.kubernetes.io/session-cookie-max-age: "172800" spec: rules: - host: nginx.twf.com http: paths: - path: / backend: serviceName: nginx servicePort: 80
|
最后通过浏览器页面发现同一主机访问显示的都是同一个pod,显示同一个pod的名称。