使用 cookie affinity 配置 Ingress 时出现问题
Problems configuring Ingress with cookie affinity
我一直在寻找如何在 GKE 中使用 cookie affinity,为此使用 Ingress。
我发现以下 link 可以做到这一点:https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service
我创建了一个包含以下内容的 yaml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-bsc-deployment
spec:
selector:
matchLabels:
purpose: bsc-config-demo
replicas: 3
template:
metadata:
labels:
purpose: bsc-config-demo
spec:
containers:
- name: hello-app-container
image: gcr.io/google-samples/hello-app:1.0
---
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
name: my-bsc-backendconfig
spec:
timeoutSec: 40
connectionDraining:
drainingTimeoutSec: 60
sessionAffinity:
affinityType: "GENERATED_COOKIE"
affinityCookieTtlSec: 50
---
apiVersion: v1
kind: Service
metadata:
name: my-bsc-service
labels:
purpose: bsc-config-demo
annotations:
beta.cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
spec:
type: NodePort
selector:
purpose: bsc-config-demo
ports:
- port: 80
protocol: TCP
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-bsc-ingress
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: my-bsc-service
servicePort: 80
---
一切似乎都很顺利。当我检查创建的 Ingress 时,我看到了 2 个后端服务。其中一个设置了cookie,另一个没有。
如果我创建部署,并从 GCP 的控制台创建服务和入口,则只会出现一个后端服务。
有人知道为什么使用 yaml 我得到 2 个,但从控制台执行它我只得到一个?
提前致谢
奥斯卡
您可以像
那样在入口处启用 cookie
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-sticky
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
rules:
- host: ingress.example.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /
您可以像这样创建服务:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
sessionAffinity: ClientIP
如果您使用的是 traefik ingress 而不是 nginx 和 deault GKe ingress,您可以像这样编写服务
apiVersion: v1
kind: Service
metadata:
name: session-affinity
labels:
app: session-affinity
annotations:
traefik.ingress.kubernetes.io/affinity: "true"
traefik.ingress.kubernetes.io/session-cookie-name: "sticky"
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
selector:
app: session-affinity-demo
你的定义很好
你有两个后端的原因是你的入口没有定义默认后端。 GCE LB 需要一个默认后端,因此在 LB 创建期间,第二个后端被添加到 LB 作为默认后端(这个后端除了提供 404 响应外什么都不做)。默认后端不使用backendConfig。
这应该不是问题,但如果您想确保仅使用您的后端,请通过添加 spec.backend
:
在入口定义中定义默认后端值
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-bsc-ingress
spec:
backend:
serviceName: my-bsc-service
servicePort: 80
rules:
- http:
paths:
- path: /*
backend:
serviceName: my-bsc-service
servicePort: 80
但是,就像我说的,您不需要定义它,额外的后端不会真正发挥作用,也不需要会话关联(反正只有一个 pod)。如果你很好奇,有问题的默认后端 pod 在 kube-system 命名空间
中称为 l7-default-backend-[replicaSet_hash]-[pod_hash]
我一直在寻找如何在 GKE 中使用 cookie affinity,为此使用 Ingress。
我发现以下 link 可以做到这一点:https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service
我创建了一个包含以下内容的 yaml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-bsc-deployment
spec:
selector:
matchLabels:
purpose: bsc-config-demo
replicas: 3
template:
metadata:
labels:
purpose: bsc-config-demo
spec:
containers:
- name: hello-app-container
image: gcr.io/google-samples/hello-app:1.0
---
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
name: my-bsc-backendconfig
spec:
timeoutSec: 40
connectionDraining:
drainingTimeoutSec: 60
sessionAffinity:
affinityType: "GENERATED_COOKIE"
affinityCookieTtlSec: 50
---
apiVersion: v1
kind: Service
metadata:
name: my-bsc-service
labels:
purpose: bsc-config-demo
annotations:
beta.cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
spec:
type: NodePort
selector:
purpose: bsc-config-demo
ports:
- port: 80
protocol: TCP
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-bsc-ingress
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: my-bsc-service
servicePort: 80
---
一切似乎都很顺利。当我检查创建的 Ingress 时,我看到了 2 个后端服务。其中一个设置了cookie,另一个没有。
如果我创建部署,并从 GCP 的控制台创建服务和入口,则只会出现一个后端服务。
有人知道为什么使用 yaml 我得到 2 个,但从控制台执行它我只得到一个?
提前致谢
奥斯卡
您可以像
那样在入口处启用 cookieapiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-sticky
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
rules:
- host: ingress.example.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /
您可以像这样创建服务:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
sessionAffinity: ClientIP
如果您使用的是 traefik ingress 而不是 nginx 和 deault GKe ingress,您可以像这样编写服务
apiVersion: v1
kind: Service
metadata:
name: session-affinity
labels:
app: session-affinity
annotations:
traefik.ingress.kubernetes.io/affinity: "true"
traefik.ingress.kubernetes.io/session-cookie-name: "sticky"
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
selector:
app: session-affinity-demo
你的定义很好
你有两个后端的原因是你的入口没有定义默认后端。 GCE LB 需要一个默认后端,因此在 LB 创建期间,第二个后端被添加到 LB 作为默认后端(这个后端除了提供 404 响应外什么都不做)。默认后端不使用backendConfig。
这应该不是问题,但如果您想确保仅使用您的后端,请通过添加 spec.backend
:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-bsc-ingress spec: backend: serviceName: my-bsc-service servicePort: 80 rules: - http: paths: - path: /* backend: serviceName: my-bsc-service servicePort: 80
但是,就像我说的,您不需要定义它,额外的后端不会真正发挥作用,也不需要会话关联(反正只有一个 pod)。如果你很好奇,有问题的默认后端 pod 在 kube-system 命名空间
中称为l7-default-backend-[replicaSet_hash]-[pod_hash]