Docker 的第二次死亡

2020-12-10 騰訊網

作者 | Tina、田曉旭

採訪嘉賓 | 楊明越、王新勇、曉川

左耳朵耗子說過一段話,讓人深以為然:

我清楚地看到了 Go 和 Docker 這兩種技術的生態圈發展過程。讓我收穫最大的並不是這些技術本身,而是技術的變遷和行業的發展。從中,我看到了非常具體的各種思潮和思路,這些更有價值...... 這些關鍵新技術,可以讓你拿到技術的先機。這些對一個需要技術領導力的個人或公司來說都是非常重要的。

12 月 2 日,Kubernetes 發布了一則消息,表示將在即將發布的 Kubernetes 1.20 版本中棄用 Docker 支持。CNCF 大使 Ian Coldwater 特地發了一條 Twitter 消息,呼籲大家對此進行關注:「 Kubernetes 中已棄用了 Docker 支持。你需要注意這一點並做一些計劃。這將破壞你的集群。」

這些舉動,在技術圈子裡引起的震蕩就好比又宣布了一次 Docker 的死亡(第一次是「Swarm 的沒落」)。雖然這只是一盤大棋中最無關緊要的最後一小步,目的就是讓 Kubernetes「不再依賴」Docker。

容器技術圈子在短短幾年發生了一些重大的變數。

Docker 以提供鏡像打包的創新技術實現了「一次構建、處處運行」的軟體交付方式,開啟了一個全新的容器時代。面對平臺化的競爭,Docker 推出了調度引擎 Swarm,但 Swarm 從未真正流行起來,因為整個行業更傾向於採用 Kubernetes,這是 Docker 第一次死亡:它失去了平臺之戰。2016 年 9 月,Google 和 RedHat 聯合宣布了「fork Docker」,也就是後來的 CRI-O 項目,這就是這次棄用事件的起始,同時也宣告了競爭的結束。

誰會受到影響?

Docker 源於 Linux Container,可以將一臺機器的資源分成 N 份容器,做到資源的隔離,並將可運行的程序定義為標準的 docker image。相對來說,Kubernetes 屬於 Docker 容器引擎的上層:編排調度層,它可以把不同機器的每份容器進行編排、調度,組成分布式系統。

近幾年,Kubernetes 已經成為自有機房、雲上廣泛使用的容器編排方案,最廣泛的使用方式是 Kubernetes+Docker。運維工程師一方面用 Kubernetes 中的 kubctl 命令、k8s API 來操作集群,一方面在單機用 docker 命令來管理鏡像、運行鏡像。技術專家楊明越給 InfoQ 總結道:「單獨用 Kubernetes,下層不是 Docker 的情況,並不算很多」。

「棄用 Docker」,具體來說,是 Kubernetes 將在 1.20 版本中棄用 dockershim。它是一個橋接服務,幫助 Kubernetes 與 Docker 通信時屏蔽下層容器運行時之間的差異。

這種橋接服務帶來便利性的同時也帶來了複雜性。留著時間的流逝,這種複雜性不斷「膨脹」,維護 Dockershim 已成為運維 / 開發人員的沉重負擔。在下一版中,去掉 Dockershim 將是一個極大的簡化,並且恢復了調用的一致性。

儘管 Kubernetes 在發布消息的時候,表示開發人員對這種轉變「不必恐慌」,「Docker 還沒有死,它仍然有其用途」。但顯然 Kubernetes 的解釋並不能令人滿意:「是否有人質疑為什麼不選擇一種更順暢的遷移方式,而不是像谷歌那樣抨擊 Docker,勸人們趕緊遷移,越快越好」。也有更多開發人員表達了他們並不明白接下來他們需要做些什麼。

在生產環境中,企業大量的使用的是經典 Kubernetes+ Docker 方案,同時在一些公司的場景中也有單獨使用 Docker 的情況。

如果用戶的業務部署比較簡單,規模也較小,僅僅是為了使用容器做應用交付的便利,也沒有其他的功能需求的話,僅僅通過 docker run/docker-compose 這種方式也能管得好的話,實際上是沒必要非得引入 Kubernetes 這樣非常重的編排組件的。反而直接僅僅使用 Docker 會更輕量,也更好運維。比如 toB 的軟體交付的情況,如果要部署的軟體的部署架構比較簡單的話,僅僅涉及少量幾臺機器,服務進程也不多的情況下,也有不少是直接使用 Docker,而不引入 Kubernetes 的,比較輕量、簡單。

還有一個就是,使用 kubernetes 做編排引擎的情況下,實際開發者在日常的開發中,也會比較多地使用 Docker。

「對於一般的應用開發者來說,他們一般不會直接去面對 Kubernetes 的,因此,對於他們來說,可能壓根就是無感知的,應用開發者甚至都不用知道他們的業務是用容器運行的。對於整個基於 Kubernetes 生態的各個解決方案提供商來說,由於當前基於 Kubernetes 的編排是事實標準,容器的鏡像格式又是都遵守 OCI 的,因此可以說所有的之前的交付的構件,無論容器運行時怎樣變化,實際上都不會有啥影響。」網易輕舟容器平臺 NCS 負責人王新勇在接受 InfoQ 的採訪中表示,「但對於容器平臺提供商來說,可能需要一些適配和準備動作。」

根據 Sysdig 發布的 2019 年容器使用報告顯示,Docker 佔據了容器平臺市場的大部分份額,佔比為 79%,而排在第二位的是 containerd,佔比為 18%,排在第三位的 CRI-O 項目,佔比為 4%。

CRI-O 是 Kubernetes 的輕量級運行時,希望繞過現有 Docker 容器的大部分機制直接操作 Linux 容器,由 RedHat 主導,並且也是目前 Kubernetes 推崇的方式。

「網易已經有比較好的準備,實際上 Kubernetes 棄用 Docker 從很早就開始討論了。很早我們就開始關注和使用 Containerd 作為我們的容器運行時的一個選項了。後續我們會提供相關的運行時多個選項 ,並逐步過渡到使用 Containerd 作為運行時。」王新勇表示。

「我們還可以通過將 Dockershim 從 Kubernetes 中摳出來,獨立運行,作為 Kubernetes 的 cri 到 Docker API 的適配器,實現 Kubernetes 繼續支持 Docker,從而保持之前的使用習慣。」

楊明越也認為由於老技術實現的慣性,在生產環境大量使用的經典 Kubernetes+ Docker 方案依然運行,且運維已經成熟,不會很快升級。對於開發人員、企業,對於 K8S API 的使用頻率、變數,遠遠大於 Docker API,至於 Kubernetes 和 Docker 的橋接,更不用關心。因此,即便「徹底棄用 Docker」,對開發者與企業的影響也非常有限。

Docker 會消亡嗎?

Docker 和 Kubernetes 的往事已經非常久遠,從親密夥伴到反目成仇,令人不勝唏噓。

2013 年,當時名叫 dotCloud 的 Docker 公司,開源出來了自己的容器項目 Docker。Docker 通過鏡像打包的方式保持了本地環境和雲端環境的高度一致,解決了運維人員的一大心病,將運維人員從一遍遍的重複勞動中解放了出來。同時友好簡潔的封裝,對開發人員十分具有親和力,這讓 Docker 一舉走紅。很多後端和雲計算領域的優秀的開發力量都匯集在了 Docker 的周圍,生態一時間變得異常繁榮。

但此時的這個開源創業公司還必須考慮盈利壓力,於是 dotCloud 公司決定將公司名稱改為「Docker」。將這個開源項目的名稱變成了 Docker 公司的註冊商標,這意味著,任何人在商業活動中使用這個單詞,以及鯨魚的 Logo,都會立刻受到法律警告。

2014 年到 2015 年期間,是容器技術的鼎盛時期,Docker 公司一家獨大,具有十足的話語權,主導著整個社區的發展。Google 公司曾向 Docker 公司表達了合作的願望,希望共同推進一個中立的容器運行時(container runtime)庫作為 Docker 項目的核心依賴。不過,Docker 公司並沒有認同這個明顯會削弱自己地位的提議,不久後 Docker 自己還發布了一個容器運行時庫 Libcontainer。

作為開源生態的一部分,Docker 還缺少有效的商業模式,他們將眼光放到了容器編排領域,推出了 Swarm。作為 Docker 項目早期的重要貢獻者,RedHat 對 Docker 公司的這個平臺化戰略表示很不滿並憤憤退出該項目。

面對 Docker 的強硬態度,Google 聯合 RedHat,共同牽頭髮起了一個名為 CNCF(Cloud Native Computing Foundation)的中立基金會,來推動 Kubernetes 的發展。

從此之後,面對 Kubernetes 社區的崛起和壯大,Docker 公司不得不面對失敗的現實。2017 年 Docker 公司宣布將 Docker 項目改名為 Moby,交給社區自行維護,而 Docker 公司的商業產品將佔有 Docker 這個註冊商標,希望以此將原本屬於 Docker 社區的用戶轉化成了自己的客戶。

楊明越認為現在的 Kubernetes,從技術上可以說是非常開放的產物,但 Docker 已經不是。開源社區的 Moby 項目,圖標由一條鯨魚變成了一條鯨魚的尾巴,也可以看出 Docker 對開源版本的態度。原本是開源的項目,是開源生態的一部分,盈利的目標對於 Docker 來說,屬於「強扭的瓜」。正如人際關係,從風雨同舟到分道揚鑣,甚至到反目成仇,這其中的轉折點,並非一兩次衝突,而是價值取向的背離。

他強調說:「總體來說,Docker 的弱勢來自於公司的盈利、技術應用面兩方面,但如果談 Docker 的消亡,還為時過早。因為 Docker 本身也是一系列技術模塊的組合體系,而非一個東西。」

王新勇也認為 Docker 技術(或者說 Moby 項目)和 Docker 公司得分開看待。短時間內,Moby 項目不會消亡,會使用 Docker 命令可能會成為一個開發人員的必備技能,畢竟技術的慣性是很強大的。至於 Docker 公司,就算處境不樂觀,應該也是不影響 Docker 技術本身的,畢竟其背後還有強大的開源社區。

雲原生技術的未來

近幾年,雲原生技術發展速度很快,「Kubernetes 1.20 版本中棄用 Docker 支持」可能只是其中很小的一段插曲,畢竟在雲原生的全局圖中,運行時只佔很小的一部分,而且又是比較標準化的部分。

「從雲原生的角度來看 Kubernetes 棄用 Docker,其實是件好事,」楊明越表示:「Docker 已經是個商業化產品了,如果能找到一個開源替代品,對整個技術的發展會更有益處。」那麼,誰將會代替 Docker 成為雲原生技術的「新勢力」呢?在我們的採訪中,多位老師表示很看好 Podman。

Podman(Pod Manager)是一個由 RedHat 公司推出的容器管理工具,其定位就是 Docker 的替代品,在使用上與 Docker 的體驗類似。Podman 源於 CRI-O 項目,可以直接訪問 OCI 的實現(如 runC),流程比 Docker 要短。

為什麼說 Podman 是比 Docker 更先進的存在呢?曉川表示:「首先,Docker 已經是商業化的產品,而 podman 是個開源產品,在以開源為主的雲原生技術體系中更容易得到推廣和應用;其次,Docker 在實現 CRI 時,需要一個守護進程,並且以 root 來運行,這就帶來了安全隱患,而 podman 不需要,可以直接通過 OCI runtime(默認也是 runc)來啟動容器。」

Docker 與 Podman 的區別

由於 podman 的定位是 Docker 的替代品,因此在使用習慣方面也與 Docker 十分類似。

從系統構建者角度看,podman 默認軟體與 Docker 的區別不大,只是在進程模型、進程關係方面有所區別,例如關聯進程的調試方面、進程的樹狀結構查看等等,而且總體來看,podman 要比 Docker 簡單;從使用者角度看,podman 與 Docker 的命令基本兼容,包括容器運行時、本地鏡像、鏡像倉庫等。因此,podman 命令行工具與 docker 類似,比如構建鏡像、啟停容器等,甚至可以通過 alias docker=podman 可以進行替換,即便使用了 podman,仍然可以使用 docker.io 作為鏡像倉庫。

除了 Kubernetes,RHEL 7 同樣官方也不支持 Docker,只為容器環境提供 Podman、Buildah 以及 CRI-O。

採訪嘉賓:

楊明越,現從事分布式系統、雲架構方面工作,具有全方位的技術,曾任新興網際網路公司(BAT)的主任架構師,世界頂級晶片公司的 OS 技術專家,前 Top2 通訊公司高級工程師。

王新勇,網易數帆資深架構師,網易輕舟容器平臺 NCS 負責人。

曉川,曾在 RedHat 任產品測試開發工程師,具有多年 Docker 容器、K8s、Linux 和 Python 方面的經驗,在 OpenShift 從事 PaaS 平臺比較前沿的技術項目。

今日薦文

相關焦點

  • 宋寶華:Docker 最初的2小時(Docker從入門到入門)
    經過本人多年研究,虛擬化的技術分為2種,一種是虛擬一個世界,第二個是虛擬一個氛圍。比如我們在現實生活裡面是個屌絲,但是在虛擬人生的遊戲裡面,我們可以是王思聰++,集美貌智慧財富正義於一生。虛擬人生的遊戲,構建一個整個的新世界,這個世界,人人有房住,天下沒有賊。那麼這個就是硬體都變了,你的內核都變了。這個是Virtualbox,KVM這種虛擬出一個新世界的思路。
  • docker的/var/run/docker.sock參數
    歡迎訪問我的GitHub這裡分類和匯總了欣宸的全部原創(含配套源碼):https://github.com/zq2599/blog_demos關於/var/run/docker.sock參數在創建docker容器時,有時會用到/var/run/docker.sock這樣的數據卷參數,例如以下docker-compose.yml
  • 雲計算核心技術Docker教程:Dockerfile指令詳解
    CMD類似於 RUN 指令,用於運行程序,但二者運行的時間點不同:CMD 在docker run 時運行。RUN 是在 docker build。推薦使用第二種格式,執行過程比較明確。第一種格式實際上在運行的過程中也會自動轉換成第二種格式運行,並且默認可執行文件是 sh。
  • Docker集群管理之Docker Compose
    Docker Compose是由python語言實現的,它通過調用docker-py庫(可參考https://github.com/docker/docker-py)與docker engine通信實現構建docker鏡像,啟動停止docker容器等。
  • 雲計算核心技術Docker教程:Docker Compose run命令詳解
    docker-compose run web bash您使用的命令run從具有由服務定義的配置的新容器中啟動,包括卷,連結和其他詳細信息。但是,有兩個重要的區別。首先,通過的命令將run覆蓋服務配置中定義的命令。
  • 【Docker】系列教程02-操作Docker容器
    ~]# docker run -it ubuntu /bin/bashroot@8b18b6758bb6:/#docker run相當於執行了兩個步驟:將鏡像放入容器中(docker create),然後啟動容器(docker start)。
  • Docker系列教程02-操作Docker容器
    :/#docker run相當於執行了兩個步驟:將鏡像放入容器中(docker create),然後啟動容器(docker start)。>還記得上一章節,我們講過docker load載入鏡像嗎?3、用戶既可以使用docker load導入鏡像文件到本地鏡像庫,也可以使用docker import導入容器快照到本地鏡像庫。
  • 如何開始docker - docker架構及創建容器
    安裝docker很簡單,啟動服務以後要怎麼開始使用呢?docker架構傳統的虛擬機架構是 物理機 -> 宿主機作業系統 -> Hypervisor支持 -> 虛擬機作業系統 -> 應用程式docker架構是 物理機 -> 宿主機作業系統 -> docker引擎 ->
  • Docker系列教程01-使用Docker鏡像
    docker search 語法docker search 語法例如,搜索mysql相關的鏡像,命令如下:docker pull 語法docker pull 語法通常情況下, 描述一個鏡像需要包括「名稱+標籤「信息。
  • docker 門外初體驗——docker 安裝(一)
    二、安裝三、驗證四、總結前言重寫對docker的學習記錄,最主要的原因之一,花了大量的時間進行學習,形成一個從0至1的認識,但是工作中卻沒見有實際應用,導致所學的知識存活率很低,也為了豐富自身的技術體系一、docker是什麼?Docker 是一個開源的應用容器引擎。
  • 雲計算核心技術Docker教程:Docker容器使用
    docker 客戶端非常簡單 ,我們可以直接輸入 docker 命令來查看到 Docker 客戶端的所有命令選項。可以通過命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。
  • 雲計算核心技術Docker教程:docker Stack介紹
    docker stack和docker-compose使用方式相同,但是為什麼引入docker stack技術呢。docker stack的能力來源自docker引擎原生支持,你不需要安裝額外工具包去啟動docker 容器堆棧(docker stack 是docker swarm的一部分)。
  • 雲計算核心技術Docker教程:Docker多階段構建
    /bin/shecho Building alexellis2/href-counter:builddocker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \-t alexellis2/href-counter:build .
  • 雲計算核心技術Docker教程:Docker鏡像使用
    當運行容器時,使用的鏡像如果在本地中不存在,docker 就會自動從 docker 鏡像倉庫中下載,默認是從 Docker Hub 公共鏡像源下載。我們可以使用 docker images 來列出本地主機上的鏡像。
  • ​Docker 數據卷的管理及自動構建docker鏡像
    /www.nmtui.com" >/data/index.html[root@docker01 ~]# curl 10.0.0.100http://www.nmtui.com設置共享卷,使用同一個卷啟動一個新的容器[root@docker01 ~]# docker run -d -p 8080:80 -v /data:/
  • docker下高並發和高可用之docker swarm使用
    ,操作步驟參考Linux下安裝和使用Docker安裝完,使用命令sudo systemctl start docker啟動docker,再通過命令docker version查看docker版本信息利用docker swarm 命令來指定其中一臺虛擬機為docker的Manager管理機docker swarm init --advertise-addr
  • docker-4:mac使用docker部署開發用rocketmq
    目錄:(1).mac本地docker化rocketmq(2).mac本地docker化rocketmq-console(3).測試(1).mac本地docker化rocketmq現在官方rocketmq-docker:git clone https://github.com/apache/rocketmq-docker
  • Docker問答錄系列——Docker引擎相關問題(一)
    https://blog.docker.com/2015/11/docker-1-9-production-ready-swarm-multi-host-networking/https://blog.docker.com/2016/02/docker-1-10/https://blog.docker.com/2016/04/docker-engine-1-
  • Docker再體驗之Docker Compose,及它與Kubernetes的區別
    sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-composesudo chmod +x /usr
  • 不用Docker也能構建容器的4種方法
    Buildkit 有很多優點:更複雜的緩存;如果可能的話,可以先運行後面的指令——也就是說,可以在「sdk」層的構建完成之前,下載「runtime」鏡像;在第二次構建時速度超級快。--local dockerfile=. --output type=image,name=docker.io/username/image,push=true OPTIONS: --output value, -o value Define exports for build result, e.g.