Kubernetes的Service如何进行会话保持

更新时间:

问题描述

由于Kubernetes中Service的会话保持是根据ClientIP来配置,属于4层配置。当SLB监听是7层时,会话保持只能实现客户端到SLB后端ECS之间的会话保持,而ECS到Pod这个链路是无法进行会话保持。本文主要介绍该链路如何进行会话保持。

解决方案

本文以使用负载均衡的Service为例进行配置会话保持的介绍。本文中涉及的镜像地址与IP地址均为测试环境配置,正确的配置以实际情况为准。

测试会话保持是否正常

  1. 为了方便看到结果,本文使用两个返回结果不同的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: {}
  2. 然后参考以下配置,创建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
  3. 连接Kubernetes集群,详情请参见连接Kubernetes集群,在同一个客户端多次执行如下命令,确认返回结果不同,说明没有会话保持。
    curl http://[$Cluster_IP]
    说明:[$Cluster_IP]为上一步Service资源配置清单中的clusterIP值。
    系统显示类似如下。

配置会话保持

  1. 如果要实现负载均衡的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
  2. 参考测试会话保持是否正常第三步步骤,确认返回结果相同,如下图所示。

适用于

  • 容器服务Kubernetes专有版
  • 容器服务Kubernetes托管版