1. 程式人生 > >360搜尋容器雲探索與實踐

360搜尋容器雲探索與實踐

640

隨著容器化程序的加速,容器編排的需求也越來越強烈。而容器編排也經歷了從Kubernetes、Mesos和Swarm三足鼎立到今天的Kubernetes一統江湖的局面。現在越來越多的公司選擇基於Kubernetes來構建企業內部的私有云。本次分享將為大家介紹360搜尋基於Kubernetes打造私有云的整體架構,以及遇到的一些問題和解決方案,希望可以使大家在打造私有云過程中少走一些彎路。
發展歷程

640

發展初衷
  • 快速迭代:提升上線效率,開發自助上線並可以快速回滾。

  • 提高資源利用率:不用型別業務混布,充分利用機器資源。

發展歷史
360搜尋從2016年開始探索基於Kubernetes打造公司私有云平臺,由於當時Kuebrnetes對有狀態服務支援力度有限以及歷史遺留業務容器化難度較大,因此Kubernetes主要負責部署一些無狀態的Web服務。
從2017年開始Kubernetes逐漸在私有云市場佔據了絕對優勢,已然成為容器編排的標準。同時Kubernetes對有狀態的服務支援逐漸完善,我們開始完全基於Kubernetes打造私有云平臺。目前已穩定執行上萬臺容器。
架構設計

640

下圖是雲平臺整體架構。640
網路
Flannel時代
早期使用的是Flannel VXLAN網路模型,存在轉發表項太多的問題。 
640
後面Flannel優化,降低了轉發表項。
640
接入方面使用ExternalIP邊緣節點的模式,由iptables做nat。
640
後面做了dsr優化,回程資料包不走Flannel網絡卡。
640
Calico時代
由於叢集規模擴張,同時公司基礎網路也支援了BGP,所有叢集都遷移到了Calico。 
下圖是Calico的通訊模式,去掉了vxlan造成的overhead。
640
IDC網路模型:
640
關於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平臺

640

Kubernetes雖然很強大,但並不是萬能的,要打造一個簡單易用的雲平臺僅僅有Kubernetes是遠遠不夠的。比如:
  • Kubernetes配置過於複雜,直接讓開發人員配置Kubernetes物件難度太高,而且也比較容易出錯。

  • 由於Kubernetes對許可權管理並不完善,不同人員分配不同的許可權實現比較困難。

  • Kubernetes想要快速回滾到歷史版本比較困難,雖然Deployment保留了歷史的RS物件,但是很難知道每個版本做了什麼更改,想要快速回滾也比較困難。

此時,Wayne作為一個私有云平臺的統一入口應運而生。
Wayne簡介
Wayne是一個通用的、基於Web的Kubernetes多叢集一站式視覺化管理平臺。內建了豐富多樣的功能,滿足企業的通用需求,同時外掛化的方式可以方便整合定製化功能。
Wayne已大規模服務於360搜尋,承載了公司絕大部分業務,穩定管理了上萬個容器。
640
Wayne可以做什麼?
  • 視覺化操作:提供直觀、簡便的方式操作Kubernetes叢集,減小學習成本,快速上線業務。

  • 多樣的編輯模式:支援圖形化編輯,也支援Json、Yaml兩種高階定製化編輯模式。

  • 微核心架構:採用可擴充套件的外掛化方式開發,定製化選擇特性功能,更方便的整合符合企業需求的新功能。

  • 多叢集管理:可以同時管理多個Kubernetes叢集,更方便的管理多個叢集。

  • 豐富的許可權管理:將資源抽象化為部門、專案級別,角色的許可權可以更細化的控制,適用於多部門、多專案的統一集中管理。

  • 多種登入模式:支援企業級LDAP登入、支援OAuth2登入,支援資料庫登入多種模式。

  • 完備的審計:所有操作都會有完整的審計功能,方便追蹤操作歷史。

  • 開放平臺:支援APIKey開放平臺,使用者可自主申請相關APIKey並管理自己的專案。

  • 多層次監控:提供多級別的監控統計資訊,實時關注叢集的執行狀態。

整合WebShell
為了方便使用者線上檢視日誌及進入容器除錯,Wayne集成了WebShell功能,使用者可以檢視Pod列表並且可以進入容器進行除錯。 
640踩過的一些坑

640

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

解決方案:利用Kubernetes的preStop特性為每個Pod設定一個退出時間,讓每個Pod收到退出訊號時時預設等待一段時間再退出。
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包。
  1. 0xffffffff815a6a0b: nf_hook_slow+0xeb/0x110[kernel]

  2. 0xffffffff815b6bee: ip_output+0xce/0xe0[kernel]

  3. 0xffffffff815b2646: ip_forward_finish+0x66/0x80[kernel]

  4. 0xffffffff815b29c7: ip_forward+0x367/0x470[kernel]

  5. 0xffffffff815b062a: ip_rcv_finish+0x8a/0x350[kernel]

  6. 0xffffffff815b0fb6: ip_rcv+0x2b6/0x410[kernel]

  7. 0xffffffff8156f9e2: __netif_receive_skb_core+0x582/0x800[kernel]

  8. 0xffffffff8156fc78: __netif_receive_skb+0x18/0x60[kernel]

  9. 0xffffffff8156fd00: netif_receive_skb_internal+0x40/0xc0[kernel]

  10. 0xffffffff81570e88: napi_gro_receive+0xd8/0x130[kernel]

  11. 0xffffffffa0164df6: ixgbe_clean_rx_irq+0x466/0xa70[ixgbe]

  12. 0xffffffffa01661bb: ixgbe_poll+0x38b/0x840[ixgbe]

  13. 0xffffffff81570510: net_rx_action+0x170/0x380[kernel]

  14. 0xffffffff8108f2cf: __do_softirq+0xef/0x280[kernel]

  15. 0xffffffff8108f498: run_ksoftirqd+0x38/0x50[kernel]

  16. 0xffffffff810b927f: smpboot_thread_fn+0x12f/0x180[kernel]

  17. 0xffffffff810b06ff: kthread+0xcf/0xe0[kernel]

  18. 0xffffffff81696958: ret_from_fork+0x58/0x90[kernel]

640


原因:這個是nf_conntrack設計時對效能的權衡,使用rcu鎖,導致snat可能獲取到重複的local port,然後丟棄報文,上面是核心中一些函式呼叫鏈,具體程式碼不展開了。
640
解決方案:有兩種緩解方式。
  • 增加local ip數量,降低衝突概率

  • snat中local port選擇增加隨機過程,實際上centos核心模組有這個功能,只是centos7上iptables命令沒實現,可以通過修改iptables程式碼,在netlink呼叫時加入NF_NAT_RANGE_PROTO_RANDOM_FULLY


未來發展方向

640

Wayne開源
360搜尋私有云平臺在搭建過程中從很多CNCF專案中收益,本著取之開源,回饋開源的精神,我們決定將Wayne平臺開源,並且會持續開發和長期維護。考慮到目前官方Dashboard並不太好用,而且不支援多叢集和多租戶管理。相信Wayne的開源會給很多人帶來收益。
專案地址:https://github.com/Qihoo360/wayne
服務更多業務遷移
目前私有云平臺服務容器僅有上萬個,還有大量業務沒有遷移上雲,之後會加大力度協助適合的業務遷移到雲平臺。
Q&A

640

Q:BGP的Calico應該是直連容器了吧,那麼snat時syn包被丟棄這個是發生在什麼場景下的呢?A:邊緣節點發生的,使用的是ExternalIP模式,以後會改造成直連容器。
Q:如果新老業務存在相互呼叫,新老業務不在同一個虛擬網路中,之間網路如何打通?rpc呢?A:統一使用LVS VIP呼叫的,叢集內部可以使用SVC域名訪問。
相關連結:
  1. http://dockone.io/article/2578

  2. https://wilhelmguo.tk/blog/post/william/Filebeat優化實踐

Kubernetes線下實戰培訓

640?

Kubernetes應用實戰培訓將於2018年12月21日在北京開課,3天時間帶你係統學習Kubernetes本次培訓包括:容器特性、映象、網路;Docker特性、架構、元件、概念、Runtime;Docker安全;Docker實踐;Kubernetes架構、核心元件、基本功能;Kubernetes設計理念、架構設計、基本功能、常用物件、設計原則;Kubernetes的實踐、執行時、網路、外掛已經落地經驗;微服務架構、DevOps等,點選下方圖片檢視詳情。

640?