Kubernetes 中有很多概念,這些概念在 RESTful API 中表現爲對象 (「resource」 或 「kinds」)。html
其中一個比較重要的概念是 namespace (命名空間)。 Kubernetes中,命名空間將單個集羣分拆成多個虛擬的集羣。本文的主題是命名空間的應用場景。安全
首先咱們舉個生活中的例子,作一個類比:命名空間就像家族的姓氏。好比一個家族的姓是」張」,有個家族成員叫」張三」,那麼在這個家族中,你們說 「三」,咱們能夠惟一地肯定是 「張三」。可是在家族外,若是要惟一肯定這我的,則必須帶上姓: 「張三」,或者更準確一點 「趙家莊的張三」。網絡
命名空間定義了一個邏輯分區,實現了必定程度上的隔離,它使得單個集羣能夠由多個用戶(組) 使用,或者擁有多個應用的單個用戶使用,而不用關心不一樣的應用會互相影響。架構
每一個用戶、用戶組或應用都可以與其它用戶和操做隔離開,彷彿這個集羣只有這一個用戶同樣。此外,經過Resource Quota,咱們可以把Kubernetes集羣資源的一個子集分配給某個特定的命名空間。負載均衡
對於大多數應用場景,命名空間都很是受用。在這篇文章中,咱們將涵蓋谷歌雲平臺上Kubernetes用戶對命名空間的常見使用方式,具體體如今下面幾個方面:框架
命名空間在企業中的角色和責任微服務
分區:dev vs. test vs.prod佈局
非多租戶場景下的客戶分區測試
何時不使用命名空間網站
一個典型的企業包含多個業務/技術實體,這些實體的操做相互獨立,但又都在企業的管控之下。只要Kubernetes 相關的角色和職責被定義好,在這樣一個環境下管理 Kubernetes 集羣並不難。
下面是一些關於角色和職責的建議,有了他們,在大型組織中管理 Kubernetes集羣將會更簡單:
設計師/架構師角色 :該角色定義了總體的命名空間策略,須要考慮到產品/定位/團隊/成本中心這些因素,並肯定如何把這些因素映射到 Kubernetes 命名空間。設計這樣一個角色能防止命名空間膨脹和碎片化。
管理員角色 :該角色管理全部kubernetes集羣的訪問:建立/刪除集羣、添加/遷移節點來伸縮集羣。除此以外,該角色還負責集羣的更新、安全和維護,以及組織中不一樣實體間的配額實現。kubernetes管理員負責實施由設計師/架構師定義的命名空間策略。
這兩個角色以及實際開發者使用集羣的過程當中也會收到企業安全和網絡團隊對問題的支持和反饋。常見的問題有:安全隔離要求,命名空間如何適應這種模型,或協助網絡子網和負載均衡器設置。
使用命名空間進行隔離,可是沒有中心化的控制 :初期沒有圍繞kubernetes管理創建一套中心化的控制結構,有很大的風險創建起用「蘑菇農場」的拓撲結構:即沒有統一的尺寸/形狀/結構。 結果就是難以管理、高風險和因爲資源利用不足致使的高成本。
舊的 IT 控制妨礙了正常使用和創新 :一個常見的趨勢是嘗試將現有的內部控制機制和流程應用到新的、動態的框架。這樣會下降新框架的敏捷性,也抹殺了快速動態部署的優勢。
大雜燴集羣 :延遲爲命名空間建立管理機制和結構,最終會致使一個功能雜亂的大雜燴集羣,到時候再根據功能分拆成較小的使用組會很是困難。
開發團隊一般把開發流水線劃分爲離散的單元。這些單元會採用不一樣的形式或者被打上不一樣的標籤,可是最終會被劃分到幾類:開發環境、測試 (QA)環境、staging環境、生產環境。最終產生的佈局很是適合Kubernetes命名空間。流水線中的每一個環境或階段都有惟一的命名空間。
以上工做以及每一個命名空間在開發週期中能夠模板化並鏡像到下一個後續的環境,例如開發->測試->產品。事實上每一個命名空間邏輯離散容許開發團隊在一個隔離的「 development 」命名空間內工做。
DevOps(谷歌最接近的角色,被稱爲網站可靠性工程,簡稱「SRE」)將負責在流水線各階段遷移代碼並確保爲每一個團隊分配適當的環境。從根本上來講,DevOps僅負責最終的生產環境,這些環境運行着交付給終端用戶的解決方案。
將命名空間應用到開發週期的主要優點是:軟件組件(微服務/endpoints)很容易維護,在不一樣的環境之間不會產生命名衝突。這一點是藉助於命名空間的隔離性實現的,好比 dev 環境下的 serviceX 對於其它命名空間而言是惟一的;可是,若是有必要,可使用全名 service.development.mycluster.com 惟一地表示它。
在開發流水線中濫用命名空間,會產生一些沒必要要的環境。所以,若是你不作 staging 部署,就不要建立一個 」staging」 命名空間。
擁擠的命名空間。好比,把全部的開發項目都放到 「devepment」 的命名空間下。因爲命名空間相似於分區,你也能夠對項目進行分區。因爲命名空間是扁平的(不分層),你可能會但願這樣使用:projectA-dev,projectA-prod 做爲projectA 的命名空間。
舉個例子,若是你是一家諮詢公司,但願爲每一個客戶管理單獨的應用程序,那麼你可使用命名空間進行分區。你能夠爲每一個客戶、客戶項目或客戶業務單元建立一個單獨的命名空間,既能區分這些客戶,同時不須要擔憂不一樣項目使用相同的資源名稱。
有一點須要注意:目前 Kubernetes 尚未提供命名空間級別的訪問權限控制,對於你使用這種方式開發的應用,咱們建議不要暴露給外界。
多租戶應用不須要使用 Kubernetes 的命名空間,由於應用自己已經執行了分區。若是使用的話,反而增長了額外的複雜度。
客戶到命名空間的映射方式不統一。例如,你贏得一個跨國企業客戶,可能最初考慮給它一個命名空間,而沒有考慮到它們內部須要進一步分區,好比分紅 BigCorp Accounting 和 BigCorp Engineering兩個區。這種狀況下,客戶的每個部門都要保證有一個命名空間。
在某些狀況下,Kubernetes 命名空間提供的隔離不是你想要的,或者沒法提供你想要的隔離。緣由多是地理,計費或安全因素。命名空間造成的邏輯分區有不少優點,可是目前尚未能力保證利用分區的優點。Kubernetes集羣中的任何用戶或資源,在不考慮命名空間時,能夠訪問任意的集羣資源。因此,若是你須要保護或隔離資源,終極的命名空間是一個單獨的Kubernetes集羣,你能夠按期對它作安全和ACL控制。
若是你但願使用跨地理的部署,也不要考慮命名空間。舉個例子,你但願部署在接近美國、歐洲和亞洲客戶的地理位置,那麼最好在每一個區部署一個kubernetes集羣。
若是客戶要求細粒度的計費帳單,那麼建議將帳單留給你基礎設置提供商。好比,在Google雲計算平臺,你可使用一個單獨的GCP項目或計費帳戶,針對特定客戶的項目建立一個kubernetes集羣。
若是你要求客戶的保密和合規對其餘客戶是徹底不透明的,每一個客戶一個集羣的模式能夠提供這種級別的隔離。並且,你須要將資源分區委託給底層的基礎設置供應商。
目前咱們正在致力於兩個方面的開發:
1.爲命名空間提供ACL,以加強安全性;
2, 提供集羣聯邦。
這兩個特性背後的機制都會說明爲何要分離Kubernetes集羣。
一個很容易理解的反模式是使用命名空間進行版本控制。你不該該使用命名空間區分集羣資源的版本。容器和registry已經提供了版本管理的功能,在Kubernetes中部署資源時也支持版本管理。
充分利用kubernetes的容器模型,能夠實現多個版本共存,藉助於 deployment 也能夠實現版本的自動更新。另外,基於版本的命名空間會致使命名空間的不斷膨脹,增長了管理上的困難。
你可能但願建立層級的命名空間,然而事實上並不能。命名空間不能嵌套。好比說,你不能建立一個my-team.my-org 的命名空間,儘管你在 my-org 下可能有 my-team。
命名空間易於建立和使用,可是它也容易把代碼部署到錯誤的命名空間下。好的DevOps應該把這類工做文檔化和自動化,以充分減小錯誤的可能。另外,還要避免爲kubectl 上下文設置錯誤的命名空間。
如前所述,Kubernetes 目前不提供命名空間級別的安全機制。只有在信任域內(例如內部使用)你纔可使用命名空間;若是你須要保證一個集羣用戶或資源沒有權限訪問其餘命名空間的資源,不要使用命名空間。對於這部分加強安全特性,涉及到 SIG-auth, 在Kubernetes特殊興趣小組 Authentication & Authorization 分組已經討論過。