Kubernetes的Service如何进行会话保持

Kubernetes的Service如何进行会话保持

更新时间:2020-01-09 18:55:23

问题描述

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

 

解决方案

阿里云提醒您:

  • 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
  • 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
  • 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。

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

 

测试会话保持是否正常

  1. 为了方便看到结果,本文使用两个返回结果不同的Pod来做区分,且两个Deployment有相关的label,以便于一个Service能关联到这两个Pod,如下所示。测试方式是请求资源路径,其中一个pod的安装了nginx应用,请求时会返回nginx界面,另一个pod请求时则会返回404。
    apiVersion: apps/v1beta2
    kind: Deployment
    metadata:
    labels:
      app: nginx
    name: nginx
    namespace: default
    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/v1beta2
    kind: Deployment
    metadata:
    labels:
      app: nginx
    name: web
    namespace: default
    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: 172.X.X.1
    ports:
      - port: 80
        protocol: TCP
        targetPort: 80
    selector:
      app: nginx
    sessionAffinity: None
    type: ClusterIP
  3. 连接Kubernetes集群,在同一个客户端多次执行如下命令,确认返回结果不同,说明没有会话保持。
    curl http://[$Cluster_IP]
    注:[$Cluster_IP]为上一步的clusterIP值。
    系统显示类似如下。

 

配置会话保持

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

 

适用于

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