成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > Google和Facebook不使用Docker的原理解析

Google和Facebook不使用Docker的原理解析

熱門標(biāo)簽:宿城區(qū)電話機(jī)器人找哪家 10086外包用的什么外呼系統(tǒng) 上海申請高400開頭的電話 怎么找到?jīng)]有地圖標(biāo)注的店 400電話辦理介紹信 福州企業(yè)電銷機(jī)器人排名 麗江真人語音電話外呼系統(tǒng) 河南防封號電銷機(jī)器人是什么 打400電話怎么辦理收費

寫作本文的起因是我想讓修改后的分布式 PyTorch 程序能更快的在 Facebook 的集群上啟動。探索過程很有趣,也展示了工業(yè)機(jī)器學(xué)習(xí)需要的知識體系。

2007 年我剛畢業(yè)后在 Google 工作過三年。當(dāng)時覺得分布式操作系統(tǒng) Borg 真好用。

從 2010 年離開 Google 之后就一直盼著它開源,直到 Kubernetes 的出現(xiàn)。

Kubernetes 調(diào)度的計算單元是 containers(準(zhǔn)確的翻譯是“集裝箱”,而不是意思泛泛的“容器”,看看 Docker 公司的 Logo 上畫的是啥就知道作者的心意了)。

而一個 container 執(zhí)行一個 image,就像一個 process 執(zhí)行一個 program。

無論 Googlers 還是 ex-Googlers,恐怕在用 Borg 的時候都未曾接觸過 container 和 image 這兩個概念。為啥 Borg 里沒有,而 Kubernetes 卻要引入了這樣兩個概念呢?

這個曾經(jīng)問題在我腦海中一閃而過就被忽略了。畢竟后來我負(fù)責(zé)開源項目比較多,比如百度 Paddle 以及螞蟻的 SQLFlow 和 ElasticDL,Docker 用起來很順手。于是也就沒有多想。

今年(2021 年)初,我加入 Facebook。恰逢 Facebook 發(fā)論文[1]介紹了其分布式集群管理系統(tǒng) Tupperware。

不過 Tupperware 是一個注冊于 1946 年的品牌 https://en.wikipedia.org/wiki/Tupperware_Brands,所以在論文里只好起了另一個名字 Twine。

因為行業(yè)里知道 Tupperware 這個名字的朋友很多,本文就不說 Twine 了。

總之,這篇論文的發(fā)表又引發(fā)了我對于之前問題的回顧——Facebook 里也沒有 Docker!

和 Facebook Tuppware 團(tuán)隊以及 Google Borg 幾位新老同事仔細(xì)聊了聊之后,方才恍然。因為行業(yè)里沒有看到相關(guān)梳理,本文是為記錄。

一言蔽之

簡單的說,如果用 monolithic repository 來管理代碼,則不需要 Docker image(或者 ZIP、tarball、RPM、deb)之類的“包”。

所謂 monolithic repo 就是一家公司的所有項目的所有代碼都集中放在一個(或者極少數(shù))repo 里。

因為 monolithic repository 得有配套的統(tǒng)一構(gòu)建系統(tǒng)(build system)否則編譯不動那么老大一坨代碼。

而既然有統(tǒng)一的 build system,一旦發(fā)現(xiàn)某個集群節(jié)點需要執(zhí)行的程序依賴的某個模塊變化了,同步這個模塊到此節(jié)點既可。完全不需要打包再同步。

反之,如果每個項目在一個獨立的 git/svn repo 里,各自用不同的 build system,比如各個開源項目在不同的 GitHub repo 里,則需要把每個項目 build 的結(jié)果打包。

而 Docker image 這樣支持分層的包格式讓我們只需要傳輸那些容納被修改的項目的最上面幾層,而盡量復(fù)用被節(jié)點 cache 了的下面的幾層。

Google 和 Facebook 都使用 monolithic repository,也都有自己的 build systems(我這篇老文尋找 Google Blaze[2] 解釋過 Google 的 build system)所以不需要“包”,當(dāng)然也就不需要 Docker images。

不過 Borg 和 Tupperware 都是有 container 的(使用 Linux kernel 提供的一些 system calls,比如 Google Borg 團(tuán)隊十多年前貢獻(xiàn)給 Linux kernel 的 cgroup)來實現(xiàn) jobs 之間的隔離。

只是因為如果不需要大家 build Docker image 了,那么 container 的存在就不容易被關(guān)注到了。

如果不想被上述蔽之,而要細(xì)究這個問題,那就待我一層一層剝開 Google 和 Facebook 的研發(fā)技術(shù)體系和計算技術(shù)體系。

Packaging

當(dāng)我們提交一個分布式作業(yè)(job)到集群上去執(zhí)行,我們得把要執(zhí)行的程序(包括一個可執(zhí)行文件以及相關(guān)的文件,比如 *.so,*.py)傳送到調(diào)度系統(tǒng)分配給這個 job 的一些機(jī)器(節(jié)點、nodes)上去。

這些待打包的文件是怎么來的呢?當(dāng)時是 build 出來的。在 Google 里有 Blaze,在 Facebook 里有 Buck。

感興趣的朋友們可以看看 Google Blaze 的“開源版本”Bazel[3],以及 Facebook Buck 的開源版本[4]。

不過提醒在先:Blaze 和 Facebook Buck 的內(nèi)部版都是用于 monolithic repo 的,而開源版本都是方便大家使用非 mono repos 的,所以理念和實現(xiàn)上有不同,不過基本使用方法還是可以感受一下的。

假設(shè)我們有如下模塊依賴(module dependencies),用 Buck 或者 Bazel 語法描述(兩者語法幾乎一樣):

python_binary(name="A", srcs=["A.py"], deps=["B", "C"], ...)
python_library(name="B", srcs=["B.py"], deps=["D"], ...)
python_library(name="C", srcs=["C.py"], deps=["E"], ...)
cxx_library(name="D", srcs=["D.cxx", "D.hpp"], deps="F", ...)
cxx_library(name="E", srcs=["E.cxx", "E.hpp"], deps="F", ...)

那么模塊(build 結(jié)果)依賴關(guān)系如下:

A.py --> B.py --> D.so -\

     \-> C.py --> E.so --> F.so

如果是開源項目,請自行腦補(bǔ),把上述模塊(modules)替換成 GPT-3,PyTorch,cuDNN,libc++ 等項目(projects)。

當(dāng)然,每個 projects 里包含多個 modules 也依賴其他 projects,就像每個 module 有多個子 modules 一樣。

Tarball

最簡單的打包方式就是把上述文件 {A,B,C}.py, {D,E,F}.so 打包成一個文件 A.zip,或者 A.tar.gz。

更嚴(yán)謹(jǐn)?shù)恼f,文件名里應(yīng)該包括版本號。比如 A-953bc.zip,其中版本號 953bc 是 git/Mercurial commit ID。

引入版本號,可以幫助在節(jié)點本地 cache,下次運行同一個 tarball 的時候,就不需要下載這個文件了。

請注意這里我引入了 package caching 的概念。為下文解釋 Docker 預(yù)備。

XAR

ZIP 或者 tarball 文件拷貝到集群節(jié)點上之后,需要解壓縮到本地文件系統(tǒng)的某個地方,比如:/var/packages/A-953bc/{A,B,C}.py,{D,E,F}.so。

一個稍顯酷炫的方式是不用 Tarball,而是把上述文件放在一個 overlay filesystem 的 loopback device image 里。這樣“解壓”就變成了“mount”。

請注意這里我引入了 loopback device image 的概念。為下文解釋 Docker 預(yù)備。

什么叫 loopback device image 呢?在 Unix 里,一個目錄樹的文件們被稱為一個文件系統(tǒng)(filesystem)。

通常一個 filesystem 存儲在一個 block device 上。什么是 block device 呢?

簡單的說,但凡一個存儲空間可以被看作一個 byte array 的,就是一個 block device。

比如一塊硬盤就是一個 block device。在一個新買的硬盤里創(chuàng)建一個空的目錄樹結(jié)構(gòu)的過程,就叫做格式化(format)。

既然 block device 只是一個 byte array,那么一個文件不也是一個 byte array 嗎?

是的!在 Unix 的世界里,我們完全可以創(chuàng)建一個固定大小的空文件(用 truncate 命令),然后“格式化”這個文件,在里面創(chuàng)建一個空的文件系統(tǒng)。然后把上述文件 {A,B,C}.py,{D,E,F}.so 放進(jìn)去。

比如 Facebook 開源的 XAR 文件[5]格式。這是和 Buck 一起使用的。

如果我們運行 buck build A 就會得到 A.xar . 這個文件包括一個 header,以及一個 squashfs loopback device image,簡稱 squanshfs image。

這里 squashfs 是一個開源文件系統(tǒng)。感興趣的朋友們可以參考這個教程[6],創(chuàng)建一個空文件,把它格式化成 squashfs,然后 mount 到本地文件系統(tǒng)的某個目錄(mount point)里。

待到我們 umount 的時候,曾經(jīng)加入到 mount point 里的文件,就留在這個“空文件”里了。

我們可以把它拷貝分發(fā)給其他人,大家都可以 mount 之,看到我們加入其中的文件。

因為 XAR 是在 squashfs image 前面加上了一個 header,所以沒法用 mount -t squashf 命令來 mount,得用 mount -t xar 或者 xarexec -m 命令。

比如,一個節(jié)點上如果有了 /packages/A-953bc.xar,我們可以用如下命令看到它的內(nèi)容,而不需要耗費 CPU 資源來解壓縮:

xarexec -m A-953bc.xar

這個命令會打印出一個臨時目錄,是 XAR 文件的 mount point。

分層

如果我們現(xiàn)在修改了 A.py,那么不管是 build 成 tarball 還是 XAR,整個包都需要重新更新。

當(dāng)然,只要 build system 支持 cache,我們是不需要重新生成各個 *.so 文件的。

但是這個不解決我們需要重新分發(fā) .tar.gz 和 .xar 文件到集群的各個節(jié)點的麻煩。

之前節(jié)點上可能有老版本的 A-953bc87fe.{tar.gz,xar} 了,但是不能復(fù)用。為了復(fù)用 ,需要分層。

對于上面情況,我們可以根據(jù)模塊依賴關(guān)系圖,構(gòu)造多個 XAR 文件。

A-953bc.xar --> B-953bc.xar --> D-953bc.xar -\

            \-> C-953bc.xar --> E-953bc.xar --> F-953bc.xar

其中每個 XAR 文件里只有對應(yīng)的 build rule 產(chǎn)生的文件。比如,F(xiàn)-953bc.xar 里只有 F.so。

這樣,如果我們只修改了 A.py,則只有 A.xar 需要重新 build 和傳送到集群節(jié)點上。這個節(jié)點可以復(fù)用之前已經(jīng) cache 了的 {B,C,D,E,F}-953bc.xar 文件。

假設(shè)一個節(jié)點上已經(jīng)有 /packages/{A,B,C,D,E,F}-953bc.xar,我們是不是可以按照模塊依賴順序,運行 xarexec -m 命令,依次 mount 這些 XAR 文件到同一個 mount point 目錄,既可得到其中所有的內(nèi)容了呢?

很遺憾,不行。因為后一個 xarexec/mount 命令會報錯 —— 因為這個 mount point 已經(jīng)被前一個 xarexec/mount 命令占據(jù)了。

下面解釋為什么文件系統(tǒng) image 優(yōu)于 tarball。

那退一步,不用 XAR 了,用 ZIP 或者 tar.gz 不行嗎?可以,但是慢。我們可以把所有 .tar.gz 都解壓縮到同一個目錄里。

但是如果 A.py 更新了,我們沒法識別老的 A.py 并且替換為新的,而是得重新解壓所有 .tar.gz 文件,得到一個新的文件夾。而重新解壓所有的 {B,C,D,E,F}.tar.gz 很慢。

Overlay Filesystem

有一個申請的開源工具 fuse-overlayfs。它可以把幾個目錄“疊加”(overlay)起來。

比如下面命令把 /tmp/{A,B,C,D,E,F}-953bc 這幾個目錄里的內(nèi)容都“疊加”到 /pacakges/A-953bc 這個目錄里。

fuse-overlayfs -o \

  lowerdir="/tmp/A-953bc:/tmp/B-953bc:..." \

  /packages/A-953bc

而 /tmp/{A,B,C,D,E,F}-953bc 這幾個目錄來自 xarcexec -m /packages/{A,B,C,D,E,F}-953bc.xar。

請注意這里我引入了 overlay filesystem 的概念。為下文解釋 Docker 預(yù)備。fuse-overlayfs 是怎么做到這一點的呢?

當(dāng)我們訪問任何一個文件系統(tǒng)目錄,比如 /packages/A 的時候,我們使用的命令行工具(比如 ls )調(diào)用 system calls(比如 open/close/read/write) 來訪問其中的文件。

這些 system calls 和文件系統(tǒng)的 driver 打交道 —— 它們會問 driver:/packages/A 這個目錄里有沒有一個叫 A.py 的文件呀?

如果我們使用 Linux,一般來說,硬盤上的文件系統(tǒng)是 ext4 或者 btrfs。也就是說,Linux universal filesystem driver 會看看每個分區(qū)的文件系統(tǒng)是啥,然后把 system call 轉(zhuǎn)發(fā)給對應(yīng)的 ext4/btrfs driver 去處理。

一般的 filesystem drivers 和其他設(shè)備的 drivers 一樣運行在 kernel mode 里。

這是為什么一般我們運行 mount 和 umount 這類操作 filesystems 的命令的時候,都需要 sudo。而 FUSE 是一個在 userland 開發(fā) filesystem driver 的庫。

fuse-overlayfs 這命令利用 FUSE 這個庫,開發(fā)了一個運行在 userland 的 fuse-overlayfs driver。

當(dāng) ls 命令詢問這個 overlayfs driver /packages/A-953bc 目錄里有啥的時候,這個 fuse-overlayfs driver 記得之前用戶運行過 fuse-overlayfs 命令把 /tmp/{A,B,C,D,E}-953bc 這幾個目錄給疊加上去過,所以它返回這幾個目錄里的文件。

此時,因為 /tmp/{A,B,C,D,E}-953bc 這幾個目錄其實是 /packages/{A,B,C,D,E,F}-953bc.xar 的 mount points,所以每個 XAR 就相當(dāng)于一個 layer。

像 fuse-overlayfs driver 這樣實現(xiàn)把多個目錄“疊加”起來的 filesystem driver 被稱為 overlay filesystem driver,有時簡稱為 overlay filesystems。

Docker Image and Layer

上面說到用 overlay filesystem 實現(xiàn)分層。用過 Docker 的人都會熟悉一個 Docker image 由多層構(gòu)成。

當(dāng)我們運行 docker pull <image-name> 命令的時候,如果本機(jī)已經(jīng) cache 了這個 image 的一部分 layers,則省略下載這些 layers。這其實就是用 overlay filesystem 實現(xiàn)的。

Docker 團(tuán)隊開發(fā)了一個 filesystem(driver)叫做 overlayfs —— 這是一個特定的 filesystem 的名字。

顧名思義,Docker overlayfs 也實現(xiàn)了“疊加”(overlay)的能力,這就是我們看到每個 Docker image 可以有多個 layers 的原因。

Docker 的 overlayfs 以及它的后續(xù)版本 overlayfs2 都是運行在 kernel mode 里的。

這也是 Docker 需要機(jī)器的 root 權(quán)限的原因之一,而這又是 Docker 被詬病容易導(dǎo)致安全漏斗的原因。

有一個叫 btrfs 的 filesystem,是 Linux 世界里最近幾年發(fā)展很迅速的,用于管理硬盤效果很好。

這個 filesystem 的 driver 也支持 overlay。所以 Docker 也可以被配置為使用這個 filesystem 而不是 overlayfs。

不過只有 Docker 用戶的電腦的 local filesystem 是 btrfs 的時候,Docker 才能用 btrfs 在上面疊加 layers。

所以說,如果你用的是 macOS 或者 Windows,那肯定沒法讓 Docker 使用 btrfs 了。

不過如果你用的是 fuse-overlayfs,那就是用了一副萬靈藥了。只是通過 FUSE 在 userland 運行的 filesystem 的性能很一般,不過本文討論的情形對性能也沒啥需求。

其實 Docker 也可以被配置使用 fuse-overlayfs。Docker 支持的分層 filesystem 列表在這里 Docker storage drivers[7]。

為什么需要 Docker Image

總結(jié)上文所述,從編程到可以在集群上跑起來,我們要做幾個步驟:

  1. 編譯:把源碼編譯成可執(zhí)行的形式。
  2. 打包:把編譯結(jié)果納入一個“包”里,以便部署和分發(fā)
  3. 傳輸:通常是集群管理系統(tǒng)(Borg、Kubernetes、Tupperware 來做)。如果要在某個集群節(jié)點上啟動 container,則需要把“包”傳輸?shù)酱斯?jié)點上,除非這個節(jié)點曾經(jīng)運行過這個程序,已經(jīng)有包的 cache。
  4. 解包:如果“包”是 tarball 或者 zip,到了集群節(jié)點上之后需要解壓縮;如果“包”是一個 filesystem image,則需要 mount。

把源碼分成模塊,可以讓編譯這步充分利用每次修改只改動一小部分代碼的特點,只重新編譯被修改的模塊,從而節(jié)省時間。

為了節(jié)省 2,3 和 4 的時間,我們希望“包”是分層的。每一層最好只包含一個或者幾個代碼模塊。這樣,可以利用模塊之間的依賴關(guān)系,盡量復(fù)用容納底層模塊的“層”。

在開源的世界里,我們用 Docker image 支持分層的特點,一個基礎(chǔ)層可能只包括某個 Linux distribution(比如 CentOS)的 userland programs,如 ls、cat、grep 等。

在其上,可以有一個層包括 CUDA。再其上安裝 Python 和 PyTorch。再再之上的一層里是 GPT-3 模型的訓(xùn)練程序。

這樣,如果我們只是修改了 GPT-3 訓(xùn)練程序,則不需要重新打包和傳輸下面三層。

這里的邏輯核心是:存在“項目”(project)的概念。每個項目可以有自己的 repo,自己的 building system(GNU make、CMake、Buck、Bazel 等),自己的發(fā)行版本(release)。

所以每個項目的 release 裝進(jìn) Docker image 的一層 layer。與其前置多層合稱為一個 image。

為什么 Google 和 Facebook 不需要 Docker

經(jīng)過上述這么多知識準(zhǔn)備,請我們終于可以點題了。

因為 Google 和 Facebook 使用 monolithic repository,使用統(tǒng)一的 build system(Google Blaze 或者 Facebook Buck)。

雖然也可以利用“項目”的概念,把每個項目的 build result 裝入 Docker image 的一層。但是實際上并不需要。

利用 Blaze 和 Buck 的 build rules 定義的模塊,以及模塊之間依賴關(guān)系,我們可以完全去打包和解包的概念。

沒有了包,當(dāng)然就不需要 zip、tarball、以及 Docker image 和 layers 了。

直接把每個模塊當(dāng)做一個 layer 既可。如果 D.so 因為我們修改了 D.cpp 被重新編譯,那么只重新傳輸 D.so 既可,而不需要去傳輸一個 layer 其中包括 D.so。

于是,在 Google 和 Facebook 里,受益于 monolithic repository 和統(tǒng)一的 build 工具。

我們把上述四個步驟省略成了兩個:

  1. 編譯:把源碼編譯成可執(zhí)行的形式。
  2. 傳輸:如果某個模塊被重新編譯,則傳輸這個模塊。

Google 和 Facebook 沒在用 Docker

上一節(jié)說了 monolithic repo 可以讓 Google 和 Facebook 不需要 Docker image。

現(xiàn)實是 Google 和 Facebook 沒有在使用 Docker。這兩個概念有區(qū)別。

我們先說“沒在用”。歷史上,Google 和 Facebook 使用超大規(guī)模集群先于 Docker 和 Kubernetes 的出現(xiàn)。當(dāng)時為了打包方便,連 tarball 都沒有。

對于 C/C++ 程序,直接全靜態(tài)鏈接,根本沒有 *.so。于是一個 executable binary file 就是“包”了。

直到今天,大家用開源的 Bazel 和 Buck 的時候,仍然可以看到默認(rèn)鏈接方式就是全靜態(tài)鏈接。

Java 語言雖然是一種“全動態(tài)鏈接”的語言,不過其誕生和演進(jìn)扣準(zhǔn)了互聯(lián)網(wǎng)歷史機(jī)遇,其開發(fā)者發(fā)明 jar 文件格式,從而支持了全靜態(tài)鏈接。

Python 語言本身沒有 jar 包,所以 Blaze 和 Bazel 發(fā)明了 PAR 文件格式(英語叫 subpar),相當(dāng)于為 Python 設(shè)計了一個 jar。開源實現(xiàn)在這里[8]。

類似的,Buck 發(fā)明了 XAR 格式,也就是我上文所說的 squashfs image 前面加了一個 header。其開源實現(xiàn)在這里[9]。

Go 語言默認(rèn)就是全靜態(tài)鏈接的。在 Rob Pike 早期的一些總結(jié)里提到,Go 的設(shè)計,包括全靜態(tài)鏈接,基本就是繞坑而行,繞開 Google C/C++ 實踐中遇到過的各種坑。

熟悉 Google C++ style guide 的朋友們應(yīng)該感覺到了 Go 語法覆蓋了 guide 說的“應(yīng)該用的 C++ 語法”,而不支持 guide 說的 “不應(yīng)該用的 C++ 的部分”。

簡單的說,歷史上 Google 和 Facebook 沒有在用 Docker image,很重要的一個原因是,其 build system 對各種常見語言的程序都可以全靜態(tài)鏈接,所以可執(zhí)行文件就是“包”。

但這并不是最好的解法,畢竟這樣就沒有分層了。哪怕我只是修改了 main 函數(shù)里的一行代碼,重新編譯和發(fā)布,都需要很長時間,十分鐘甚至數(shù)十分鐘,要知道全靜態(tài)鏈接得到的可執(zhí)行文件往往大小以 GB 計。

所以全靜態(tài)鏈接雖然是 Google 和 Facebook 沒有在用 Docker 的原因之一,但是并不是一個好選擇。

所以也沒被其他公司效仿。大家還是更愿意用支持分層 cache 的 Docker image。

完美解法的技術(shù)挑戰(zhàn)

完美的解法應(yīng)該支持分層 cache(或者更精確的說是分塊 cache)。所以還是應(yīng)該用上文介紹的 monolithic repo 和統(tǒng)一 build system 的特點。

但是這里有一個技術(shù)挑戰(zhàn),build system 描述的模塊,而模塊通常比“項目”細(xì)粒度太多了。

以 C/C++ 語言為例,如果每個模塊生成一個 .so 文件,當(dāng)做一個“層”或者“塊”以便作為 cache 的單元,那么一個應(yīng)用程序可能需要的 .so 數(shù)量就太多了。

啟動應(yīng)用的時候,恐怕要花幾十分鐘來 resolve symbols 并且完成鏈接。

所以呢,雖然 monolithic repo 有很多好處,它也有一個缺點,不像開源世界里,大家人力的把代碼分解成“項目”。

每個項目通常是一個 GitHub repo,其中可以有很多模塊,但是每個項目里所有模塊 build 成一個 *.so 作為一個 cache 的單元。

因為一個應(yīng)用程序依賴的項目數(shù)量總不會太多,從而控制了 layer 的總數(shù)。

好在這個問題并非無解。既然一個應(yīng)用程序?qū)Ω鱾€模塊的依賴關(guān)系是一個 DAG,那么我們總可以想辦法做一個 graph partitioning,把這個 DAG 分解成不那么多的幾個子圖。

仍然以 C/C++ 程序為例,我們可以把每個子圖里的每個模塊編譯成一個 .a,而每個子圖里的所有 .a 鏈接成一個 *.so,作為一個 cache 的單元。

于是,如何設(shè)計這個 graph partitioning 算法就成了眼前最重要的問題了。

相關(guān)鏈接:

https://engineering.fb.com/2019/06/06/data-center-engineering/twine/

https://zhuanlan.zhihu.com/p/55452964

https://bazel.build/

https://buck.build/

https://github.com/facebookincubator/xar

https://tldp.org/HOWTO/SquashFS-HOWTO/creatingandusing.html

https://docs.docker.com/storage/storagedriver/select-storage-driver/

https://github.com/google/subpar

https://github.com/facebookincubator/xar

到此這篇關(guān)于Google和Facebook不使用Docker的原理解析的文章就介紹到這了,更多相關(guān)Google和Facebook不使用Docker內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

標(biāo)簽:連云港 運城 隴南 荊門 朝陽 遵義 面試通知 雞西

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Google和Facebook不使用Docker的原理解析》,本文關(guān)鍵詞  Google,和,Facebook,不,使用,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Google和Facebook不使用Docker的原理解析》相關(guān)的同類信息!
  • 本頁收集關(guān)于Google和Facebook不使用Docker的原理解析的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    快射av在线播放一区| 亚州色图欧美色图| 99亚偷拍自图区亚洲| 激情黄产视频在线免费观看| 日本www.色| 亚洲天堂中文在线| 亚洲精品人成电影网| 波多野结衣一区二区三区在线| 日韩高清欧美| 亚洲人成电影网站色…| 亚洲在线免费视频| 国产日韩欧美a| 九九在线高清精品视频| 曰批又黄又爽免费视频| 一级黄色免费在线观看| 懂色av一区二区三区四区五区| 日韩av中文在线| 在线成人私人影院| 欧美丰满嫩嫩电影| gogogo免费视频观看亚洲一| 99蜜桃臀久久久欧美精品网站| 91亚洲精品视频在线观看| 6080午夜不卡| 东方欧美亚洲色图在线| 四虎网站在线观看| 国内精品偷拍视频| 欧美精品乱人伦久久久久久| 久久精品亚洲成在人线av网址| 亚洲日本一区二区三区在线观看| 免费在线一级视频| 99久热这里只有精品视频免费观看| 国产一区二区在线视频你懂的| 久久99精品久久久水蜜桃| 国产亚洲高清在线观看| 国产日韩欧美精品一区| 中文字幕免费在线观看视频一区| 欧美激情视频免费看| 精品人伦一区二区| 超碰激情在线| 成人在线观看亚洲| 日韩精品不卡一区二区| 日韩不卡在线视频| 在线不卡免费视频| 国产一级性生活| 91日韩中文字幕| 国产精品中文久久久久久久| 国产99久一区二区三区a片| 青青久在线视频| 黄网在线免费| 色婷婷狠狠18| 国产欧美日韩精品丝袜高跟鞋| 天堂在线视频免费观看| 色哟哟国产精品免费观看| 久草免费资源站| 99这里都是精品| 乱亲女h秽乱长久久久| 亚洲伦理在线观看| 五月天激情图片| 国产精品无人区| 15—17女人毛片| 欧美日韩在线一二三| 四虎4hutv紧急入口| 亚洲性视频网址| 久久影院一区二区三区| 国产精品久久久久久久久果冻传媒| 国产伦精品一区二区三区四区视频_| 亚洲免费影视第一页| 成人免费观看在线观看| 亚洲人xxxx| 羞羞的视频在线看| 精品福利樱桃av导航| 偷拍欧美精品| 国产成人鲁色资源国产91色综| 国产精品扒开腿爽爽爽视频| 另类图片国产| 亚州精品国产| 亚洲最大成人在线| 黄色大片a级| 国产中文字幕视频| 日韩在线无毛| 9久re热视频在线精品| 日韩写真欧美这视频| 日韩欧美在线电影| 亚洲一级在线观看| 91精品国产综合久久香蕉的用户体验| 99热在线精品观看| 欧美大片va欧美在线播放| 亚洲丝袜精品| 久久久久亚洲精品国产| 中文精品99久久国产香蕉| 成人国产免费电影| av在线电影免费观看| 日韩精品午夜视频| av电影免费在线观看| 台湾十八成人网| 精品免费99久久| 一区二区三区自拍| 欧美日韩不卡合集视频| 亚洲 欧美 精品| 岛国片在线看| 精品无人区卡一卡二卡三乱码免费卡| 久久久久久久9| 欧美亚洲国产视频| 亚洲综合激情五月| 亚洲欧美另类久久久精品| 欧美激情另类| 9国产精品视频| 久热久精久品这里在线观看| 亚洲a成人v| 欧美一区二区在线视频| 黄色av免费播放| 96sao在线精品免费视频| www.色精品| 91精品丝袜国产高跟在线| 久久久久毛片免费观看| 欧美精彩视频一区二区三区| 亚洲天堂网在线播放| 亚洲欧美在线人成swag| 亚洲一区国产| 日韩专区一卡二卡| 成年人看的羞羞网站| 91免费观看视频在线| 国产精品13p| 国产91色在线|亚洲| 欧美大奶一区二区| 日韩国产精品久久久久久亚洲| 一本大道久久a久久综合婷婷| 手机看片国产1024| 天天干天天玩天天操| 90岁老太婆乱淫| 欧美精品一区二区久久| 国产偷人爽久久久久久老妇app| 欧美丰满日韩| 先锋影音av资源站| 欧美激情一区二区三区四区| 在线观看黄色| 无码人妻精品一区二区| 李宗瑞91在线正在播放| 超碰97人人在线| 四虎成人欧美精品在永久在线| 日日干夜夜草| 3atv在线一区二区三区| 99久久精品免费看国产交换| 亚洲美女视频网| 羞羞的视频在线看| 国产成人av一区二区三区不卡| 九九精品视频在线看| 青青草国产成人久久91网| 欧美一a一片一级一片| 国产精品无码无卡无需播放器| 日本福利小视频| 亚洲午夜在线电影| 亚洲乱码精品久久久久..| 91一区二区在线| 一本色道久久88综合亚洲精品ⅰ| 国产农村妇女精品一区| 114美女做爰视频在线| 一级毛片视频| 亚洲私拍视频| 欧美人与牲禽动交com| 人妻精品无码一区二区三区| 日韩毛片久久久| 亚洲欧洲成人精品av97| 又黄又爽又色视频| 国产精品久久久久久久久果冻传媒| 亚洲国产精品一区二区第一页| 欧美国产日本在线| 亚洲激情网站免费观看| 欧美日本中文| 青青草国产成人久久91网| 亚洲国产精品成人久久蜜臀| 韩国三级午夜理伦三级三| 亚洲欧美日韩国产综合| 国产欧美一区二区白浆黑人| 午夜精品亚洲一区二区三区嫩草| 国产v亚洲v天堂无码久久久| 国产精品18久久久久久首页狼| 香蕉人妻av久久久久天天| 制服丝袜中文字幕亚洲| 美乳美女在线观看香蕉| 亚洲人妖av一区二区| 麻豆av在线免费看| 四虎永久在线精品免费一区二区| 香蕉视频1024| av成人综合网| 欧美精品久久一区二区三区| 久久精品无码专区| 九九热视频精品在线观看| 国产在线免费av| 久久久成人精品一区二区三区| 欧洲精品一区二区| 黄色av免费在线观看| 理论片日本一区| 亚洲欧美在线精品| fc2ppv在线播放| ...av二区三区久久精品| 久久久青草婷婷精品综合日韩| 97欧洲一区二区精品免费| 国产精品视频一区二区三区四蜜臂| 欧美日本一区二区视频在线观看| 亚洲色图狠狠干| 3d动漫精品啪啪一区二区三区免费| avhd101老司机| 国产在线播放一区三区四| 日韩欧美国产激情| 污污的网站18| 91嫩草视频在线观看| 久无码久无码av无码| 美女福利视频导航| 国产女精品视频网站免费| 丝袜美腿诱惑一区二区三区| 欧美成人aa大片| 在线观看黄色| 国产丝袜视频在线播放| 久久综合色占| 国产在线精品一区在线观看麻豆| 国产精品一区二区免费福利视频| 牛人国产偷窥女洗浴在线观看| 秋霞午夜理伦电影在线观看| 日产精品一区二区| 中文字幕手机在线视频| 成人高潮片免费视频| 国产成人免费在线观看视频| 久久人人爽人人人人片| 丝袜一区二区三区| 亚洲天堂精品一区| 在线免费av片| 欧美丰满少妇人妻精品| 亚洲一区二区在线播放相泽| 免费观看的av| 欧美日韩在线免费播放| 小香蕉视频在线| 国产成人精品999在线观看| 亚洲天堂中文字幕在线| 亚洲久久在线观看| 欧美日本免费| 欧美高清视频手机在在线| 水蜜桃av无码| 色综合久久久久综合| 自拍偷拍欧美精品| 亚洲国产精品成人天堂| 亚洲春色在线| 欧美一区二区三区粗大| 黄色免费看视频| 国产乱子轮xxx农村| 亚洲一区二区三区无码久久| 午夜视频国产| 18欧美乱大交| 第一福利在线视频| 国产模特精品视频久久久久| 丰满人妻一区二区| 国产美女久久久久| jlzzjlzz亚洲女人18| 色婷婷激情综合| 成人18在线| 欧美va亚洲va在线观看蝴蝶网| 色一区二区三区| 亚洲综合av网| 黄网站免费久久| 涩涩日韩在线| 97影视大全免费追剧大全在线观看| 日韩欧美电影一区二区| 国产综合精品| 欧美黑人性受xxxx精品| 日韩精品视频观看| 欧美黄色片在线观看| 香蕉精品视频在线| 中文字幕第一页在线视频| 久久综合九色综合久久久精品综合| 麻豆视频久久| 久久久久亚洲av无码网站| 美女又爽又黄免费视频| 涩爱av在线播放一区二区| 免费不卡的av| 亚洲911精品成人18网站| 成人免费91在线看| 粗大黑人巨茎大战欧美成人| 夜色福利资源站www国产在线视频| 国产精品高潮呻吟视频| 亚洲av无码成人精品区| 爱豆国产剧免费观看大全剧苏畅| 天天性天天草| 久久色视频免费观看| 欧美视频一区二| 在线免费看黄av| 亚洲国产精品女人| 亚洲av无码乱码国产麻豆| 五月精品在线| 日本熟女毛茸茸| 欧美国产激情一区二区三区蜜月| 豆国产97在线 | 亚洲| 国产亚洲精品久久久久久无几年桃| 日本美女视频网站| 国产精品高潮呻吟久久av无限| 成人在线观看视频网站| 91浏览器在线视频| xxx.xxx欧美| 波多野结衣av无码| 男人天堂va| 亚洲国产日韩一级| 日本在线视频免费| 日本麻豆一区二区三区视频| 亚洲影院在线| 国产资源精品在线观看| 久久香蕉综合色| 星空影院最新电视剧免费观看| aaa黄色大片| 国产一区二区播放| 美女网站视频久久| 久99九色视频在线观看| 日韩中文在线观看| 欧美激情亚洲视频| 亚洲日本成人在线观看| 国产精品天堂| 国产亚av手机在线观看| 成人精品在线视频| 欧美xxxx黑人又粗又长密月| 国产精品视频免费看| 精品人妻一区二区三区麻豆91| 亚洲qvod图片区电影| 中文字幕永久在线| 亚洲精品综合网| 天堂中文在线官网| 国产精品视频免费观看www| 日韩中文字幕久久久经典网| 丰满少妇xoxoxo视频| 亚洲自拍第二页| 一区二区免费在线视频|