首页 > 解决方案 > 如何正确获取由前端设置的 kubernetes 集群中的服务发出的 cookie?

问题描述

情况如下:我有一堆应用程序要部署到我的 k8s 集群:

我的 kubernetes 集群托管在 Jelastic 上。我在集群前面使用 nginx 负载均衡器启用了 SSL:

在此处输入图像描述

在我的集群内部,我有通常的 nginx-ingress-controller。

现在,我正忙于尝试正确实施身份验证。按照这个建议,这就是我正在做的事情:

基本上,我的前端由 k8s 集群上的 nginx docker 映像提供服务,与 hasura api 对话,后者与内部 openfaas 登录功能对话,后者与内部 fusionauth 对话。前端和 hasura api 都定义了一个入口:

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: admin-ui
  namespace: services-108-staging
  labels:
    app.kubernetes.io/instance: admin-ui
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: admin-ui
    app.kubernetes.io/version: '0.0'
    helm.sh/chart: admin-ui-0.0.0
  annotations:
    meta.helm.sh/release-name: admin-ui
    meta.helm.sh/release-namespace: services-108-staging
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Access-Control-Allow-Origin: $http_origin";
    nginx.ingress.kubernetes.io/cors-allow-credentials: 'true'
    nginx.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS'
    nginx.ingress.kubernetes.io/enable-cors: 'true'
spec:
  rules:
    - host: admin-staging.my-env.the-jelastic-host.com
      http:
        paths:
          - path: /
            backend:
              serviceName: admin-ui
              servicePort: 4000
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: api
  namespace: services-108-staging
  labels:
    app.kubernetes.io/instance: api
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: api
    app.kubernetes.io/version: '0.0'
    helm.sh/chart: api-0.0.0
  annotations:
    kubernetes.io/ingress.class: nginx
    meta.helm.sh/release-name: api
    meta.helm.sh/release-namespace: services-108-staging
spec:
  rules:
    - host: api-staging.my-env.the-jelastic-host.com
      http:
        paths:
          - path: /
            backend:
              serviceName: api
              servicePort: 8080

只有前端的 nginx 负载均衡器可以同时访问admin-staging.my-env.the-jelastic-host.comapi-staging.my-env.the-jelastic-host.comURL。这两个应用程序分别通过其他域上的前端负载均衡器提供服务,例如admin-staging.my-host.comapi-staging.my-host.com。前端负载均衡器像这样重新路由它的传入请求(例如对于admin-stagingurl):

server {
  server_name admin-staging.my-host.com;

  listen 443 ssl;

  [...]
  
  location / {
    [...]
    proxy_pass http://admin-staging.my-env.the-jelastic-host.com;
  }
}

我的目标是让会话 cookie 存储在我的前端应用程序中。目前,虽然我Set-Cookie在调用logingraphql 突变时得到了标题:

在此处输入图像描述

我没有在我的前端应用程序的 cookie 中得到它:

在此处输入图像描述

我不知道我应该设置什么来让会话 cookie 出现在我的前端存储中。一切都通过 https 提供:hasura api 和前端应用程序。domain我应该在我的 cookie 中设置一个特定的值吗?cookie 是从 k8s 集群内部发出的,来自我托管的无服务器功能

auth.services-108-staging.svc.cluster.local

(这是 .Net Core 调用的结果Request.Host.ToUriComponent())。我应该在我的 cookie 中设置一个特定的域吗?我应该设置会话亲和力吗?我应该在哪个入口定义会话亲和性?这足以在我的集群中定义会话亲和性吗?我的集群前面的 nginx 负载均衡器呢?本质上,负载均衡器将请求路由到 k8s 集群。我必须在那里设置一些特别的东西吗?

标签: authenticationcookieskubernetesjelastichasura

解决方案


看起来会话亲和性是首先尝试的不错选择。

您能否尝试在所有入口规则中添加以下注释并检查是否可以帮助您解决问题?

nginx.ingress.kubernetes.io/affinity     cookie
nginx.ingress.kubernetes.io/affinity-mode   persistent
nginx.ingress.kubernetes.io/session-cookie-name hasura-backend
nginx.ingress.kubernetes.io/session-cookie-change-on-failure    true

或者,您可以尝试消除 https2http 终止,这很可能是您的 FE 应用程序看不到 cookie 的原因。

在屏幕截图中,可以看到 Set-Cookie 标头设置了安全标志。为了消除 SSL 终止,您可以将公共 IP 地址附加到 K8s 的工作节点,然后在入口中激活 SSL 注释并与您的前端建立直接的 https 连接。


推荐阅读