K8s 平臺能夠如何處理 Pod 預受權問題

前言

TKEx-CSIG 是基於騰訊公有云 TKE 和 EKS 容器服務開發的內部上雲容器服務平臺,爲解決公司內部容器上雲提供雲原平生臺,以兼容雲原生、適配自研業務、開源協同爲最大特色。html

業務容器上雲過程當中,會遇到一些問題,有的須要業務進行容器化改造,有的須要平臺賦能。平臺賦能的部分,有一類問題是 CVM 場景下已經有解決方案的,而因運維方式不一樣在 Kubernetes 平臺上不兼容的,好比 Pod 預受權的問題。咱們但願用雲原生的方式解決這一類問題並提供平臺化的能力,讓每一位用戶都可以在平臺上便捷的部署和管理本身的業務。前端

背景

**新部署業務或者擴容,如何對新設備進行預受權?**相信你們對這個問題並不陌生,基於安全考慮,公司內部每每重要組件、存儲都會對訪問請求進行來源控制,常見的如 CDB 的 IP 訪問受權,OIDB、VASKEY 命令字的模塊受權等。它們或者有本身的受權 WEB 可讓用戶提單申請,或者提供受權 API 可讓運維平臺調用。而路由系統每每在發現註冊時須要準確獲取 IP 設備的地域信息以提供就近訪問的能力,這就須要預註冊 CMDB。後端

在之前使用 CVM/TVM 部署業務時,這個問題能夠較容易的處理,由於咱們是預先拿到了一臺虛擬機,已經分配好了 IP 註冊好了 CMDB,業務要作的就是用這個 IP 去提單受權,部署業務程序,在一切完備後加上路由上線,這個過程是能夠用運維平臺的流水線能力作成自動化。安全

區別於 VM 的拿到可用設備後的步驟型過程化部署,Kubernetes管理的是 Pod 從生產、IP 分配、業務容器啓動、路由維護的整個生命週期,由多個系統 Controller 的 Control Loop 作自動化的管理,基於鏡像的部署提供了業務實例的伸縮一致性保障,Pod 的銷燬重建變成常態,IP 也並不是能固定下來。網絡

業務每每面對多種預受權的須要,受權均值時間從秒級到幾分鐘不等,受權 API 大多並無設計爲承載高 QPS,有必定的複雜性。咱們須要能找到一種方法,在 Pod IP 分配後,業務容器起來前處理受權,阻塞住並保障成功後再進行後續過程,而且控制重建過程對受權API的壓力。架構

通過設計與迭代優化,TKEx-CSIG 平臺提供給了業務易用的產品能力化的受權能力,方便應對這類 Pod 預受權的問題。併發

架構和能力解析

架構

上圖所示是受權系統的架構,核心思路是使用 init Container 先於業務容器執行的特性,實如今業務 Pod 啓動前進行復雜的邏輯預處理。官方對 init Container 的定義以下app

This page provides an overview of init containers: specialized containers that run before app containers in a Pod. Init containers can contain utilities or setup scripts not present in an app image

若是是小規模或單個業務的解決方案,咱們是能夠作的很簡單,在業務 Worklooad yaml 中注入 init Container,調用須要的受權 API 實現便可,而要作成平臺產品化的能力,還須要考慮如下幾點:運維

  • 易用與可維護異步

    須要充分考慮業務使用上的效率和可管理性,將權限做爲一項資源由平臺記錄管理,減少變動對業務的侵入性影響。

  • 限頻與自愈

    權限 API 每每並無對高 QPS 的設計,須要限制調用保護下游。

  • 權限收斂

    安全性,Pod 的銷燬重建可能致使 IP 變化,考慮主動回收已通過期的權限

受權過程產品能力化

業務僅需在平臺 WEB 控制檯上登記須要的權限資源,配置權限組,關聯權限組到 Workload,平臺自動進行 init Container 的配置注入,經過 ENV 傳遞受權配置索引和相關信息,在 Pod 建立時進行受權過程。受權過程涉及的幾個組件功能設計以下:

  • init-action-client

    init Container,僅做一個觸發裝置,僅作一件事,就是發起 HTTP 調用請求,保持不可變,這樣當功能迭代時沒必要修改業務的 yaml,主邏輯後移處理

  • init-action-server

    deployment 部署可橫向擴展,執行預處理邏輯,預註冊 CMDB 等操做,併發起流水線調用,啓動權限的申請過程並輪詢查詢,將過程信息關聯 POD 暴露出來方便業務自查和管理員定位問題。後文提到的退避重試和斷路器邏輯也在這裏實現。

  • PermissionCenter

    平臺管控組件,位於集羣外,負責權限資源的存儲和實際申請。包含一個權限資源中心,存儲業務登記的權限詳情參數方便複用,提供權限 Set 組管理,簡化受權過程當中的參數傳遞;使用生產者/消費者模式,基於 Pipline 實現受權 API 的調用和結果查詢。

斷路器和退避重試機制

可能致使受權過程的異常情況很多,例如權限參數錯誤的配置,受權 API 服務質量降低或不可用,甚至是網絡緣由致使的接口錯誤、超時等。受權 API 每每也並無設計支持高 QPS,咱們採用超時重試,加斷路器和指數退避重試去作一個容錯性。

  • 超時重試

    體如今接口調用和異步任務的超時設置與重試機制,應對瞬時故障,init-action-client 容器非正常退出也會進行重建,每次建立就是新一輪的重試。

  • 斷路器

    使用一個 Configmap 專門記錄集羣裏 Pod 權限申請的失敗次數,3次即斷路不給申請。並提供一個重置能力,暴露給前端,讓用戶和管理員能夠便捷進行重試。

  • 指數退避

    斷路器模式能夠阻斷用戶配置錯誤這類永遠也不可能受權成功的案例,可是沒法應對長時間的瞬時故障。好比裁撤期,受權 API 後端可能會有一段時間的拒絕服務,10分鐘到幾小時,此時會有大量 Pod 受權命中斷路器規則沒法繼續受權,人爲處理時效性差也繁瑣。咱們爲每一個 Pod 添加了一個帶抖動的指數退避器並記錄最近的失敗時間戳,可以在一段時間後容許嘗試一次,若是成功就重置對指定 Pod 的退避,如若不成功更新時間戳從新計時,參數以下,

bk := &PodBreaker{
    NamespacePod:   namespacePod,
    LastRequestFailTime: time.Now(),
    Backoff:        wait.Backoff{
        Duration: 2 * time.Minute,
        Factor:   2.0,
        Jitter:   1.0,
        Steps:    5,
        Cap:      1 * time.Hour,
    },
}

Finalizer 收斂權限

權限的收斂問題每每被忽略,可是也是安全須要考慮的,Pod 的銷燬重建多是常態,IP 指不許也動態變化,長時間可能產生大量垃圾權限,或者已經受權過的 IP 分配到別的業務 Pod,產生安全風險。咱們作了一個 Finalizer 控制器來在 Pod 銷燬前進行權限回收,回收動做是冪等性的,並且是盡力而爲的,由於回收的能力也依賴於權限方是否具有回收能力,咱們對新對接的權限都會考慮這一點,好比騰訊雲 MySQL 的 IP 自動受權。

爲了減小打 Finalizer 的動做,儘量不影響非受權關心的 Pod,咱們只在 Pod 進行了變動事件時識別有受權 init Container 的 Pod,Patch 上 Finalizer 標記,在這些 Pod 縮容銷燬時進行權限的回收並刪除 Finalizer,隨後 GC 會刪除這個 Pod。

kind: Pod
metadata:
  annotations:
~
  creationTimestamp: "2020-11-13T09:16:52Z"
  finalizers:
  - stke.io/podpermission-protection

總結

本文解決的是業務使用容器平臺時,在業務進程啓動前的預處理如自動化受權的一類問題。使用 init Container 實現業務容器啓動前的預處理,並將受權特性產品能力化讓業務能較爲方便的管理和申請權限資源,斷路器和退避重試機制提供容錯性,使用 Finalizer 提供一個回收的能力防止權限擴散。

參考文章

Init Containers [譯] 重試、超時和退避 Using Finalizers

【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公衆號,及時獲取更多幹貨!!

相關文章
相關標籤/搜索