首先毯炮,確保 Docker 就緒瘟则。在命令行運行 docker info ,看看 Docker 是否存在和正常膜钓。
運行第一個容器
docker run -i -t ubuntu /bin/bash
對命令產(chǎn)生疑問嗽交,可以使用docker help命令來查看命令說明
在第一條命令中,我們先告訴了 Docker 執(zhí)行 docker run 命令颂斜,并指定了 -i -t 兩個命令行參數(shù)夫壁。其中 -i 表示開啟 STDIN,-t 表示 Docker 要為創(chuàng)建的容器分配一個偽 tty 終端沃疮。這樣新創(chuàng)建的容器才能提供一個交互式 shell盒让。
接下來,我們指明了使用 ubuntu 鏡像來創(chuàng)建容器司蔬。ubuntu 鏡像是一個常備鏡像邑茄,可作為“基礎(chǔ)(base)”鏡像,類似的鏡像還有 fedora俊啼、debian肺缕、centos,它們都是由 Docker 官方提供的,保存在 Docker Hub Registry 上同木。
實際上發(fā)生了什么浮梢?
- 首先,Docker 在本地查找 ubuntu 鏡像(由于我們沒有指明鏡像的版本彤路,默認為最新版鏡像 ubuntu:latest )黔寇,如果沒有找到,就連接官方 Docker Hub Registry 查看 Docker Hub 中有沒有 ubuntu 鏡像斩萌。一旦找到就會下載到本地宿主機中缝裤。
- 隨后,Docker 在文件系統(tǒng)內(nèi)用這個鏡像創(chuàng)建了一個容器颊郎。容器擁有自己的網(wǎng)絡(luò)憋飞、IP,以及一個用來和宿主機進行通信的橋接網(wǎng)絡(luò)接口姆吭。
- 最后榛做,我們告訴 Docker 在新容器中要執(zhí)行什么命令,例中我們執(zhí)行了 /bin/bash 内狸。當容器創(chuàng)建完畢检眯,Docker 就會執(zhí)行容器中的 /bin/bash 命令,就可以看到容器中的 shell 了昆淡。
root@10871b426af0:/#
容器命名
docker run --name my_ubuntu -i -t ubuntu /bin/bash
上述命令將會創(chuàng)建名為 my_ubuntu 的容器锰瘸。一個合法的容器名只能包含以下字符:a-z、A-Z昂灵、0-9避凝、下劃線、句號眨补、減號管削,用正則表達式表示為 [a-zA-Z0-9-_.](因為句號在正則表達式中為通配字符,所以請把 . 理解為轉(zhuǎn)義后的句號)撑螺。
在 Docker 中可以用容器名含思、UUID 縮寫、UUID 來唯一指定一個容器甘晤。但是推薦為容器命名含潘,這樣更加方便理解與管理。
容器的命名不可重復(fù)安皱,如果試圖創(chuàng)建和已有容器相同名稱的新容器调鬓,命令會執(zhí)行失敗∽靡粒可以先執(zhí)行 docker rm 命令刪除已有容器腾窝,再創(chuàng)建新容器缀踪。
查看容器
docker ps 命令可以顯示當前正在運行的容器;如果指定參數(shù) -a 虹脯,則可以顯示所有容器驴娃;指定參數(shù) -l ,則只顯示最后一個啟動的容器循集。還可以使用 docker ps -n x命令唇敞,它會顯示最后x個容器,不論這些容器的運行狀態(tài)如何咒彤。
啟動停止的容器
docker start 與 docker restart 這兩個命令疆柔,前者可以啟動已經(jīng)停止的容器,后者無論容器處于運行還是停止狀態(tài)都可以重新啟動容器镶柱。
類似地旷档,docker create 命令可以創(chuàng)建一個容器,但不運行它歇拆。
附著到容器上
執(zhí)行 docker attach 命令鞋屈,可以附著到處于運行狀態(tài)容器的會話上。如果用在上面的 ubuntu 容器故觅,則會進入 shell厂庇,此時如果退出 shell,容器也將停止输吏。
創(chuàng)建守護式容器
除了上述的交互式容器(interactive container)权旷,也可以創(chuàng)建長期運行的容器。守護式容器(daemonized container)沒有交互式會話评也,適合運行應(yīng)用程序和服務(wù)炼杖。
在 docker run 命令中指定 -d 參數(shù),Docker 便會創(chuàng)建守護式容器放到后臺運行盗迟。
docker run --name daemon_hello_world -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
該命令創(chuàng)建了一個守護式容器,并于后臺運行熙含,運行后執(zhí)行了循環(huán)打印 hello world 的命令罚缕。
看看容器內(nèi)部在做什么
針對上面的例子,我們知道容器正在每隔1秒打印一條 hello world 日志怎静。使用以下命令可以參看容器的日志:
docker logs daemon_hello_world
它將獲取到最后的一些日志并返回邮弹。我們還可以對 docker logs 命令指定 -f 參數(shù)來跟蹤打印日志,-t 參數(shù)用于顯示日志的打印時間蚓聘‰缦纾可以這樣指定參數(shù) -ft。
docker logs 命令還可以指定參數(shù) --tail 7 表示只打印最后的7條日志夜牡。 下面我們結(jié)合使用一下:
docker logs --tail 3 -ft daemon_hello_world 這條命令就表示与纽,立刻打印最近3條日志并跟蹤打印日志,且每行打印都帶有時間戳。
2019-03-11T16:34:38.962240900Z hello world
2019-03-11T16:34:39.963360400Z hello world
2019-03-11T16:34:40.964409500Z hello world
2019-03-11T16:34:41.964991100Z hello world
2019-03-11T16:34:42.966022100Z hello world
2019-03-11T16:34:43.967181500Z hello world
查看容器中的進程
docker top daemon_hello_world
執(zhí)行結(jié)果:
PID USER TIME COMMAND
19039 root 0:00 /bin/sh -c while true; do echo hello world; sleep 1;done
19143 root 0:00 sleep 1
Docker統(tǒng)計信息
docker stats
該命令可以顯示一個或多個容器的統(tǒng)計信息急迂。輸出樣式如下:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
6174c0b2ac26 daemon_hello_world 0.14% 968KiB / 1.934GiB 0.05% 928B / 0B 2.16MB / 0B 2
4dc6ef70adf6 redis 0.14% 1.977MiB / 1.934GiB 0.10% 3.38kB / 0B 8.53MB / 0B 4
658af9c3a304 mysql 8.12% 376.4MiB / 1.934GiB 19.00% 6.52MB / 29.4MB 113MB / 22.5MB 35
ce5da739a2a3 rabbitmq 0.33% 88.3MiB / 1.934GiB 4.46% 2.88kB / 0B 39.9MB / 123kB 88
在容器內(nèi)運行進程
使用 docker exec 命令在新容器內(nèi)額外啟動新進程影所。容器內(nèi)運行的進程有兩種:后臺任務(wù)和交互式任務(wù)(須保持在前臺)。
docker exec -d daemon_hello_world touch /etc/new_config_file
上面的命令中 -d 表明要運行的是一個后臺進程僚碎,命令在容器中新建了 /etc/new_config_file 空文件猴娩。
我們還可以使用命令 docker exec -i -t daemon_hello_world /bin/bash ,在 daemon_hello_world 容器中創(chuàng)建一個新的 bash 會話勺阐。
停止守護式容器
可以使用 docker stop 停止正在運行的容器售睹。如果想快速停止容器,還可以使用 docker kill 命令牛哺。
docker stop 向容器進程發(fā)送 SIGTERM 新號颜说。而 docker kill 向容器發(fā)送 SIGKILL 新號。
自動重啟的容器
默認的容器是不會自動重啟的腰吟,通過 --restart 標志无埃,可以讓 Docker 自動重新啟動容器。
docker run --restart=always --name daemon_restart -d ubuntu /bin/sh -c "while true; do echo hello xxx; sleep 1; done"
上面的命令中 --restart 標志被設(shè)置為 always 毛雇。表示無論容器的退出代碼是什么嫉称,Docker 都會自動重啟該容器。還可以設(shè)置為 on-failure 灵疮,如此只有當退出碼不為 0 的時候织阅,才會重啟;同時 on-failure 還接受一個重啟次數(shù)可選參數(shù)震捣,--restart=on-failure:5荔棉,沒錯這條命令表示當異常退出容器時,最多重啟5次蒿赢。
刪除容器
可以使用 docker rm 來刪除不用的容器润樱。默認執(zhí)行是不可以刪除運行中的容器的,但是可以使用 -f 標志來強制刪除正在運行的容器羡棵。
如果你想一次性刪除所有的容器壹若,可以使用以下命令
docker rm `docker ps -a -q`
注意:命令中的符號 ` 不是單引號,而是Tab鍵上方的那個反單引號皂冰,我第一次看的時候就看錯了店展。
上面的命令中的 -q 表示只列出容器的 ID,如果對命令參數(shù)有什么疑問秃流,可以使用help命令查看赂蕴。比如上面這個命令中,我對-q標志有疑問舶胀,可以使用 docker help ps 來查看詳細的命令說明概说。
深入容器
除了通過 docker ps 獲取獲取容器信息碧注,還可以用 docker inspect 來獲得更多的容器信息。
執(zhí)行:docker inspect daemon_hello_world
結(jié)果:
[
{
"Id": "64ded64e3207d3583a19e1ac4d8ed86f6813e2d06764c7b618b3bb52911ac8ef",
"Created": "2019-03-12T11:01:33.8559955Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true; do echo hello world; sleep 1; done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 6588,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-03-12T11:01:34.5640346Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:47b19964fb500f3158ae57f20d16d8784cc4af37c52c49d3b4f5bc5eede49541",
"ResolvConfPath": "/var/lib/docker/containers/64ded64e3207d3583a19e1ac4d8ed86f6813e2d06764c7b618b3bb52911ac8ef/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/64ded64e3207d3583a19e1ac4d8ed86f6813e2d06764c7b618b3bb52911ac8ef/hostname",
"HostsPath": "/var/lib/docker/containers/64ded64e3207d3583a19e1ac4d8ed86f6813e2d06764c7b618b3bb52911ac8ef/hosts",
"LogPath": "/var/lib/docker/containers/64ded64e3207d3583a19e1ac4d8ed86f6813e2d06764c7b618b3bb52911ac8ef/64ded64e3207d3583a19e1ac4d8ed86f6813e2d06764c7b618b3bb52911ac8ef-json.log",
"Name": "/daemon_hello_world",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
50,
120
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/f84227ba5382db67d06e819a3a4c16230bb2dfa3f2daab5054c0935d79fd5c2a-init/diff:/var/lib/docker/overlay2/8a9e1bb011fe79aa7d9a139a55f4bc00fa9ede6e9ba877b23f20110b9dceb600/diff:/var/lib/docker/overlay2/430a6679897b4216a7b5cb76a32197aba98c6d539b08ee23bb23f0e9a3a070c6/diff:/var/lib/docker/overlay2/99d8f0e93a56d6b8147d50b09dd937a0fcc2d34a2a76f71b782cc7b27891d4ca/diff:/var/lib/docker/overlay2/585e92baad5fb64f4b3aa63992f39c8746be7f8c5429bef61257a9595738aa83/diff",
"MergedDir": "/var/lib/docker/overlay2/f84227ba5382db67d06e819a3a4c16230bb2dfa3f2daab5054c0935d79fd5c2a/merged",
"UpperDir": "/var/lib/docker/overlay2/f84227ba5382db67d06e819a3a4c16230bb2dfa3f2daab5054c0935d79fd5c2a/diff",
"WorkDir": "/var/lib/docker/overlay2/f84227ba5382db67d06e819a3a4c16230bb2dfa3f2daab5054c0935d79fd5c2a/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "64ded64e3207",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"while true; do echo hello world; sleep 1; done"
],
"Image": "ubuntu",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "2cc78ade49335bcd8ea4e319b9a8623aae807e75d24dc8b62112b557710a9964",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/2cc78ade4933",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "d8e464ae9ea5f91625c24ca59898edb990cc9046f131345ec9ba39cfb0a870e0",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.5",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:05",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "fb546420908ebd183567666f618142803234d185b401fbe1b7dd3500553c3a35",
"EndpointID": "d8e464ae9ea5f91625c24ca59898edb990cc9046f131345ec9ba39cfb0a870e0",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.5",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:05",
"DriverOpts": null
}
}
}
}
]
docker inspect 還可以用 -f --format 標志選定查看結(jié)果席怪,以及也可以同時指定多個容器应闯。
執(zhí)行:docker inspect -f '{{.NetworkSettings.IPAddress}}' daemon_hello_world redis mysql
結(jié)果:
172.17.0.5
172.17.0.2
172.17.0.3
至此,你學(xué)會了一些基本的 docker 命令挂捻,但是還沒到能實用的地步碉纺,讓我們繼續(xù)下一篇吧。