我有三个项目:A,B,C。
每个项目有2个版本:v1,v2。
如何配置istio以限制A(v1)只向B(v1)和C(v1)发送请求?
这是Istio的请求路由,如本教程所述:https://istio.io/latest/docs/tasks/traffic-management/request-routing/
基本上,你需要首先定义一些DestinationRules
来根据你的版本创建一些子集,例如:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
然后,创建一些VirtualServices
来定义路由规则。这里,你想使用sourceLabels匹配,所以它会像这样:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- match:
- sourceLabels:
version: v2
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
表示:如果任何进入服务reviews
的流量来自标签为version: v2
的服务,则路由到reviews
v2;否则作为默认规则,路由到v1。您可以在该VirtualService
中添加任意数量的路由规则,并可以对所有服务重复此操作。
除了@Joel已经告诉的,我想澄清这是如何在网格内工作的。还添加了一个测试示例。
如果我理解正确,你正在寻找一种方法,从网格内部使用Istio虚拟服务,从项目的特定版本调用到另一个项目的相同版本。
在这种情况下,你可以使用mesh gateway。根据文档:
保留词mesh用于暗示网格中的所有侧车。当省略此字段时,将使用默认网关(mesh),这将对mesh中的所有侧车应用该规则。如果提供了一个网关名称列表,则规则将仅适用于网关。要将规则应用于网关和侧车,请指定mesh作为网关名称之一。
所以有两个选项
可以使用mesh gateway作为网关之一:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-mesh-gateway
spec:
gateways:
- "mesh"
hosts:
- "service.default.svc.cluster.local"
http:
route:
- destination:
host: service.default.svc.cluster.local
或者您可以创建没有网关列表的虚拟服务,因此默认网关将是mesh网关.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-mesh-gateway
spec:
hosts:
- "service.default.svc.cluster.local"
http:
route:
- destination:
host: service.default.svc.cluster.local
我用2个ubuntu pod做了一个例子
- ubu1 with label version v1 ubu2 with label version v2
也有2个nginx pod
- nginx1 with label nginx1
- nginx2 with label nginx2
我们稍后将根据目的地规则将其更改为v1和v2。
所有的yamls。
apiVersion: v1
kind: Pod
metadata:
name: ubu1
labels:
version: v1
spec:
containers:
- name: ubu2
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "apt-get update && apt-get install curl -y && sleep 3000"]
---
apiVersion: v1
kind: Pod
metadata:
name: ubu2
labels:
version: v2
spec:
containers:
- name: ubu1
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "apt-get update && apt-get install curl -y && sleep 3000"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
spec:
selector:
matchLabels:
run: nginx1
replicas: 1
template:
metadata:
labels:
run: nginx1
app: projectA
spec:
containers:
- name: nginx1
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo This is version 1 of project A > /usr/share/nginx/html/index.html"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
spec:
selector:
matchLabels:
run: nginx2
replicas: 1
template:
metadata:
labels:
run: nginx2
app: projectA
spec:
containers:
- name: nginx2
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo This is version 2 of project A > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: project-a
labels:
app: projectA
spec:
ports:
- port: 80
protocol: TCP
selector:
app: projectA
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: project-a-vs
spec:
hosts:
- project-a.default.svc.cluster.local
http:
- name: v1-match-v1
match:
- sourceLabels:
version: v1
route:
- destination:
host: project-a.default.svc.cluster.local
port:
number: 80
subset: v1
- name: v2-match-v2
match:
- sourceLabels:
version: v2
route:
- destination:
host: project-a.default.svc.cluster.local
port:
number: 80
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: project-a-dr
spec:
host: project-a.default.svc.cluster.local
subsets:
- name: v1
labels:
run: nginx1
- name: v2
labels:
run: nginx2
和一些测试:
ubu1 pod有v1版本标签,所以它应该调用nginx部署的v1版本。
kubectl exec -ti ubu1 -- /bin/bash
root@ubu1:/# curl project-a
This is version 1 of project A
root@ubu1:/# curl project-a
This is version 1 of project A
root@ubu1:/# curl project-a
This is version 1 of project A
ubu1 pod有v2版本标签,所以应该调用nginx部署的v2版本。
kubectl exec -ti ubu2 -- /bin/bash
root@ubu2:/# curl project-a
This is version 2 of project A
root@ubu2:/# curl project-a
This is version 2 of project A
root@ubu2:/# curl project-a
This is version 2 of project A
正如@Joel提到的
您可以在该VirtualService中添加任意数量的路由规则,并且可以对所有服务重复此操作。
所以我希望上面的例子你可以改变它为你的用例。