我建議你別基于k8s用寫應用 No.178
最近一個月大蕉斷更了,主要就在做一些跟 k8s 相關的事情,就在昨天剛剛交付產(chǎn)品了一個版本,這幾周幾乎把大蕉榨干了。但是大蕉從來不是一個怕事的人,干就完了,一個當十個用,沒什么大問題。
但是經(jīng)過了幾個月基于k8s寫應用,我還是建議你別輕易嘗試用 k8s ,這時候就有人問了,我看你前幾個月還叫我們沒事多學學 k8s 呢,為什么今天就說輕易別基于 k8s 寫應用呢?
且聽我細細說來。
基于 Docker 定義運行環(huán)境實在是太方便了,你可能沒法像以前一樣有一大堆的發(fā)布腳本排查發(fā)布環(huán)境的問題了。
這樣線上環(huán)境太穩(wěn)定,可能會裁剪一部分的開發(fā)運維人員。對于一個 Python 應用來說,以前我們需要安裝 Linux,安裝Python,安裝 pip,安裝相關的依賴庫??墒菍τ?Docker 鏡像定義方式 Dockerfile 來說。
- FROM python:3
- RUN pip install MySQL-python
這兩行,Python 環(huán)境 和 MySQL 依賴就裝好了,已經(jīng)不需要害怕每個人的環(huán)境不一樣,不需要害怕線上環(huán)境被誰搞壞了。運維可能會失業(yè)。
應用升級和回滾真的太方便了,你可能沒法像以前一樣搞一大堆的發(fā)布步驟。
加一個配置文件,換一個依賴包,升級一下linux內(nèi)核版本,還要兼容一下。搞得每次發(fā)布都能由你自己搞。有了 k8s 你已經(jīng)沒這個機會了。這樣你的價值會大大縮水。用 k8s 升級只需要這一行就夠了。
- kubectl set image deployment your-app your-container=image:tag
這樣 k8s 集群會對你的應用進行滾動升級,你不需要害怕升級的時候因為同時重啟的問題導致服務不可用,它都幫你解決了。它升級的做法是先啟動一個容器,確認這個容器正常服務了,再干掉原來的容器。
當然,發(fā)布出問題也是很常見的,以前的回滾要找發(fā)布包,回滾依賴,一堆事情做?,F(xiàn)在有了 k8s ,回滾也變得簡單起來。
- kubectl rollout undo deployment/your-app
回滾的步驟跟升級是一樣的,會先啟動原來鏡像版本的容器,然后再干掉現(xiàn)在版本的容器。這一波操作,會導致你的存在感降低,你無法在發(fā)布的時候進行一頓瘋狂操作了,很可惜,你很可能會被優(yōu)化掉。
服務間暴露和調(diào)用真的太方便了,只能由你解決的調(diào)用 bug 可能一去不復返了。
想想這個場景,一個新人加入團隊,面對代碼里一堆的根據(jù) ip 調(diào)用的邏輯,這個新人能怎么辦呢?必然只能問你啊,這個 ip 是什么,另外一個 ip 又是什么?k8s 自帶名字服務和負載均衡,如果只是在集群內(nèi)調(diào)用,你終于不需要再用 ip + 端口的模式調(diào)用集群內(nèi)的其他服務了,無論是 RPC 還是 HTTP 調(diào)用,都需要ip + 端口吧?很遺憾 k8s 集群默認并不會給你分配任何一個固定 ip 和端口,所有的 ip 和 端口都是動態(tài)分配的,你已經(jīng)不能使用 ip 大法了。那么 k8s 是怎么做到的呢?
首先要明確一個 k8s 的 label 機制。我們俗稱 label 名字叫 打標簽,就是我會給我的應用(Deployment)打上一些標簽,比如打一個標簽名叫 app=my-app ,這個就類似給驢的腳底打上三顆痣。然后我再定義一個 Service ,不管這個應用長啥樣,也不管它在哪里,只需要找標簽為 app=my-app 的應用就完事了,就是說,無論你是剃光頭還是留胡子,我都不管,我就找三顆痣,找到了你就是我的寵物。
很多很多的 magic ,等你你來發(fā)現(xiàn),且聽我細細說,如果你對 k8s 有興趣,留言告訴我,我考慮寫個實戰(zhàn)系列。
如果你是靠各種邪術寫魔法代碼混職場的,我強烈建議你千萬別用 k8s ,你很可能會混不下去。