Nocalhost —— 讓雲原生開發迴歸原始而又簡單

CODING發表於2021-11-29
本文為 CODING Nocalhost 研發負責人王煒在騰訊雲 CIF 工程效能峰會上所做的分享。文末可前往峰會官網,觀看回放並下載 PPT。

大家好,歡迎參加 CIF 大會,今天我跟大家分享的內容是:破解 Kubernetes 應用開發困局。首先做個簡單的自我介紹,我是來自騰訊雲 CODING DevOps 的王煒,目前是 Nocalhost 專案研發負責人,同時也是 CNCF 大使。話不多說,讓我們進入正題。

這次分享主要分為五個方面:

  1. 首先是 K8s 環境下的開發困局;
  2. 以及主流的雲原生開發方式;
  3. 接下來是實現容器應用和熱載入的原理;
  4. 開發和除錯演示,這裡會用一個 Demo 來進行演示;
  5. 最後是開源共建和展望。

首先是第一部分:K8s 環境下的開發困局。提到雲原生開發,我們就不得不先從 Docker 開始說起。當我們的微服務越來越多,執行環境越來越複雜的時候,Docker 映象為我們提供了很好的解決方案。但是當映象和容器越來越多,服務的編排就成為了一個難題。這時候也出現了很多方案,例如 K8s、Docker Swarm 等等。當然 K8s 已經幾乎成為了事實標準,也成為了容器編排的首選方案,然而這個事實標準提供的能力卻是面向運維的。例如,我們可以通過 Liveness 和 Readiness 定義服務的自動恢復機制,通過 Resource 定義資源用量等。這些定義其實對開發人員來說是增加了極大的額外負擔,也造成了開發和除錯兩難的問題。

此外雲原生的技術棧跨度非常大,這就對開發人員提出了更高的要求,這也要求團隊對雲原生架構設計也需要更加符合業務的需要。所以總體而言,對企業來說,招聘和用人的成本也更高了。

下圖是一張 CNCF 雲原生應用開發的全景圖,我們會發現雲原生開發工具這一環節目前仍然是缺失的。雲原生開發這麼難,那麼主流的開發方式又是什麼呢?或者說我們現在是怎麼解決問題的?

經過總結,目前雲原生開發方式主要有以下四種。

  1. 全手工的流程。例如手工構建以及推送映象,修改映象版本,並且等待排程生效。我們把每次檢視編碼效果稱為編碼的反饋迴圈,這種開發方式編碼的反饋迴圈大概需要十分鐘一次,這是非常漫長的過程。
  2. 全自動的流程,也就是把手動的環節變成了自動。這種方式顯然會更快一些,但是它的反饋迴圈也只是縮短為了五分鐘左右一次。
  3. 第三種是對雲原生比較瞭解的團隊經常會使用的方案,也就是使用 Telepresence 這款工具來開發。Telepresence 主要是打通本地和叢集的網路,使開發者能夠在本地進行開發。這種開發方式把編碼的反饋迴圈降低到了 10 秒 1 次,但是因為開發服務以原始碼的方式執行在本地,這種方式有一定的限制,我將在後文深入講解。
  4. 第四種是使用 Nocalhost,直接在容器裡開發。這種方式可以擺脫 Telepresence 在某些場景下的使用限制。

接下來我們詳細聊一聊以 Telepresence 為代表的網路打通方案的使用限制。首先它最大的限制是本地環境和工作負載的執行環境有很大的差異,這就導致業務原始碼很難在本地執行。比如說業務在 K8s Manifest 裡宣告瞭 configmap、secret、volume 的掛載等等,這些很難在本地重建。其次還有環境方面的差異,以及跨平臺,比如說像 Linux 和 Windows 之間的這些平臺差異,以及在部分場景下的網路限制。

說了這麼多,相信大家也能夠理解,在 K8s 環境下開發的最大問題是:每次編碼檢視效果都需要重新構建映象,這就導致了長時間的無效的等待。有沒有不需要重新構建映象的方案呢?答案是肯定的。如果我們能在容器裡實現程式或者是應用的熱載入,每次編碼之後可以實時生效,我們是不是就不需要重新構建映象了呢?

接下來我們繼續探討這種方式的實現原理和方案。首先從 Dockerfile 說起。Dockerfile 裡定義了容器的啟動命令,一般來說,這是業務程式的啟動方式。例如執行一個可執行檔案,如果我們進入容器內執行 PS 命令,會發現這個程式對應在容器裡面,也就是 PID=1 的程式。我們以 Go 應用為例,如果讓這個 PID=1 的程式替換為以原始碼的方式執行,go run main.go 這種方式,我們是不是就可以實現應用熱載入,並且修改程式碼後只需要重新執行這條命令,就可以看到程式碼效果呢?

我們思路沒有錯,但是如果要實現這個方案,還需要三個條件。第一是容器的原始碼從哪裡來?除了指令碼型語言以外,一般的業務容器都沒有原始碼;第二是以 Go 應用為例,編譯的環境從哪裡來?我們知道一般情況下構建的業務容器,因為儲存大小的考慮,會保持最小的可執行環境;第三,如果將 PID=1 的程式替換掉之後,怎麼阻止容器 Crash?

我們分別來看如何解決這些問題。首先第一點原始碼問題,我們可以從本地同步到容器裡來解決;第二是編譯環境,我們可以把執行中的業務映象,替換成具有編譯環境的開發映象,就能夠提供編譯環境;第三,我們可以將 PID=1 的程式替換為一個阻塞的程式,這三個問題就解決了。當我們實現這些方案後,容器其實已經具備了熱載入的基礎,Nocalhost 的原理正是基於上述的方案來實現的。接下來我會用一個 Demo 來演示應用的熱載入和一鍵 Debug 的效果。

Nocalhost 提供了 VSCode 外掛和 JetBrains 的全系列外掛,只要安裝就可以立即使用。接下來我將以 Golang 的為例,演示開發 Demo 專案 Booking for。

【請點選文末閱讀原文,前往 CIF 峰會「開源生態與效能提升」專場 - 《破解 Kubernetes 應用開發困局》,於 08:00 處觀看 Demo 演示】

容器應用的實時熱載入以及一鍵除錯的演示到這裡就結束了,感興趣的同學可以按照 Nocalhost(nocalhost.dev)官網的 Quick Start 指導動手來試一試。

通過演示相信大家已經理解 Nocalhost 帶來的全新雲原生的開發體驗。最後一部分我將與大家分享開源共建和展望。Nocalhost 目前是一個完全開源的專案,程式碼託管在 GitHub 上,已經有 900+ star,同時也是 CNCF Landscape 專案,並且被收錄在雲原生全景圖當中,也歡迎大家關注和貢獻。

關於展望,在這次的分享中,我介紹了 Telepresence 和 Nocalhost 兩種開發方式,它們在解決問題的思路上其實是各有不同的,你可以根據自己的業務情況選擇一種方法來使用。此外 Nocalhost 提供了完整的開發環境和開發過程的管理能力,對於希望統一管理開發環境的團隊,則可以安裝 Nocalhost Server 來集中管理開發叢集、應用、以及開發環境,當然 Server 也是開源並且免費的,我在這裡提供幾張 Server 的截圖,感興趣的同學可以遵循官方文件進行安裝以及使用。

我的分享到這裡就結束了。歡迎大家訪問 Nocalhost(nocalhost.dev)官網,並根據官方文件進行安裝和試用,謝謝大家。

點選此處連結,觀看 CIF 峰會回放

相關文章