聊聊如何在K8S中實現會話保持

linyb極客之路發表於2023-03-14

前言

故事的起因是朋友所在的部門最近基於auth2實現單點登入,他們在測試環境單點登入,執行得好好的,但他們把單點登入上到預釋出環境,發現單點登入不好使了。他們有部分系統是以授權碼式接入,發現第一次登入拿到授權碼進行換取token時,會提示授權碼失效。而他們測試環境和預釋出環境的程式碼是一樣的。

後面朋友和我聊天,我就問朋友兩套環境有存在什麼不一樣的地方,朋友說測試環境是單POD部署,而預釋出環境是多POD部署。最後我還從朋友的口中得到一個資訊,他們auth2是基於國內開源的sa-token進行實現,剛好我也玩過這個玩意兒,這玩意兒的授權碼是基於cookies進行保持。我就跟朋友說可能是因為你部署了多個pod,pod的會話沒保持住。然後我就跟朋友提供以下方案

會話保持方案

方案一:透過service進行配置

在service配置配置形如下內容

apiVersion: v1
kind: Service
metadata:
  namespace: uat
  name: uat-sso
spec:
  selector:
    app: uat-sso
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30666
  type: NodePort
  # 會話保持3小時
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

其中關鍵配置如下

sessionAffinity: ClientIP
sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

透過指定sessionAffinity: ClientIP開啟了session保持。當設定了session保持之後,k8s會根據訪問的ip來把請求轉發給他以前訪問過的pod,這樣session就保持住了。其中timeoutSeconds指的是session保持的時間,這個時間預設是10800秒,也就是三個小時。

不過朋友說他配置了這個之後,貌似沒產生作用,因為朋友他們單點登入是透過ingress進行轉發,於是就有了第二種方案

方案二:透過ingress配置會話保持

配置形如下

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/affinity-mode: persistent
    nginx.ingress.kubernetes.io/session-cookie-name: route
  name: uat-sso-ingress
  namespace: uat
spec:
  rules:
  - host: sso.com
    http:
      paths:
      - backend:
          service:
            name: uat-sso
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - sso.com
    secretName: tls.sso.com

其中關鍵配置如下

metadata:
  annotations:
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/affinity-mode: persistent
    nginx.ingress.kubernetes.io/session-cookie-name: route

其中nginx.ingress.kubernetes.io/affinity 屬性,啟用會話保持, 其值僅僅支援cookie。
nginx.ingress.kubernetes.io/affinity-mode 屬性,設定為persistent時,則請求一直請求至同一pods服務,設定為balanced (預設設定)則請求會使用輪詢的方式至後端pods服務
nginx.ingress.kubernetes.io/session-cookie-name 屬性,自定義cookie名稱, 其預設設定為 INGRESSCOOKIE,但我們可自定義,如上文的route。

更多詳細的配置可以檢視如下連結
https://kubernetes.github.io/ingress-nginx/examples/affinity/cookie/

總結

朋友後面是透過配置ingress這種方式解決問題,本文就作為一個記錄

相關文章