為遠端叢集設定 istioctl

使用代理伺服器來支援具有外部控制平面的網格中的 istioctl 命令。

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

當在遠端叢集上使用 istioctl CLI 時,若該遠端叢集屬於外部控制平面多叢集 Istio 部署,某些命令預設將無法運作。例如,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,依次呼叫每一個,然後在傳回給使用者之前聚合結果。

CLI with local access to istiod pods
具有本機存取 istiod Pod 的 CLI

另一方面,當使用遠端叢集時,這是不可行的,因為 istiod 實例在網格叢集外部執行,網格使用者無法存取。這些實例甚至可能未使用 Kubernetes 叢集上的 Pod 來部署。

幸運的是,istioctl 提供了一個組態選項來解決此問題。您可以設定 istioctl,使其使用一個可以存取 istiod 實例的外部代理服務的位址。與一般的負載平衡服務將傳入的請求委派給其中一個實例不同,此代理服務必須委派給所有 istiod 實例,聚合回應,然後傳回組合的結果。

如果外部代理服務實際上在另一個 Kubernetes 叢集上執行,則代理實作程式碼可以與 istioctl 在主要叢集案例中執行的實作程式碼非常相似,即,找到所有正在執行的 istiod Pod,依次呼叫每一個,然後聚合結果。

CLI without local access to istiod pods
沒有本機存取 istiod Pod 的 CLI

可以在此處找到包含此類 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

代理服務是 gRPC 伺服器,在連接埠 9090 上提供服務。

$ 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 以使用閘道位址作為代理服務。這將是一個「正確」的方法。

但是,由於這只是一個簡單的示範,我們可以使用兩個叢集,因此我們將簡單地將代理服務 `port-forward` 到 `localhost`。

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

我們現在設定 istioctl 以使用 localhost:9090 來存取代理,方法是設定 ISTIOCTL_XDS_ADDRESS 環境變數。

$ 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` 欄傳回一般值 ``,而不是實例名稱 (例如,`istiod-666fb6694d-jklkt`),如果 pod 在本機執行,則會顯示該名稱。在這種情況下,網格使用者無法取得或不需要此詳細資訊。它僅在外部叢集上提供,供網格運算子檢視。

總結

在本文中,我們使用範例代理伺服器來設定 istioctl 以與外部控制平面安裝搭配使用。我們已經看到,某些 istioctl CLI 命令無法在由外部控制平面管理的遠端叢集上直接運作。諸如 istioctl proxy-status 之類的命令需要存取管理網格的 istiod 服務實例,當控制平面在網格叢集外部執行時,這些實例不可用。為了解決此問題,已設定 istioctl 以委派給與外部控制平面一起執行的代理伺服器,該伺服器代表它存取 istiod 實例。

分享這篇文章