为远程集群配置 istioctl

使用代理服务器在具有外部控制平面的网格中支持 istioctl 命令。

2022 年 3 月 25 日 | 作者:Frank Budinsky - IBM

远程集群上使用

istioctl CLI 时,一些命令默认情况下无法正常工作。例如,istioctl proxy-status 需要访问 istiod 服务以检索其管理的代理的状态和配置。如果您尝试在远程集群上运行它,您将收到类似以下的错误消息

$ istioctl proxy-status
Error: unable to find any Istiod instances

请注意,错误消息不仅说明无法访问 istiod 服务,还具体说明无法找到 istiod 实例。这是因为 istioctl proxy-status 的实现需要检索所有 istiod 实例的同步状态,而不仅仅是单个实例。当运行多个 istiod 实例(副本)时,每个实例仅连接到网格中运行的代理的子集。istioctl 命令需要返回整个网格的状态,而不仅仅是其中一个实例管理的子集。

istiod 服务在集群本地运行的普通 Istio 安装中(即 主集群),该命令的实现方式是简单地找到所有正在运行的

istiod Pod,依次调用每个 Pod,然后在将结果返回给用户之前将它们聚合。

CLI with local access to istiod pods
CLI 可以本地访问 istiod Pod

另一方面,在使用远程集群时,这不可行,因为 istiod 实例运行在网格集群外部,网格用户无法访问它们。这些实例甚至可能不是在 Kubernetes 集群上使用 Pod 部署的。

幸运的是,istioctl 提供了一个配置选项来解决此问题。您可以使用具有访问 istiod 实例权限的外部代理服务的地址来配置 istioctl。与普通负载均衡器服务不同,后者将传入请求委托给其中一个实例,此代理服务必须将请求委托给所有 istiod 实例,聚合响应,然后返回组合结果。

如果外部代理服务实际上运行在另一个 Kubernetes 集群上,则代理实现代码可以与 istioctl 在主集群情况下运行的实现代码非常相似,即找到所有正在运行的 istiod Pod,依次调用每个 Pod,然后聚合结果。

CLI without local access to istiod pods
CLI 无法本地访问 istiod Pod

可以在此处找到包含此类 istioctl 代理服务器实现的 Istio 生态系统项目。要试用它,您需要两个集群,其中一个集群被配置为使用在另一个集群中安装的控制平面的远程集群。

使用远程集群拓扑安装 Istio

为了演示 istioctl 在远程集群上运行,我们将首先使用外部控制平面安装说明来设置一个具有在单独的外部集群中运行的外部控制平面的单个远程集群网格。

完成安装后,我们应该有两个环境变量:CTX_REMOTE_CLUSTERCTX_EXTERNAL_CLUSTER,它们分别包含远程(网格)和外部(控制平面)集群的上下文名称。

我们还应该在网格中(即远程集群上)运行 helloworldsleep 示例

$ kubectl get pod -n sample --context="${CTX_REMOTE_CLUSTER}"
NAME READY STATUS RESTARTS AGE helloworld-v1-776f57d5f6-tmpkd 2/2 Running 0 10s sleep-557747455f-v627d 2/2 Running 0 9s

请注意,如果您尝试在远程集群中运行 istioctl proxy-status,您将看到前面描述的错误消息

$ istioctl proxy-status --context="${CTX_REMOTE_CLUSTER}"
Error: unable to find any Istiod instances

配置 istioctl 以使用示例代理服务

要配置 istioctl,我们首先需要将代理服务部署到正在运行的 istiod Pod 旁边。在我们的安装中,我们在 external-istiod 命名空间中部署了控制平面,因此我们使用以下命令在外部集群上启动代理服务

$ kubectl apply -n external-istiod --context="${CTX_EXTERNAL_CLUSTER}" \ -f https://raw.githubusercontent.com/istio-ecosystem/istioctl-proxy-sample/main/istioctl-proxy.yaml
service/istioctl-proxy created serviceaccount/istioctl-proxy created secret/jwt-cert-key-secret created deployment.apps/istioctl-proxy created role.rbac.authorization.k8s.io/istioctl-proxy-role created rolebinding.rbac.authorization.k8s.io/istioctl-proxy-role created

您可以运行以下命令来确认 istioctl-proxy 服务是否与 istiod 运行在一起

$ kubectl get po -n external-istiod --context="${CTX_EXTERNAL_CLUSTER}"
NAME READY STATUS RESTARTS AGE istioctl-proxy-664bcc596f-9q8px 1/1 Running 0 15s istiod-666fb6694d-jklkt 1/1 Running 0 5m31s

代理服务是一个在端口 9090 上提供服务的 gRPC 服务器

$ kubectl get svc istioctl-proxy -n external-istiod --context="${CTX_EXTERNAL_CLUSTER}"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istioctl-proxy ClusterIP 172.21.127.192 <none> 9090/TCP 11m

但是,在我们能够使用它之前,我们需要将其公开到外部集群之外。这有很多方法,具体取决于部署环境。在我们的设置中,我们在外部集群上运行了一个入口网关,因此我们可以更新它以公开端口 9090,更新相关的虚拟服务以将端口 9090 请求定向到代理服务,然后配置 istioctl 使用网关地址作为代理服务。这将是一种“适当”的方法。

但是,由于这只是一个简单的演示,我们可以访问这两个集群,因此我们将简单地将代理服务 端口转发localhost

$ kubectl port-forward -n external-istiod service/istioctl-proxy 9090:9090 --context="${CTX_EXTERNAL_CLUSTER}"

现在,我们通过设置 ISTIOCTL_XDS_ADDRESS 环境变量来配置 istioctl 使用 localhost:9090 访问代理

$ export ISTIOCTL_XDS_ADDRESS=localhost:9090 $ export ISTIOCTL_ISTIONAMESPACE=external-istiod $ export ISTIOCTL_PREFER_EXPERIMENTAL=true

由于我们的控制平面运行在 external-istiod 命名空间中,而不是默认的 istio-system 中,因此我们还需要设置 ISTIOCTL_ISTIONAMESPACE 环境变量。

设置 ISTIOCTL_PREFER_EXPERIMENTAL 是可选的。它指示 istioctlistioctl command 调用重定向到实验等效项 istioctl x command,对于任何具有稳定和实验实现的 command 都是如此。在我们的例子中,我们需要使用 istioctl x proxy-status,即实现代理委托功能的版本。

运行 istioctl proxy-status 命令

现在我们已经完成了 istioctl 的配置,我们可以通过再次运行 proxy-status 命令来试用它

$ istioctl proxy-status --context="${CTX_REMOTE_CLUSTER}"
NAME CDS LDS EDS RDS ISTIOD VERSION helloworld-v1-776f57d5f6-tmpkd.sample SYNCED SYNCED SYNCED SYNCED <external> 1.12.1 istio-ingressgateway-75bfd5668f-lggn4.external-istiod SYNCED SYNCED SYNCED SYNCED <external> 1.12.1 sleep-557747455f-v627d.sample SYNCED SYNCED SYNCED SYNCED <external> 1.12.1

如您所见,这次它正确地显示了网格中运行的所有服务的同步状态。请注意,ISTIOD 列返回通用值 <external>,而不是如果 Pod 在本地运行则会显示的实例名称(例如 istiod-666fb6694d-jklkt)。在这种情况下,网格用户无法获取或不需要此详细信息。它仅在外部集群中对网格操作员可见。

总结

在本文中,我们使用了一个示例代理服务器来配置 istioctl 以与外部控制平面安装一起使用。我们看到了在外部控制平面管理的远程集群上,一些 istioctl CLI 命令如何无法开箱即用地工作。例如 istioctl proxy-status 等命令需要访问管理网格的 istiod 服务实例,而当控制平面运行在网格集群外部时,这些实例不可用。为了解决此问题,istioctl 被配置为委托给与外部控制平面一起运行的代理服务器,该服务器代表它访问 istiod 实例。

分享此帖子