在单个集群中安装多个 Istio 控制平面

本指南将引导您完成在单个集群中安装多个 Istio 控制平面的过程,以及将工作负载限定到特定控制平面的方法。这种部署模型包含单个 Kubernetes 控制平面和多个 Istio 控制平面和网格。网格之间的分离由 Kubernetes 命名空间和 RBAC 提供。

Multiple meshes in a single cluster
单个集群中的多个网格

使用 discoverySelectors,您可以将集群中的 Kubernetes 资源限定到由 Istio 控制平面管理的特定命名空间。这包括用于配置网格的 Istio 自定义资源(例如,Gateway、VirtualService、DestinationRule 等)。此外,discoverySelectors 可用于配置哪些命名空间应包含特定 Istio 控制平面的 istio-ca-root-cert 配置映射。这些功能共同使网格运营商能够为给定控制平面指定命名空间,从而基于一个或多个命名空间的边界实现多个网格的软多租户。本指南使用 discoverySelectors 以及 Istio 的修订功能,演示如何在单个集群上部署两个网格,每个网格都使用集群资源的适当限定子集。

开始之前

本指南要求您拥有一个 Kubernetes 集群,其中包含以下任何一个 支持的 Kubernetes 版本: 1.28、1.29、1.30、1.31。

此集群将托管两个控制平面,它们安装在两个不同的系统命名空间中。网格应用程序工作负载将在多个特定于应用程序的命名空间中运行,每个命名空间根据修订版和发现选择器配置与一个或另一个控制平面关联。

集群配置

部署多个控制平面

在单个集群上部署多个 Istio 控制平面可以通过为每个控制平面使用不同的系统命名空间来实现。然后使用 Istio 修订版和 discoverySelectors 来限定每个控制平面管理的资源和工作负载。

  1. 创建第一个系统命名空间 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
  2. 创建第二个系统命名空间 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
  3. 部署一项策略,使 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
  4. 部署一项策略,使 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

验证多个控制平面的创建

  1. 检查每个控制平面的系统命名空间的标签

    $ 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
  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 部署。

  3. 运行以下命令以列出已安装的 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-validatoristio-revision-tag-default-usergroup-1,它们是用于处理来自与任何修订版无关的资源的请求的默认 Webhook 配置。在每个控制平面都通过适当的命名空间标记与其资源相关联的完全限定环境中,不需要这些默认 Webhook 配置。它们永远不应该被调用。

根据用户组部署应用程序工作负载

  1. 创建三个应用程序命名空间

    $ kubectl create ns app-ns-1 $ kubectl create ns app-ns-2 $ kubectl create ns app-ns-3
  2. 为每个命名空间添加标签,将其与相应的控制平面关联

    $ 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
  3. 为每个命名空间部署一个 curlhttpbin 应用程序

    $ kubectl -n app-ns-1 apply -f samples/curl/curl.yaml $ kubectl -n app-ns-1 apply -f samples/httpbin/httpbin.yaml $ kubectl -n app-ns-2 apply -f samples/curl/curl.yaml $ kubectl -n app-ns-2 apply -f samples/httpbin/httpbin.yaml $ kubectl -n app-ns-3 apply -f samples/curl/curl.yaml $ kubectl -n app-ns-3 apply -f samples/httpbin/httpbin.yaml
  4. 等待几秒钟,直到 httpbincurl Pod 运行并注入 Sidecar

    $ kubectl get pods -n app-ns-1
    NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-zc2v4 2/2 Running 0 115m curl-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 curl-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 curl-78ff5975c6-sg4tq 2/2 Running 0 115m

验证应用程序到控制平面的映射

现在应用程序已部署,您可以使用 istioctl ps 命令确认应用程序工作负载由其相应的控制平面管理,即 app-ns-1usergroup-1 管理,app-ns-2app-ns-3usergroup-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 curl-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 curl-78ff5975c6-fthmt.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117 curl-78ff5975c6-nxtth.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117

验证应用程序连接仅限于各自的用户组

  1. usergroup-1app-ns-1curl Pod 向 usergroup-2app-ns-2httpbin 服务发送请求。通信应失败

    $ kubectl -n app-ns-1 exec "$(kubectl -n app-ns-1 get pod -l app=curl -o jsonpath={.items..metadata.name})" -c curl -- 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
  2. usergroup-2app-ns-2curl Pod 向 usergroup-2app-ns-3httpbin 服务发送请求。通信应该正常工作

    $ kubectl -n app-ns-2 exec "$(kubectl -n app-ns-2 get pod -l app=curl -o jsonpath={.items..metadata.name})" -c curl -- 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

清理

  1. 清理第一个用户组

    $ istioctl uninstall --revision usergroup-1 --set values.global.istioNamespace=usergroup-1 $ kubectl delete ns app-ns-1 usergroup-1
  2. 清理第二个用户组

    $ istioctl uninstall --revision usergroup-2 --set values.global.istioNamespace=usergroup-2 $ kubectl delete ns app-ns-2 app-ns-3 usergroup-2
这些信息是否有用?
您有什么改进建议吗?

感谢您的反馈!