深入解析 Istioctl:如何正確更新 Istio 配置?
安裝 Istio
最近這段時間一直在做服務網格(Istio)相關的工作,背景是我們準備自建 Istio,首先第一件事情就是要安裝。
我這里直接使用官網推薦的 istioctl 進行安裝:
$ cat <<EOF > ./my-config.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-1-18-5
spec:
profile: minimal
revision: istio-1-18-5
meshConfig:
accessLogFile: /dev/stdout
EOF
$ istioctl install -f my-config.yaml -n istio-1-18-5
這里我使用的 profile 是 minimal,它只會安裝核心的控制面,具體差異見下圖:
圖片
輸出以下內容時代表安裝成功:
This will install the Istio 1.18.5 minimal profile with ["Istio core" "Istiod"] components into the cluster. Proceed? (y/N) y
? Istio core installed
? Istiod installed
? Installation complete
之后我們便可以在指定的 namespace 下查詢到控制面的 Pod:
k get pod -n istio-1-18-5
NAME READY STATUS RESTARTS AGE
istiod-istio-1-18-5-6cb9898585-64jtg 1/1 Running 0 22h
然后只需要將需要注入 sidecar 的 namespace 中開啟相關的配置即可,比如我這里將 test 這個 namespace 開啟 sidecar 注入:
apiVersion: v1
kind: Namespace
metadata:
labels:
istio.io/rev: istio-1-18-5
kubernetes.io/metadata.name: test
最主要的就是加上 istio.io/rev: istio-1-18-5 的標簽,標簽的值就是我們在安裝 istio 時指定的值:revision: istio-1-18-5。
此時只要我們在這個 namespace 下部署一個 Pod 就會為這個 Pod 掛載一個 sidecar。
圖片
更新配置的坑
圖片
圖片
默認情況下 Istio 會將應用 Pod 的暴露出來的 metrics 和 sidecar 的指標合并在一起,然后暴露為 :15020/stats/prometheus 這個 endpoint。
而我們自己在 Pod 上定義的注解則是被覆蓋掉了:
圖片
但我們是將應用和 sidecar 的指標分開采集的,所以我們不需要這個自動合并。
圖片
會單獨配置 15090 端口的采集任務
所以我需要將這個功能關閉,安裝文檔的說明只需要在控制面中將 enablePrometheusMerge 修改為 false 即可。
安裝好 Istio 控制面之后會創建一個 IstioOperator 的 CRD 資源:
k get IstioOperator -A
NAMESPACE NAME REVISION STATUS AGE
istio-1-18-5 installed-state-istio-1-18-5 istio-1-18-5 27h
所有控制面的配置都可以在這里面修改,所以我想當然的在這里加入了 enablePrometheusMerge: false 的配置。
圖片
加上之后我重啟了 Pod 發現依然還是 Istio 的注解:
圖片
也就是說這個配置并沒有生效,即便是我把控制面也重啟了也沒有效果。
按照原理來說,這些配置應該是控制面下發給數據面的,大膽猜測下也就是控制面沒有拿到最新的配置。
但是我卸載控制面,再安裝的時候就指定這個配置確是生效的,也就是說配置沒問題,只是我在安裝完成后再修改就沒法同步。
之后我在 stackoverflow 上找到了類似的問題:
圖片
簡單來說安裝好 istio 之后我們也可以繼續使用 istioctl install -f xx.yaml 進行更新。
原理
后來我仔細看了下 istioctl 這個命令的 help 文檔,發現其實已經在描述里寫清楚了:
圖片
甚至還有個別名就叫 apply 這就和 kubectl apply 的命令非常類似了,也更容易理解了,任何的修改只需要 apply 執行一次就可以了。
不過我也在好奇,既然創建的是一個 IstioOperator 的 CRD,理論上是需要一個 Operator 來讀取這里的數據然后再創建一個控制面,同步配置之類的操作。
但當我安裝好 Istio 之后并沒看到有一個 Operator 的 Pod 在運行,所以就比較好奇 install 這個命令是如何實現配置同步的。
經過對 istioctl 的 debug 找到了具體的原因:
圖片
圖片
在 istioctl install -f xx.yaml 執行之后會直接解析 xx.yaml 里的 IstioOperator 生成所有的 manifest 資源,在這個過程中也會生成一個 ConfigMap,所有的配置都是存放在其中的。
所以其實我手動修改這個 ConfigMap 也可以動態更新控制面的配置,之前我只是修改了 CRD,我以為還有一個 Operator 來監聽這里的變化然后同步數據;實際上并不存在這個邏輯,而是直接應用的 manifest。
參考鏈接:
- https://istio.io/v1.18/docs/setup/install/istioctl
- https://istio.io/latest/docs/ops/integrations/prometheus/#option-1-metrics-merging
- https://stackoverflow.com/questions/70076326/how-to-update-istio-configuration-after-installation