容器精华问答 | Docker和虚拟机有什么差别?
戳藍字“CSDN云計算”關注我們哦!
容器技術是這兩年熱門的話題,因為容器技術給我們帶來了很多方便的地方,節約了不少成本,不管是在運維還是開發上。今天,就讓我們來看看關于容器更加有深度的問題吧。
1
Q:宿主如果和容器系統不同的話,那不是和虛擬機一樣,一層層的調用,那么Docker和虛擬機還有什么差別?
A:要把Windows和Linux分清楚,更要把內核(kernel)和用戶空間(userland)分清楚。容器內的進程是直接運行于宿主內核的,這點和宿主進程一致,只是容器的userland不同,容器的?userland由容器鏡像提供,也就是說鏡像提供了rootfs。假設宿主是Ubuntu,容器是CentOS。CentOS?容器中的進程會直接向Ubuntu宿主內核發送syscall,而不會直接或間接的使用任何?Ubuntu?的?userland?的庫。
這點和虛擬機有本質的不同,虛擬機是虛擬環境,在現有系統上虛擬一套物理設備,然后在虛擬環境內運行一個虛擬環境的操作系統內核,在內核之上再跑完整系統,并在里面調用進程。
還以上面的例子去考慮,虛擬機中,CentOS的進程發送syscall內核調用,該請求會被虛擬機內的CentOS的內核接到,然后CentOS內核訪問虛擬硬件時,由虛擬機的服務軟件截獲,并使用宿主系統,也就是Ubuntu的內核及userland的庫去執行。
而且,Linux和Windows在這點上非常不同。Linux的進程是直接發syscall的,而Windows則把?syscall隱藏于一層層的DLL服務之后,因此Windows的任何一個進程如果要執行,不僅僅需要 Windows內核,還需要一群服務來支撐,所以如果Windows要實現類似的機制,容器內將不會像Linux這樣輕量級,而是非常臃腫。看一下微軟移植的Docker就非常清楚了。
所以不要把Docker和虛擬機弄混,Docker容器只是一個進程而已,只不過利用鏡像提供的?rootfs提供了調用所需的userland庫支持,使得進程可以在受控環境下運行而已,它并沒有虛擬出一個機器出來。
Q:如果 Docker 升級或者重啟的話,那容器是不是都會被停掉然后重啟啊?
? ? ? A:在?1.12?以前的版本確實如此,但是從?1.12?開始,Docker 引擎加入了?--live-restore?參數,使用該參數可以避免引擎升級、重啟導致容器停止服務的情況。
? ? ? ?默認情況該功能不會被啟動,如需啟動,需要配置?docker?服務配置文件。比如?Ubuntu 16.04?這類?systemd?的系統,可以修改?/etc/systemd/system/multi-user.target.wants/docker.service?文件,在?ExecStart=?后面配置上?--live-restore:
? ? 上面的格式中使用了行尾?\?的換行形式,這點和?bash?腳本一樣,systemd?支持這種換行形式,如對此不了解可以先去學習?bash?程序設計。
? ?需要注意的是,--live-restore?和?Swarm Mode?不兼容,所以在集群環境中不要使用。實際上集群環境也不用擔心某個服務器重啟的問題,因為其上的服務都會被調度到別的節點上,因此服務并不會被中斷。
? ? ??Q:怎么固定容器 IP 地址?每次重啟容器都要變化 IP 地址怎么辦?
? ? ? A:一般情況是不需要指定容器 IP 地址的。這不是虛擬主機,而是容器。其地址是供容器間通訊的,容器間則不用 IP 直接通訊,而使用容器名、服務名、網絡別名。
? ? 為了保持向后兼容,docker run?在不指定?--network?時,所在的網絡是?default bridge,在這個網絡下,需要使用?--link?參數才可以讓兩個容器找到對方。
? ? ? ?但這是有局限性的,因為這個時候使用的是?/etc/hosts?靜態文件來進行的解析,比如一個主機掛了后,重新啟動IP可能會改變。雖然說這種改變Docker是可能更新/etc/hosts文件,但是這有諸多問題,可能會因為競爭冒險導致?/etc/hosts?文件損毀,也可能還在運行的容器在取得?/etc/hosts?的解析結果后,不再去監視該文件是否變動。種種原因都可能會導致舊的主機無法通過容器名訪問到新的主機。
? ? ? ?如果可能不要使用這種過時的方式,而是用下面說的自定義網絡的方式。而對于新的環境(Docker 1.10以上),應該給容器建立自定義網絡,同一個自定義網絡中,可以使用對方容器的容器名、服務名、網絡別名來找到對方。這個時候幫助進行服務發現的是Docker 內置的DNS。所以,無論容器是否重啟、更換IP,內置的DNS都能正確指定到對方的位置。
Q:如何修改容器的?/etc/hosts?文件?
A:容器內的?/etc/hosts?文件不應該被隨意修改,如果必須添加主機名和 IP 地址映射關系,應該在?docker run?時使用?--add-host?參數,或者在?docker-compose.yml?中添加?extra_hosts?項。不過在用之前,應該再考慮一下真的需要修改?/etc/hosts?么?如果只是為了容器間互相訪問,應該建立自定義網絡,并使用 Docker 內置的 DNS 服務。
Q:怎么映射宿主端口?Dockerfile?中的EXPOSE和?docker run -p?有什么區別?
? ? A:Docker中有兩個概念,一個叫做?EXPOSE?,一個叫做?PUBLISH?。
? ? ? EXPOSE?是鏡像/容器聲明要暴露該端口,可以供其他容器使用。這種聲明,在沒有設定?--icc=false的時候,實際上只是一種標注,并不強制。也就是說,沒有聲明EXPOSE的端口,其它容器也可以訪問。但是當強制--icc=false的時候,那么只有EXPOSE的端口,其它容器才可以訪問。
? ? ? ?PUBLISH則是通過映射宿主端口,將容器的端口公開于外界,也就是說宿主之外的機器,可以通過訪問宿主IP及對應的該映射端口,訪問到容器對應端口,從而使用容器服務。
? ? ? ?EXPOSE的端口可以不PUBLISH,這樣只有容器間可以訪問,宿主之外無法訪問。而PUBLISH?的端口,可以不事先EXPOSE,換句話說PUBLISH等于同時隱式定義了該端口要EXPOSE。
? ? ?docker run命令中的-p,?-P參數,以及docker-compose.yml中的ports部分,實際上均是指PUBLISH。
? ? ? ?小寫-p是端口映射,格式為?[宿主IP:]<宿主端口>:<容器端口>,其中宿主端口和容器端口,既可以是一個數字,也可以是一個范圍,比如:1000-2000:1000-2000。對于多宿主的機器,可以指定宿主IP,不指定宿主IP時,守護所有接口。
? ? ? 大寫?-P?則是自動映射,將所有定義?EXPOSE?的端口,隨機映射到宿主的某個端口。
小伙伴們沖鴨,后臺留言區等著你!
關于容器,今天你學到了什么?還有哪些不懂的?除此還對哪些話題感興趣?快來留言區打卡啦!留言方式:打開第XX天,答:……
同時歡迎大家搜集更多問題,投稿給我們!風里雨里留言區里等你~
---------------- ?完? --------------
1.微信群:
添加小編微信:color_ld,備注“進群+姓名+公司職位”即可,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
2.征稿:
投稿郵箱:liudan@csdn.net;微信號:color_ld。請備注投稿+姓名+公司職位。
推薦閱讀
Kafka學習筆記
“拼多多”驚爆重大 Bug!程序員的眼淚,羊毛黨的狂歡
“黃鱔門”視頻女主播一審宣判!
12306能扛住明星出軌這種流量沖擊嗎?
V神說,解釋以太坊2.0最好的文章就是這篇了
以太坊升級的拖油瓶,竟只是這幾行代碼
程序員有話說 | 程序猿在乘地鐵的時候都在想什么??文?推 薦?
點擊“閱讀原文”,打開 CSDN App 閱讀更貼心!
喜歡就點擊“好看”吧!總結
以上是生活随笔為你收集整理的容器精华问答 | Docker和虚拟机有什么差别?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微粒贷上征信吗
- 下一篇: android read设置超时时间,在