為什麼在Kubernetes上開發很糟糕? | Tilt部落格
Kubernetes改變了我執行軟體的方式,但是,當我編寫軟體時,Kuberentes會讓事情變得更難。在這篇文章中,我想敘述我自己在Kubernetes上開發軟體時遇到的所有問題。完全披露:雖然我在Tilt工作是我工作的一部分,我們的目的是解決其中的一些問題,但我的另一部分工作是編寫在Kubernetes上執行的軟體。當有另一種工具比Tilt更好地解決問題時,我會使用它。
無數的開發環境
Minikube,MicroK8s,適用於Mac的Docker,KIND,所有這些都是本地的Kubernetes環境。換句話說:它們是Kubernetes,只是在你的膝上型電腦上。您無需前往網路與大型Kubernetes叢集(可能與生產資料互動)進行通訊,您可以在膝上型電腦上啟動一個小型叢集來檢查問題。
當你想在這些叢集中的多個叢集上執行程式碼/ Kubernetes配置時會出現問題,因為它們各自擁有自己的......怪癖。它們的行為彼此不同,或者與真正的Kubernetes叢集完全相同。我不會在這裡列舉這些差異,但在討論網路和身份驗證等棘手問題時,我會在整篇部落格文章中提到這個問題。
除了在雲中真正的Kubernetes叢集中進行開發之外,沒有任何我知道的工具可以解決這些問題,這是我最近工作的方式。如果您在本地開發群集的市場中,我們最近釋出了一個選擇開發群集的指南,以幫助理解所有選項。
許可權/驗證
如果您正在使用Kubernetes開發軟體,那麼您可能正在使用Kubernetes進行生產。如果您在生產中使用Kubernetes,則可能已鎖定身份驗證設定。例如,常見的設定是隻允許開發人員訪問在一個名稱空間中建立/編輯物件。要做到這一點,你需要設定一些東西:
- 一名角色
- 一個角色繫結
- 一個secret
如果您正在使用“真正的”Kubernetes叢集,這非常有用,但只要您開始使用本地Kuberentes設定,事情就會變得奇怪。還記得那些本地開發環境嗎?事實證明,其中一些處理RBAC的方式與您預期的完全不同。我遇到了一個問題,kubeadm有訪問控制設定允許一切。結果,我有一種虛假的信心會刺激我的設定實際上限制了許可權,而事實上他們沒有起效。當然,kubeadm-dind-cluster已被棄用,但它表明並非所有Kubernetes叢集都是相同的。我還遇到了另一個問題,試圖在Docker for Mac的Kubernetes叢集中重現該問題,其中沒有強制執行RBAC規則。
像NetworkPolicies這樣的測試也很充實。NetworkPolicies在Docker for Mac或microk8s上根本不起作用,並且需要Minikube的特殊標誌。
網路除錯
網路入口是Kubernetes最重要的事情之一。不幸的是,入口由不同的雲提供商以不同的方式實現,因此很難測試。不同的實現還支援不同的擴充套件,通常配置標籤,這些擴充套件在環境之間絕對不可移植。我很幸運能夠訪問一個臨時叢集來測試入口更改,但即使這樣,更改也可能需要30分鐘才能生效,並且可能導致不可思議的錯誤訊息。如果你在當地的Kubernetes環境中,你幾乎沒有運氣。
網路是我最不喜歡在Kubernetes工作的東西,而且我認為這個領域仍然需要最多的愛。但是,有一些工具可以提供幫助。
至少可以看到您的服務如何連線的一個很好的工具是Octant。Octant為您提供所有pod的視覺概覽以及它們所屬的服務。至少在Octant中,我可以輕鬆地從一段程式碼轉到連線到網際網路的方式。
對於複雜的Kubernetes物件,如在不同雲平臺上表現不同的入口,Kubespy是一個非常寶貴的工具。Kubespy向您展示建立物件時引擎蓋下發生的事情。例如,如果我建立一個服務,它會顯示哪些IP地址Kubespy將為其提供流量的Pod:
> kubespy trace svc test-frontend <p class="indent">[ADDED v1/Service] default/test-frontend <p class="indent">[ADDED v1/Endpoints] default/test-frontend Directs traffic to the following live Pods: - [Ready] test-frontend-f6d6ff44-b7jzd @ 192.168.1.1 |
登入到容器並做事情
每個開發人員都會遇到的一個常見問題是SSH。也許在將來,SSH將像軟盤圖示一樣不合時宜,但是現在,我想登入到一個容器,四處尋找,看看狀態是什麼,並且可能執行一些命令,如strace或tcpdump。
Kubernetes並不容易。工作流程如下所示: kubectl get pods 查詢我的pod名稱 kubectl exec -it $podname -- /bin/bash
事情變得很煩人。
> kubectl exec -it dan-test-75d7b88d8f-4p45c -- /bin/bash OCI runtime exec failed: exec failed: container_linux.go:345: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown command terminated with exit code 126 |
這到底是什麼?我知道在製作中我希望我的容器映象很小(考慮映象推送效能和安全性),但這些資訊有點多。
我最喜歡的解決這個問題的工具之一是Kubebox。Kubebox可讓您輕鬆檢視所有pod,只需按“r”即可將遠端shell新增到其中一個。
無論如何,大映象在本地叢集上應該不是問題,對嗎?
推/拉映象
在你的膝上型電腦上推映象應該超級快,因為沒有必要去網路。不幸的是,無數本地Kubernetes設定再一次暴露了醜陋。
讓我們來談談快樂的道路:Minikube和Docker for Mac。這兩個設定都執行一個Docker守護程式,您可以從本地膝上型電腦和Kubernetes叢集內部進行通訊。這意味著你需要做的就是將映象放入Kubernetes中來構建它; 您的pod可以直接從本地登錄檔“拉”它,而不需要處理透過網路移動資料。
MicroK8s預設情況下不附帶群集內登錄檔,但可以使用標誌輕鬆啟用。
相比之下,KIND是另一頭野獸。它有一個特殊的命令,用於將映象載入到叢集中kind load。不幸的是,這是無法忍受的緩慢。
$ time kind load docker-image golang:1.12 real 0m39.225s user 0m0.438s sys 0m2.159s |
這是因為KIND會複製映象的每一層,並且只進行非常原始的內容協商。這意味著如果您只更改1.5 GB映象的最後15 KB圖層中的一個檔案,KIND可以複製整個1.5 GB映象。
幸運的是,那些致力於KIND專案的人們最近對映象載入做了很多改進。我們還發布了在KIND中執行登錄檔的概念證明,這有助於進一步提高速度。
如果我要使用本地開發環境,我傾向於使用Docker for Mac或MicroK8s,儘管如前所述,這些天我更喜歡在真正的雲Kubernetes叢集中進行開發。這個領域也出現了很好的工具。Garden在遠端登錄檔中快取映象層,減少每個開發人員需要重建的內容。使用live_update可以幫助我完全不需要推送和拉取映象,這就是我用來解決這個問題的方法。
安裝/檔案同步
即使您在推送映象時可以避免上網,只需構建映象也會很長時間。特別是如果您不使用多階段構建,特別是如果您使用具有額外依賴性的特殊開發映象。與熱重新載入本地JavaScript設定相比,即使是最快的映象構建也可能太慢。
我想要做的只是將檔案同步到我的pod。手工完成這個過程相對簡單,但很乏味:
kubectl cp <file-spec-src> <file-spec-dest> |
此外,如果您的容器因任何原因重新啟動,例如,如果您的程式崩潰或pod被驅逐,您將丟失所有更改。
有像ksync,skaffold和Tilt這樣的工具可以幫助解決這個問題,儘管他們需要投入一些資金來設定。
日誌/觀測/活動
在開發中,我想tail相關的日誌,這樣我就可以看到我在做什麼。Kubernetes並不那麼容易。每個Kubernetes pod都有自己的日誌,我必須單獨查詢,每個日誌都有很多容器。真地,很容易看到只有一個pod(kubectl logs podname)的日誌。但是,要檢視聚合檢視,您需要了解很多關於pod的組織方式,比如哪些標籤適用於應用程式的哪些部分,以便您可以執行命令kubectl logs -l app=myapp。
然後是Kubernetes事件,您可以透過完全獨立的命令觀察。這很糟糕,因為它在事件日誌中我會找到重要的開發資訊,比如我的pod無法安排或者我推出的新映象無法執行。
我可以使用一組很好的可觀察性工具來幫助生成這些工具,但我不想在本地執行它們。有時我買不起資源 - 我的膝上型電腦相當受限制。雖然這些工具在各自的利基中都非常出色,但我寧願使用一種工具來輕鬆完成常見任務。換句話說,我應該始終能夠在一個視窗中開始除錯。有些問題可能是如此獨特或特殊,以至於我最終會使用其他工具來解決這些問題,但我不能透過十二個視窗來檢查一個問題。
我在另一篇部落格文章中探討了這個問題,我認為Tilt解決了這個問題,特別是現在它包括Kubernetes事件和pod日誌。前面提到的Kubebox和花園是另外兩個很棒的選擇。
結論
雖然在Kubernetes上的開發仍然很糟糕,但在過去的一年裡我們已經走了很長的路。其最大漏洞是網路。如果我們想讓開發人員能夠建立端到端的完整堆疊微服務架構,我們需要提供一些方法來解決網路問題。在此之前,最後一次推向生產將始終揭示隱藏的網路問題。
相關文章
- 為什麼程式設計師應該寫部落格?用什麼部落格系統?程式設計師
- 為什麼要搭建自己的部落格
- 為什麼要寫技術部落格?
- 基於.NetCore開發部落格專案 StarBlog - (1) 為什麼需要自己寫一個部落格?NetCore
- 為什麼軟體開發方法論讓你覺得糟糕
- 在github上寫部落格Github
- 1.多使用者部落格網站開發實戰之開篇(程式設計師為什麼寫部落格)網站程式設計師
- 幽默:K8S沒有那麼難,部署在Kubernetes上個人部落格K8S
- 程式設計師為什麼值得寫部落格程式設計師
- 技術人員為什麼要寫部落格?
- 做為技術人員為什麼要寫部落格?
- 做為技術人員為什麼要寫部落格
- 淺析--為什麼軟體開發方法論讓你覺得糟糕?
- 為什麼明明是發自己的部落格,阿里卻刪除我發部的開源作品?阿里
- 我如何將部落格遷移到 Kubernetes(上)
- 為什麼這麼多人覺得前端開發很難做下去?前端
- 我為什麼鼓勵工程師寫部落格工程師
- 為什麼有些技術人員不寫部落格?
- 軟體工程--為什麼軟體開發方法論讓你覺得糟糕軟體工程
- 為什麼糟糕的開發者更有成效
- 為什麼糟糕的軟體成功了
- 個人部落格如何搭建 用什麼系統好?學網站建設從開發一個部落格開始網站
- 為什麼開發一款APP價格那麼高APP
- 程式設計師 為什麼要堅持寫部落格程式設計師
- 阮一峰:為什麼寫部落格?(圖靈訪談)圖靈
- Googler為什麼很幸福?Go
- 個人部落格開發系列:前臺部落格頁面開發部署完成
- [樂譯 第11期] 為什麼軟體開發方法論讓你覺得糟糕?
- 為什麼在大公司工作,總是很無聊?
- 在 Linux 上搭建Jekyll靜態部落格Linux
- 使用Hexo在Github上搭建自己的部落格HexoGithub
- 最近的部落格釋出位置在GitHub上Github
- Python為什麼發展這麼快速?原因很簡單!Python
- React個人部落格開發React
- 為什麼有些公司的IT很亂?
- 為什麼每個專業人士都需要考慮寫部落格?
- 什麼是前端開發?為什麼要學前端開發?前端
- 讀 why Software Development Methodologies Suck?為什麼軟體開發方法論讓你覺得糟糕?dev