へっぽこITエンジニア@名古屋のブログ

Follow me on GitHub

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-1app1-2app2-1app2-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が登録されています。

Cookie確認

これにより、Sticky Sessionを実現できます。

まとめ

Sticky Sessionを利用して、アクセスするPod(Server)を固定できました。 これにより、Statefulなアプリも複数APサーバで実行できます。 利用するにはannotationsを使うだけなので、意外に簡単ですね。

ですが、やはりオートヒーリング、オートスケールにちゃんと対応するため Redisなどを使ってセッションを永続化するのがよいと思われます。

第5回を参考にしてください。