在单集群中安装多个 Istio 控制面
本指南向您演示在单集群中安装多个 Istio 控制面的过程以及将工作负载的作用域指定到特定控制面的方式。 这个部署模型采用单个 Kubernetes 控制面以及多个 Istio 控制面和多个网格。 网格之间的分离通过 Kubernetes 命名空间和 RBAC 实现。
使用 discoverySelectors
,您可以将集群中 Kubernetes 资源的作用域指定到某个 Istio 控制面管理的特定命名空间。
这包括用于配置网格的 Istio 自定义资源(例如 Gateway、VirtualService、DestinationRule 等)。
此外,discoverySelectors
可用于配置哪个命名空间应包括用于特定 Istio 控制面的 istio-ca-root-cert
ConfigMap。
这些功能共同允许网格操作员为给定的控制面指定命名空间,从而基于一个或多个命名空间的边界为多个网格启用软多租户。
本指南使用 discoverySelectors
以及 Istio 的修订功能来演示如何在单集群上部署两个网格,每个网格使用适当作用域的集群资源子集。
开始之前
本指南要求您有一个 Kubernetes 集群,其上安装了任一支持的 Kubernetes 版本: 1.28, 1.29, 1.30, 1.31。
本集群将包含两个不同的系统命名空间中安装的两个控制面。 网格应用负载将运行在多个应用特定的命名空间中,每个命名空间基于修订和发现选择器配置与一个或另一个控制面关联。
集群配置
部署多个控制面
在单集群上部署多个 Istio 控制面可通过为每个控制面使用不同的系统命名空间来达成。
Istio 修订和 discoverySelectors
然后用于确定每个控制面托管的资源和工作负载的作用域。
创建第一个系统命名空间
usergroup-1
并在其中部署 istiod:$ kubectl create ns usergroup-1 $ kubectl label ns usergroup-1 usergroup=usergroup-1 $ istioctl install -y -f - <<EOF apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: usergroup-1 spec: profile: minimal revision: usergroup-1 meshConfig: discoverySelectors: - matchLabels: usergroup: usergroup-1 values: global: istioNamespace: usergroup-1 EOF
创建第二个系统命名空间
usergroup-2
并在其中部署 istiod:$ kubectl create ns usergroup-2 $ kubectl label ns usergroup-2 usergroup=usergroup-2 $ istioctl install -y -f - <<EOF apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: usergroup-2 spec: profile: minimal revision: usergroup-2 meshConfig: discoverySelectors: - matchLabels: usergroup: usergroup-2 values: global: istioNamespace: usergroup-2 EOF
在
usergroup-1
命名空间中为工作负载部署策略,以便只能接收双向 TLS 流量:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: "usergroup-1-peerauth" namespace: "usergroup-1" spec: mtls: mode: STRICT EOF
在
usergroup-2
命名空间中为工作负载部署策略,以便只能接收双向 TLS 流量:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: "usergroup-2-peerauth" namespace: "usergroup-2" spec: mtls: mode: STRICT EOF
确认创建多个控制面
查看每个控制面的系统命名空间上的标签:
$ kubectl get ns usergroup-1 usergroup2 --show-labels NAME STATUS AGE LABELS usergroup-1 Active 13m kubernetes.io/metadata.name=usergroup-1,usergroup=usergroup-1 usergroup-2 Active 12m kubernetes.io/metadata.name=usergroup-2,usergroup=usergroup-2
确认控制面被部署且正在运行:
$ kubectl get pods -n usergroup-1 NAMESPACE NAME READY STATUS RESTARTS AGE usergroup-1 istiod-usergroup-1-5ccc849b5f-wnqd6 1/1 Running 0 12m
$ kubectl get pods -n usergroup-2 NAMESPACE NAME READY STATUS RESTARTS AGE usergroup-2 istiod-usergroup-2-658d6458f7-slpd9 1/1 Running 0 12m
您会注意到在指定的命名空间中为每个用户组创建了一个 Istiod Deployment。
执行以下命令列出已安装的 Webhook:
$ kubectl get validatingwebhookconfiguration NAME WEBHOOKS AGE istio-validator-usergroup-1-usergroup-1 1 18m istio-validator-usergroup-2-usergroup-2 1 18m istiod-default-validator 1 18m
$ kubectl get mutatingwebhookconfiguration NAME WEBHOOKS AGE istio-revision-tag-default-usergroup-1 4 18m istio-sidecar-injector-usergroup-1-usergroup-1 2 19m istio-sidecar-injector-usergroup-2-usergroup-2 2 18m
请注意,输出包括
istiod-default-validator
和istio-revision-tag-default-usergroup-1
,它们是用于处理来自与任何修订无关的资源请求的默认 Webhook 配置。 在一个完整作用域的环境中,每个控制面都通过适当的命名空间标签与其资源相关联,不需要这些默认的 Webhook 配置。 它们不应该被调用。
每个用户组部署应用负载
创建三个应用命名空间:
$ kubectl create ns app-ns-1 $ kubectl create ns app-ns-2 $ kubectl create ns app-ns-3
为每个命名空间打标签,将其与各自的控制面相关联:
$ kubectl label ns app-ns-1 usergroup=usergroup-1 istio.io/rev=usergroup-1 $ kubectl label ns app-ns-2 usergroup=usergroup-2 istio.io/rev=usergroup-2 $ kubectl label ns app-ns-3 usergroup=usergroup-2 istio.io/rev=usergroup-2
为每个命名空间部署一个
sleep
和httpbin
应用:$ kubectl -n app-ns-1 apply -f samples/sleep/sleep.yaml $ kubectl -n app-ns-1 apply -f samples/httpbin/httpbin.yaml $ kubectl -n app-ns-2 apply -f samples/sleep/sleep.yaml $ kubectl -n app-ns-2 apply -f samples/httpbin/httpbin.yaml $ kubectl -n app-ns-3 apply -f samples/sleep/sleep.yaml $ kubectl -n app-ns-3 apply -f samples/httpbin/httpbin.yaml
等待几秒钟,让
httpbin
和sleep
Pod 在注入 Sidecar 的情况下运行:$ kubectl get pods -n app-ns-1 NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-zc2v4 2/2 Running 0 115m sleep-78ff5975c6-fml7c 2/2 Running 0 115m
$ kubectl get pods -n app-ns-2 NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-sd9ln 2/2 Running 0 115m sleep-78ff5975c6-sz728 2/2 Running 0 115m
$ kubectl get pods -n app-ns-3 NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-8ll27 2/2 Running 0 115m sleep-78ff5975c6-sg4tq 2/2 Running 0 115m
确认应用到控制面的映射
现在应用已部署,您可以使用 istioctl ps
命令确认应用负载由其各自的控制面管理,
即 app-ns-1
由 usergroup-1
管理,app-ns-2
和 app-ns-3
由 usergroup-2
管理:
$ istioctl ps -i usergroup-1
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
httpbin-9dbd644c7-hccpf.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-1-5ccc849b5f-wnqd6 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
sleep-78ff5975c6-9zb77.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-1-5ccc849b5f-wnqd6 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
$ istioctl ps -i usergroup-2
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
httpbin-9dbd644c7-vvcqj.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
httpbin-9dbd644c7-xzgfm.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
sleep-78ff5975c6-fthmt.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
sleep-78ff5975c6-nxtth.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
确认应用连接仅在各个用户组内
将
usergroup-1
中app-ns-1
中的sleep
Pod 的请求发送到usergroup-2
中app-ns-2
中的httpbin
服务:$ kubectl -n app-ns-1 exec "$(kubectl -n app-ns-1 get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -sIL http://httpbin.app-ns-2.svc.cluster.local:8000 HTTP/1.1 503 Service Unavailable content-length: 95 content-type: text/plain date: Sat, 24 Dec 2022 06:54:54 GMT server: envoy
将
usergroup-2
中app-ns-2
中的sleep
Pod 的请求发送到usergroup-2
中app-ns-3
中的httpbin
服务:通信应发挥作用:$ kubectl -n app-ns-2 exec "$(kubectl -n app-ns-2 get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -sIL http://httpbin.app-ns-3.svc.cluster.local:8000 HTTP/1.1 200 OK server: envoy date: Thu, 22 Dec 2022 15:01:36 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 3
清理
清理第一个用户组:
$ istioctl uninstall --revision usergroup-1 --set values.global.istioNamespace=usergroup-1 $ kubectl delete ns app-ns-1 usergroup-1
清理第二个用户组:
$ istioctl uninstall --revision usergroup-2 --set values.global.istioNamespace=usergroup-2 $ kubectl delete ns app-ns-2 app-ns-3 usergroup-2