Docker、k8sまとめ[第9回] IngressでSticky Session
第8回ではIngressを使ってL7ロードバランシングを作りました。
今回はIngressでSticky Sessionを実装しています。
目次
Sticky Sessionを使う理由
Sticky Sessionとはロードバランシングで複数のPod(サーバ)がある場合、
cookieを利用して、アクセスするサーバを固定するものです。
第5回であったように、Redisを使ってセッションを分離していればよいのですが、そうでない場合も多いのではないでしょうか。そんな時に使うのが、Sticky Sessionです。
Ingressから呼び出すアプリの準備
第8回の前半部と同じです。 Yamlを再度記載しておきます。
# deploymentで2つのPodを作成
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.12
        ports:
        - name: http-port
          containerPort: 80
---
# NodePortのServiceでPodに分散
apiVersion: v1
kind: Service
metadata:
  name: http-service
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: http-port
  selector:
    app: nginx
2つPodができるので、それぞれ、中身を変えて作成ください。
- /usr/share/nginx/html/app1/index.html
- /usr/share/nginx/html/app2/index.html
私はapp1-1、app1-2、app2-1、app2-2、という感じで登録しました。
Sticky Sessionの設定
まずは、設定のYamlを記載します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sample-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/session-cookie-path: /
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
spec:
  rules:
  - host: sample.example.com
    http:
      paths:
      - path: /(app1/.*)
        pathType: Prefix
        backend:
          service:
            name: http-service
            port:
              number: 8080
  - host: sample.example.com
    http:
      paths:
      - path: /(app2/.*)
        pathType: Prefix
        backend:
          service:
            name: http-service
            port:
              number: 8080
前回との違いは、 annotationsを足しています。
metadata:
  name: sample-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/session-cookie-path: /
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
また、pathを正規表現にしています。
spec:
  rules:
  - host: sample.example.com
    http:
      paths:
      - path: /(app1/.*)
正規表現を使っている場合は
nginx.ingress.kubernetes.io/session-cookie-path
を設定する必要があります。
nginx.ingress.kubernetes.io/rewrite-targetの$1は正規表現/(app1/.*)
でヒットした1番目という意味です。ここは1つしか書いていないので、パスすべてが取れます。
cookieの確認
上記を設定してhttp://sample.example.com/app1/もしくはhttp://sample.example.com/app1/
にアクセスして、Ctrl+F5を繰り返して押してください。
初回画面はキャッシュがかかるせいでうまく出ないかもしれませんが、 繰り返しても別のPodにいかないことがわかると思います。
F12でApplication→Cookiesを見ると、rootという値でCookieが登録されています。

これにより、Sticky Sessionを実現できます。
まとめ
Sticky Sessionを利用して、アクセスするPod(Server)を固定できました。
これにより、Statefulなアプリも複数APサーバで実行できます。
利用するにはannotationsを使うだけなので、意外に簡単ですね。
ですが、やはりオートヒーリング、オートスケールにちゃんと対応するため Redisなどを使ってセッションを永続化するのがよいと思われます。
第5回を参考にしてください。