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

本指南向您演示在单集群中安装多个 Istio 控制面的过程以及将工作负载的作用域指定到特定控制面的方式。 这个部署模型采用单个 Kubernetes 控制面以及多个 Istio 控制面和多个网格。 网格之间的分离通过 Kubernetes 命名空间和 RBAC 实现。

Multiple meshes in a single cluster
Multiple meshes in a single cluster

使用 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 然后用于确定每个控制面托管的资源和工作负载的作用域。

  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 usergroup-2 --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 Deployment。

  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-1 中的 curl Pod 的请求发送到 usergroup-2app-ns-2 中的 httpbin 服务:

    $ 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-2 中的 curl Pod 的请求发送到 usergroup-2app-ns-3 中的 httpbin 服务:通信应发挥作用:

    $ 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
这些信息有用吗?
您是否有更多建议和改进意见?

感谢您的反馈!