Ⅰ Docker基礎
Docker 是一個開源的應用容器引擎,基於Go 語言 並遵從 Apache2.0 協議開源。
Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後發布到任何流行的 linux 機器上,也可以實現虛擬化。
容器是完全使用沙箱機制,相互之間不會有任何介面(類似 iPhone 的 app),更重要的是容器性能開銷極低。
Docker最早是在Ubuntu 12.04上開發實現的;
Red Hat則從RHEL6.5開始對Docker進行支持。
而後Windows和Mac上也相應有了Docker版本支持。
在Docker容器技術出現之前,Linux上是已經有一個docker的工具的,但此docker非彼Docker。
這個docker是一個窗口停靠欄程序,就像蘋果的Mac系統中的dock那個程序一樣的一個工具。
為了區分開來,我們以Docker和docker來進行區分。
Docker:指容器技術。
docker:指窗口停靠欄程序。
Docker技術出來後,因為Linux系統上已經有了docker這個工具,所以Docker軟體名也不能跟人家重名啊,要不然沒辦法安裝。
由於那個時候Docker的官網是docker.io,所以就在軟體名稱上加了io的後綴,在Ubuntu中就是docker.io,在CentOS中就是docker-io。
但是雖然軟體名跟docker程序不一樣了,但軟體安裝後的操作命令還是一樣的,都是docker的這個命令,所以要安裝Docker軟體,要先看看有沒有安裝了那個停靠欄程序docker,有的話要先卸載才行,要不然執行的命令是不對的。
這個時期要安裝Docker,就要用docker加io後綴的方式來安裝。
Docker容器使用docker.io和docker-io為軟體名,主要是前期的一段時間。
後來隨著Docker的發展,軟體包名改成了docker-engine,不同系統中名稱達到了統一。
再後來,隨著Docker技術的火爆,在徵得docker停靠欄程序作者同意下,原先的停靠欄程序docker名稱改掉了,改成了wmdocker,Docker容器技術的軟體包名才正式成了docker這個名稱,Docker軟體包的名稱又得到了一次完全的統一。
到Docker1.13.1版本之前,Docker軟體包的名稱有兩次變化,從docker-io(docker.io)到docker-engine,再到docker。
Docker發展到1.13.1版本號後,Docker公司把Docker分成了社區版(免費)Docker CE和商業版(付費)Docker EE兩種形式,並且版本號命名方式也改了,以前是那種常用的版本號命令方式,比如0.1、0.2、1.0之類的,現在分社區和商業版後,版本號是「年.月」的形式命名的,比如2019年10月發布的,版本號就是19.10。
所以在Docker1.13.1之後,直接是Docker-ce 17.03.0版本了,也就是2017年03月發布的。
現在要安裝最新版的Docker軟體包,就是使用docker-ce這個名稱了,如果是商業版的就是docker-ee了。
目前docker的默認存儲引擎為overlay2,不同的存儲引擎需要相應的文件系統支持,如需要磁碟分區的時候傳遞d-type穩健分層功能,即需要傳遞內核參數並開啟格式化磁碟的時候指定的功能。
存儲引擎的選擇文檔
AUFS
AUFSAnotherUnionFileSystem是一種UnionFS。V2版本後更名為 advanced multi‐layered unification fileystem,即高級多層統一文件系統。所謂UnionFS就是把不同物理位置的目錄合並mount到同一個目錄中。簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統下的文件系統。這種系統可以一層一層的疊加修改文件。無論底下有多少層都是只讀,只有最上層的文件系統是可讀寫。當需要修改一個文件時,AUFS創建該文件的一個副本。使用CoWCopy-on-Write將文件從只讀層復制到可寫層進行修改,結果也保留在可寫層、在Docker中。底下的制度層就是image,可寫層就是Container。
Overlay
一種Union FS文件系統,Linux內核3.18後支持
Overlay2
overlay的升級版,到目前為止,所有Linux發行版推薦使用的存儲類型
devicemapper
是CentOS和RHEL的推薦存儲驅動程序,但是依賴於direct-lvm,存在空間受限的問題,雖然可以通過後期配置解決;因為之前的內核版本不支持overlay2(集中在Centos/RHEL7.2之前版本);但當前較新版本Centos和RHEL現已經支持overlay2。
https://www.cnblogs.com/youruncloud/p/5736718.html
zfs/btrfs(Oracle-2007)
目前沒有廣泛應用;這些文件系統允許使用高級選項,例如創建「快照」,但需要更多的維護和設置。並且每一個都依賴於正確配置的後備文件系統。
vfs
用於測試環境,適用於無法適用Cow文件系統的情況。此存儲驅動程序的性能很差,通常不建議在生產中使用。
1)overlay存儲驅動程序已在Docker Engine-Enterprise 18.09中棄用,並將在以後的版本中刪除。建議將overlay存儲驅動程序的用戶遷移到overlay2。
2)devicemapper存儲驅動程序已在Docker Engine 18.09中棄用,並將在以後的版本中刪除。建議將devicemapper存儲驅動程序的用戶遷移到overlay2。
建議使用overlay2存儲驅動程序。首次安裝Docker時,默認情況下使用overlay2。早期版本,默認情況下會使用aufs。如果要在新版本中使用aufs,則需要對其配置,並且可能需要安裝其他軟體包,例如linux-image-extra。
對於Docker,支持文件系統是所在的文件系統 /var/lib/docker/。一些存儲驅動程序僅適用於特定的後備文件系統。
配置 Docker 存儲驅動非常簡單,只需要修改配置文件即可。
Ⅱ VsCode輕松使用docker容器-Remote Containers
演示視頻: BiliBili
使用docker容器過程中,最常見的操作是進入容器內查看文件、修改配置等操作
使用shell進入容器內,使用linux命令操作
像VsCode操作本地文件一樣去查看文件、修改配置。可以界面化得操作文件,不需要使用shell命令(如:ls cat echo vi等)
開發過程中,往往部署服務會在伺服器上,所以需要遠程到伺服器上部署docker,下面伺服器為ubuntu
遠程到伺服器後,很多操作需要輸入密碼,使用起來不方便,可以使用SSH key減少密碼輸入
Ⅲ Docker容器網路-實現篇
前面介紹了: Docker容器網路-基礎篇
前文說到容器網路對Linux虛擬化技術的依賴,這一篇章我們將一探究竟,看看Docker究竟是怎麼做的。通常,Linux容器的網路是被隔離在它自己的Network Namespace中,其中就包括:網卡(Network Interface)、回環設備(Loopback Device)、路由表(Routing Table)和iptables規則。對於一個進程來說,這些要素,就構成了它發起和響應網路請求的基本環境。
我們在執行 docker run -d --name xxx 之後,進入容器內部:
並執行 ifconfig:
我們看到一張叫eth0的網卡,它正是一個Veth Pair設備在容器的這一端。
我們再通過 route 查看該容器的路由表:
我們可以看到這個eth0是這個容器的默認路由設備。我們也可以通過第二條路由規則,看到所有對 169.254.1.1/16 網段的請求都會交由eth0來處理。
而Veth Pair 設備的另一端,則在宿主機上,我們同樣也可以通過查看宿主機的網路設備來查看它:
在宿主機上,容器對應的Veth Pair設備是一張虛擬網卡,我們再用 brctl show 命令查看網橋:
可以清楚的看到Veth Pair的一端 vethd08be47 就插在 docker0 上。
我現在執行docker run 啟動兩個容器,就會發現docker0上插入兩個容器的 Veth Pair的一端。如果我們在一個容器內部互相ping另外一個容器的IP地址,是不是也能ping通?
容器1:
容器2:
從一個容器ping另外一個容器:
我們看到,在一個容器內部ping另外一個容器的ip,是可以ping通的。也就意味著,這兩個容器是可以互相通信的。
我們不妨結合前文時所說的,理解下為什麼一個容器能訪問另一個容器?先簡單看如一幅圖:
當在容器1里訪問容器2的地址,這個時候目的IP地址會匹配到容器1的第二條路由規則,這條路由規則的Gateway是0.0.0.0,意味著這是一條直連規則,也就是說凡是匹配到這個路由規則的請求,會直接通過eth0網卡,通過二層網路發往目的主機。而要通過二層網路到達容器2,就需要127.17.0.3對應的MAC地址。所以,容器1的網路協議棧就需要通過eth0網卡來發送一個ARP廣播,通過IP找到MAC地址。
所謂ARP(Address Resolution Protocol),就是通過三層IP地址找到二層的MAC地址的協議。這里說到的eth0,就是Veth Pair的一端,另一端則插在了宿主機的docker0網橋上。eth0這樣的虛擬網卡插在docker0上,也就意味著eth0變成docker0網橋的「從設備」。從設備會降級成docker0設備的埠,而調用網路協議棧處理數據包的資格全部交給docker0網橋。
所以,在收到ARP請求之後,docker0就會扮演二層交換機的角色,把ARP廣播發給其它插在docker0網橋的虛擬網卡上,這樣,127.17.0.3就會收到這個廣播,並把其MAC地址返回給容器1。有了這個MAC地址,容器1的eth0的網卡就可以把數據包發送出去。這個數據包會經過Veth Pair在宿主機的另一端veth26cf2cc,直接交給docker0。
docker0轉發的過程,就是繼續扮演二層交換機,docker0根據數據包的目標MAC地址,在CAM表查到對應的埠為veth8762ad2,然後把數據包發往這個埠。而這個埠,就是容器2的Veth Pair在宿主機的另一端,這樣,數據包就進入了容器2的Network Namespace,最終容器2將響應(Ping)返回給容器1。在真實的數據傳遞中,Linux內核Netfilter/Iptables也會參與其中,這里不再贅述。
CAM就是交換機通過MAC地址學習維護埠和MAC地址的對應表
這里介紹的容器間的通信方式就是docker中最常見的bridge模式,當然此外還有host模式、container模式、none模式等,對其它模式有興趣的可以去閱讀相關資料。
好了,這里不禁問個問題,到目前為止只是單主機內部的容器間通信,那跨主機網路呢?在Docker默認配置下,一台宿主機的docker0網橋是無法和其它宿主機連通的,它們之間沒有任何關聯,所以這些網橋上的容器,自然就沒辦法多主機之間互相通信。但是無論怎麼變化,道理都是一樣的,如果我們創建一個公共的網橋,是不是集群中所有容器都可以通過這個公共網橋去連接?
當然在正常的情況下,節點與節點的通信往往可以通過NAT的方式,但是,這個在互聯網發展的今天,在容器化環境下未必適用。例如在向注冊中心注冊實例的時候,肯定會攜帶IP,在正常物理機內的應用當然沒有問題,但是容器化環境卻未必,容器內的IP很可能就是上文所說的172.17.0.2,多個節點都會存在這個IP,大概率這個IP是沖突的。
如果我們想避免這個問題,就會攜帶宿主機的IP和映射的埠去注冊。但是這又帶來一個問題,即容器內的應用去意識到這是一個容器,而非物理機,當在容器內,應用需要去拿容器所在的物理機的IP,當在容器外,應用需要去拿當前物理機的IP。顯然,這並不是一個很好的設計,這需要應用去配合配置。所以,基於此,我們肯定要尋找其他的容器網路解決方案。
在上圖這種容器網路中,我們需要在我們已有的主機網路上,通過軟體構建一個覆蓋在多個主機之上,且能把所有容器連通的虛擬網路。這種就是Overlay Network(覆蓋網路)。
關於這些具體的網路解決方案,例如Flannel、Calico等,我會在後續篇幅繼續陳述。
Ⅳ Docker容器間網路互聯原理,講不明白算我輸
如上紅字所描述:同一個宿主機上的不同容器之間的網路如何互通的???
我們安裝完docker之後,docker daemon會為我們自動創建3個網路,如下:
其實docker有4種網路通信模型,分別是:bridge、host、none、container
默認的使用的網路模型是bridge,也是我們生產上會使用到的網路模型。
下文中跟大家分享docker容器互通原理到時候呢,用到的也是bridge網路模型
另外,當我們安裝完docker之後,docker會為我們創建一個叫docker0的網路設備
通過ifconfig命令可以查看到它,看起來它貌似和eth0網路地位相當,像是一張網卡。然而並不是,docker0其實是一個Linux網橋
何以見得?可以通過下面的命令查看操作系統上的網橋信息
那大家怎麼理解Linux網橋的概念呢?
其實大家可以把docker0理解成一台虛擬的交換機!然後像下面這樣類比著理解,就會豁然開朗
1、它好比是大學在機房上課時,老師旁邊的那個大大的交換機設備。
2、把機房裡的電腦都連接在交換機上,類比成docker 容器作為一台設備都連接著宿主機上的docker0。
3、把交換機和機房中的機器的ip在同一個網段,類比成docker0、和你啟動的docker容器的ip也同屬於172網段。
類比成這樣:
我們剛才做類比理解docker0的時候說:把機房裡的電腦都連接在交換機上,類比成docker 容器作為一台設備都連接著宿主機上的docker0。那具體的實現落地實現用的是啥技術呢?
答案是:veth pair
veth pair的全稱是:virtual ethernet,就是虛擬的乙太網卡。
說到乙太網卡大家都不陌生呀,不就是我們常見的那種叫eth0或者是ens的網路設備嗎?
那這個veth pair是怎麼玩的呢?有啥用呢?大家可以看下面這張圖
veth-pair設備總是會成對的出現,用於連接兩個不同network-namespace.
就上圖來說,從network-namespace1的veth0中發送的數據會出現在 network-namespace2的veth1設備中。
雖然這種特性很好,但是如果出現有多個容器,你就會發現組織架構會越來越復雜,越來越亂
不過好在我們已經循序漸進的了解Linux網橋(docker0),以及這里的veth-pair設備,於是我們可以把整體的架構圖重新繪製成下面這樣
因為不同容器有自己隔離後的network-namespace所以他們都有自己的網路協議棧
那我們能不能找到容器裡面的網卡和物理機上的哪張卡是一對網路vethpair設備呢?
如下:
回到宿主機
意思是就是說,容器545ed62d3abf的eth0網卡和宿主機通過ip addr命令查看的網路設備標號55的設備組成一對vethpair設備,彼此流量互通!
先看個簡單的,同一個區域網中的不同主機A、B之間是如何互聯交換數據的。如下圖
那,既然是同一個區域網中,說明A、B的ip地址在同一個網段,如上圖就假設它們都在192.168.1.0網段。
還得再看下面這張OSI 7層網路模型圖。
主機A向主機B發送數據,對主機A來說數據會從最上層的應用層一路往下層傳遞。比如應用層使用的http協議、傳輸層使用的TCP協議,那數據在往下層傳遞的過程中,會根據該層的協議添加上不同的協議頭等信息。
根據OSI7層網路模型的設定,對於接受數據的主機B來說,它會接收到很多數據包!這些數據包會從最下層的物理層依次往上層傳遞,依次根據每一層的網路協議進行拆包。一直到應用層取出主機A發送給他的數據。
那麼問題來了,主機B怎麼判斷它收到的數據包是否是發送給自己的呢?萬一有人發錯了呢?
答案是:根據MAC地址,邏輯如下。
那對於主機A來說,它想發送給主機B數據包,還不能讓主機B把這個數據包扔掉,它只能中規中矩的按乙太網網路協議要求封裝將要發送出去的數據包,往下傳遞到數據鏈路層(這一層傳輸的數據要求,必須要有目標mac地址,因為數據鏈路層是基於mac地址做數據傳輸的)。
那數據包中都需要哪些欄位呢?如下:
其中的dst ip好說,我們可以直接固定寫,或者通過DNS解析域名得到目標ip。
那dst mac怎麼獲取呢?
這就不得不說ARP協議了! ARP其實是一種地址解析協議,它的作用就是:以目標ip為線索,找到目的ip所在機器的mac地址。也就是幫我們找到dst mac地址!大概的過程如下幾個step
推薦閱讀:白日夢的DNS筆記
簡述這個過程:主機A想給主機B發包,那需要知道主機B的mac地址。
嗯,在arp協議的幫助下,主機A順利拿到了主機B的mac地址。於是數據包從網路層流轉到數據鏈路層時已經被封裝成了下面的樣子:
根據OIS7層網路模型,我們都知道數據包經過物理層發送到機器B,機器B接收到數據包後,再將數據包向上流轉,拆包。流轉到主機B的數據鏈路層。
那主機B是如何判斷這個在數據鏈路層的包是否是發給自己的呢?
答案前面說了,根據目的mac地址判斷。
這個例子比較簡單,dst ip就是主機B的本機ip 所以它自己會處理這個數據包。
那數據包處理完之後是需要給主機A一個響應包,那問題又來了,響應包該封裝成什麼樣子呢?對主機B來說響應包也需要src ip、src mac、dst ip、dst mac
同樣的道理,響應包也會按照如下的邏輯被主機A接受,處理。
這一次,讓我在網路告訴你,當你請求 www..com 時都發生了什麼?
有了上面那些知識儲備呢?再看我們今天要探究的問題,就不難了。
如下紅字部分:同一個宿主機上的不同容器是如何互通的?
那我們先分別登陸容器記錄下他們的ip
先看實驗效果:在9001上curl9002
實驗結果是網路互通!
我們再完善一下上面的圖,把docker0、以及兩個容器的ip補充上去,如下圖:
那兩台機器之前要通信是要遵循OSI網路模型、和乙太網協議的。
我們管172.17.0.2叫做容器2
我們管172.17.0.3叫做容器3
比如我們現在是從:容器2上curl 容器3,那麼容器2也必須按照乙太網協議將數據包封裝好,如下
那現在的問題是容器3的mac地址是多少?
容器2會先查自己的本地緩存,如果之前沒有訪問過,那麼緩存中也沒有任何記錄!
不過沒關系,還有arp機制兜底,於是容器2會發送arp請求包,大概如下
容器2會查詢自己的路由表,將這個arp請求從自己的gateway發送出去
我們發現容器2的網關對應的網路設備的ip就是docker0的ip地址,並且經由eth0發送出去!
哎?eth0不就是我們之前說的veth-pair設備嗎?
並且我們通過下面的命令可以知道它的另一端對應著宿主機上的哪個網路設備:
而且我們可以下面的小實驗,驗證上面的觀點是否正確
所以說從容器2的eth0出去的arp請求報文會同等的出現在宿主機的第53個網路設備上。
通過下面的這張圖,你也知道第53個網路設備其實就是下圖中的veth0-1
所以這個arp請求包會被發送到docker0上,由docker0拿到這個arp包發現,目標ip是172.17.0.3並不是自己,所以docker0會進一步將這個arp請求報文廣播出去,所有在172.17.0.0網段的容器都能收到這個報文!其中就包含了容器3!
那容器3收到這個arp報文後,會判斷,哦!目標ip就是自己的ip,於是它將自己的mac地址填充到arp報文中返回給docker0!
同樣的我們可以通過抓包驗證,在宿主機上
於是容器2就拿到了容器3的mac地址,乙太網數據包需要的信息也就齊全了!如下:
再之後容器2就可以和容器3正常互聯了!
容器3會收到很多數據包,那它怎麼知道哪些包是發給自己的,那些不是呢?可以參考如下的判斷邏輯
Ⅳ 如何進入 Docker 容器
如何進入Docker容器
概述
在使用Docker創建了容器之後,大家比較關心的就是如何進入該容器了,其實進入docker容器有好幾多種方式,這里我們就講一下常用的幾種進入Docker容器的方法。
進入Docker容器比較常見的幾種做法如下:
使用docker attach
使用SSH
使用nsenter
使用exec
下面我們來逐一講一下每種方式。
一、使用docker attach進入Docker容器
Docker提供了attach命令來進入Docker容器。
接下來我們創建一個守護態的Docker容器,然後使用docker attach命令進入該容器。
[plain] view plain
$ sudo docker run -itd ubuntu:14.04 /bin/bash
然後我們使用docker ps查看到該容器信息,接下來就使用docker attach進入該容器
[plain] view plain
$ sudo docker attach 44fc0f0582d9
可以看到我們已經進入到該容器中了。
但在,使用該命令有一個問題。當多個窗口同時使用該命令進入該容器時,所有的窗口都會同步顯示。如果有一個窗口阻塞了,那麼其他窗口也無法再進行操作。下來我們來演示一下。打開兩個窗口,都使用attach命令進入同一個容器裡面。如下所示:
接下來我們只在第一個窗口進行操作,可以看到第一個窗口的操作同步到第二個窗口顯示了,如下:
因為這個原因,所以docker attach命令不太適合於生產環境,平時自己開發應用時可以使用該命令。
二、使用SSH進入Docker容器
在生產環境中排除了使用docker attach命令進入容器之後,相信大家第一個想到的就是ssh。在鏡像(或容器)中安裝SSH Server,這樣就能保證多人進入容器且相互之間不受干擾了,相信大家在當前的生產環境中(沒有使用Docker的情況)也是這樣做的。但是使用了Docker容器之後不建議使用ssh進入到Docker容器內。關於為什麼不建議使用,請參考如下幾篇文章:
Why you don't need to run SSHd in your Docker containers
上面這篇文章是英文的,如果英語不好的話可以參考如下譯文
為什麼不需要在 Docker 容器中運行 sshd
三、使用nsenter進入Docker容器
在上面兩種方式都不適合的情況下,還有一種比較方便的方法,即使用nsenter進入Docker容器。關於什麼是nsenter請參考如下文章:
https://github.com/jpetazzo/nsenter
在了解了什麼是nsenter之後,我們需要把nsenter安裝到主機中(注意是主機而非容器或鏡像),具體的安裝命令如下:
[plain] view plain
$ wget https:/。。。r.gz
$ tar -xzvf util-linux-2.24.tar.gz
$ cd util-linux-2.24/
$ ./configure --without-ncurses
$ make nsenter
$ sudo cp nsenter /usr/local/bin
安裝好nsenter之後可以查看一下該命令的使用。
nsenter可以訪問另一個進程的名稱空間。所以為了連接到某個容器我們還需要獲取該容器的第一個進程的PID。可以使用docker inspect命令來拿到該PID。
docker inspect命令使用如下:
[plain] view plain
$ sudo docker inspect --help
inspect命令可以分層級顯示一個鏡像或容器的信息。比如我們當前有一個正在運行的容器
可以使用docker inspect來查看該容器的詳細信息。
[plain] view plain
$ sudo docker inspect 44fc0f0582d9
由其該信息非常多,此處只截取了其中一部分進行展示。如果要顯示該容器第一個進行的PID可以使用如下方式
[plain] view plain
$ sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9
在拿到該進程PID之後我們就可以使用nsenter命令訪問該容器了。
[plain] view plain
$ sudo nsenter --target 3326 --mount --uts --ipc --net --pid
其中的3326即剛才拿到的進程的PID
當然,如果你認為每次都輸入那麼多參數太麻煩的話,網上也有許多做好的腳本供大家使用。
地址如下:
四、使用docker exec進入Docker容器
除了上面幾種做法之外,docker在1.3.X版本之後還提供了一個新的命令exec用於進入容器,這種方式相對更簡單一些,下面我們來看一下該命令的使用:
[plain] view plain
$ sudo docker exec --help
接下來我們使用該命令進入一個已經在運行的容器
[plain] view plain
$ sudo docker ps
$ sudo docker exec -it 775c7c9ee1e1 /bin/bash
網上還有一種做法是使用nsinit,沒有親身實踐過所以不在此羅列了,有興趣的話可以嘗試一下。
Ⅵ Docker(5)——數據管理
docker 容器的文件系統在宿主機上存在的方式很復雜,這會帶來下面幾個問題:
為了能夠 保存(持久化) 數據以及 共享 容器間的數據,docker 引入了數據卷(volume) 機制。數據卷是存在於一個或多個容器中的特定文件或文件夾,它可以繞過默認的聯合文件系統,以正常的文件或者目錄的形式存在於宿主機上。
其生存周期獨立於容器的生存周期。
容器中主要有 兩種 管理數據方式: 數據卷(Data Volumes) , 數據卷容器(Data Volume Containers) 。
數據卷是一個可供容器使用的特殊目錄,它繞過文件系統,可以提供很多有用的特性:
數據卷的使用類似 linux 下對目錄或文件進行 mount 操作,目前Docker提供了 三種 不同的方式將數據從宿主機掛載到容器中,分別是
其中 volume 、 bind mount 比較常用, tmpfs mount 基本不會用.
volumes作為Docker管理宿主機文件系統的一部分 ,默認位於 /var/lib/docker/volumes 目錄中,不是宿主機已有數據,而是新建的。
docker 專門提供了 volume 子命令來操作數據卷:
先創建一個名稱為 hello 的數據卷並通過 ls 命令進行查看:
然後可以使用 inspect 命令看看數據卷hello的詳細信息
該數據卷使用的 Driver 為默認的 local ,表示數據卷使用宿主機的本地存儲;
Mountpoint 是 volumes 的掛載點,默認是本機 /var/lib/docker/volumes 下的一個目錄。
所有Container的數據都保存在了這個目錄下邊,由於沒有在創建時指定卷,所以Docker幫我們默認創建許多匿名卷。
使用 -v 選項也可以指定掛載一個本地的已有目錄到容器中去作為數據卷:
docker run -it –-name robot1 -v /var/data:/opt/mydata ros/kinetic /bin/bash
上面的命令掛載主機的 /var/data 目錄到容器的 /opt/mydata 目錄。
這個功能在測試的時候特別方便,比如用戶可以放置一些程序或數據到本地目錄中,然後在容器中使用。另外,本地目錄的路徑必須是絕對路徑,如果目錄不存在,Docker 會自動創建。
Docker 掛載數據卷的默認許可權是可讀寫 rw ,用戶也可以通過 ro 標記指定為只讀:
docker run -it –-name robot1 -v /var/data:/opt/mydata:ro ros/kinetic /bin/bash
加了 :ro 之後,容器內掛載的數據卷內的數據就變成只讀的了。
除了把數據卷中的數據存儲在宿主機,docker 還允許我們通過指定 volume driver 的方式把數據卷中的數據存儲在其它的地方,比如 Azrue Storge 或 AWS 。
通過 vieux/sshfs 驅動把數據卷的存儲在雲主機上,docker 默認是不安裝 vieux/sshfs 插件的,我們可以通過下面的命令進行安裝:
docker plugin install --grant-all-permissions vieux/sshfs
然後通過 vieux/sshfs 驅動創建數據卷,並指定遠程主機的登錄用戶名、密碼和數據存放目錄:
注意:確保指定的遠程主機上的掛載點 /home/nick/sshvolume 目錄是存在的,否則在啟動容器時會報錯。
最後在啟動容器時指定掛載這個數據卷:
在容器中 /world 目錄下操作的文件都存儲在遠程主機的 /home/nick/sshvolume 目錄中。進入容器 testcon 然後在 /world 目錄中創建一個文件,然後打開遠程主機的 /home/nick/sshvolume 目錄進行查看,新建的文件會出現在那裡。
當使用 bind mounts 將主機上的目錄掛載到容器中時,目錄由其在主機上的完整或相對路徑引用。
bind mount 和 volume 其實都是利用宿主機的文件系統,不同之處在於volume是docker自身管理的目錄中的子目錄,所以不存在許可權引發的掛載的問題,並且目錄路徑是docker自身管理的,所以也不需要在不同的伺服器上指定不同的路徑,不需要關心路徑
bind mounts 可以掛載在宿主機系統的任意位置 ,但 bind mount 在不同的宿主機系統是不可移植的,比如Windows和Linux的目錄結構是不一樣的, bind mount 所指向的 host 目錄也不能一樣。這也是為什麼 bind mount 不能出現在Dockerfile中的原因,因為這樣Dockerfile就不可移植了。
如果使用 Bind mounts 掛載 宿主機目錄 到 容器內非空目錄 ,那麼 此容器中的非空目錄中的文件會被隱藏 ,容器訪問這個目錄時能夠訪問到的文件均來自於宿主機目錄。這也是Bind mounts模式和Volumes模式最大的行為上的不同。
掛載存儲在宿主機系統的內存中,而不會寫入宿主機的文件系統;
這張圖說明 bind mount 和 volume 其實都是利用宿主機的文件系統, Bind mounts 模式是將宿主機上的任意文件或文件夾掛載到容器,而 Volumes 本質上是將Docker服務管理的一塊區域(默認是 /var/lib/docker/volumes 下的文件夾)掛載到容器。所以 volume 不存在許可權引發的掛載的問題,並且目錄路徑是docker自身管理的,所以也不需要在不同的伺服器上指定不同的路徑,不需要關心路徑。
相對於 bind mount , volume 是Docker Engine在自己的「地盤」分配了一個路徑作為掛載點,自己地盤的許可權肯定是安排的明明白白。所以,以上掛載宿主機路徑的問題都解決了。
在使用 volume 作為數據卷掛載到容器時,直接用 volume 名稱代替宿主機路徑名就行:
docker run -d -v test_vol:/var/data some_image
這樣就將數據卷 test_vol 掛載到了容器內的 /var/data 目錄下。
命名的容器掛載數據卷,其它容器通過掛載這個(父容器)實現數據共享,掛載數據卷的容器,稱之為數據卷容器
可以利用數據卷容器對其中的數據卷進行備份、恢復,以實現數據的遷移。
備份
使用下面的命令來備份 mydata 數據卷容器內的數據卷:
sudo docker run --volumes-from mydata -v $(pwd):/backup –-name worker ubuntu tar cvf /backup/backup.tar /data
這個命令首先利用 Ubuntu 鏡像創建了一個容器 worker。又使用 --volumes-from mydata 參數來讓 worker 容器掛載 mydata 容器的數據卷。接下來使用 -v $(pwd):/backup 參數來掛載本地的當前目錄到 worker 容器的 /backup 目錄。
在 worker 容器啟動後,使用了 tar cvf /backup/backup.tar /data 命令來將 /data 下內容備份為容器內的 /backup/backup.tar,即宿主主機的當前目錄下的backup.tar。
恢復
如果要恢復數據到一個容器,可以按照下面的操作。首先創建一個帶有數據卷的容器 mydata2:
sudo docker run -v /data –-name mydata2 ubuntu /bin/bash
然後創建另一個新的容器,掛載 mydata2 的數據卷,並使用 tar 解壓縮備份文件到所掛載的容器卷中:
sudo docker run --volumes-from mydata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
如果用戶需要在容器之間共享一些持續更新的數據,最簡單的方式是使用數據卷容器。數據卷容器其實就是一個普通的容器,專門用它提供數據卷供其他容器掛載。下面簡單介紹其使用方法。
首先要創建一個數據卷容器 mydata,並在其中創建一個數據卷掛載到 /data 目錄。
sudo docker run -it -v /data –-name mydata ubuntu
然後在其他容器中使用 --volumes-from 來掛載 mydata 容器中的數據卷。例如創建兩個容器 mycon1 和 mycon2,並從 mydata 容器掛載數據卷:
sudo docker run -it --volumes-from mydata –-name mycon1 ubuntu
sudo docker run -it --volumes-from mydata –-name mycon2 ubuntu
(注意,命令中沒有指定數據卷的信息,也就是說新容器中掛載數據卷的目錄和源容器中是一樣的。)
此時容器 mycon1 和 mycon2 都掛載同一個數據卷到相同的目錄 /data。三個容器任何一個在該目錄下寫入數據其他容器都能看到。
可以多次使用 --volumes-from 參數來從多個容器掛載多個數據卷。還可以從其他已經掛載了容器的容器來掛載數據卷。並且使用 --volumes-from 參數所掛載數據卷的容器自身並不需要保持在運行狀態。
但刪除掛載了數據卷的容器時,數據卷並不會被自動刪除。如果要刪除一個數據卷,必須在刪除最後一個還掛載著它的容器時顯式的使用 docker rm -v 命令來指定同時刪除關聯的容器。
如何對已經運行的容器掛載目錄?
https://blog.51cto.com/hjun169/2440799
手動修改mount掛載的json文件,狂神的那個視頻裡面也有寫。
深刻理解Docker鏡像大小
https://blog.csdn.net/shlazww/article/details/47375009
理解docker的分層鏡像實現 base 鏡像共享(DockerFile)
https://blog.csdn.net/lu_1110/article/details/106533490
Ⅶ Docker容器使用--net=host的方式啟動後怎樣訪問
<ol><li>如果容器里沒有運行sshd,可以登錄宿主機後執行docker exec -it CONTAINER_NAME_OR_ID /bin/sh</li><li>可以在容器里運行個sshd,通過SSH客戶端登錄。 但由於是用的host網路,所以容器里的sshd進程無法使用默認埠,需要修改其配置文件把埠改成非22埠</li></ol>
Ⅷ docker 外網訪問不了docker容器
出現問題的原因有3種,
1:你安裝docker的伺服器沒有關閉防火牆,也就是說你訪問你安裝docker的物理機都訪問不了,物理機里的docker就更訪問不了了。
2:docker在創建鏡像的時候沒有做埠映射,這是就出現能訪問物理機,但訪問不了docker,你可以使用docker ps 查看鏡像的埠映射情況。
3:埠映射不正確,如你docker中某一容器的8080埠映射到安裝docker物理機的80埠,加入你在鏡像裡面安裝了tomcat,但是你tomcat使用的是8080以外的任意埠,這是你訪問物理機ip+80埠也無法訪問。
Ⅸ 如何解決docker宿主機無法訪問容器中的服務
有時候,查看資源管理器你會發現一個奇怪的現象。物理內存使用率沒超過50%,就開始使用swap空間了。用swap顯然沒有使用物理內存快。如何修改?
在ubuntu 裡面,swappiness的值的大小對如何使用swap分區是有著很大的聯系的。
swappiness=0的時候表示最大限度使用物理內存,然後才是 swap空間;swappiness=100的時候表示積極的使用swap分區,並且把內存上的數據及時的搬運到swap空間裡面。兩個極端,對於 ubuntu的默認設置,這個值等於60,建議修改為10。具體這樣做:
1、查看你的系統裡面的swappiness,在終端輸入 cat /proc/sys/vm/swappiness,不出意外結果應該是60
2、修改swappiness值為10。在終端輸入 sudo gedit /etc/sysctl.conf ,然後在最後一行添加 vm.swappiness=10 ,保存。
3、重啟電腦,使設置生效。
這樣Ubuntu就能最大限度使用物理內存了!!
Ⅹ 20在群暉系統安裝使用Docker容器
學過linux的都知道,docker是一項非常好的開源容器引擎,它不單單能在linux和windows系統運行,還可以在群暉系統中運行,我們這里就演示一下怎麼在群暉系統中運行docker容器。
1、首先安裝docker容器套件,在套件中心搜索docker,就能找到docker安裝套件,直接點擊安裝套件即可,非常簡單。
2、打開docker套件,首先看到的是幫助頁面。
3、我們點開軟體中的注冊表(我們以安裝nginx容器為例),選中nginx,點擊上面的下載,然後選擇容器標簽,默認latest,為最新版。
4、下載完成完成後,我們選中鏡像,下載nginx鏡像就在這里,我們點擊啟動。
5、打開容器創建頁面,填寫容器名稱,使用高許可權執行容器和啟用資源限制,根據需求選擇,然後點擊「高級設置」
6、容器的高級設置頁面,我們選中「啟用自動重新啟動」,這樣容器遇到關機時會自動重新啟動。
7、存儲空間頁面,添加docker容器在群暉存儲上的裝載路徑。
8、埠頁面設置nginx容器埠和群暉本地埠
9、信息摘要
10、創建完成,點擊docker的容器,我們看到一個啟動的nginx容器已經生成。
11、在你的電腦上,通過瀏覽器訪問nginx容器,運行正常。