Kubernetes有一個以前系統用來作不少工做的REST-ish HTTP API。這個API是開放的,並且文檔十分齊全,很容易整合,能夠從代碼方面管理集羣。然而這個API還有一個不直接映射到HTTP的概念:WATCH。resource有任何的修改,它就會通知API用戶。然而這個功能的調用,仍是有必定工做量的,咱們來探個究竟。python
從Python使用Kubernetes API,若是使用Request庫的話,就十分輕鬆。API運行得十分好,老是使用而且返回JSON消息。可是發行watch請求就變得複雜多了。發一個watch請求理論上有兩種方法:一個是用流傳輸結果的普通HTTP請求,同時使用分塊編碼;另外一種方法是使用websockets。不幸的是,當測試Kubernetes1.1 master的時候,並無正確地使用websocket協議,因此使用流傳輸結果纔是正確的方法。web
當使用分塊編碼流傳輸的時候,Kubernetes master會經過發送分塊的尺寸開始傳輸分塊。可是它不會發送一整個分塊,它只會發送一行文本,再被一行新的文本終止。這行文本是JSON編碼對象,裏面還有event以及修改過的resource項目。因此協議是基於行的,而分塊編碼只是當結果可得的時候一個用來分流這些結果的方法。從表面上看用請求來作這個彷佛不那麼難:編程
然而iter_lines方法並無按照你想要的方向來作,它保有一個外部緩衝,這個緩衝意味着你永遠都看不到最後一個event由於你還在等着填滿那個緩衝。服務器
這個問題的提出意味着經過實施你本身的iter_lines()
函數來使用原套socket,從迴應socket到讀取socket。很不幸,那個簡單的方法犯了一些錯誤。首先,它沒有正確地處理分塊編碼,描述分塊大小的八位元數會出如今輸出過程。可是更加劇要的是,另外一個緩衝層次正在繼續,一個你不能進行應急操做的緩衝層次。額外的緩衝是由於請求使用的是原始套接字的生成文件方法從中讀取數據。這對於Requests來講就講得通了,Python標準庫和OS都擅長經過緩衝加速。然而這並不意味着在Requests解析了響應的標頭後,緩衝就已經不知道使用了響應自己多大的字節,並且這些字節沒法檢索。因此使用Requests來使用watch API基本上不太可能。websocket
因此如何從Python使用watch API?經過本身發出請求和處理響應。這個作起來其實很簡單,socket編程其實沒那麼嚇人。首先,你須要鏈接socket到服務器,而後發送HTTP request。HTTP很是簡單,你只須要在socket上發送一些標頭便可:網絡
注意,Host
標頭被Kubernetes master要求用來接受request。socket
解析HTTP響應稍微有點複雜。然而http-parser庫實施HTTP解析方面的東西的時候,沒有涉及到sockets或者任何相似於網絡的東西。因此咱們能夠輕鬆地讀取和解析響應:函數
如今咱們來響應已經被解析的標頭。極可能,一些本體數據已經接收到了,這很棒,這些本體數據在解析器中仍處於緩衝好的的狀態,直到咱們檢索它。可是首先讓咱們來保持讀取數據,直到沒有剩下的爲止(不要在生產過程當中這麼作,對你的存儲系統很差)。post
上圖展現瞭如何使用select
在數據可得的時候只讀數據,而不是先阻斷,而後使數據再次可讀。固然,一旦使用了全部的數據,Kubernetes master 可能就會發送下一版本更新到PodList,可是讓咱們如今先來讀一下接收到的events:測試
就是它!若是數據接收截至在換行符,而後lines.split()
調用會回到一個空的字符串(b'')
做爲最後一個項目。若是數據沒有在一個新的換行符那裏結束,那麼一個未完成的event會被接收,這樣當咱們得到其它數據的時候咱們就須要保存下來。
因此爲了正確地使用Kubernetes watch API調用的響應,你須要建立你本身的socket鏈接,而且解析HTTP響應。很幸運,這並無想象得那麼難。你並不須要所有本身來寫!咱們已經都實施過了,並且更多信息在咱們的kube項目裏,這也給咱們提供了一個至關好的被包裝成一個迭代器API的安裝啓用。Kube自己仍然須要更多的新功能,可是watch功能的實現已經十分有用了。
(若是須要轉載,請聯繫咱們哦,尊重知識產權人人有責:)