kubernetes - Ingress 仅将流量路由到一个路由
问题描述
我有两个 pod,每个都有一个 LoadBalancer svc。每个服务的 IP 地址都在工作。
我的第一个服务是:
apiVersion: v1
kind: Service
metadata:
name: hello-world-1
spec:
type: LoadBalancer
selector:
greeting: hello
version: one
ports:
- protocol: TCP
port: 60000
targetPort: 50000
我的第二项服务是:
apiVersion: v1
kind: Service
metadata:
name: hello-world-2
spec:
type: LoadBalancer
selector:
greeting: hello
version: two
ports:
- protocol: TCP
port: 5000
targetPort: 5000
我的入口是:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: gce
spec:
defaultBackend:
service:
name: hello-world-1
port:
number: 60000
rules:
- http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: hello-world-1
port:
number: 60000
- path: /v2
pathType: ImplementationSpecific
backend:
service:
name: hello-world-2
port:
number: 5000
只有第一条路线以这种方式工作,当我放
<MY_IP>/v2
在我得到的网址栏中
Cannot GET /v2
如何配置入口,以便在未指定子路径时命中 / 路由,在指定 /v2 时命中 /v2 路由?
如果我将第一条路线更改为
backend:
service:
name: hello-world-2
port:
number: 5000
并摆脱它的第二个工作。
但是如果我将路由更改为 /v2 它会停止工作吗?
***** 编辑 *****
按照本教程的ingress tut,我尝试更改 yaml,以便不同的路由位于不同的端口上,这会破坏它。有人知道为什么吗?
解决方案
默认情况下,当您在集群中创建入口时,GKE 会创建一个 HTTP(S) 负载均衡器并将其配置为将流量路由到您的应用程序,如以下文档 [1] 中所述。因此,您不应该将服务配置为 LoadBalancer 类型,而是需要将它们配置为 NodePort。
在这里,您可以按照与您想要完成的类似的完整实现示例进行操作:
- 为每个版本创建一个在指定端口中运行应用程序容器映像的清单:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web1
namespace: default
spec:
selector:
matchLabels:
run: web1
template:
metadata:
labels:
run: web1
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: web1
ports:
- containerPort: 8000
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web2
namespace: default
spec:
selector:
matchLabels:
run: web2
template:
metadata:
labels:
run: web2
spec:
containers:
- image: gcr.io/google-samples/hello-app:2.0
imagePullPolicy: IfNotPresent
name: web2
ports:
- containerPort: 9000
protocol: TCP
- 创建两个服务(每个版本一个)作为类型NodePort。在此步骤中非常重要的一点是,指定的targetPort应该是应用程序正在侦听的目标端口,在我的情况下,两个服务都指向端口 8080,因为我使用的是相同的应用程序但版本不同:
apiVersion: v1
kind: Service
metadata:
name: web1
namespace: default
spec:
ports:
- port: 8000
protocol: TCP
targetPort: 8080
selector:
run: web1
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: web2
namespace: default
spec:
ports:
- port: 9000
protocol: TCP
targetPort: 8080
selector:
run: web2
type: NodePort
- 最后,您需要使用路径规则创建入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: gce
spec:
defaultBackend:
service:
name: web1
port:
number: 8000
rules:
- http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: web1
port:
number: 8000
- path: /v2
pathType: ImplementationSpecific
backend:
service:
name: web2
port:
number: 9000
如果您正确配置了所有内容,命令kubectl get ingress my-ingress的输出应该是这样的:
NAME CLASS HOSTS ADDRESS PORTS AGE
my-ingress <none> * <External IP> 80 149m
而且,如果您的服务指向正确的端口,并且您的应用程序正在侦听这些端口,则对您的外部 ip ( curl External IP ) 进行 curl 应该可以让您进入应用程序的版本一,这是我的示例输出:
Hello, world!
Version: 1.0.0
Hostname: web1-xxxxxxxxxxxxxx
对您的外部 ip /v2 ( curl External IP/v2 ) 进行 curl 应该可以让您进入应用程序的第二版:
Hello, world!
Version: 2.0.0
Hostname: web2-xxxxxxxxxxxxxx
[1] https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
推荐阅读
- azure - Azure Monitor (Application Insights) 日志查询图表 - Y 轴上有什么?
- sql - 无法使用 REPLACE 格式化 CROSS APPLY 以修复地址
- gateway - Azure IoT Edge 离线功能
- python - Python 2 中 Sha1 的默认编码是什么?
- python - 使用稀疏列对 pandas.DataFrame 中的行进行基于索引的访问
- react-native - 应用程序因 react-native-beacons-manager 崩溃
- .net - 在没有重复成员的情况下实现通用和非通用接口
- python - 来自csv名称中的字符串的熊猫名称数据框
- node.js - 有没有办法在不编辑我的 PATH 变量的情况下使用 Node.js oracledb 库?
- sql - 为什么我的 SQL 查询会增加数据库并填满磁盘?