場景:一個 RPM,多個 Node
在資源有限的 UAT 或測試環境中,我們不想開 3 台 VM 來跑 Elasticsearch Cluster。 SRE 的標準做法是:「RPM 安裝一次,透過 Systemd 與環境變數控制多個實例 (Instances)。」
我們通常會建立多個設定檔:
/etc/sysconfig/elasticsearch-node01/etc/sysconfig/elasticsearch-node02/etc/sysconfig/elasticsearch-node03
並在裡面定義不同的 ES_PATH_CONF 指向 /etc/elasticsearch/node01 等目錄。
服務啟動很正常,Cluster 也綠燈了。直到有一天,你需要重置 elastic 帳號的密碼。
報錯:CLI 工具的「預設行為」
當你嘗試執行標準指令:
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i
系統會直接報錯,或者更糟——它跑去改了預設 /etc/elasticsearch 裡的 keystore,而不是你 node01 的 keystore。
原因很簡單: Elasticsearch 的 binary 工具(位於 /bin 下的執行檔)並不知道你是透過 Systemd 啟動的,它當然也不會去讀 /etc/sysconfig/ 下的檔案。 它只會傻傻地去讀預設路徑。
解法:讓 Shell 變數「繼承」給子程序
你可能試過 source /etc/sysconfig/elasticsearch-node01,然後發現沒用。 這是因為 source 雖然把變數載入到當前 Shell 了,但預設並沒有 Export 出去。當你執行 elasticsearch-reset-password 時,它是一個新的 Sub-process,讀不到那些變數。
這就是為什麼你需要這行 Magic Command:
# 1. 開啟自動 Export 模式 (關鍵!)
set -a
# 2. 載入該 Node 的專屬變數 (包含 ES_PATH_CONF)
source /etc/sysconfig/elasticsearch-node00
# 3. 關閉自動 Export 模式 (恢復原狀)
set +a
# 4. 執行工具,這時候它就能讀到正確的設定檔路徑了
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i
為什麼是 set -a?
set -a (或 set -o allexport) 是一個 Shell 選項。 當開啟後,所有後續被定義或修改的變數,都會自動被標記為 Export。
這樣一來,source 進來的 ES_PATH_CONF, ES_HOME 等變數,就會自動變成環境變數,完美傳遞給 elasticsearch-reset-password 工具。
結論
在維運 Single Host Multi-Instance 架構時,永遠記得: Systemd 知道的事,CLI 工具通常不知道。
下次要生憑證 (elasticsearch-certutil) 或重置密碼時,別忘了先用 set -a; source ... 把環境掛載上去,才不會改錯設定檔,造成災難。