在多集群网格中安装 Kiali

在网格中的一个集群上部署 Kiali server,授予其对其他所有集群的读取访问权限,并创建用于在这些集群上进行身份验证的资源。

NOTE

在此操作步骤中,CLUSTER1East 集群,用于托管 Kiali server;CLUSTER2West 集群,仅提供远程集群资源。

如果网格跨越两个以上的集群,您可以在每个其他集群上重复 West 步骤,以调整这些说明。

前提条件

  • 您已按照安装多主多网络网格安装主节点-远程多网络网格中的任一说明部署了多集群网格。

  • 您已在网格中的每个集群上安装 Alauda Build of Kiali Operator,包括未部署 Kiali server 的集群。请参阅安装 Alauda Build of Kiali

  • 网格中的每个集群都使用 ACP Monitoring with VictoriaMetrics 收集指标,并且所有集群都将指标报告到同一个 VictoriaMetrics Center。请参阅 ACP Monitoring with VictoriaMetrics

    Kiali 从单个端点读取整个网格的指标。运行以下命令读取共享端点的地址:

    kubectl get feature monitoring -o jsonpath='{.spec.accessInfo.database.address}'

    报告到同一个 VictoriaMetrics Center 的每个集群都会返回此地址。该地址就是您在 Kiali 资源的 spec.external_services.prometheus.url 中设置的值。

  • 您已按照配置 Service Mesh 监控中的说明配置指标收集。Kiali 根据 Istio 添加到这些指标中的 source_clusterdestination_cluster 标签区分集群,并根据 mesh_id 标签筛选指标,因此每个资源的部署位置都很重要:

    • 在网格中的每个集群上创建 ServiceMonitorPodMonitor 对象,因为监控会分别抓取每个集群。
    • 在运行控制平面的每个集群上创建 Telemetry 资源,并包含其 mesh_id 标签覆盖。在主节点-远程网格中,主节点控制平面还会配置远程集群的 sidecar;在远程集群上应用此资源会被 validation.istio.io webhook 拒绝,因为该处的 istiod service 没有端点。
  • Kiali 部署命名空间和实例名称在所有集群上都相同。如果您更改了任一默认值,请在每个集群的 Kiali 资源中,将相同的值应用于 spec.deployment.namespacespec.deployment.instance_name。此操作步骤使用默认值 istio-systemkiali

  • 您知道网格的 meshID 以及 Istio 为每个集群使用的名称。后续步骤会将集群名称传递给 --remote-cluster-name 选项,并将其用作远程集群 secret 的键,因此该名称必须完全匹配。根据拓扑不同,读取该名称的位置也不同:

    • 在多主模式网格中,每个集群都有自己的 Istio 资源,其中包含 spec.values.global.meshIDspec.values.global.multiCluster.clusterName
    • 在主节点-远程网格中,只有主集群的 Istio 资源包含这些字段。远程集群的名称会出现在该集群自己的 Istio 资源中,作为 spec.values.istiodRemote.injectionPath 的一部分,其形式为 /inject/cluster/<cluster-name>/net/<network>

    此操作步骤使用 mesh1cluster1cluster2

  • 您已为 kubectl 配置每个集群对应的上下文。以下环境变量会在整个操作步骤中使用:

    export CTX_CLUSTER1=<your cluster1 context>
    export CTX_CLUSTER2=<your cluster2 context>

操作步骤

东部集群上部署 Kiali server

按照使用 Kiali 配置监控中的说明,在东部集群上创建 Kiali 资源,然后添加以下多集群特定设置。

由于监控存储还包含网格外部生成的指标,因此请设置查询范围,将 Kiali 限制在此网格中:

kiali-query-scope.yaml
spec:
  external_services:
    prometheus:
      query_scope:
        mesh_id: mesh1
  1. 必须与网格中每个集群的 Istio 资源中的 .spec.values.global.meshID 匹配。Kiali 会将此标签追加到每个指标查询中,因此不包含该标签的序列会被忽略。

运行以下命令应用该设置:

kubectl --context "${CTX_CLUSTER1}" -n istio-system patch kiali kiali \
  --type merge -p "$(cat kiali-query-scope.yaml)"

西部集群上创建仅生成远程集群资源的 Kiali 资源

创建名为 kiali-remote.yaml 的 YAML 文件,内容如下:

kiali-remote.yaml
apiVersion: kiali.io/v1alpha1
kind: Kiali
metadata:
  name: kiali
  namespace: istio-system
spec:
  deployment:
    instance_name: kiali
    remote_cluster_resources_only: true
  1. 必须是东部集群上 Kiali server 所在的同一命名空间。
  2. 必须是 Kiali server 在东部集群上使用的同一实例名称。Operator 会根据该名称派生 service account 名称,因此名称不匹配会导致 server 无法进行身份验证。
  3. 指示 Operator 仅创建远程 Kiali server 所需的资源:一个 kiali-service-account service account,以及一个带有绑定的 kiali-viewer cluster role。不会在此集群上创建 Kiali server、service 或 ingress。

运行以下命令,在西部集群上应用 YAML 文件:

kubectl --context "${CTX_CLUSTER2}" apply -f kiali-remote.yaml

等待资源完成调谐:

kubectl --context "${CTX_CLUSTER2}" wait --for=condition=Successful \
  kialis/kiali -n istio-system --timeout=3m

西部集群上创建长期有效的 service account 令牌

Kiali server 使用不会过期的 service account 令牌向远程集群进行身份验证。Kubernetes 不再自动生成此类令牌,因此请显式创建它。

创建名为 kiali-svc-account-token.yaml 的 YAML 文件,内容如下:

kiali-svc-account-token.yaml
apiVersion: v1
kind: Secret
metadata:
  name: kiali-service-account
  namespace: istio-system
  annotations:
    kubernetes.io/service-account.name: kiali-service-account
type: kubernetes.io/service-account-token
  1. 将令牌绑定到第 2 步创建的 service account。对于非默认实例名称,请使用 <instance_name>-service-account
  2. 使令牌控制器填充此 secret 的 token 键。

运行以下命令,在西部集群上应用 YAML 文件:

kubectl --context "${CTX_CLUSTER2}" apply -f kiali-svc-account-token.yaml

获取使用平台 API 端点的西部集群 kubeconfig

从 Alauda Container Platform Web 控制台下载西部集群的 kubeconfig,或通过平台 API 获取:

curl -sS -k -H "Authorization: Bearer <your-platform-api-token>" \
  "<platform-url>/auth/v1/clusters/<west-cluster-name>/kubeconfig" \
  -o west-kubeconfig.json
WARNING

平台 API 以 JSON 格式返回 kubeconfig,其中的 certificate-authority-data 以 PEM 块而不是 base64 形式提供。未经修改地保存响应并将 kubectl 指向该文件会导致 illegal base64 data at input byte 0。请在使用前对该字段进行编码,或者改为从 Web 控制台下载 kubeconfig

以下命令会对该字段进行编码,将文件转换为 YAML,并将每个凭证内联,以便稍后轻松合并。第一个命令可以安全地多次运行,因为它只会处理仍为 PEM 格式的值:

jq '.clusters[].cluster."certificate-authority-data" |=
  (if startswith("-----BEGIN") then @base64 else . end)' \
  west-kubeconfig.json > west-kubeconfig-fixed.json

KUBECONFIG=west-kubeconfig-fixed.json \
  kubectl config view --flatten --raw > west-kubeconfig.yaml

下载的 kubeconfig 包含两个上下文。请使用 proxy-connect 上下文,该上下文为默认上下文,其 server 地址格式如下:

<platform-url>/kubernetes/<west-cluster-name>
DANGER

远程集群 secret 必须通过此平台端点访问远程集群,不能通过 direct-connect 上下文使用的集群 API server 地址访问。

平台端点同时接受 Kiali service account 令牌和已登录用户的平台令牌,而集群 API server 只接受前者。使用 direct-connect 地址时,Kiali server 仍会报告集群可访问,但每个用户范围的请求都会失败,并且远程集群不会向 Kiali 控制台提供任何命名空间。有关这些症状,请参阅远程集群报告为可访问,但其命名空间未显示在控制台中

proxy-connect 上下文添加到同时包含东部集群上下文的 kubeconfig 中,使单个 kubeconfig 能够访问两个集群,然后导出其名称:

export CTX_CLUSTER2_PROXY=<your cluster2 proxy-connect context>
NOTE

每个集群下载的 kubeconfig 都会将其上下文命名为 proxy-connectdirect-connect。合并多个集群的文件时,请先重命名上下文,以免发生冲突。

东部集群上创建远程集群 secret

远程集群 secret 包含一个 kubeconfig,使东部集群上的 Kiali server 能够读取西部集群。使用 kiali-prepare-remote-cluster.sh 脚本生成该 secret。

运行以下命令下载脚本并使其可执行:

curl -L -o kiali-prepare-remote-cluster.sh \
  https://raw.githubusercontent.com/kiali/kiali/master/hack/istio/multicluster/kiali-prepare-remote-cluster.sh
chmod +x kiali-prepare-remote-cluster.sh

运行以下命令执行脚本:

./kiali-prepare-remote-cluster.sh \
  --kiali-cluster-context "${CTX_CLUSTER1}" \
  --remote-cluster-context "${CTX_CLUSTER2_PROXY}" \
  --remote-cluster-name cluster2 \
  --remote-cluster-namespace istio-system \
  --kiali-resource-name kiali-service-account \
  --process-remote-resources false \
  --process-kiali-secret true \
  --view-only false

这些选项的作用如下:

  • --remote-cluster-name:Istio 用于远程集群的名称,取自 .spec.values.global.multiCluster.clusterName。请始终显式设置此选项,因为脚本从上下文派生的名称可能包含 secret 键中无效的字符。
  • --remote-cluster-namespace:远程集群上存放 service account 及其令牌的命名空间。
  • --kiali-resource-name:Operator 在第 2 步中创建的 service account。
  • --process-remote-resources false:跳过创建 service account 和角色,因为 Kiali 资源已经管理它们。
  • --process-kiali-secret true:在东部集群的 Kiali 部署命名空间中创建 secret。
  • --view-only false:授予 Kiali 对远程集群的写入权限。将其设置为 true 可将 Kiali 限制为仅对该集群执行只读操作。

成功后,脚本会报告从上下文读取的 server 地址以及所创建 secret 的名称:

INFO: remote_cluster_server_url=<platform-url>/kubernetes/<west-cluster-name>
secret/kiali-remote-cluster-secret-cluster2 created
TIP

使用 --help 选项可显示脚本支持的所有选项,包括用于删除其创建内容的 --delete true

Operator 会根据标签查找生成的 secret。有关注册远程集群 secret 的其他方式,请参阅注册远程集群 secret

触发 Kiali server 的调谐

Operator 在调谐 Kiali 资源时,会将远程集群 secret 挂载到 Kiali server pod 中。为该资源添加注解以启动调谐:

kubectl --context "${CTX_CLUSTER1}" annotate kiali kiali -n istio-system \
  --overwrite kiali.io/reconcile="$(date)"

运行以下命令,等待资源和 server 就绪:

kubectl --context "${CTX_CLUSTER1}" wait --for=condition=Successful \
  kialis/kiali -n istio-system --timeout=3m
kubectl --context "${CTX_CLUSTER1}" rollout status deployment/kiali -n istio-system

登录 Kiali 控制台

<platform-url>/clusters/<east-cluster-name>/kiali 打开东部集群的 Kiali 控制台。

验证

  1. 运行以下命令,确认 Kiali server 已发现每个集群:

    kubectl --context "${CTX_CLUSTER1}" logs -n istio-system deployment/kiali | grep "Discovered cluster"

    网格中的每个集群都会显示为 Accessible=true,其中恰好有一个集群显示为 IsKialiHome=true

    INF Discovered cluster: Name=[cluster1], Accessible=true, IsKialiHome=true, ApiEndpoint=[https://100.4.0.1:443], SecretName=[]
    INF Discovered cluster: Name=[cluster2], Accessible=true, IsKialiHome=false, ApiEndpoint=[<platform-url>/kubernetes/<west-cluster-name>], SecretName=[kiali-remote-cluster-secret-cluster2]
  2. 在 Kiali 控制台中,导航到命名空间,确认列出了每个集群中的命名空间。每个命名空间卡片上都会显示集群名称。

  3. 导航到网格,确认网格中的每个集群都已显示。控制平面的绘制方式取决于拓扑:

    • 在多主模式网格中,每个集群都会在其数据平面节点旁显示自己的控制平面节点。
    • 在主节点-远程集群网格中,只有主节点集群会显示控制平面节点。每个远程集群都会显示一个数据平面节点,主节点的控制平面会连接到该节点。
  4. 导航到流量图,选择一个存在于多个集群中的命名空间,确认图中分别绘制了各个集群,并显示集群之间的边。启用显示 > 集群框,按集群对节点进行分组。

从 Kiali 中移除集群

操作步骤

  1. 从承载 Kiali server 的集群上的 Kiali 部署命名空间中删除远程集群 secret:

    kubectl --context "${CTX_CLUSTER1}" -n istio-system \
      delete secret kiali-remote-cluster-secret-cluster2
    NOTE

    如果使用 kiali-prepare-remote-cluster.sh 创建了 secret,请使用相同选项以及 --delete true 再次运行脚本。

  2. 删除远程集群的 Kiali 资源,以从远程集群中移除 service account 和角色:

    kubectl --context "${CTX_CLUSTER2}" -n istio-system delete kiali kiali
    NOTE

    长期有效的令牌 secret 会随其所属的 service account 一同消失,因此无需删除其他内容。

  3. 让 Kiali server 停止查找已删除的 secret:

    • 使用基于标签的自动检测时,触发一次调谐:

      kubectl --context "${CTX_CLUSTER1}" annotate kiali kiali -n istio-system \
        --overwrite kiali.io/reconcile="$(date)"
    • 使用显式声明时,从 spec.clustering.clusters 中删除相应条目。

    • 使用一个组合 secret时,无需执行任何操作。Operator 会注意到此更改并重新部署 Kiali server。

  4. 如果已移除的集群本身拥有远程集群 secret,请重新创建 Kiali server 部署,使其停止挂载已删除的 secret:

    kubectl --context "${CTX_CLUSTER1}" -n istio-system delete deployment kiali
    kubectl --context "${CTX_CLUSTER1}" annotate kiali kiali -n istio-system \
      --overwrite kiali.io/reconcile="$(date)"
    kubectl --context "${CTX_CLUSTER1}" wait --for=condition=Successful \
      kialis/kiali -n istio-system --timeout=3m
    kubectl --context "${CTX_CLUSTER1}" rollout status deployment/kiali -n istio-system

    确认已移除的集群不再具有卷:

    kubectl --context "${CTX_CLUSTER1}" get deployment kiali -n istio-system \
      -o jsonpath='{range .spec.template.spec.volumes[*]}{.name}{"\n"}{end}'
    WARNING

    不要跳过此步骤。仅进行调谐不会从 Kiali server 部署中删除已删除的远程集群 secret 对应的卷。正在运行的 pod 会继续提供服务,但下一次重启后会卡在 ContainerCreating。仅当所有远程集群共享一个组合 secret 时,才无需执行此步骤,因为此时卷引用的仍是现存的 secret。

清理 Kiali

首先注销远程集群,最后删除 Kiali server,从整个网格中移除 Kiali。如果顺序相反,Kiali server 会先被删除,而远程集群尚未完成清理,其未使用的 service account 和角色会继续保留。

操作步骤

  1. 按照从 Kiali 中移除集群中的说明,逐一从 Kiali 中移除所有远程集群。

    NOTE

    下一步会删除 Kiali server,因此可以跳过步骤 4,该步骤用于重新创建其部署。

  2. East 集群上删除 Kiali 资源:

    kubectl --context "${CTX_CLUSTER1}" -n istio-system delete kiali kiali

    确认 Operator 已移除 server:

    kubectl --context "${CTX_CLUSTER1}" -n istio-system get deployment kiali

    输出示例

    Error from server (NotFound): deployments.apps "kiali" not found
NOTE

Alauda Build of Kiali Operator 仍安装在每个集群上。若还要将其以及 Kiali 自定义资源定义一并移除,请参阅卸载 Alauda Build of Kiali

其他资源