Istio 如何限制 v1 项目总是访问 v1 项目?
Istio how to limit v1 projects always access v1 projects?
我有 3 个项目:A、B、C。
每个项目有两个版本: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 虚拟服务来从特定版本的项目调用另一个项目的相同版本。
在这种情况下,您可以使用 网状网关。
The reserved word mesh is used to imply all the sidecars in the mesh. When this field is omitted, the default gateway (mesh) will be used, which would apply the rule to all sidecars in the mesh. If a list of gateway names is provided, the rules will apply only to the gateways. To apply the rules to both gateways and sidecars, specify mesh as one of the gateway names.
所以有2个选项。
您可以使用 网状网关 作为网关之一:
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
或者您可以在没有网关列表的情况下创建虚拟服务,因此默认网关将是 网状网关。
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 pods
做了一个例子
- ubu1 标签版本为 v1
- ubu2 标签版本为 v2
还有2个nginxpods
- 带有标签 nginx1 的 nginx1
- 带有标签 nginx2 的 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 提到的那样
You can add any number of route rules in that VirtualService, and can repeat the operation for all your services.
所以我希望您可以根据您的用例更改上面的示例。
我有 3 个项目:A、B、C。
每个项目有两个版本: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 虚拟服务来从特定版本的项目调用另一个项目的相同版本。
在这种情况下,您可以使用 网状网关。
The reserved word mesh is used to imply all the sidecars in the mesh. When this field is omitted, the default gateway (mesh) will be used, which would apply the rule to all sidecars in the mesh. If a list of gateway names is provided, the rules will apply only to the gateways. To apply the rules to both gateways and sidecars, specify mesh as one of the gateway names.
所以有2个选项。
您可以使用 网状网关 作为网关之一:
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
或者您可以在没有网关列表的情况下创建虚拟服务,因此默认网关将是 网状网关。
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 pods
做了一个例子- ubu1 标签版本为 v1
- ubu2 标签版本为 v2
还有2个nginxpods
- 带有标签 nginx1 的 nginx1
- 带有标签 nginx2 的 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 提到的那样
You can add any number of route rules in that VirtualService, and can repeat the operation for all your services.
所以我希望您可以根据您的用例更改上面的示例。