標籤:

來自滬江、滴滴、蘑菇街、扇貝架構師的 Docker 實踐分享

架構師小組交流會是由國內知名公司架構師參與的技術交流會,每期選擇一個時下最熱門的技術話題進行實踐經驗分享。

Docker 作為當前最具顛覆性的開源技術之一,其輕量虛擬化、可移植性是 CI/CD、DevOps、微服務的重要實現技術。但目前技術還不夠成熟,在生產實踐中還存在很多問題。對此,滬江黃凱、滴滴田智偉、蘑菇街張振華、蘑菇街向靖、扇貝丁彥以及七牛雲袁曉沛在本期交流會上分享了各自的經驗。本文是對此次交流的整理,歡迎探討。

自由交流

  • 滬江黃凱

大家好,我是來自滬江的 Java 架構師,我叫黃凱。在加入滬江之前,曾在 HP 和 IBM 的雲計算部門擔任核心開發和架構職位。對 IaaS、PaaS、SaaS,尤其是雲存儲有較深入的了解。2015 年加入滬江,擔任架構師職位,主導的產品有:課件雲存儲,雲轉碼等等。在這些項目中,我們使用 Mesos 和 Marathon 做 Docker 的編排工具,並開發了一個 Mesos Framework 做雲轉碼的核心框架。

是由國內知名互聯網公司架構師參與的在線技術交流會,每期選擇一個時下最熱門的技術話題進行實踐經驗分享。

那麼我們為什麼要使用 Docker,也是機緣巧合。由於我們的服務開始的時候不是特別多,採用的就是一種普通的架構,後來隨著服務的增多,發現部署和運維花的時間太長,我們想使用一些新的方式。開始的時候研究過 Openstack,後來覺得 Openstack 慢慢沒落,於是我們就選中現在使用的 Docker。我們並不把 Docker 當成 VM 在用,而是使用它的原生的,在 Baremetal 上直接安裝 Docker,這樣運行效率比在 VM 運行 Docker 要來的快。課件雲是由很多微服務組成,不光是一些存儲,這種微服務是使用 Docker 部署,就相當於編排,把這些微服務部署上去。轉碼這一塊是使用了 Mesos 框架,和 Docker 沒有特別大的關係,但是轉碼的應用程序,比如說我們現在應用 FFmpeg,這個程序是運行在 Docker 裡面的。

為什麼要選擇 Marathon?第一,我覺得 Mesos+Marathon 非常的容易理解。我們也研究過 Kubernetes 和其他的一些方法,發現從運維和研究的方面來說的話,Kubernetes 實在是太重而且太複雜,後來選擇了Marathon。我們現在是內部服務使用,兩個部門在使用轉碼集群,大概是 Baremetal 有 20 台的物理機。除去我們 API 的一些服務,還有一些第三方組件的服務的話,大概是有 400 多個 Docker 容器在跑。

滴滴田智偉

大家好,我是滴滴代駕事業部架構師,代駕事業部是公司最早嘗試 Docker 虛擬化的事業部。目前主要方向是業務系統及部分中間件的 Docker 化,我們做的時間也不太長,半年多的時間。線上是因為我們有老的一套發布系統,集成涉及的部門比較多,所以我們基於原來的發布系統完成了預發布環境 Docker 的部署。線下環境基於 Docker+K8s 開發內部的自動化持續交付系統及開發測試環境管理。我們在做開發和測試環境的自動化,另一方面也是做環境管理的,兩套環境。對於項目並行的時候發現原來很多不夠用,原來很多配置是基於埠綁死的情況。現在基於開發 Kubernetes 的話,網路隔離用了一部分,然後主要是用環境變數這一部分,主要考慮是解決一個配置可以應用到在多個環境的情況,基於這個需求才用它。開發 Kubernetes 基於 Namespace,同一個服務在不同的 Namespace 下,它其實環境變數名可以是相同的,但是IP不同,而這一部分 IP 其實是由開發 Kubernetes 自己去管理的。基於環境變數獲取一些配置的話,比如 IP 地址這種,就可以做到拿一份配置可以打出多套環境。

考慮業務的安全性和穩定性,線上基於純 Docker 的方式在做。我們是基於裸的 Docker 來工作,主要是用資源隔離,沒有藉助調度框架,也沒有自動伸縮。我們是兩步走,一步是驗證 Docker,其次是做開發 Kubernetes 線下使用和預研。為什麼沒有考慮 Mesos?剛才跟滬江的同學,我們的考慮是相反的。Mesos 側重點更專一一點,首先不會有模塊的劃分,比如 Kubernetes 有 Replication controller ,Namespace 這種概念,而 Mesos 下幾乎沒有這種概念。我們拿 Kubernetes 主要是做一些編排的功能,而正好開發 Kubernetes 在整個發布和編排上,體系更全面一點。Mesos 最早是做資源管理,基於 Docker 做一個 Framework 接進來的話,它不是專門為編排而生。Kubernetes 首先解決我們的問題是,我們可能不需要加多份配置就可以搭多套不同的環境,它就是基於 Namespace 做一個多租戶的概念,會對 Service 做一層隔離,對於動態配置,擴容這一部分暫時我們沒用到,確實用到的一些場景比較少。主要是做不同環境的隔離,並沒有太多使用編排細節上的東西,動態伸縮之類的目前線下沒有太大必要,線上可能會用到。

蘑菇街向靖

大家好,我是向靖,來自蘑菇街的運維架構師。我們接下來會做一個 PaaS 平台,想做 Docker 和結合虛擬機以及我們用到公有雲產品,做成一個混合雲的架構平台。我們現在 Docker 也在用,更多的是當虛擬機用,後面我們想基於 Docker 原生的方式去用,可能會涉及資源調度,服務發現的問題。除了 Docker,我們還會用到公有雲,公有雲更多是虛擬機的方式提供。出於混合雲,想在資源層做一個抽象,對於上層業務來講它沒有關係,它是跑在 Docker 上,還是雲主機上,還是 KVM 虛擬機上,那麼我想在這上面做一個抽象。另外還有,剛才我也是提問滴滴架構師的問題,配置怎樣和代碼做隔離,這個也是我考慮的問題。因為我看 Docker 用了環境變數,通過環境變數做一些配置的參數的傳遞,但是在虛擬機上,特別是在物理機上,通過環境變數的方式,我還在考慮有沒有安全的風險,Docker 可能是一個只讀的,不會被修改的,但是對於虛擬機以及物理機來說,可能會存在被修改的風險。

蘑菇街張振華

大家好,我叫張振華,花名郭嘉,我是 14 年從思科加入蘑菇街。我們算是國內用 Docker 比較早的,我們一開始用 Docker 是 1.3.2 的版本,當時我們採用集群管理工具還是 Openstack,因為當時 Kubernetes 還不是很成熟。當時也走了一些彎路,比如我們把 Docker 當成虛擬機來用,曾經在線上的規模也達到幾百台虛擬機幾千個容器,但是我們逐步發現不能把 Docker 當成虛擬機來使用,因此我們做了一個轉型,從去年開始研究 Kubernetes,現在 Kubernetes 加 Docker 的版本開發完成了,準備逐步上線。

我們為什麼選用 Kubernetes?編排工具的選擇我們也是做過一番調研的,它們沒有誰好誰不好這一說,只能說誰更貼切你的需求。對於我們蘑菇街來說,我們需要解決是資源利用率的問題,和運維的對接,我們需要有預發和線上環境的持續集成持續部署的過程,還有我們需要有對資源的隔離,對部署的快速迭代,包括集群管理,這些方面,我們覺得 Kubernetes 更加適合於我們。

在網路方面,我們研究過現在在開源界比較常用的一些方案,但是我們都覺得不太適合,比較 Fannel,Caico 等等,他們一般用的技術都是 VXLAN,或者是用 BGP。因為我們之前對 Openstack 的網路是比較有經驗的,然後我們發現有一個項目,具體名字不記得,Neutron 和 Kubernetes 做一個對接,我們在這個項目的基礎上做了 VLAN 的方案,我們的網路沒有用 VXLAN 來做,而是選擇 VLAN 來做,這樣的話一個 Docker 它可以獲得跟一個物理理同一個網路平面的 IP,我們的應用程序可以直接對外訪問,因為我們內部業務有這個需求選擇這個方案。雖然 Docker 內部網路和外部網路是通的,但 Docker 還是獨立的一個網段,不需要一層 NAT 的轉換。我們直接走二層的,是在交換機走 Chunk,本來物理機交換機的 Access 口,這樣的話,一台物理機上面允許跑多個 VLAN 的容器,比如說 A 業務和 B 業務要走隔離的話,通過網路的 VLAN 走隔離,它們的數據之間不會有干擾。

Load Balance 我們還沒有涉及到這一塊,Load Balance 我們應該會在 nginx 上做一層。因為據我了解,現在 Kubernetes 這一塊 Proxy 還不是很成熟,這上面還存在一些問題,因此還不敢用 Kubernetes 現有提供的服務。服務發現和註冊這一塊我們還在做開發,這塊會和配置管理中心打通。我們內部也有其他團隊在做這些功能,所以我們會和內部的中間件團隊合作。

七牛雲袁曉沛

大家好,我是七牛雲數據處理技術總監袁曉沛。我們的數據處理業務包括了圖片和視頻的實時在線及非同步處理。數據處理的業務量比較大,日均請求量達到百億級。平台採用容器技術的原因是藉助容器技術快速部署,啟動的特性,數據處理程序可以根據數據處理量快速地彈性伸縮。藉助容器技術內核級別的資源隔離和訪問控制,每個數據處理程序可以運行在一個私有的環境,不被其它程序所干擾,保證其上運行數據是安全可靠的。而且容器技術是輕量的,它以最小的資源損耗提供資源隔離和訪問控制,而資源特別是計算資源在數據處理中是非常寶貴的。

我們在資源調度上採用的是 Mesos,而二層的業務調度框架則是自己自研的。七牛自身擁有近千台的物理機,容器是直接運行的物理機上,可以減少虛擬層對資源的消耗,提高資源的利用率。

在網路上,對於七牛的自定義數據處理服務直接使用的是 Host 模式,而對第三方數據處理服務則使用的是 Bridge 模式,因為這些程序是用戶自己部署運行的,並不知道用戶是否有開啟其他的埠使用,所以使用的是 Bridge 模式,需要對外使用埠的都需要通過 NAT 進行暴露,這樣服務內部使用了什麼埠並不會對外界環境造成影響,對平台環境做了非常好的安全隔離。我們是使用 Consul 做註冊中心,支持跨數據中心的服務發現。我們為什麼自研的調度框架,而不用 Marathon。因為 Marathon 不支持跨數據中心的內部服務或外部服務的發現,而七牛有多個數據中心,影響整體的調度,其次如果選用 Marathon 的話,根據我們業務的特點,還是要再做一層對 Marathon 的包裝才能作為 Dora 的調度服務,這樣模塊就會變多,部署運維會複雜。

扇貝丁彥

大家好,我是扇貝的技術總監丁彥,之前在暴走漫畫,先後在暴走漫畫和扇貝設計和主導了基於 Docker 的微服務架構系統,以及數據收集和分析系統。去年來到扇貝,這裡是 Python 的開發環境。後來發現業務增長快,水平擴展一些機器,出現問題需要換個機器等等,都需要非常熟悉業務的少數開發去做。另外公司對預算控制嚴格,機器基本都是滿負荷運作,平時也不可能多開空置的機器,已有的機器還要根據負載情況調整服務分布情況,所以這種切換服務,增刪服務的操作還是比較頻繁的。因此,我們用了 2-3 個月的時間將所有的運行環境都切換到 Docker上,這大大提高了我們的運維能力。

Docker 包裝有幾個好處。

第一個好處是,環境升級非常方便。因為只要pull 一下最新的鏡像,啟動一個 Container,環境就升級了。而如果直接基於公有雲的鏡像升級的話就很難,因為一台機器上跑哪些服務其實不一定是固定的,並且之前做的鏡像只要有一台機器是還基於它的話,就刪除不掉的,鏡像數量又有上限。所以 Docker 非常好地解決了我們的問題。

其次是環境的顆粒度會更小,一台機器上配好幾個應用的話,往往配著配著,到最後你就不太能精確地記得上面裝的程序或者庫是給哪個應用服務的,應用之間如果依賴有版本的衝突也很難調和。你想做些服務的遷移,把負載比較小的放一起,把負載比較大的抽出來,這個時候就非常痛苦,但你如果用 Docker 包裝後就非常簡單,只要在不同的機器上起不同的 Container,就可以實現這一點。

第三,我們不光用了 Docker,還加入了服務發現,剛剛討論配置管理這些,我們一併做了。Docker 啟動時候,我們自己寫了一些工具,可以自定義 Docker 啟動參數,包括配置參數,比如說,一些程序要運行的參數,我們主要用兩種方式,一種方式是通過環境變數灌進去,還有一種方式讓程序的啟動腳本支持參數,然後拼接不同的參數灌進去,最終都是落實到 Docker 的啟動命令上。服務發現是基於 Consul,Docker 的啟動命令是從 Consul 里取的。首先 Consul有 HTTP 的 API,我們是自己寫的 pip 包,只要 Include 一下這個包就可以了,Docker 的服務啟動後會自動註冊到 Consul。比如要在負載後加一個服務,只需要找到一台機器,啟動對應的 container,剩下的事情它自己會到 Consul,註冊它的參數地址一系列東西,自動把它加進去。所以這些都是自動化的,如果檢測那台機器/服務掛了,Health Check 也會到 Consul 裡面更新。該增加機器就增加機器,該下線就下線。總體來說,我們的生產環境全部跑在 Docker 上面的,然後區分有狀態和無狀態兩種,有狀態的定死在機器上,無狀態的靈活的自由切換。還有一點,如果是有狀態的容器要定死在機器上的時候,我們一般來說都會採取冗餘的結構,至少保證有兩個在運行,一個掛了,保證整體的服務在運行。其次基於 Docker,我們還做了一套數據搜集以及分析的機制。數據搜集是基於日誌來搜集的,利用 Docker 的 Log driver,把日誌打到 Filter,把結果存在存儲服務上。同時監控也是基於日誌做的。第三部分非生產環境,比如開發環境跟測試環境都是 Docker 做的,因為我們每一個服務都做了 Image、鏡像,用容器方式跑的。通過參數來決定啟動方式的,我們可以在開發環境以及測試環境採用不同的參數來啟動容器。 通過 Consul 來隔離的,因為 Consul 的服務發現,開發、生產、測試環境在不同的自動發現框架里不會相互影響到。目前機器在 120 台左右,基於雲服務。有些基礎的東西不需要依賴於 Docker,比如說申請雲主機,申請的時候就可以指定它的 CPU 和內存這些伺服器資源的配置。所以這部分東西還是屬於 Human schedule,不是完全讓編排的系統自己決定該怎麼樣。

編排工具我們現在在研究進一步,我剛來這工作的時候,所有的服務沒有一個跑在 Docker 上面的,我現在把它遷進來。現在數據增長,已經有一些編排的瓶頸,現在在做調研,可能基於 Swarm,做自動編排的設計。

指定話題交流

主持人:容器多的情況下 Kubernetes 存在性能問題,各位在這方面有沒有好的經驗?

扇貝丁彥:我們其實也遇到了這個問題,找不到辦法所以放棄了 Kubernetes。我們也是用公有雲,網路直接依賴公有雲的網路,有可能是因為公有雲造成的,我沒有試過在祼機上試過。

滬江黃凱:Kuberneters 的 Fannel 有一種模式是 VXLAN,它的封裝摺包是做內核里做的,效率會高一點。容器多就會效率會低是因為,在 Kubernetes 1.2 的時候,走這樣的一種模式,數據先到內核態中,然後把數據拉回到用戶態,用 Proxy 的方式分發給各個容器當中的。其實在 Kubernetes 1.3 以後,它直接在iptables里設規則,相當於用戶數據不用跑到用戶態,在內核直接分發出去了,這種效率會非常高。所以可以研究一下 Kubernetes 新版本。

扇貝丁彥:我們碰到過網路方面的問題。默認的 Docker engine 的啟動參數裡面有個 iptables,不知道大家有沒有定製化過,如果不定製化這個參數,它默認會幫你建 iptables 的轉發規則,並會開啟內核的網路追蹤的模塊。一開始我們沒有注意這件事情,當我們的 Nginx 遷到 Docker 的時候,Nginx 服務瞬間會掛。後來查原因,是因為這些參數會開啟網路追蹤模塊。因為我們的 Nginx 流量非常大,當時只有 3 台 Linux 雲主機,分發 http 請求的,然後會導致 3 台Linux宿主機,內存會被刷破,網路會出現堵塞。所以我們關掉了 iptables 參數,並採用 Host 的網路模型。所以它的容器拿到的 IP 就是 Host 的 IP。我們一開始也想上一些 Kubernetes 這些東西,然後發現簡單跑個模型根本跑不起來,所以一開始就放棄了這一套東西,直接搞了個裸的 Docker。

主持人:關於跨數據中心容器集群的使用,大家有經驗么?

滬江黃凱:我們跨數據中心主要是IP分配上的問題,我們現在也在嘗試使用 Calico,如果 Host 網路是通的話,那麼它的內部網路也就通了,可以自由劃 VLAN,這樣你就可以解決跨 Data center 的問題。還有一個問題就在跨 Data center 時,服務註冊與發現的問題。這個問題也困擾我們很久了,我們現在使用 Consul 做服務註冊與發現。雖然 Consul 它是官方支持跨 Data center,但是我們在使用當中的話會發現註冊的 IP,在另外一個註冊中心,它會發現的比較慢,甚至有時候出現 IP 衝突的時候。

我們的做法是把 Host 的 IP 地址直接用 Environment 的形式注到 Docker 鏡像內部,接下 來 Docker 鏡像要註冊,它就會讀取 App 的 IP,然後發送給 Consul,只要保證 Host 的 IP 和 Docker內部容器的 IP 能夠互通的就行了。如果不能通的話,比如說完全和 Host IP 隔離,那麼起碼有幾台機器要暴露出去,又比如說,Consul 它本身自己要暴露出去才能訪問到。Host 的 IP 是容器啟動之後注進去的,啟動命令中把 Host 的 IP 地址加在 -e 的後面,容器在啟動之後,它的環境就會有這麼一個 IP。我們用 Mesos 就沒這個問題,但是用 Kubernetes 就有這個問題。Mesos 會自動幫你把這些東西注入容器中去。

滴滴田智偉:其實 Kubernetes 本身也是可以解決這個問題,我們現在在做線下持續交付的時候。定義完 Service 之後,容器會同一個 Namespace 默認加一個系統環境變數。

滬江黃凱:我們試過,在 Pod 啟動之後,Pod 里容器想訪問 host 的 IP 地址,是沒有辦法做到的。

蘑菇街張振華:因為我們之前也遇到這個問題,然後我們業務方,他們可能有一些程序會獲取本機 IP 地址,如果是內部的 IP 地址,他們程序可能會出現問題,於是我們當時沒有用 Docker 默認的網路,而是採用 VLAN。

主持人:我們提到好多 Mesos、Kubernetes、網路,發現沒有提自動伸縮,有沒有項目涉及到容器的自動伸縮?

滬江黃凱:我們滬江是基於 Mesos+Marathon 做了自己的一個服務,它這個服務是幹嘛的呢,就是監測,不停的監測每一個 Docker 的 CPU 和內存的利用率,一旦超過百分之多少以後,就向 Marathon 發一個命令,說我要擴容,它還可以支持時間點,比如 15 分鐘監測一次,如果在 15 分鐘發現它超過閾值了,就馬上擴容出來,但是縮的話,不是適用於頻繁監控,如果小於 20% 的話就會縮,一旦縮的話會影響線上用戶的請求。怎麼辦呢?我們在縮的時候可以規定它的時間點,比如半夜裡 2-3 點,訪問量少於多少點時候把它縮掉。我們監測的是 Docker 內部的 CPU 的使用率。就是監測一個服務,它可以監控所有同一服務的 Container,比如一個服務有 100 個容器,那麼這一百多個 CPU 利用率加起來除於一百,相當於平均的利用率。如果平均利用率超過 80%了,那說明這個集群到了擴展程度了,它會以一種比例來擴展。針對單個容器,可以設置內存的限制。我們給每一個容器呢,比如它只能用 4 個 CPU,只能用 8G 的內存,或者更小一點的內存,這些都設好,設好之後它自動擴展相同規格的容器。這麼做是因為 Cgroup 有個問題,當利用率到達了啟動的限制,Cgroup 會把這個容器 kill 掉。這個是不可理喻的問題,所以我們想到用 Load scale 來擴容,不讓他直接死掉。

滴滴田志偉:關於自動擴容,我們線下的時候遇到一個問題,我們最早的時候是用騰訊的公有雲,它限制了 NET 的模塊,導致我們最初用 Cgroup 的方案去做,綁定埠。內部使用所有應用,埠是要做分配的,要不然出現埠衝突。然後遇到問題是,在這種情況下,如果要做動態擴容的話,它每次先創建一個,再殺掉一個,導致每次起來的時候就起不來了,因為埠的問題。服務啟動的時候埠是隨機,會出現衝突問題,因為用的是 Host 的模式。

主持人:關於自動伸縮為什麼沒有考慮到請求數?因為如果內存佔用率如果超過一定預支,那麼請求數也可能超過一定預支了。把單個容器所處理的請求數給限定了,那麼它內存自然不會超,然後也不會被幹掉。

滬江黃凱:我個人認為,第一,請求數很難測,你不知道請求數到多少時要擴容,還不如根據 CPU 到 80%,或者 90% 來的直觀。我們的 API 也是根據 CPU 來算的。你真正是高並發的 API 的話,我也測過,最後我們能夠監測到的,其實還是 CPU 和內存。

扇貝丁彥:我們擴容是根據響應時間,跟請求數類似,請求數定指標不太好定,我們是根據響應時間,比如平時的響應時間是 50 毫秒,當響應時間是 300 毫秒的時候就要擴容了。

主持人:大家對於容器有狀態無狀態有沒有遇到什麼問題?大家一般用容器的本地磁碟還是共享磁碟呢?

滬江黃凱:關於存儲,我們是有一些研究的。現在容器存儲問題分為兩種,Kubernetes 官方支持一種理念,任何一種存儲都是一個 Volume。Volume 先於 Docker 存在的,而不是 Docker 啟動之後再掛載 Volume。不管是網路存儲還是本地存儲,全部以卷的形式,掛載在 Pod 裡面或者是宿主機上,以 Driver mapper 來驅動這個 Volume,來讀到你所要的內容。

還有一種情況,就是 Docker 公司主導的存儲模型,任何的存儲都是一種驅動。如果你想用 NFS 或者如 Ceph 這樣分散式存儲的話,讓 Ceph 開發 Docker 的驅動,Docker run 的時候指定存儲的驅動,Docker storage driver 這種方式,外部的存儲在容器內部它展現形式可以是目錄,也可以是掛載卷、塊的形式。如果用塊掛載到容器中,這個容器自己格式化它,或直接讀取它都是可以的。它只不過它是相當於用了一個 Driver 的形式,把你的容器和分散式存儲建立一個連接而已。對於容器,如果原本綁定塊或 Volume,容器出現故障的話,直接把容器殺掉,再啟動掛在同樣一個 塊或Volume 就解決了。優點是直接讀取,而不是通過再轉一層,效率比較高一點。所有存儲都是 Volume 的形式理解度比較高一點,所以我們還是贊同於用 Volume 的形式。

有狀態的容器。我知道 k8s 的新的計劃,如果你沒有用 Kubernetes 最新版本的話,一般來說我們都是容器啟動在固定 Host 上,下次啟動還是在這台 Host 上,它的存儲它的內存,包括一些 log,全部是在這台 Host 上。還有一種是用最新的版本,有個 PetSet 的新 kind,Kubernetes 它自己會記錄 Pod 在什麼 Host 上啟動過,不用自己去指定一定要在某一台 Host 上啟動,這種方法比較智能化,但是不是特別穩定的一種方法,因為它是剛剛開發出來的新功能。

主持人:數據多副本,假設有一個節點故障的話,是建議它直接把原來的副本重新綁定還是重新起一個新的實例,通過分散式數據的遷移呢?

滬江黃凱:我個人認為還是在同一台機器上起一個新的實例,不要讓它做數據遷移,因為數據遷移會佔用很多資源。而且如果你的想法是說,所有的分散式的存儲只是以 Volume 的形式掛載在宿主同上,這也就沒什麼問題了。因為存儲和 Docker 是完全分開來的。如果只有一個 Volume,存儲的可靠性會得不到保障,所以在 Kubernetes 新版本當中,它會建立一個 Volume 的 kind,也相當於建立 RC kind一樣,是一個 Pod,那這樣由 Kubernetes 來保障這個 Volume 的高可用。

想要了解雲計算領域的技術洞見?

歡迎關注@七牛雲 機構帳號!

以上。

推薦閱讀:

如何成為一名Android架構師?
Web前端職業生涯是怎樣的?一般多少年能夠成為初級、中級、高級、架構師,大家看看下面的是否合理。
互聯網架構設計:高可用
想做架構師應該怎麼學習?
什麼是架構,什麼是架構師?

TAG:Docker | 架构师 |