現在、私は2つのロードバランサーを使用してGoogle CloudでKubernetesクラスターを作成しようとしています:1つはバックエンド(Springブート)用で、もう1つはフロントエンド( Angularでは)、各サービス(ロードバランサー)は2つのレプリカ(ポッド)と通信します。それを実現するために、次のイングレスを作成しました。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sample-ingress
spec:
rules:
- http:
paths:
- path: /rest/v1/*
backend:
serviceName: sample-backend
servicePort: 8082
- path: /*
backend:
serviceName: sample-frontend
servicePort: 80
上記のIngressにより、フロントエンドアプリはREST APIがバックエンドアプリで利用可能になります。ただし、スティッキーセッション。これにより、バックエンドによって提供される認証メカニズムのために、すべてのユーザーが同じPODと通信します。1人のユーザーがPOD#1で認証すると、CookieはPOD#2で認識されません。
この問題を追い抜くために、私はNginx-ingressがこの状況に対処することができ、ここで利用可能な手順に従ってインストールしたことを読みました: https ://kubernetes.github.io/ingress-nginx/deploy/ Helmを使用。
以下に、私が構築しようとしているアーキテクチャの図を示します。
次のサービスを使用します(サービスの1つを貼り付けるだけで、他のサービスも同様です)。
apiVersion: v1
kind: Service
metadata:
name: sample-backend
spec:
selector:
app: sample
tier: backend
ports:
- protocol: TCP
port: 8082
targetPort: 8082
type: LoadBalancer
そして、私は次のイングレスを宣言しました:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sample-nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/affinity-mode: persistent
nginx.ingress.kubernetes.io/session-cookie-hash: sha1
nginx.ingress.kubernetes.io/session-cookie-name: sample-cookie
spec:
rules:
- http:
paths:
- path: /rest/v1/*
backend:
serviceName: sample-backend
servicePort: 8082
- path: /*
backend:
serviceName: sample-frontend
servicePort: 80
その後、kubectl apply -f sample-nginx-ingress.yaml
イングレスを適用するには、作成され、そのステータスはOKです。しかし、「エンドポイント」列に表示されるURLにアクセスすると、ブラウザがそのURLに接続できません。私は何か悪いことをしていますか?
**サービスとイングレス構成を更新**
いくつかの助けの後、私はなんとかIngress Nginxを介してサービスにアクセスできました。この上に設定があります:
パスに「」を含めないでください。必要なパスをルーティングするために「」が必要なデフォルトのKubernetesイングレスとは異なります。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sample-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "sample-cookie"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
rules:
- http:
paths:
- path: /rest/v1/
backend:
serviceName: sample-backend
servicePort: 8082
- path: /
backend:
serviceName: sample-frontend
servicePort: 80
また、サービスのタイプは「LoadBalancer」ではなく、「ClusterIP」のようにする必要があります。
apiVersion: v1
kind: Service
metadata:
name: sample-backend
spec:
selector:
app: sample
tier: backend
ports:
- protocol: TCP
port: 8082
targetPort: 8082
type: ClusterIP
ただし、まだ403が取得され、Cookie名も置き換えられないため、Kubernetesクラスターでスティッキーセッションをまだ実行できないため、注釈が期待どおりに機能していないと思います。
私はこの問題を調査し、あなたの問題の解決策を見つけました。
両方のパスでスティッキーセッションを実現するには、イングレスの2つの定義が必要です
プロセス全体を示すサンプル構成を作成しました。
再現手順:
クラスターがプロビジョニングされ、正常に動作していると想定しています。
この Ingress link に従って、インフラストラクチャにIngressコントローラーをインストールする前に、必要な前提条件があるかどうかを確認します。
以下のコマンドを適用して、すべての必須前提条件を提供します。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
以下のコマンドを実行して、一般的な構成を適用してサービスを作成します。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml
以下は、特定のサービスのIngressトラフィックに応答するための2つの配置例です。
hello.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
selector:
matchLabels:
app: hello
version: 1.0.0
replicas: 5
template:
metadata:
labels:
app: hello
version: 1.0.0
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-app:1.0"
env:
- name: "PORT"
value: "50001"
次のコマンドを呼び出して、この最初のデプロイメント構成を適用します。
$ kubectl apply -f hello.yaml
goodbye.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: goodbye
spec:
selector:
matchLabels:
app: goodbye
version: 2.0.0
replicas: 5
template:
metadata:
labels:
app: goodbye
version: 2.0.0
spec:
containers:
- name: goodbye
image: "gcr.io/google-samples/hello-app:2.0"
env:
- name: "PORT"
value: "50001"
次のコマンドを呼び出して、この2番目のデプロイメント構成を適用します。
$ kubectl apply -f goodbye.yaml
デプロイでポッドが正しく構成されているかどうかを確認します。
$ kubectl get deployments
それはそのようなものを示すはずです:
NAME READY UP-TO-DATE AVAILABLE AGE
goodbye 5/5 5 5 2m19s
hello 5/5 5 5 4m57s
以前に作成したポッドに接続するには、サービスを作成する必要があります。各サービスは1つのデプロイメントに割り当てられます。これを実現する2つのサービスを以下に示します。
hello-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
type: NodePort
selector:
app: hello
version: 1.0.0
ports:
- name: hello-port
protocol: TCP
port: 50001
targetPort: 50001
次のコマンドを呼び出して、最初のサービス構成を適用します。
$ kubectl apply -f hello-service.yaml
goodbye-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: goodbye-service
spec:
type: NodePort
selector:
app: goodbye
version: 2.0.0
ports:
- name: goodbye-port
protocol: TCP
port: 50001
targetPort: 50001
次のコマンドを呼び出して、2番目のサービス構成を適用します。
$ kubectl apply -f goodbye-service.yaml
両方の構成レイアウトタイプ:NodePort
サービスが正常に作成されたかどうかを確認します。
$ kubectl get services
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
goodbye-service NodePort 10.0.5.131 <none> 50001:32210/TCP 3s
hello-service NodePort 10.0.8.13 <none> 50001:32118/TCP 8s
スティッキーセッションを実現するには、2つのイングレス定義を作成する必要があります。
定義を以下に示します。
hello-ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "hello-cookie"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/affinity-mode: persistent
nginx.ingress.kubernetes.io/session-cookie-hash: sha1
spec:
rules:
- Host: DOMAIN.NAME
http:
paths:
- path: /
backend:
serviceName: hello-service
servicePort: hello-port
goodbye-ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: goodbye-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "goodbye-cookie"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/affinity-mode: persistent
nginx.ingress.kubernetes.io/session-cookie-hash: sha1
spec:
rules:
- Host: DOMAIN.NAME
http:
paths:
- path: /v2/
backend:
serviceName: goodbye-service
servicePort: goodbye-port
両方のイングレスのDOMAIN.NAME
をケースに合わせて変更してください。 Ingress Sticky session リンクを確認することをお勧めします。両方のIngressがHTTPのみのトラフィックに設定されています。
コマンドを呼び出すそれらの両方を適用します。
$ kubectl apply -f hello-ingress.yaml
$ kubectl apply -f goodbye-ingress.yaml
両方の構成が適用されたかどうかを確認します。
$ kubectl get ingress
出力は次のようになります。
NAME HOSTS ADDRESS PORTS AGE
goodbye-ingress DOMAIN.NAME IP_ADDRESS 80 26m
hello-ingress DOMAIN.NAME IP_ADDRESS 80 26m
ブラウザを開き、http://DOMAIN.NAME
に移動します。出力は次のようになります。
Hello, world!
Version: 1.0.0
Hostname: hello-549db57dfd-4h8fb
Hostname: hello-549db57dfd-4h8fb
はポッドの名前です。数回更新してください。
それは変わらないはずです。
別のルートが機能しているかどうかを確認するには、http://DOMAIN.NAME/v2/
に移動します。出力は次のようになります。
Hello, world!
Version: 2.0.0
Hostname: goodbye-7b5798f754-pbkbg
Hostname: goodbye-7b5798f754-pbkbg
はポッドの名前です。数回更新してください。
それは変わらないはずです。
Cookieが開いている開発者ツール(おそらくF12)を変更していないことを確認し、Cookieのある場所に移動します。ページをリロードして、変更されていないかどうかを確認できます。
Service
の設定が間違っていると思います。削除するだけtype: LoadBalancer
で、タイプはデフォルトでClusterIP
になります。
LoadBalancer:クラウドプロバイダーのロードバランサーを使用して、サービスを外部に公開します。外部ロードバランサーがルーティングするNodePortおよびClusterIPサービスが自動的に作成されます。詳しくはこちらをご覧ください: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer 。
apiVersion: v1
kind: Service
metadata:
name: sample-backend
spec:
selector:
app: sample
tier: backend
ports:
- protocol: TCP
port: 8082
targetPort: 8082