以運維和開發的視角縱觀Docker

      網友投稿 723 2025-03-31

      本章的初衷是在繼續深入研究Docker之前,對Docker進行一個整體介紹。

      本章主要包含兩部分內容。

      運維(Ops)視角。

      開發(Dev)視角。

      在運維視角中,主要包括下載鏡像、運行新的容器、登錄新容器、在容器內運行命令,以及銷毀容器。

      在開發視角中,更多關注與應用相關的內容。本書會從GitHub拉取一些應用代碼,解釋其中的Dockerfile,將應用容器化,并在容器中運行它們。

      通過上面兩部分內容,讀者可以從整體上理解Docker究竟是什么,以及主要組件之間是如何相互配合的。推薦讀者對開發和運維兩部分內容都要閱讀。

      讀者無須因為不了解本章部分內容而擔心。本書并不準備通過本章的介紹讓讀者成為專家。本章主要目的是給讀者一個宏觀概念——這樣在后續章節中介紹更細節的內容時,讀者能明白各部分之間是如何交互的。

      為了能完成本章節閱讀,讀者只需一個可連接到互聯網的Docker主機。Docker節點可以是Linux或者Windows,并且無論這個節點是筆記本上的虛擬機,還是公有云上的一個實例,亦或是數據中心的物理機都沒有關系。只需要這個節點能運行Docker并且連接到互聯網即可。本書接下來的例子涵蓋了Linux和Windows!

      此外還有一種快速啟動Docker的方式,是Play With Docker(PWD)。Play With Docker是一個基于Web界面的Docker環境,并且可以免費使用。只需要瀏覽器就可以使用(可能需要讀者用Docker Hub賬戶登錄)。這也是我最喜歡的啟動臨時Docker環境的方式。

      4.1 運維視角

      當讀者安裝Docker的時候,會涉及兩個主要組件:Docker客戶端和Docker daemon(有時也被稱為“服務端”或者“引擎”)。

      daemon實現了Docker引擎的API。

      以運維和開發的視角縱觀Docker

      使用Linux默認安裝時,客戶端與daemon之間的通信是通過本地IPC/UNIX Socket完成的(/var/run/docker.sock);在Windows上是通過名為npipe:////./pipe/docker_engine的管道(pipe)完成的。讀者可以使用docker version命令來檢測客戶端和服務端是否都已經成功運行,并且可以互相通信。

      >?docker?version Client: ?Version:???????18.01.0-ce ?API?version:???1.35 ?Go?version:????go1.9.2 ?Git?commit:????03596f5 ?Built:?Wed?Jan?10?20:11:05?2018 ?OS/Arch:???????linux/amd64 ?Experimental:??false ?Orchestrator:??swarm Server: ?Engine: ??Version:??????18.01.0-ce ??API?version:??1.35?(minimum?version?1.12) ??Go?version:???go1.9.2 ??Git?commit:???03596f5 ??Built:????????Wed?Jan?10?20:09:37?2018 ??OS/Arch:??????linux/amd64 ??Experimental:?false

      如果讀者能成功獲取來自客戶端和服務端的響應,那么可以繼續后面的操作。如果讀者正在使用 Linux,并且服務端返回了異常響應,則可嘗試在命令的前面加上?sudo——sudo docker version。如果加上sudo之后命令正常運行,那么讀者需要將當前用戶加入到docker用戶組,或者給本書后面的命令都加上sudo前綴。

      4.1.1 鏡像

      將Docker鏡像理解為一個包含了OS文件系統和應用的對象會很有幫助。如果讀者實際操作過,就會認為與虛擬機模板類似。虛擬機模板本質上是處于關機狀態的虛擬機。在Docker世界中,鏡像實際上等價于未運行的容器。如果讀者是一名開發者,可以將鏡像比作類(Class)。

      在Docker主機上運行docker image ls命令。

      $?docker?image?ls REPOSITORY????TAG?????IMAGE?ID?????CREATED?????SIZE

      如果讀者運行命令環境是剛完成Docker安裝的主機,或者是Play With Docker,那么Docker主機中應當沒有任何鏡像,命令輸出內容會如上所示。

      在Docker主機上獲取鏡像的操作被稱為拉取(pulling)。如果使用Linux,那么會拉取ubuntu:latest鏡像;如果使用Windows,則會拉取microsoft/powershell:nanoserver鏡像。

      latest:?Pulling?from?library/ubuntu50aff78429b1:?Pull?completef6d82e297bce:?Pull?complete275abb2c8a6f:?Pull?complete9f15a39356d6:?Pull?completefc0342a94c89:?Pull?completeDigest:?sha256:fbaf303...c0ea5d1212Status:?Downloaded?newer?image?for?ubuntu:latest

      再次運行docker image ls命令來查看剛剛拉取的鏡像。

      $?docker?images REPOSITORY???????TAG??????IMAGE?ID???????CREATED???????SIZE ubuntu???????????latest???00fd29ccc6f1???3?weeks?ago???111MB

      關于鏡像的存儲位置以及鏡像內部構成,本書會在后續的章節中詳細介紹。現在,讀者只需知道鏡像包含了基礎操作系統,以及應用程序運行所需的代碼和依賴包。剛才拉取的ubuntu鏡像有一個精簡版的Ubuntu Linux文件系統,其中包含部分Ubuntu常用工具。而Windows示例中拉取的microsoft/powershell鏡像,則包含了帶有PowerShell的Windows Nano Server操作系統。

      如果拉取了如nginx或者microsoft/iis這樣的應用容器,則讀者會得到一個包含操作系統的鏡像,并且在鏡像中還包括了運行Nginx或IIS所需的代碼。

      重要的是,Docker的每個鏡像都有自己的唯一ID。用戶可以通過引用鏡像的ID或名稱來使用鏡像。如果用戶選擇使用鏡像ID,通常只需要輸入ID開頭的幾個字符即可——因為ID是唯一的,Docker知道用戶想引用的具體鏡像是哪個。

      4.1.2 容器

      到目前為止,讀者已經擁有一個拉取到本地的鏡像,可以使用docker container run命令從鏡像來啟動容器。

      在Linux中啟動容器的命令如下。

      $?docker?container?run?-it?ubuntu:latest?/bin/bash root@6dc20d508db0:/#

      在Windows中啟動容器的命令如下。

      >?docker?container?run?-it?microsoft/powershell:nanoserver?pwsh.exeWindows?PowerShellCopyright?(C)?2016?Microsoft?Corporation.?All?rights?reserved.PS?C:\>

      仔細觀察上面命令的輸出內容,會注意到每個實例中的提示符都發生了變化。這是因為-it參數會將Shell切換到容器終端——現在已經位于容器內部了!

      接下來分析一下docker container run命令。docker container run告訴Docker daemon啟動新的容器。其中-it參數告訴Docker開啟容器的交互模式并將讀者當前的Shell連接到容器終端(在容器章節中會詳細介紹)。接下來,命令告訴Docker,用戶想基于ubuntu:latest鏡像啟動容器(如果用戶使用Windows,則是基于microsoft/powershell:nanoserver鏡像)。最后,命令告訴Docker,用戶想要在容器內部運行哪個進程。對于Linux示例來說是運行Bash Shell,對于Windows示例來說則是運行PowerShell。

      在容器內部運行ps命令查看當前正在運行的全部進程。

      Linux示例如下。

      root@6dc20d508db0:/#?ps?-elf F?S?UID????PID??PPID???NI?ADDR?SZ?WCHAN??STIME?TTY??TIME?CMD4?S?root?????1?????0????0?-??4560?wait???13:38??????00:00:00?/bin/bash0?R?root?????9?????1????0?-??8606?-??????13:38??????00:00:00?ps?-elf

      Windows示例如下。

      PS?C:\>?ps Handles???NPM(K)???PM(K)???WS(K)???CPU(s)?????Id???SI?ProcessName -------???------???-----???-----???------?????--???--?-----------??????0????????5?????964????1292?????0.00???4716????4?CExecSvc??????0????????5?????592?????956?????0.00???4524????4?csrss??????0????????0???????0???????4???????????????0????0?Idle??????0???????18????3984????8624?????0.13????700????4?lsass??????0???????52???26624???19400?????1.64???2100????4?powershell??????0???????38???28324???49616?????1.69???4464????4?powershell??????0????????8????1488????3032?????0.06???2488????4?services??????0????????2?????288?????504?????0.00???4508????0?smss??????0????????8????1600????3004?????0.03????908????4?svchost??????0???????12????1492????3504?????0.06???4572????4?svchost??????0???????15???20284???23428?????5.64???4628????4?svchost??????0???????15????3704????7536?????0.09???4688????4?svchost??????0???????28????5708????6588?????0.45???4712????4?svchost??????0???????10????2028????4736?????0.03???4840????4?svchost??????0???????11????5364????4824?????0.08???4928????4?svchost??????0????????0?????128?????136????37.02??????4????0?System??????0????????7?????920????1832?????0.02???3752????4?wininit??????0????????8????5472???11124?????0.77???5568????4?WmiPrvSE

      Linux容器中僅包含兩個進程。

      PID 1:代表/bin/bash進程,該進程是通過docker container run命令來通知容器運行的。

      PID 9:代表ps -elf進程,查看當前運行中進程所使用的命令/程序。

      命令輸出中展示的ps -elf進程存在一定的誤導,因為這個程序在ps命令退出后就結束了。這意味著容器內長期運行的進程其實只有/bin/bash。

      Windows 容器運行中的進程會更多,這是由 Windows 操作系統工作方式決定的。雖然Windows容器中的進程比Linux容器要多,但與常見的Windows服務器相比,其進程數量卻是明顯偏少的。

      按Ctrl-PQ組合鍵,可以在退出容器的同時還保持容器運行。這樣Shell就會返回到Docker主機終端。可以通過查看Shell提示符來確認。

      現在讀者已經返回到Docker主機的Shell提示符,再次運行ps命令。

      Linux示例如下。

      $?ps?-elf F?S?UID???????PID??PPID????NI?ADDR?SZ?WCHAN??TIME?CMD4?S?root????????1?????0?????0?-??9407?-??????00:00:03?/sbin/init1?S?root????????2?????0?????0?-?????0?-??????00:00:00?[kthreadd]1?S?root????????3?????2?????0?-?????0?-??????00:00:00?[ksoftirqd/0]1?S?root????????5?????2?????-20?????0?-??????00:00:00?[kworker/0:0H]1?S?root????????7?????2????-0?-?????0?-??????00:00:00?[rcu_sched] 0?R?ubuntu??22783?22475?????0?-??9021?-??????00:00:00?ps?-elf

      Windows示例如下。

      >?ps Handles???NPM(K)????PM(K)????WS(K)????CPU(s)?????Id??SI?ProcessName -------???------????-----????-----????------?????--??--?-----------????220???????11?????7396?????7872??????0.33???1732???0?amazon-ssm-agen?????84????????5??????908?????2096??????0.00???2428???3?CExecSvc?????87????????5??????936?????1336??????0.00???4716???4?CExecSvc????203???????13?????3600????13132??????2.53???3192???2?conhost????210???????13?????3768????22948??????0.08???5260???2?conhost????257???????11?????1808??????992??????0.64????524???0?csrss????116????????8?????1348???????580?????0.08????592???1?csrss?????85????????5??????532??????1136?????0.23???2440???3?csrss????242???????11?????1848???????952?????0.42???2708???2?csrss?????95????????5??????592???????980?????0.00???4524???4?csrss????137????????9?????7784??????6776?????0.05???5080???2?docker????401???????17????22744?????14016????28.59???1748???0?dockerd????307???????18????13344??????1628?????0.17????936???1?dwm ???????1888????????0??????128???????136????37.17??????4???0?System????272???????15?????3372??????2452?????0.23???3340???2?TabTip?????72????????7?????1184?????????8?????0.00???3400???2?TabTip32????244???????16?????2676??????3148?????0.06???1880???2?taskhostw????142????????7?????6172??????6680?????0.78???4952???3?WmiPrvSE????148????????8?????5620?????11028?????0.77???5568???4?WmiPrvSE

      可以看到與容器相比,Docker主機中運行的進程數要多很多。Windows容器中運行的進程要遠少于Windows主機,Linux容器中的進程數也遠少于Linux主機。

      在之前的步驟當中,是使用Ctrl-PQ組合鍵來退出容器的。在容器內部使用該操作可以退出當前容器,但不會殺死容器進程。讀者可以通過docker container ls命令查看系統內全部處于運行狀態的容器。

      $?docker?container?lsCONTAINER?ID???IMAGE??????????COMMAND??????CREATED??STATUS????NAMES e2b69eeb55cb???ubuntu:latest??"/bin/bash"??7?mins???Up?7?min??vigilant_borg

      上述的輸出顯示只有一個運行中的容器。這就是前面示例中創建的那個容器。輸出中有該容器,證明了容器在退出后依然是運行的。讀者可以看到這個進程是7min之前創建的,并且一直在運行。

      4.1.3 連接到運行中的容器

      執行docker container exec命令,可以將Shell連接到一個運行中的容器終端。因為之前示例中的容器仍在運行,所以下面的示例會創建到該容器的新連接。

      Linux示例如下。

      $?docker?container?exec?-it?vigilant_borg?bash root@e2b69eeb55cb:/#

      示例中的容器名為“vigilant_brog”。讀者環境中的容器名稱會不同,所以請記得將“vigilant_brog”替換為自己Docker主機上運行中的容器名稱或者ID。

      Windows示例如下。

      >?docker?container?exec?-it?pensive_hamilton?pwsh.exe Windows?PowerShell Copyright?(C)?2016?Microsoft?Corporation.?All?rights?reserved. PS?C:\>

      本例中使用的容器為“pensive_hamilton”。同樣,讀者環境中的容器名稱會不同,所以請記得將“pensive_hamilton”替換為自己Docker主機上運行中的容器名稱或者ID。

      注意,Shell提示符又發生了變化。此時已登錄到了容器內部。

      docker container exec命令的格式是docker container exec ??。在示例中,將本地Shell連接到容器是通過-it參數實現的。本例中使用名稱引用容器,并且告訴Docker運行Bash Shell(在Windows示例中是PowerShell)。使用十六進制ID的方式也可以很容易地引用具體容器。

      再次使用Ctrl-PQ組合鍵退出容器。

      Shell提示符應當退回到Docker主機中。

      再次運行docker container ls命令來確認容器仍處于運行狀態。

      $?docker?container?lsCONTAINER?ID???IMAGE??????????COMMAND??????CREATED??STATUS????NAMES e2b69eeb55cb???ubuntu:latest??"/bin/bash"??9?mins???Up?9?min??vigilant_borg

      通過docker container stop和docker container rm命令來停止并殺死容器。切記需要將示例中的名稱/ID替換為讀者自己的容器對應的名稱和ID。

      $?docker?container?stop?vigilant_borg vigilant_borg $?docker?container?rm?vigilant_borg vigilant_borg

      通過運行docker container ls命令,并指定-a參數來確認容器已經被成功刪除。添加-a的作用是讓Docker列出所有容器,甚至包括那些處于停止狀態的。

      $?docker?container?ls?-aCONTAINER?ID????IMAGE????COMMAND????CREATED????STATUS????PORTS????NAMES

      4.2 開發視角

      容器即應用!

      在本節中,會分析一份應用代碼中的Dockerfile并將其容器化,最終以容器的方式運行。相關代碼可從本書配套資源或我的Github主頁中獲取。

      本節接下來的內容會基于 Linux 示例進行演示。但其實兩個示例中都容器化了相同的Web 應用代碼,所以步驟也是一樣的。

      進入到倉庫文件目錄之下,查看其內容。

      $?cd?psweb $?ls?-l total?28-rw-rw-r--?1?ubuntu?ubuntu??341?Sep?29?12:15?app.js -rw-rw-r--?1?ubuntu?ubuntu??216?Sep?29?12:15?circle.yml -rw-rw-r--?1?ubuntu?ubuntu??338?Sep?29?12:15?Dockerfile -rw-rw-r--?1?ubuntu?ubuntu??421?Sep?29?12:15?package.json -rw-rw-r--?1?ubuntu?ubuntu??370?Sep?29?12:15?README.md drwxrwxr-x?2?ubuntu?ubuntu?4096?Sep?29?12:15?test drwxrwxr-x?2?ubuntu?ubuntu?4096?Sep?29?12:15?views

      對于Windows示例,讀者需要cd到dotnet-docker-samples\aspnetapp目錄當中。

      Linux的示例是一個簡單的Node.js Web應用。Windows示例是一個簡單的ASP.NET Web應用。

      每個倉庫中都包含一個名為Dockerfile的文件。Dockerfile是一個純文本文件,其中描述了如何將應用構建到Docker鏡像當中。

      查看Dockerfile的全部內容。

      $?cat?DockerfileFROM?alpineLABEL?maintainer="nigelpoulton@hotmail.com"RUN?apk?add?--update?nodejs?nodejs-npmCOPY?.?/srcWORKDIR?/srcRUN??npm?installEXPOSE??8080ENTRYPOINT?["node",?"./app.js"]

      Windows示例中的Dockerfile內容會有所不同。但是,這些區別在現階段并不重要。關于Dockerfile的更多細節本書會在接下來的章節中進行詳細介紹。現在,只需要知道Dockerfile的每一行都代表一個用于構建鏡像的指令即可。

      使用docker image build命令,根據Dockerfile中的指令來創建新的鏡像。示例中新建的Docker鏡像名為test:latest。

      一定要在包含應用代碼和Dockerfile的目錄下執行這些命令。

      $?docker?image?build?-t?test:latest?. Sending?build?context?to?Docker?daemon?74.75kB Step?1/8?:?FROM?alpine latest:?Pulling?from?library/alpine88286f41530e:?Pull?completeDigest:?sha256:f006ecbb824...0c103f4820a417d Status:?Downloaded?newer?image?for?alpine:latest ?--->?76da55c8019dSuccessfully?built?f154cb3ddbd4 Successfully?tagged?test:latest

      {注:}

      Windows示例構建可能花費比較長的時間。構建時間長短是由構建過程中要拉取的鏡像大小和復雜度決定的。

      一旦構建完成,就可以確認主機上是否存在test:latest鏡像。

      $?docker?image?ls REPO?????TAG????????IMAGE?ID?????????CREATED?????????SIZETest?????latest?????f154cb3ddbd4?????1?minute?ago????55.6MB ...

      讀者現在已經擁有一個新的Docker鏡像,其中包含了應用程序。

      從鏡像啟動容器,并測試應用。

      Linux代碼如下。

      $?docker?container?run?-d?\??--name?web1?\ ??--publish?8080:8080?\ ??test:latest

      打開Web瀏覽器,在地址欄中輸入容器運行所在的Docker主機的DNS名稱或者IP地址,并在后面加上端口號8080。然后就能看到圖4.1的Web頁面。

      如果讀者使用的是Windows示例或者Mac版Docker,則需要將地址替換為localhost:8080或者127.0.0.1:8080;如果讀者使用的是Play with Docker,需要單擊終端界面上的8080超鏈接。

      圖4.1 Linux系統測試應用Web界面

      Windows代碼如下。

      >?docker?container?run?-d?\??--name?web1?\ ??--publish?8080:80?\ ??test:latest

      打開Web瀏覽器,在地址欄中輸入容器運行所在的Docker主機的DNS名稱或者IP地址,并在后面加上端口號8080,然后就能看到圖4.2的Web頁面。

      圖4.2 Windows系統測試應用Web界面

      如果讀者使用的是Windows示例或者Mac版Docker,則可參考上面的規則。

      讀者已經成功將應用代碼構建到了Docker鏡像當中,然后以容器的方式啟動該鏡像,這個過程叫作“應用容器化”。

      4.3 本章小結

      在運維部分,我們下載了Docker鏡像,啟動容器并且登錄到容器內部執行相應的命令,最后停止容器并刪除。

      在開發部分,我們完成了簡單應用的容器化過程:從GitHub拉取應用源代碼,并且通過Dockerfile中的指令,將應用代碼構建到鏡像之中。接著運行了該容器化應用。

      本章的整體介紹能幫助讀者更好地理解接下來的章節,包括鏡像與容器相關細節。

      本文摘自:《深入淺出Docke》

      《深入淺出Docker》([英],Nigel,Poulton(奈吉爾·波爾頓))

      全書分為17章,從Docker概覽和Docker技術兩部分進行全面解析,深入淺出地介紹了Docker的相關知識,清晰詳細的操作步驟結合大量的實際代碼幫助讀者學以致用,將Docker知識應用到真實的項目開發當中。

      ###本書特色

      零基礎起步,幫助讀者快速建立Docker技術知識體系

      抽絲剝繭,層層深入,清晰透徹地闡述復雜的邏輯

      涵蓋廣泛,從安裝入門到應用部署,展示Docker應用全景

      ###目錄結構

      軟件開發

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:辦公表格軟件下載免費安裝(電腦辦公表格軟件免費)
      下一篇:如何將圖片/圖像鎖定到Excel中的單元格或內部單元格?
      相關文章
      国产成人亚洲精品影院| 亚洲国产精品一区二区三区久久 | 亚洲电影国产一区| 国产精品亚洲精品日韩已方| 亚洲A丁香五香天堂网 | 亚洲精品无码久久久久牙蜜区| 亚洲制服丝袜第一页| 亚洲人成网站18禁止久久影院| 亚洲综合激情视频| 久久久久亚洲AV无码观看| 久久精品国产亚洲AV电影 | 日韩亚洲人成网站| 亚洲?V无码成人精品区日韩| 五月天婷亚洲天综合网精品偷| 亚洲av手机在线观看| 亚洲精品99久久久久中文字幕 | 国产区图片区小说区亚洲区| gogo全球高清大胆亚洲| 亚洲精品人成无码中文毛片 | 在线观看国产区亚洲一区成人| 国产亚洲精品无码拍拍拍色欲| 亚洲综合图色40p| 亚洲av无码一区二区三区网站| 亚洲AV日韩AV永久无码久久| 久久久无码精品亚洲日韩蜜臀浪潮| 亚洲黄色片在线观看| 亚洲导航深夜福利| 亚洲www77777| 久久久亚洲精华液精华液精华液| 青青青亚洲精品国产| 亚洲男人av香蕉爽爽爽爽| 亚洲永久精品ww47| 亚洲AV人无码综合在线观看| 18亚洲男同志videos网站| 亚洲不卡在线观看| 亚洲αⅴ无码乱码在线观看性色| 偷自拍亚洲视频在线观看| 综合亚洲伊人午夜网| 内射干少妇亚洲69XXX| 亚洲伊人精品综合在合线| 亚洲精品无码高潮喷水A片软|