Kubernetes本地Metallb LoadBalancer 和粘性会话

问题描述

我在本地安装了一个 Kubernetes Master 和两个 kubernetes worker。

在我使用以下命令将 Metallb 安装为 LoadBalancer 之后:

$ kubectl edit configmap -n kube-system kube-proxy 
apiVersion: kubeproxy.config.k8s.io/v1alpha1 
kind: KubeProxy
Configuration mode:
"ipvs" ipvs:
   strictARP: true

kubectl apply -f https://raw.githubusercontent.com/Metallb/Metallb/v0.9.6/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/Metallb/Metallb/v0.9.6/manifests/Metallb.yaml
kubectl create secret generic -n Metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

vim config-map.yaml
apiVersion: v1
kind: ConfigMap
Metadata:
  namespace: Metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 10.100.170.200-10.100.170.220

kubectl apply -f config-map.yaml
kubectl describe configmap config -n Metallb-system

我创建的 yaml 文件如下:

myapp-tst-deploy.yaml

apiVersion: apps/v1
kind: Deployment
Metadata:
  name: myapp-tst-deployment
  labels:
    app: myapp-tst
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp-tst
  template:
    Metadata:
      labels:
        app: myapp-tst
    spec:
      containers:
      - name: myapp-tst
        image: myapp-tomcat
        securityContext:
          privileged: true
          capabilities:
            add:
              - SYS_ADMIN

myapp-tst-service.yaml

apiVersion: v1
kind: Service
Metadata:
  name: myapp-tst-service
  labels:
    app: myapp-tst
spec:
  externalTrafficPolicy: Cluster
  type: LoadBalancer
  ports:
  - name: myapp-tst-port
    nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: myapp-tst
  sessionAffinity: None

myapp-tst-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
Metadata:
  name: myapp-tst-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-name: "INGRESSCOOKIE"
    Nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
    Nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
  rules: 
    - http:
        paths:
          - path: /
            backend:
              serviceName: myapp-tst-service
              servicePort: myapp-tst-port

我对所有三个文件都运行 kubectl -f apply,这是我的结果:

kubectl get all -o wide
NAME                                     READY   STATUS    RESTARTS   AGE     IP          NODE               NOMINATED NODE   READInesS GATES
pod/myapp-tst-deployment-54474cd74-p8cxk   1/1     Running   0          4m53s   10.36.0.1   bcc-tst-docker02   <none>           <none>
pod/myapp-tst-deployment-54474cd74-pwlr8   1/1     Running   0          4m53s   10.44.0.2   bca-tst-docker01   <none>           <none>

NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE     SELECTOR
service/myapp-tst-service   LoadBalancer   10.110.184.237   10.100.170.15   80:30080/TCP   4m48s   app=myapp-tst,tier=backend
service/kubernetes        ClusterIP      10.96.0.1        <none>          443/TCP        6d22h   <none>

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                  SELECTOR
deployment.apps/myapp-tst-deployment   2/2     2            2           4m53s   myapp-tst      mferraramiki/myapp-test   app=myapp-tst

NAME                                           DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                  SELECTOR
replicaset.apps/myapp-tst-deployment-54474cd74   2         2         2       4m53s   myapp-tst      myapp/myapp-test   app=myapp-tst,pod-template-hash=54474cd74

但是当我尝试使用 LB 外部 IP (10.100.170.15) 进行连接时,系统会重定向浏览器请求 (在同一个浏览器上)在一个 pod 上,如果我刷新或打开一个新选项卡(在同一个 url 上),系统回复会将请求重定向到另一个 pod。

我需要当用户在浏览器中输入 url 时,他必须在所有会话期间连接到特定的 pod,而不是切换到其他 pod。

如果可能,如何解决这个问题? 在我的 VM 中,我使用 stickysession 解决了这个问题,如何在 LB 或 Kubernetes 组件中启用它?

解决方法

在 myapp-tst-service.yaml 文件中,“sessionAffinity”设置为“None”。

您应该尝试将其设置为“ClientIP”。

来自第 https://kubernetes.io/docs/concepts/services-networking/service/ 页:

“如果您想确保每次都将来自特定客户端的连接传递到同一个 Pod,您可以通过将 service.spec.sessionAffinity 设置为“ClientIP”(即默认为“无”。您还可以通过适当设置 service.spec.sessionAffinityConfig.clientIP.timeoutSeconds 来设置最大会话粘性时间。(默认值为 10800,计算为 3 小时)。”

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...