轉載自筆者的部落格
kubernetes 容器平臺分析
Docker 容器算是目前最火的雲端計算產品了,因為它解決了很多運維和開發上的痛點問題,比如抹平了開發和生產的環境區別,甚至可以做到在生產環境使用 RHEL,而開發使用 Ubuntu,也能平滑部署,但是想要真正的將其投放到生產環境中,實際上還有很多問題亟待解決。而 kubernetes 就是這樣一個 Best Practise
生產環境容器化的需求
脫離了業務環境的架構都是耍流氓,想要將容器真正落地,就需要真正分析其需求,這裡就整理了一下容器化平臺的需求
- 儲存
- 網路
- 容器編排和服務發現
- 負載均衡
- 日誌收集
- 認證授權
- 資源配額
- 分散式服務
可以看到,真正想要部署一個容器平臺實際上需要解決的問題是十分繁多的,Docker 只是解決了最根本的容器分發和執行,但是 kubernetes 卻解決了上面的大部分問題,這裡就一一講述一下。
儲存
容器都是無狀態的,很容易就被殺死,然後重新啟動,因此儲存是重中之重,Docker 自身提供了名為資料卷的儲存方案,但是實際上沒什麼用,因為它支援的最好的就是本地儲存,掛在本地路徑,這樣的強依賴是不可能做到生產環境的分散式服務的,除非每一臺容器節點都持有一份同樣的檔案儲存,但是這樣會大大的消耗儲存空間,而且 Docker 在檔案許可權管理等方面也有很多問題。kubernetes 提出的方案是通過持久化儲存鏈,實際上就是做了個抽象層外掛,各方可以開發自己的外掛用於支援各類儲存工具,目前已經支援 ceph、glusterfs 等主流的分散式檔案系統了,但是這些分散式檔案系統在部署上都很麻煩,甚至有效能的損失,因此使用 nas 作為儲存是最便捷效能最好的。
網路
網路也是容器平臺的重點問題,因為不可能依靠一個容器提供所有的服務,比如一個容器提供了資料庫和 web 服務,而且這樣也不利於解耦,因此容器之間需要通過網路通訊,用過 Docker 自身網路的都知道,Docker 實際上是通過網橋來實現容器之間網路通訊的,預設設定是無法做到跨節點網路,但是可以通過設定 flannel 產生一個 SDN,然後 Docker 使用此網路作為容器的網路,這樣便能做到跨界點通訊,kubernetes 則定義了一套 CNI 標準,只要符合這套標準就能讓 kubernetes 使用 SDN,而目前來說已經有很多軟體定義網路實現了這套協議,比如 flannel、weave,不過目前而言最好用的還是 flannel。
容器編排和服務發現
容器之間存在依賴必然需要編排功能,這也是 kubernetes 重點解決的問題,在容器編排上,kubernetes 有 pod、controller 概念,pod 可以認為是抽象的容器,它有可變的 ip,並且容易被殺死重啟。controller 則是控制 pod 運作的控制器,replication controller、deployment、statefulsets、daemon sets,各有各的用法,比如 deployment 能夠做到水平伸縮。在服務發現上面,kubernetes 有 pod、service 概念,看到這裡相信大家都會有疑問,pod ip 可變總不能每次都要手動改程式或者配置才能訪問吧,實際上 kubernetes 提供的 service 就是用來解決這個問題的,service 是一套虛擬的 ip,service 通過 selector 選擇器挑選出自己身後的 pod,這樣就能做到提供穩固的 ip 介面,其他容器無需關心資料庫的 ip,只需要關心資料庫這個 service 就可以。service 本身的 ip 則不是通過 SDN 產生的,而是通過 iptables 導流,將其匯入到實際的 pod 中,但是這樣子依舊存在一個問題,就是 service 的 ip 同樣需要提前知道,這時候就需要服務發現出馬了,kubernetes 自身提供了一套簡單好用的 DNS 發現機制,kube-dns 將 service 註冊到 dns 中,通過 dns 就能解析得到 service 對應的 ip。
負載均衡
負載均衡實際上就是需要一個前端負載均衡器,將流量統一匯入到不同的容器中,kubernetes 的方案是通過 ingress 定義規則,然後根據規則產生模板配置,就比如 nginx 作為負載均衡器,產生配置後 reload 就能生效,但是目前官方提供的 ingress controller 容器映象存在著一個問題,當 ingress 定義一個 TCP/UDP 四層負載均衡轉發的時候,nginx 容器則必須修改容器部署,因為需要繫結主機埠。因此目前最好的方案還是通過雲伺服器提供商的負載均衡器,比如 GCE、AWS 提供的負載均衡器。
日誌收集
日誌收集實際上不光是收集容器通過標準輸出標準錯誤產生的日誌,還需要收集容器執行時資訊,比如記憶體、cpu 佔用等資訊,這裡不細講了,因為無論是 Docker 還是 kubernetes 都提供了收集方案,不過 kubernetes 更加靈活好用,並且收集的資訊更全面,連容器節點的資訊都能收集
認證授權
kuberentes 有幾大元件 apiserver、controller manager、scheduler、proxy、kubelet,所有的元件都通過 apiserver 通訊和管理,因此需要通過認證和授權來防止非法操作,在這上面 kubernetes 提供了很多方案,比如 basic auth、bearar token、keystone 等,但是真正能投入生產環境使用的,只有 OpenID Connector,不知道這種認證授權的可以自行谷歌,更糟的是,官方甚至沒有提供部署方案,需要自行研發 OpenID Connector 伺服器並且部署下去。CoreOS 倒是開源了一套 dex 系統,但是這玩意實際上也不靠譜,照樣需要研發力量的支援,從這上面就決定了 kubernetes 高門檻的准入標準。
資源配額
kubernetes 資源配額方案非常豐富,無論是儲存配額還是記憶體甚至是 cpu 限額,都可以通過 yaml 檔案定義
分散式服務
分散式服務是大規模執行容器平臺的關鍵,因為容器平臺必然是部署在多節點上的,而 kubernetes 天生就是為分散式部署開發的,apiserver、controller manager、scheduler 實際上就是主節點,而 proxy 和 kubelet 則是每個 slave 節點都需要的。不過目前主流的做法包括 kubeadm 半自動部署方案都是讓主節點通過 kubelet 在容器中執行 apiserver 等東西。
總結
想要在生產環境大規模應用容器化技術,看似開源了產品,但是 kubernetes 本質上是一個半成品,甚至連自動化部署方案都不成熟,並且需要研發力量的支援才能真正執行起來,以筆者個人的意見來說,kubernetes 實際上並非是一個面向企業終端使用者的產品,而是一個面向雲端計算廠商的半成品,它真正的用法應當是雲端計算公司提供自動化節點部署方案,雲端計算平臺提供 SDN 、負載均衡和分散式儲存,甚至可能的話,讓雲端計算廠商提供一套管理控制 web 介面,並且做好認證授權系統,kube-dashboard 這個官方提供的 web ui 介面實際上功能是全了,但是認證授權功能的缺失則導致普通使用者很難部署使用,或者說 kube-dashboard 本來就不是為了普通使用者部署而開發的,而是為了提供給廠商做二次開發準備。kube-dashboard 則是負責定義 web 管理介面應該有哪些功能。