当前位置: 首页 > 知识库问答 >
问题:

Kubernetes群集上的粘性会话

秦奇
2023-03-14

目前,我正在尝试在Google云上创建一个Kubernetes集群,其中包含两个负载平衡器:一个用于后端(在Spring boot中),另一个用于前端(在Angular中),其中每个服务(负载平衡器)与两个副本(POD)通信。为了实现这一点,我创建了以下入口:

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

上面提到的入口可以使前端应用程序与后端应用程序提供的REST API进行通信。但是,我必须创建粘性会话,以便每个用户都与同一个POD进行通信,因为后端提供的身份验证机制。澄清一下,如果一个用户在POD#1中进行身份验证,则POD#2不会识别cookie。

为了解决这个问题,我了解到Nginx ingress能够处理这种情况,我通过以下步骤进行了安装:https://kubernetes.github.io/ingress-nginx/deploy/使用头盔。

您可以在下面的图表中找到我正在尝试构建的体系结构:

使用以下服务(我只粘贴其中一个服务,另一个类似):

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应用-fsample-nginx-ingress.yaml来应用入口,它被创建并且状态正常。但是,当我访问出现在“endpoint”列中的URL时,浏览器无法连接到该URL。我做错了什么吗?

**更新的服务和入口配置**

在得到一些帮助后,我成功地通过Ingress Nginx访问了这些服务。以上是您的配置:

路径不应包含“”,这与默认Kubernetes入口不同,默认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名称也没有被替换,所以我想注释没有按预期工作。

共有2个答案

焦驰
2023-03-14

我认为您的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
温智明
2023-03-14

我调查了这件事,找到了解决你问题的办法。

要实现两条路径的粘性会话,需要两种入口定义。

我创建了示例配置来向您展示整个过程

复制步骤:

  • 应用入口定义
  • 创建部署
  • 创建服务
  • 创建入口
  • 测试

我假设集群已配置,并且工作正常。

在基础架构上安装Ingress controller之前,请遵循此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

以下是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-您好。yaml

再见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"

通过调用命令应用第二个部署配置:

<代码>$kubectl apply-再见。yaml

检查部署是否正确配置了POD:

$kubectl获取部署

它应该显示这样的内容:

NAME      READY   UP-TO-DATE   AVAILABLE   AGE
goodbye   5/5     5            5           2m19s
hello     5/5     5            5           4m57s

要连接到早期创建的POD,您需要创建服务。每个服务将分配给一个部署。以下是实现这一目标的两项服务:

您好,服务。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服务。yaml

再见服务。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

通过调用命令应用第二个服务配置:

$kubectl应用-fgoodbye-service.yaml

请记住,在两种配置中,类型为:<代码>节点端口

检查是否已成功创建服务:

<代码>$kubectl获得服务

输出应如下所示:

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个入口定义。

定义如下:

你好,安格斯。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

再见,安格尔。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更改为适合您的情况。我建议查看这个入口粘性会话链接。两个入口都配置为仅HTTP流量。

应用它们调用命令:

<代码>$kubectl apply-f hello ingress。yaml

<代码>$kubectl apply-再见进入。yaml

检查是否应用了两种配置:

$kubectl获取入口

输出应如下所示:

NAME              HOSTS        ADDRESS          PORTS   AGE
goodbye-ingress   DOMAIN.NAME   IP_ADDRESS      80      26m
hello-ingress     DOMAIN.NAME   IP_ADDRESS      80      26m

打开浏览器并转到超文本传输协议://DOMAIN. NAME输出应该是这样的:

Hello, world!
Version: 1.0.0
Hostname: hello-549db57dfd-4h8fb

主机名:hello-549db57dfd-4h8fb是pod的名称。刷新几次。

它应该保持不变。

要检查其他路由是否正常工作,请转到超文本传输协议://DOMAIN. NAME/v2/输出应如下所示:

Hello, world!
Version: 2.0.0
Hostname: goodbye-7b5798f754-pbkbg

主机名:再见-7b5798f754-pbkbg是pod的名称。刷新几次。

它应该保持不变。

确保Cookie不会更改开放式开发人员工具(可能是F12),并导航到使用Cookie的位置。您可以重新加载页面以检查它们是否没有更改。

 类似资料:
  • 我正试图在我的kubernetes集群中安装Jenkins。当我探索的时候,我发现有两个方面。我理解的第一种方法是,安装詹金斯主从。在这里,我找到了在kubernetes集群上安装Jenkins主从代理的文档。第二种方法是我发现Kubernetes插件的用法。如果我们用这种方法,只需要安装master和配置插件。当创建一个部署时,从吊舱将自动工作。 在第一种方法中,我们需要定义安装主从机的工作机器

  • 本文描述了如何销毁 Kubernetes 集群上的 TiDB 集群。 销毁使用 TidbCluster 管理的 TiDB 集群 要销毁使用 TidbCluster 管理的 TiDB 集群,执行以下命令: kubectl delete tc ${cluster_name} -n ${namespace} 如果集群中通过 TidbMonitor 部署了监控,要删除监控组件,可以执行以下命令: kube

  • 在使用 TiDB 集群的过程中,如果你发现某个 Pod 存在内存泄漏等问题,需要对集群进行重启,本文描述了如何优雅滚动重启 TiDB 集群内某个组件的所有 Pod 或通过优雅重启指令来将 TiDB 集群内某个 Pod 优雅下线然后再进行重新启动。 警告: 在生产环境中,未经过优雅重启而手动删除某个 TiDB 集群 Pod 节点是一件极其危险的事情,虽然 StatefulSet 控制器会将 Pod

  • 基于 Kubernetes 环境部署的 TiDB 集群监控可以大体分为两个部分:对 TiDB 集群本身的监控、对 Kubernetes 集群及 TiDB Operator 的监控。本文将对两者进行简要说明。 TiDB 集群的监控 TiDB 通过 Prometheus 和 Grafana 监控 TiDB 集群。在通过 TiDB Operator 创建新的 TiDB 集群时,可以参考通过 TidbMo

  • 在 Kubernetes 集群内访问 TiDB 时,使用 TiDB service 域名 ${cluster_name}-tidb.${namespace} 即可。 若需要在集群外访问,则需将 TiDB 服务端口暴露出去。在 TidbCluster CR 中,通过 spec.tidb.service 字段进行配置: spec: ... tidb: service: ty

  • 本文介绍 TiDB 在 Kubernetes 中如何进行水平扩缩容和垂直扩缩容。 水平扩缩容 TiDB 水平扩缩容操作指的是通过增加或减少节点的数量,来达到集群扩缩容的目的。扩缩容 TiDB 集群时,会按照填入的 replicas 值,对 PD、TiKV、TiDB 进行顺序扩缩容操作。扩容操作按照节点编号由小到大增加节点,缩容操作按照节点编号由大到小删除节点。目前 TiDB 集群使用 TidbCl