[TOOLS] 13 分鐘閱讀OraCore 編輯部

Flink Operator 1.15 把狀態變訊號

我把 Flink Kubernetes Operator 1.15.0 的 release notes 拆成一份可直接抄的 ops 模板,重點是 Conditions、logging、metrics、savepoint 與刪除流程。

分享 LinkedIn
Flink Operator 1.15 把狀態變訊號

Flink Operator 1.15.0 把狀態、logging、metrics 和 recovery 變成更好用的 ops 訊號。

我跑 Flink on Kubernetes 也一陣子了,最煩的從來不是它會不會掛,而是它明明快掛了,卻還一直裝沒事。deployment 看起來綠的,job 其實還沒 ready;savepoint 明明做過了,cleanup 卻卡在半路;FlinkSessionJob 刪掉了,finalizer 還像在等一個永遠不會回來的人。這種問題很少一次炸開,通常是慢慢堆,堆到你半夜只想把整套 operator 砍掉重來。我看到這種 release notes 時,第一個反應不是興奮,是先看它有沒有真的碰到這些痛點。

這次讓我停下來的來源是 Apache Flink 的 Flink Kubernetes Operator 1.15.0 release announcement。它沒有只講版本號,反而直接點出 Conditions、Logback、內建 metrics reporter、Flink 2.2 相容性,還有一串 savepoint 與 session job 的修正。我也對照了 operator docsGitHub repo,以及 Kubernetes 的 Conditionskubectl wait

別再把 deployment status 當成一坨 JSON

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

The operator now exposes a standard Kubernetes Condition in the status field of FlinkDeployment resources. The Running condition gives tooling a consistent, machine-readable signal of whether the deployment is up and running, directly usable with kubectl wait, GitOps controllers, and any tool that speaks Kubernetes conditions.

翻譯一下就是:它終於開始用 Kubernetes 團隊看得懂的語言講話了。這件事很土,但很重要。自訂 status 欄位給人看可以,給機器看就很容易出事。因為每個 controller 都會長出自己的語意,最後你寫的不是 automation,是一堆猜測字串的 shell 腳本。

Flink Operator 1.15 把狀態變訊號

我以前真的踩過這種坑。兩個 controller 各自說自己 ready,結果一個是「資源已建立」,另一個才是真正可用。你只要維護過這種東西,就會開始討厭 free-form status。Condition 的好處不是漂亮,是一致。它讓 kubectl wait 能直接等,也讓 GitOps controller 不必硬猜。

實操上我會這樣做:把 readiness gate 從字串比對改成 Condition。只要下一個 job 要等 FlinkDeployment 起來,就直接盯 Running。如果你用 Argo CD、Flux,或只是 CI pipeline,也一樣,別再用 grep status 文字。你要的是可預期的 contract,不是祈禱。

  • 機器判斷用 Conditions。
  • 人類排障看 logs。
  • 不要把兩者混在一起,然後叫它 observability。

Logging 不是小事,尤其你公司早就定了 Logback

這版多了 Logback 支援,安裝時可以用新的 logging.framework Helm value 選擇。release announcement 也寫得很直白:chart 會帶 logback-operator.xmllogback-console.xml,而且可以像原本的 Log4j2 properties 一樣改。

這種改動看起來很小,但只要你待過有平台規範的公司,就知道它有多煩。今天是 operator,明天是另一個 Java service,後天又來一個 chart 想自己玩一套 logging。最後你花掉的時間不是在做產品,是在調整基礎設施去配合別人的預設值。這種工最沒成就感,但最常見。

白話講,這版是讓 operator 沒那麼死抱著某一套 logging 方案。你如果整個平台早就標準化在 Logback,就不用為了它特別開例外。這不只是美觀問題,還會影響 appender、routing、以及你們內部既有的 log 收斂方式。

我自己的做法是:先決定 logging framework,再裝 chart。不要先上線再補救。把 logging.framework 寫進 base values,然後清楚標出 operator log 跟 console output 各改哪個檔案。你如果團隊裡還在 Log4j2 跟 Logback 亂切,這版正好拿來收斂。

相關設定可以直接對照 Flink Kubernetes Operator docs,不要只看 release note 摘要就自己猜。

Metrics 有沒有真的能用,差別在有沒有先幫你補齊

1.15.0 直接把 flink-metrics-dropwizard reporter 打包進去,不用你自己手動補 JAR。公告也提到 metrics 文件重寫過,會講清楚 operator scope 的 metric 名稱、kubernetes.operator.metrics.* 前綴,還有 Prometheus 的完整設定方式。更實際的是,現在文件把所有暴露的 metrics 集中列出來了。

Flink Operator 1.15 把狀態變訊號

我很吃這種改法,因為 metrics 文件通常是很多專案默默失敗的地方。你會拿到一串名字,偶爾有範例,然後剩下的就靠自己 reverse engineer。那不叫 observability,那叫尋寶。當文件把 lifecycle、job status、blue-green deployment、state snapshot、autoscaler 這些東西講清楚,團隊省下來的不是一兩分鐘,是一堆猜測跟對帳時間。

翻成白話就是:它想讓監控這件事變得可預期。內建 reporter 少掉一個手動步驟,重新整理過的文件則讓你更容易把 operator metrics 接到 Prometheus 或你們現有的監控系統。你如果曾經跟同事解釋「這個 metric 有,但就是沒出現在 dashboard」,你就知道這有多實際。

實操上,我會先盤點團隊真的會拿來告警的 metrics,再對照文件上的名稱與 prefix,不要繼續沿用那些已經漂掉的舊 dashboard。若你用 Prometheus,就把 operator-scoped 的設定模式直接套進 values。若你以前還要自己補 Dropwizard reporter,先確認這版已經內建,別再做重複包裝。

  • 先列出真的有 alert 的 metrics。
  • 不要假設 chart 已經幫你帶齊 reporter。
  • Dashboard 以文件為準,不要以記憶為準。

Flink 2.2 相容性不是加分題,是升級能不能過的門檻

公告說 Operator 1.15.0 已經完整驗證 Apache Flink 2.2,支援 2.2.x、2.1.x、2.0.x、1.20.x、1.19.x。這個矩陣我最在意,因為版本支援往往就是升級計畫能不能成立的分水嶺。

我看過很多團隊卡在一個很尷尬的位置:應用 runtime 想升,operator 或 chart 卻還沒跟上。結果升級被拆成兩個 project,兩邊都慢。清楚的相容性矩陣至少能把這種鬼打牆減少一半,平台團隊也能直接回答「這版能不能一起上」。

也就是說,它不是幫你省測試,而是幫你少掉一層 compatibility fog。你還是要驗證,但不必從零開始猜。

我會這樣落地:如果你現在在 1.19 或 1.20,先拿這個矩陣對齊下一次升級,再碰 production。若你已經在試 2.2,operator version 也要一起 pin 進同一個 change set,這樣驗證才有意義。最後,把這張矩陣寫進內部平台文件,因為真的沒人會把 release notes 看第二次。

Savepoint 修正的重點不是 bug,而是你能不能信它

公告提到一個 race condition:savepoint 或 last-state upgrade 在 JobManager 起得太慢時,可能把 job state 弄丟。還有一個問題是 savepoint history 會在真正成功 dispose file 之前就從 status 刪掉,結果留下 orphaned files。這種 bug 很像鬧鬼,但其實只是順序搞錯。

白話一點,這版是在 state 操作上更小心。對有 stateful Flink job 的團隊來說,「status 更新了」跟「artifact 真的處理完了」不是同一件事。這中間的空窗,正是資料遺失故事跟檔案垃圾堆出來的地方。

我以前也碰過類似問題,controller 先回成功,底層 storage 卻還沒真的穩住。表面上沒事,等到下一次 maintenance window,舊 artefact 跟半完成狀態才一起冒出來。那時你才會懂,state management 不只是 happy path 正確,而是不能亂報完成。

實操上,我會先檢查所有假設「savepoint 記錄消失=檔案已安全處理」的 automation。如果你有 cleanup job、retention policy、DR script,全部都要確認它們不會太早相信 status。還有,JobManager 起得慢的環境要納進測試矩陣,別只在快機器上驗證。

Session job 刪除不該像綁架案

這版新增一個設定,可以在刪除 FlinkSessionJob 時直接取消正在跑的 session job,而不是卡在 finalizer 裡面等到天荒地老。它也改善了 session cluster 暫時不可達時的刪除流程,修掉會卡住的 finalizer,還補回 session cluster recovery 時重建的 JobManager Deployment ownerReferences。

我很喜歡這段,因為它讀起來像是有人真的盯著刪除流程卡死過。finalizer 很有用,但一旦變成你忘記鬆開的手煞車,就很煩。cluster 掛了或 unreachable 時,刪除流程應該能優雅退場,不該把安全機制做成死鎖。

翻成白話就是:teardown 終於比較像 teardown,不像你在跟資源談判。這件事很現實,因為刪除不是邊角料。你在救壞掉的 deploy、輪替 workload、清 test cluster 時,刪除流程就是日常。

我會這樣做:先決定你的平台到底要不要在刪除時直接 cancel active session jobs,還是要等 cleanup 完成。決定完就寫進 config,不要靠口耳相傳。再來,刪除流程要測兩次,一次在 cluster 正常時,一次在 session cluster 不可達時。你只測 happy path,finalizer 之後一定會回來找你。

可抄的模板

# Flink Kubernetes Operator 1.15.0 rollout template

## 1) 安裝值
logging:
  framework: logback   # 如果你們平台標準是 Log4j2,就改成 log4j2

webhook:
  create: false        # 只有在你們真的把 webhook 另外管時才關掉

# Metrics:保留 operator-scoped prefix
# kubernetes.operator.metrics.*

## 2) Readiness gate
# 用 Kubernetes Conditions,不要解析 status 文字。
# 範例:
# kubectl wait flinkdeployment/my-job --for=condition=Running --timeout=120s

## 3) Monitoring checklist
- 確認 flink-metrics-dropwizard 已包含在 chart
- 把 operator metrics 對應到 Prometheus scrape rules
- 驗證 lifecycle、JobStatus、autoscaler、snapshot metrics
- Dashboard 只用文件上列出的 metric 名稱

## 4) Upgrade compatibility
- 目標 Flink 版本:2.2.x / 2.1.x / 2.0.x / 1.20.x / 1.19.x
- 驗證 operator 版本:1.15.0
- 測 upgrade + rollback,包含 slow JobManager startup

## 5) State and savepoint safety checks
- 驗證 rolling upgrade 時的 savepoint 建立
- 確認 savepoint history 不會早於 artifact disposal 被移除
- 檢查 cleanup 後是否留下 orphaned files
- 稽核所有把 status 當 completion 的 script

## 6) Session job deletion policy
sessionJobDeletion:
  cancelOnDelete: true

## 7) Pre-prod validation steps
- 建立 FlinkDeployment,等待 Running Condition
- 觸發 savepoint,確認 cleanup 順序
- 在 session cluster healthy 時刪除 FlinkSessionJob
- 在 session cluster unreachable 時再刪一次
- 確認 recovery 時 JobManager Deployment 的 ownerReferences 正確

## 8) Notes for operators
- logging framework 在所有環境保持一致
- metrics 文件當成 source of truth
- 不要只靠 finalizer 決定 user-visible deletion timing

這段我會直接丟給平台團隊。它不花俏,但很能防止每季都重演同一批痛點。如果你要看原始 release announcement,就去看官方文章和它底下連的 release notes;我這篇是在幫你翻成能上手的 ops 語言。

原始來源是 Apache Flink 的 1.15.0 release announcement,再加上 官方文件GitHub repoKubernetes Conditionskubectl wait。上面這份模板是我根據官方內容整理出的衍生版本,不是原文照抄。