360搜尋容器雲探索與實踐
發展歷程發展初衷
快速迭代:提升上線效率,開發自助上線並可以快速回滾。
提高資源利用率:不用型別業務混布,充分利用機器資源。
360搜尋從2016年開始探索基於Kubernetes打造公司私有云平臺,由於當時Kuebrnetes對有狀態服務支援力度有限以及歷史遺留業務容器化難度較大,因此Kubernetes主要負責部署一些無狀態的Web服務。
從2017年開始Kubernetes逐漸在私有云市場佔據了絕對優勢,已然成為容器編排的標準。同時Kubernetes對有狀態的服務支援逐漸完善,我們開始完全基於Kubernetes打造私有云平臺。目前已穩定執行上萬臺容器。
架構設計
網路
Flannel時代
早期使用的是Flannel VXLAN網路模型,存在轉發表項太多的問題。
後面Flannel優化,降低了轉發表項。
接入方面使用ExternalIP邊緣節點的模式,由iptables做nat。
後面做了dsr優化,回程資料包不走Flannel網絡卡。
Calico時代
由於叢集規模擴張,同時公司基礎網路也支援了BGP,所有叢集都遷移到了Calico。
下圖是Calico的通訊模式,去掉了vxlan造成的overhead。
IDC網路模型:
關於Calico的一些改造點:
伺服器相同as號,方便部署
使用原有預設路由,ToR不向下宣告路由
聚合到27位路由,宣告給ToR
通過annotation實現32位路由
網路改造具體詳見團隊同事的文章:《容器網路——從CNI到Calico[1]》。
儲存
由於搜尋有狀態的業務較多,最早有狀態的服務無法遷移,自己維護了一套Gluster叢集,支援了很長一段時間業務儲存。
後來公司儲存團隊提供了Ceph RBD和Cephfs儲存服務,有狀態的業務逐漸遷移到了Ceph。儲存管理自己開發了Robin(即將開源,敬請期待)元件,用於管理RBD的image物件以及Cephfs的路徑。
日誌
目前我們的日誌蒐集方式是業務輸出日誌到std,Docker將std輸出存放到日誌目錄,Kubelet通過軟連的方式連線到/var/log/containers目錄。
早期日誌是Logstash統一到/var/log/containers目錄下蒐集,經過處理髮送到Kafka,之後業務去Kafka消費或者直接進HDFS。但隨著業務日誌量的增加,Logstash耗費資源越來越多,日誌積壓也越來越嚴重,此時Filebeat功能已經逐漸完善,但缺少了一些解析Kubernetes資源的功能,於是我們自己擴充套件了一下Filebeat,自己實現了一個Kubernetes Processor,用於增加Kubernetes的相關標籤,比如Deployment Name、Pod Name等。同時還做了一些效能優化,使得單機處理能力大幅提升。具體可以參見我之前寫過的部落格:《Filebeat優化實踐[2]》。Wayne平臺
Kubernetes配置過於複雜,直接讓開發人員配置Kubernetes物件難度太高,而且也比較容易出錯。
由於Kubernetes對許可權管理並不完善,不同人員分配不同的許可權實現比較困難。
Kubernetes想要快速回滾到歷史版本比較困難,雖然Deployment保留了歷史的RS物件,但是很難知道每個版本做了什麼更改,想要快速回滾也比較困難。
Wayne簡介
Wayne是一個通用的、基於Web的Kubernetes多叢集一站式視覺化管理平臺。內建了豐富多樣的功能,滿足企業的通用需求,同時外掛化的方式可以方便整合定製化功能。
Wayne已大規模服務於360搜尋,承載了公司絕大部分業務,穩定管理了上萬個容器。
Wayne可以做什麼?
視覺化操作:提供直觀、簡便的方式操作Kubernetes叢集,減小學習成本,快速上線業務。
多樣的編輯模式:支援圖形化編輯,也支援Json、Yaml兩種高階定製化編輯模式。
微核心架構:採用可擴充套件的外掛化方式開發,定製化選擇特性功能,更方便的整合符合企業需求的新功能。
多叢集管理:可以同時管理多個Kubernetes叢集,更方便的管理多個叢集。
豐富的許可權管理:將資源抽象化為部門、專案級別,角色的許可權可以更細化的控制,適用於多部門、多專案的統一集中管理。
多種登入模式:支援企業級LDAP登入、支援OAuth2登入,支援資料庫登入多種模式。
完備的審計:所有操作都會有完整的審計功能,方便追蹤操作歷史。
開放平臺:支援APIKey開放平臺,使用者可自主申請相關APIKey並管理自己的專案。
多層次監控:提供多級別的監控統計資訊,實時關注叢集的執行狀態。
為了方便使用者線上檢視日誌及進入容器除錯,Wayne集成了WebShell功能,使用者可以檢視Pod列表並且可以進入容器進行除錯。
踩過的一些坑Pod健康檢查正常,但通過邊緣節點無法訪問到這個節點上的Pod。
原因:由於我們之前試用的是Flannel網路,Flannel掛了無法正常啟動,會導致這臺機器上的服務無法正常訪問。
解決方案:需要監控Falnnel元件的狀態,如果異常立即報警。
Deployment滾動更新過程中流量負載均衡異常,會出現丟失請求的情況。
原因:Pod Terminating過程中,有些機器的Iptable還未重新整理,導致部分流量仍然請求到Terminating的Pod上,導致請求出錯。詳情參見:
https://github.com/kubernetes/kubernetes/issues/47597
https://github.com/kubernetes/kubernetes/issues/43576
Kubernetes1.9之前Apiserver掛掉之後Kubernetes Endpoints不更新,導致部分訪問失敗。
原因:Kubernetes1.9之前只要Apiserver啟動成功Kubernetes Endpoints便不再更新,需手動維護。
解決方案:升級到Kubernetes 1.10版本後設置 –endpoint-reconciler-type = lease Use an endpoint reconciler (master-count, lease, none)Iptables莫名丟棄syn包。
0xffffffff815a6a0b: nf_hook_slow+0xeb/0x110[kernel]
0xffffffff815b6bee: ip_output+0xce/0xe0[kernel]
0xffffffff815b2646: ip_forward_finish+0x66/0x80[kernel]
0xffffffff815b29c7: ip_forward+0x367/0x470[kernel]
0xffffffff815b062a: ip_rcv_finish+0x8a/0x350[kernel]
0xffffffff815b0fb6: ip_rcv+0x2b6/0x410[kernel]
0xffffffff8156f9e2: __netif_receive_skb_core+0x582/0x800[kernel]
0xffffffff8156fc78: __netif_receive_skb+0x18/0x60[kernel]
0xffffffff8156fd00: netif_receive_skb_internal+0x40/0xc0[kernel]
0xffffffff81570e88: napi_gro_receive+0xd8/0x130[kernel]
0xffffffffa0164df6: ixgbe_clean_rx_irq+0x466/0xa70[ixgbe]
0xffffffffa01661bb: ixgbe_poll+0x38b/0x840[ixgbe]
0xffffffff81570510: net_rx_action+0x170/0x380[kernel]
0xffffffff8108f2cf: __do_softirq+0xef/0x280[kernel]
0xffffffff8108f498: run_ksoftirqd+0x38/0x50[kernel]
0xffffffff810b927f: smpboot_thread_fn+0x12f/0x180[kernel]
0xffffffff810b06ff: kthread+0xcf/0xe0[kernel]
0xffffffff81696958: ret_from_fork+0x58/0x90[kernel]
原因:這個是nf_conntrack設計時對效能的權衡,使用rcu鎖,導致snat可能獲取到重複的local port,然後丟棄報文,上面是核心中一些函式呼叫鏈,具體程式碼不展開了。
解決方案:有兩種緩解方式。
增加local ip數量,降低衝突概率
snat中local port選擇增加隨機過程,實際上centos核心模組有這個功能,只是centos7上iptables命令沒實現,可以通過修改iptables程式碼,在netlink呼叫時加入NF_NAT_RANGE_PROTO_RANDOM_FULLY
未來發展方向Wayne開源
360搜尋私有云平臺在搭建過程中從很多CNCF專案中收益,本著取之開源,回饋開源的精神,我們決定將Wayne平臺開源,並且會持續開發和長期維護。考慮到目前官方Dashboard並不太好用,而且不支援多叢集和多租戶管理。相信Wayne的開源會給很多人帶來收益。
專案地址:https://github.com/Qihoo360/wayne
服務更多業務遷移
目前私有云平臺服務容器僅有上萬個,還有大量業務沒有遷移上雲,之後會加大力度協助適合的業務遷移到雲平臺。
Q&AQ:BGP的Calico應該是直連容器了吧,那麼snat時syn包被丟棄這個是發生在什麼場景下的呢?A:邊緣節點發生的,使用的是ExternalIP模式,以後會改造成直連容器。
Q:如果新老業務存在相互呼叫,新老業務不在同一個虛擬網路中,之間網路如何打通?rpc呢?A:統一使用LVS VIP呼叫的,叢集內部可以使用SVC域名訪問。
相關連結:
http://dockone.io/article/2578
https://wilhelmguo.tk/blog/post/william/Filebeat優化實踐