当前,我正在尝试在Google Cloud上创建一个Kubernetes集群,该集群具有两个负载均衡器:一个用于后端(在Spring引导中),另一个用于前端(在Angular中),其中每个服务(负载平衡器)与2个副本(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/使用Helm。
您可以在下面的图表中找到我要构建的体系结构:
使用以下服务(我将仅粘贴其中一项服务,另一项类似):
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
但是,我仍然无法在Kubernetes集群中实现粘性会话,一旦我仍然获得403,甚至cookie名称都没有被替换,因此我猜注释不能按预期工作。
答案 0 :(得分:1)
我调查了此事,找到了解决您问题的方法。
要实现两条路径的粘性会话,您将需要两个入口定义。
我创建了示例配置来向您展示整个过程:
复制步骤:
我认为群集已配置并且可以正常工作。
请遵循此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
下面是两个示例部署,用于响应特定服务上的入口流量:
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"
通过调用以下命令来应用第二个部署配置:
$ kubectl apply -f goodbye.yaml
检查部署是否正确配置了Pod:
$ kubectl get deployments
它应该显示如下内容:
NAME READY UP-TO-DATE AVAILABLE AGE
goodbye 5/5 5 5 2m19s
hello 5/5 5 5 4m57s
要连接到先前创建的Pod,您将需要创建服务。每个服务将分配给一个部署。以下是完成此任务的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
通过调用命令来应用第二个服务配置:
$ 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 链接。
两个入口均配置为仅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的地方。您可以重新加载页面以检查它们是否保持不变。
答案 1 :(得分:0)
我认为您的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