溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

docker常用命令有哪些及怎么用

發(fā)布時間:2022-05-20 15:49:28 來源:億速云 閱讀:123 作者:iii 欄目:大數(shù)據(jù)

這篇“docker常用命令有哪些及怎么用”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“docker常用命令有哪些及怎么用”文章吧。

一、鏡像相關(guān)

1.1 列出本機所有鏡像

docker常用命令有哪些及怎么用

后面的操作,都以ubuntu做為練習(xí)的目標(biāo)。

另外:如果某些鏡像文件不想要了,可以用下面的命令刪除

1.2 刪除鏡像

docker rmi 鏡像id(即:1.1圖中的image id)

有時候刪除會失敗,比如:有一個容器正在使用該鏡像文件。這時可以加參數(shù)-f 強制刪除,如果不清楚每個命令可以加哪些參數(shù),可以用

docker 命令 --help

查看幫助,比如:

 bin docker rmi --help
usage: docker rmi [options] image [image...]
remove one or more images
 -f, --force=false force removal of the image
 --help=false   print usage
 --no-prune=false  do not delete untagged parents

二、容器相關(guān)

2.1 最基本的啟動

docker run -it ubuntu

參數(shù)-it的含義,可以用docker run --help查看,就不展開了

2.2 啟動后執(zhí)行命令

docker run -it ubuntu echo 'hello world'

2.3 啟動時指定容器名稱

docker run -it --name 'myubuntu' ubuntu

容器名稱是一個很有意思的東東,后面馬上會講到。上面的命令運行完以后,先用exit退出,以便后面學(xué)習(xí)其它命令。

2.4 查看最近運行過的所有容器

docker ps -a  

docker常用命令有哪些及怎么用  

從圖上可以看出,如果啟動時未顯示指定容器名稱,docker會自動生成一個好玩的名稱,命令的風(fēng)格大致是:什么樣的_誰誰,比如圖中的insane_lamarr,字面的意思為"瘋狂的拉馬爾",從這些細節(jié)可以感受到,docker的創(chuàng)造者們都是一幫很愛玩的家伙。

除了容器名稱,還有二列非常重要:container id及status,其中status中以up開頭的,表示容器正在運行(注:容器是否處于運行狀態(tài),排除人為docker stop的因素外,很大程序上是由docker run 最后的命令參數(shù)決定的,如果啟動時不指定任何命令參數(shù),默認執(zhí)行/bin/bash,如果指定了類似echo "hello world"之類瞬間就執(zhí)行完的命令,run起來,馬上就會轉(zhuǎn)為關(guān)閉,因為命令已經(jīng)執(zhí)行完了),而container id在很多場景中都會用到(比如:刪除容器)

docker常用命令有哪些及怎么用

另外,對于同一個鏡像(比如ubuntu),默認不指定容器名稱的話,每次容器啟動docker都會生成一個唯一的名稱,這個有點象oop編程,鏡像相當(dāng)于class類定義,是一個只讀的模板,而容器則是類的運行實例,java中每次new出來的實例,其hashcode必然不同,所以每次啟動的docker容器,名稱也不一樣,只不過與oop不同的是,oop中實例消亡了,所有關(guān)聯(lián)的信息全清掉了,而docker容器就算停止掉,docker仍會記住其最后的運行狀態(tài)。

可以做一個小試驗,剛才我們已經(jīng)創(chuàng)建了一個名為myubuntu的容器:

docker run -it --name 'myubuntu' ubuntu

這一行命令再次運行的話,就會報錯:

error response from daemon: conflict. the name "myubuntu" is already in use by container d1c261ad0b1e. you have to remove (or rename) that container to be able to reuse that name.

大意是容器名稱mybutun已經(jīng)被另一個容器(id為d1c261ad0b1e)占用了,要么把原來的容器刪除,要么換個名字。

這其中的設(shè)計思想,可以仔細琢磨一二,想想也十分合理:類比一下,我們寫代碼時,同一個類new出多個實例,每個實例都會有自己不同的應(yīng)用場景,比如:同樣是一個order實例,可以用在訂單創(chuàng)建的業(yè)務(wù)場景中,也可以用在訂單查詢的返回結(jié)果中...,docker的鏡像也是如此,同樣一個ubuntu鏡像文件,有人用它創(chuàng)建容器是為了安裝nginx當(dāng)成web server,有人用它創(chuàng)建容器是為了學(xué)習(xí)hadoop...,為了能以一種友好的方式來區(qū)分,所以名字不能沖突,然后,同一個名字的容器,今天安裝了軟件a,玩事兒后將它關(guān)閉,明天可能會繼續(xù)在這個容器上折騰其它事情,所以每次容器停止,不可能象oop中的實例一樣,徹底丟棄實例的所有信息,否則明天就沒辦法接著玩了。

2.5 停止運行中的容器

docker stop 容器名稱

2.6 刪除容器

docker rm 容器id

如果容器處于運行狀態(tài),上面的操作會失敗,可以加-f參數(shù)強制刪除  

2.7 在已運行的容器中,直接執(zhí)行命令

docker exec 容器名稱 命令

例如:  

docker exec myubuntu apg-get update

2.8 附加到已經(jīng)運行的容器

docker attach 容器名稱

注:該命令運行后,mac上屏幕沒任何輸出,還以為卡死了,這是假象,直接繼續(xù)輸入命令,比如pwd之類的就能看到結(jié)果了.

attach這個命令不太好用,進入終端后,沒辦法退出而不停止容器,要退出只能輸入exit,但這樣就將容器停止了,另外一個缺點是,如果多個容器同時attach到相同的容器,在一個窗口中操作的結(jié)果,會同步顯示到所有窗口。

建議用下面的命令代替:

docker exec -it 容器名稱 sh

當(dāng)然進入容器還有其它一些辦法,比如網(wǎng)絡(luò)端口22映射本機某個端口,容器里啟動ssh服務(wù),然后ssh連接進入,或者用nsenter結(jié)合進程id進入,但個人覺得這些方法操作都太復(fù)雜,遠不如上面這行命令簡單

2.9 保存對容器所做的修改

在容器上做了一堆操作后,比如在ubuntu的基礎(chǔ)上安裝了一些軟件、部署了一些應(yīng)用之類,希望分發(fā)到其它機器,最簡單的辦法就是把容器重新生成一個新鏡像,然后其它人直接docker pull你的新鏡像就可以了。

docker commit -a 作者名字 -m 提交原因 -p 容器id 鏡像名稱:版本號

比如:

docker commit -a 'yjmyzz' -m 'test commit' -p d1c261ad0b1e yjmyzz/ubuntu:v2

提交完成后,可以

docker images 查看

docker常用命令有哪些及怎么用

從圖中可以看出,在ubuntu原來的基礎(chǔ)上,生成一個名為yjmyzz/ubuntu的新鏡像,然后用新鏡像創(chuàng)建容器試試看

docker run -it --name 'myubuntu2' yjmyzz/ubuntu:v2

三、卷(volumn)相關(guān)

我們平時在使用電腦的過程中,會經(jīng)常通過usb插入一些外部存儲設(shè)備,比如:u盤之類,插好后,就能象常規(guī)硬盤目錄一樣訪問外部存儲設(shè)備。卷(volume)的意思其實跟這個差不多,可以把host機上的某個目錄"插入"到容器中,然后容器中就能直接訪問host機上的文件了,即使容器刪除掉,卷里的數(shù)據(jù)仍然可能持久保存。

3.1 創(chuàng)建卷

docker run -it -v /users/yjmyzz/docker_volumn:/opt/webapp --name myubuntu ubuntu /bin/bash

這個命令略長,但并不復(fù)雜,跟前面提到的啟動容器相比,只是多了一個-v /users/yjmyzz/docker_volumn:/opt/webapp的部分,意思就是將本機/users/yjmyzz/docker_volumn這個目錄映射到容器中的/opt/webapp,啟動成功后,保持當(dāng)前窗口不退出,可以再新開一個terminal容器,進入容器驗證一下

docker常用命令有哪些及怎么用

可以嘗試在host本機修改下/users/yjmyzz/docker_volumn/index.html這個文件,然后在容器中cat看下內(nèi)容,應(yīng)該馬上就能看到最新的內(nèi)容。

三個大坑:

其一:

-v 參數(shù)可以只寫前面第一部分,-v /users/yjmyzz/docker_volumn 這樣啟動也不會報錯,但是這樣做的效果,在最新版本的docker(1.9.1)上,只會把本機目錄掛到容器中,容器中看不到本機的任何文件,所以一定要記得寫:后的部分

其二:

權(quán)限問題,mac機上如果從網(wǎng)上down(非apple store官方)了一個文件到本機,該文件甚至保存文件的目錄權(quán)限,都會被設(shè)置成特殊權(quán)限@,見下面的截圖:

docker常用命令有哪些及怎么用

這本來是mac 10.5以后做的一項安全改進,有此標(biāo)識的程序,在首次執(zhí)行時會提示

docker常用命令有哪些及怎么用

但是有這類特殊權(quán)限的目錄或文件,被掛到容器中后,docker容器內(nèi)根本看不到,也就是無權(quán)讀取。處理辦法:

ll -l@ -a

先用這個顯示特殊權(quán)限的詳細信息:

docker常用命令有哪些及怎么用

然后用xattr -r -d 詳細信息 * 去掉這些特殊權(quán)限(參考下圖),然后再重新掛到容器中,就能正常使用了

docker常用命令有哪些及怎么用

其三:

mac上掛載的本機目錄,必須是在~/(即:當(dāng)前用戶的目錄)下,類似/opt/www這樣的目錄,就算給它所有權(quán)限,掛到容器中后,也只能看到目錄,讀不到任何文件,centos上沒這問題。

此外,還可以用命令

docker inspect myubuntu

查看此時容器的所有狀態(tài),會看到一段長長的json輸出,類似下面這樣:

[
{
 "id": "21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48",
 "created": "2016-01-28t02:23:43.91086474z",
 "path": "/bin/bash",
 "args": [],
 "state": {
  "status": "running",
  "running": true,
  "paused": false,
  "restarting": false,
  "oomkilled": false,
  "dead": false,
  "pid": 1843,
  "exitcode": 0,
  "error": "",
  "startedat": "2016-01-28t02:26:09.414485616z",
  "finishedat": "2016-01-28t02:25:43.868883111z"
 },
 "image": "8693db7e8a0084b8aacba184cfc4ff9891924ed2270c6dec6a9d99bdcff0d1aa",
 "resolvconfpath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/resolv.conf",
 "hostnamepath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/hostname",
 "hostspath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/hosts",
 "logpath": "/mnt/sda1/var/lib/docker/containers/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48/21d15713166ae83b022eea8806bd466da9917422e487e874cc098a0f1329dd48-json.log",
 "name": "/myubuntu",
 "restartcount": 0,
 "driver": "aufs",
 "execdriver": "native-0.2",
 "mountlabel": "",
 "processlabel": "",
 "apparmorprofile": "",
 "execids": null,
 "hostconfig": {
  "binds": [
   "/users/yjmyzz/docker_volumn:/opt/webapp"
  ],
  "containeridfile": "",
  "lxcconf": [],
  "memory": 0,
  "memoryreservation": 0,
  "memoryswap": 0,
  "kernelmemory": 0,
  "cpushares": 0,
  "cpuperiod": 0,
  "cpusetcpus": "",
  "cpusetmems": "",
  "cpuquota": 0,
  "blkioweight": 0,
  "oomkilldisable": false,
  "memoryswappiness": -1,
  "privileged": false,
  "portbindings": {},
  "links": null,
  "publishallports": false,
  "dns": [],
  "dnsoptions": [],
  "dnssearch": [],
  "extrahosts": null,
  "volumesfrom": null,
  "devices": [],
  "networkmode": "default",
  "ipcmode": "",
  "pidmode": "",
  "utsmode": "",
  "capadd": null,
  "capdrop": null,
  "groupadd": null,
  "restartpolicy": {
   "name": "no",
   "maximumretrycount": 0
  },
  "securityopt": null,
  "readonlyrootfs": false,
  "ulimits": null,
  "logconfig": {
   "type": "json-file",
   "config": {}
  },
  "cgroupparent": "",
  "consolesize": [
   0,
   0
  ],
  "volumedriver": ""
 },
 "graphdriver": {
  "name": "aufs",
  "data": null
 },
 "mounts": [
  {
   "source": "/users/yjmyzz/docker_volumn",
   "destination": "/opt/webapp",
   "mode": "",
   "rw": true
  }
 ],
 "config": {
  "hostname": "21d15713166a",
  "domainname": "",
  "user": "",
  "attachstdin": true,
  "attachstdout": true,
  "attachstderr": true,
  "tty": true,
  "openstdin": true,
  "stdinonce": true,
  "env": null,
  "cmd": [
   "/bin/bash"
  ],
  "image": "ubuntu",
  "volumes": null,
  "workingdir": "",
  "entrypoint": null,
  "onbuild": null,
  "labels": {},
  "stopsignal": "sigterm"
 },
 "networksettings": {
  "bridge": "",
  "sandboxid": "893c76e283a75e3eebb474bf1b5bce901a37778de3514b526312134fcc858d2c",
  "hairpinmode": false,
  "linklocalipv6address": "",
  "linklocalipv6prefixlen": 0,
  "ports": {},
  "sandboxkey": "/var/run/docker/netns/893c76e283a7",
  "secondaryipaddresses": null,
  "secondaryipv6addresses": null,
  "endpointid": "a7fee41964177719fbd149df820bf66dbd976ebe7cea0b68497ae2fe4c06efc5",
  "gateway": "172.17.0.1",
  "globalipv6address": "",
  "globalipv6prefixlen": 0,
  "ipaddress": "172.17.0.2",
  "ipprefixlen": 16,
  "ipv6gateway": "",
  "macaddress": "02:42:ac:11:00:02",
  "networks": {
   "bridge": {
    "endpointid": "a7fee41964177719fbd149df820bf66dbd976ebe7cea0b68497ae2fe4c06efc5",
    "gateway": "172.17.0.1",
    "ipaddress": "172.17.0.2",
    "ipprefixlen": 16,
    "ipv6gateway": "",
    "globalipv6address": "",
    "globalipv6prefixlen": 0,
    "macaddress": "02:42:ac:11:00:02"
   }
  }
 }
}
]

90~97行的mounts節(jié)點描述了當(dāng)前容器掛載的"卷"信息。

最后指出一點:目前docker僅支持在run(創(chuàng)建)容器時使用-v創(chuàng)建卷,對于一個已經(jīng)start的容器,如果想動態(tài)添加卷,是十分困難的。雖然國外有牛人,實現(xiàn)了在容器啟動后動態(tài)添加卷,但過程十分曲折,而且并不能能用,有興趣的可以參考下面的文章

3.2 列出所有卷

docker常用命令有哪些及怎么用

docker volume ls

3.3 刪除卷

docker volume rm 卷名稱

注:刪除一個容器時,默認不會刪除容器關(guān)聯(lián)的卷,所以隨著時間的推移,host上可能會存在大量的"僵尸"卷,占用硬盤空間。建議每次docker rm 容器時,加上參數(shù)-v,這樣刪除容器時會一并將對應(yīng)的卷刪除,但是這樣也會有一個副作用,如果多個容器同時關(guān)聯(lián)到同一個卷,可能會影響到其它容器。所以在使用卷的時候要規(guī)劃清楚,最好一個容器只對應(yīng)一個卷。

tips:如果要批量刪除所有卷,一個一個rm顯然太麻煩了,可以用下面的方式快速搞定

a) 進入docker虛擬機defaut

docker-machine ssh default

b) 查看volume所在的目錄

docker常用命令有哪些及怎么用

c)切換到sudo模式

sudo -i

d) 進入volume所在根目錄

cd /var/lib/docker/volumes/ 

docker常用命令有哪些及怎么用  

上圖的ls命令已經(jīng)說明,所謂的數(shù)據(jù)卷,其實就是一個個目錄,再次印證了linux里的一句名言『一切皆是文件』,剩下的事情,地球人都知道了,邪惡的

rm -rf *

,最后還要重啟虛擬機,退回到mac主機

docker-machine restart default 

3.4 數(shù)據(jù)卷容器

如果多個容器之間希望共享一份數(shù)據(jù),除了上面的方式外,docker還允許定義一個專用的容器,這個容器啥也不干,只用來放數(shù)據(jù),這種容器稱為『數(shù)據(jù)卷容器』

示例:

docker run -it -v /users/yjmyzz/docker_volumn:/sites --name site_files kitematic/hello-world-nginx echo 'only for nginx web files'

上面的命令跟之前創(chuàng)建卷的完全一樣,現(xiàn)在我們有了一個名為site_files的數(shù)據(jù)卷容器,注意:創(chuàng)建數(shù)據(jù)卷容器時,最后的命令通常都是些打醬油的echo之類,反正只是一個存數(shù)據(jù)的容器,不用執(zhí)行其它命令,甚至它本身都不需要處于啟動狀態(tài)。

然后,其它容器創(chuàng)建時,就可以使用它了:

docker run -d --volumes-from site_files --name nginx1 kitematic/hello-world-nginx sh ./start.sh

注意上面的--volumes-from site_files 這個就是使用數(shù)據(jù)卷容器的關(guān)鍵,其它跟之前的完全相同,多個容器可以掛同一個數(shù)據(jù)卷容器,一個容器也可以掛多個數(shù)據(jù)卷容器。

四、網(wǎng)絡(luò)相關(guān)

4.1 端口映射

-p ip:host_port:container_port

上面的參數(shù)表示將本機ip上的hostport映射到容器的container_port,示例:  

docker run -it -v /users/yjmyzz/documents/kitematic/hello-world-nginx/website_files:/website_files -p 0.0.0.0:10080:80 --name my-nginx kitematic/hello-world-nginx sh /start.sh

這個命令更長了,結(jié)合了之前所有學(xué)習(xí)到的參數(shù),注意多出的問題-p 0.0.0.0:10080:80,表示將本機10080端口映射到容器80端口 

注:如果把-p換成大寫的-p,系統(tǒng)會隨機映射到本機一個空閑的端口號 

4.2 指定hostname

默認創(chuàng)建容器時,hostname是一個唯一的隨機字符串,很難記,可以在docker run -h hostname名稱來指定,這個就不演示了

4.3 容器間的網(wǎng)絡(luò)連接

假如有二個容器mysql, appserver,通常appserver中要訪問數(shù)據(jù)庫,所以需要appserver能直接訪問mysql,下面演示了如何實現(xiàn):

a) 先創(chuàng)建mysql容器

docker run -it -h mysql --name mysql ubuntu /bin/bash

b) 再創(chuàng)建appserver容器  

docker run -it -h appserver --name appserver --link mysql:mysqlserver ubuntu /bin/bash

注意其中的--link mysql:mysqlserver,冒號前的為容器名稱,冒號后的為容器別名,啟動后appserver中就能直接ping通mysql容器了,見下圖:

docker常用命令有哪些及怎么用

注:這個連接是單向的,即appserver可以ping通mysql容器,但反過來不行。而且最新版的docker在ps時,name列也不再象之前網(wǎng)上說的那個顯示成a/b這種格式,要查看一個容器是否有連接,最直接的方式還是docker inspect 容器名稱

以上就是關(guān)于“docker常用命令有哪些及怎么用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI