赞
踩
上节学习了镜像(image),本节学习容器(container)。
容器是 Docker 的三个基本概念中的又一核心概念。容器是镜像的运行时实例。可以从单个镜像上启动一个或多个容器。简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
再来温习一下虚拟机和容器的差异:
虚拟机和容器最大的区别是容器更快并且更轻量级——与虚拟机运行在完整的操作系统之上相比,容器会共享其所在主机的操作系统/内核。
基于一个镜像启动容器的命令:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
下面以操作镜像 centos 为例,来启动一个centos 应用的容器。
docker run -it centos
参数说明:
-i: 交互式操作,让容器的标准输入保持打开。
-t: 终端,Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上。
centos: centos 镜像。
在交互模式下,用户可以通过所创建的终端来输入命令。
仔细观察,就会发现 Shell 提示符发生了变化,说明目前已经位于容器内部了。在上面的示例中,Shell 提示符已经变为 root@12e7a7b65fea:/#。@ 之后的一长串数字就是容器唯一 ID 的前 12 个字符。若尝试在容器内执行一些基础命令,可能会发现某些指令无法正常工作。这是因为大部分容器镜像都是经过高度优化的。这意味着某些命令或者包可能没有安装。
当利用 docker run
来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个 ip 地址给容器
执行用户指定的应用程序
执行完毕后容器被终止
要退出终端,直接输入 exit:
exit
可以利用 docker start
命令,直接将一个已经终止的容器启动运行。
容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 ps
或 top
来查看进程信息。
可见,容器中仅运行了指定的 bash 应用。这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d
参数来实现。
下面举两个例子来说明一下。
如果不使用 -d
参数运行容器。
docker run centos:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
容器会把输出的结果 (STDOUT) 打印到宿主机上面
如果使用了 -d
参数运行容器。
docker run centos:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面。
输出结果可以用 docker logs
查看:
docker logs [OPTIONS] CONTAINER
参数说明:
CONTAINER:容器ID 或容器name
注: 容器是否会长久运行,是和 docker run
指定的命令有关,和 -d
参数无关。
使用 -d
参数启动后会返回一个唯一的 id,也可以通过 docker container ls
或 docker ps 命令来查看容器信息。
要获取容器的输出信息,可以通过 docker container logs
命令。
注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec(下面会介绍到)。
可以使用 docker stop
来终止一个运行中的容器。
docker stop <容器 ID>
此外,当 Docker 容器中指定的应用终结时,容器也自动终止。
例如对于上一章节中只启动了一个终端的容器,用户通过 exit
命令或 Ctrl+d
来退出终端时,所创建的容器立刻终止。
终止状态的容器可以用 docker ps -a
命令看到。例如
处于终止状态的容器,可以通过 docker start
命令来重新启动。
docker restart <容器 ID>
此外,docker restart
命令会将一个运行态的容器终止,然后再重新启动它。
docker restart <容器 ID>
在使用 -d 参数时,容器启动后会进入后台,以守护态运行。此时想要进入容器,可以通过以下指令进入:
- docker attach [容器ID]
- docker exec [容器ID]
推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
下面演示了使用 docker attach 命令。
注:如果从这个容器退出,会导致容器的停止。
下面演示了使用 docker exec 命令。
可以看到我使用进入命令进入容器,报错提示这个容器未运行,验证了之前的说法,我重启后再次进入即可
注意
:如果从这个容器退出,不会导致容器的停止,这就是为什么推荐大家使用 docker exec 的原因。
docker exec
后边可以跟多个参数,这里主要说明 -i
-t
参数。
只用 -i
参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。
当 -i
-t
参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
更多参数说明请使用 docker exec --help
命令查看。
如果要导出本地某个容器,可以使用 docker export
命令。
这样将导出容器快照到本地文件。
可以使用 docker import
从容器快照文件中再导入为镜像,
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
例如:
此外,也可以通过指定 URL 或者某个目录来导入,例如
[root@iZ8vbdmp7p7nu6o38oalgoZ ~]# docker import http://example.com/exampleimage.tgz example/imagerepo
注:用户既可以使用 docker load
来导入镜像存储文件到本地镜像库,也可以使用 docker import
来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
可以使用 docker rm
来删除一个处于终止状态的容器。
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
例如:
- [root@Roker~]# docker rm myDemo
- myDemo
- [root@Roker~]#
如果要删除一个运行中的容器,可以添加 -f
参数。Docker 会发送 SIGKILL
信号给容器。
清理所有处于终止状态的容器
用 docker ps -a
命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
docker container prune
显示容器的配置细节和运行时信息。该命令接收容器名称和容器 ID 作为主要参数。
Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...]
- [root@iZ8vbdmp7p7nu6o38oalgoZ ~]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- eb31302470a4 mysql "docker-entrypoint..." 4 days ago Up 19 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
- [root@iZ8vbdmp7p7nu6o38oalgoZ ~]# docker inspect eb31302470a4
- [
- {
- "Id": "eb31302470a446421a4c53712437e10e3d17e4d052181154cb1871c9e0b7e30c",
- "Created": "2020-07-03T09:14:07.298906124Z",
- "Path": "docker-entrypoint.sh",
- "Args": [
- "mysqld"
- ],
- "State": {
- "Status": "running",
- "Running": true,
- "Paused": false,
- "Restarting": false,
- "OOMKilled": false,
- "Dead": false,
- "Pid": 16484,
- "ExitCode": 0,
- "Error": "",
- "StartedAt": "2020-07-07T07:11:09.879088408Z",
- "FinishedAt": "2020-07-07T05:35:31.816272022Z"
- },
- "Image": "sha256:be0dbf01a0f3f46fc8c88b67696e74e7005c3e16d9071032fa0cd89773771576",
- "ResolvConfPath": "/var/lib/docker/containers/eb31302470a446421a4c53712437e10e3d17e4d052181154cb1871c9e0b7e30c/resolv.conf",
- "HostnamePath": "/var/lib/docker/containers/eb31302470a446421a4c53712437e10e3d17e4d052181154cb1871c9e0b7e30c/hostname",
- "HostsPath": "/var/lib/docker/containers/eb31302470a446421a4c53712437e10e3d17e4d052181154cb1871c9e0b7e30c/hosts",
- "LogPath": "",
- "Name": "/mysql",
- "RestartCount": 0,
- "Driver": "overlay2",
- "MountLabel": "",
- "ProcessLabel": "",
- "AppArmorProfile": "",
- "ExecIDs": null,
- "HostConfig": {
- "Binds": null,
- "ContainerIDFile": "",
- "LogConfig": {
- "Type": "journald",
- "Config": {}
- },
- "NetworkMode": "default",
- "PortBindings": {
- "3306/tcp": [
- {
- "HostIp": "",
- "HostPort": "3306"
- }
- ]
- },
- "RestartPolicy": {
- "Name": "no",
- "MaximumRetryCount": 0
- },
- "AutoRemove": false,
- "VolumeDriver": "",
- "VolumesFrom": null,
- "CapAdd": null,
- "CapDrop": null,
- "Dns": [],
- "DnsOptions": [],
- "DnsSearch": [],
- "ExtraHosts": null,
- "GroupAdd": null,
- "IpcMode": "",
- "Cgroup": "",
- "Links": null,
- "OomScoreAdj": 0,
- "PidMode": "",
- "Privileged": false,
- "PublishAllPorts": false,
- "ReadonlyRootfs": false,
- "SecurityOpt": null,
- "UTSMode": "",
- "UsernsMode": "",
- "ShmSize": 67108864,
- "Runtime": "docker-runc",
- "ConsoleSize": [
- 0,
- 0
- ],
- "Isolation": "",
- "CpuShares": 0,
- "Memory": 0,
- "NanoCpus": 0,
- "CgroupParent": "",
- "BlkioWeight": 0,
- "BlkioWeightDevice": null,
- "BlkioDeviceReadBps": null,
- "BlkioDeviceWriteBps": null,
- "BlkioDeviceReadIOps": null,
- "BlkioDeviceWriteIOps": null,
- "CpuPeriod": 0,
- "CpuQuota": 0,
- "CpuRealtimePeriod": 0,
- "CpuRealtimeRuntime": 0,
- "CpusetCpus": "",
- "CpusetMems": "",
- "Devices": [],
- "DiskQuota": 0,
- "KernelMemory": 0,
- "MemoryReservation": 0,
- "MemorySwap": 0,
- "MemorySwappiness": -1,
- "OomKillDisable": false,
- "PidsLimit": 0,
- "Ulimits": null,
- "CpuCount": 0,
- "CpuPercent": 0,
- "IOMaximumIOps": 0,
- "IOMaximumBandwidth": 0
- },
- "GraphDriver": {
- "Name": "overlay2",
- "Data": {
- "LowerDir": "/var/lib/docker/overlay2/e55c3a894a955decf9855ff9c4891e473ae91ebe0930cbe470a90d9f2b4e9d92-init/diff:/var/lib/docker/overlay2/7bd107ffabb5689f779b705daf5ffcf2c668170085d5b6e52ad834f4cb724e8d/diff:/var/lib/docker/overlay2/6bf0d8d767582ce705ba8161ffbf623aba39371b14ed8c32af30cc6b4200bc17/diff:/var/lib/docker/overlay2/307e7e6341373d2838878a29b85aa5ed7a16460be548d8a1cc33829660e217e2/diff:/var/lib/docker/overlay2/5168738ad442c95cb430279cbf9fe21b13be93b26356727cf6403a4d3039ba43/diff:/var/lib/docker/overlay2/c5b216ad92d6f71d124b4c6771d4266ffefc271b9ec9677d251c2c12bbb1408e/diff:/var/lib/docker/overlay2/0f4f3bbb8487b0a95cf15050e8eebd26e8e7498c33511a47f6fe4d2937fe1379/diff:/var/lib/docker/overlay2/5de030164b5a5f9c56de563259135e7af84ea4ce4b2829c5a0206ed8baf82c4d/diff:/var/lib/docker/overlay2/e62c1b354dfb87c17f10b40bfe1d15d5e0b0dc48e17bd3ef0a6cdd31ee3dcd1c/diff:/var/lib/docker/overlay2/3b2b9f340fec2219b9cbb792b0ec17798a0882e17abb1a63e5fe22ad1e5104d8/diff:/var/lib/docker/overlay2/561d54b951cec23637e970adc36fbef56446d898c82fdc0041aa1fc656933532/diff:/var/lib/docker/overlay2/56441d46f7c1bbd67ba7440bfd089afe3b26c778ffee983a6ac3da5e2e7fb18f/diff:/var/lib/docker/overlay2/1c25bd256e180fbeca31389e7278a26102a8f4e002c5798725a8b3af06bfb4fb/diff",
- "MergedDir": "/var/lib/docker/overlay2/e55c3a894a955decf9855ff9c4891e473ae91ebe0930cbe470a90d9f2b4e9d92/merged",
- "UpperDir": "/var/lib/docker/overlay2/e55c3a894a955decf9855ff9c4891e473ae91ebe0930cbe470a90d9f2b4e9d92/diff",
- "WorkDir": "/var/lib/docker/overlay2/e55c3a894a955decf9855ff9c4891e473ae91ebe0930cbe470a90d9f2b4e9d92/work"
- }
- },
- "Mounts": [
- {
- "Type": "volume",
- "Name": "da1b1b391fb4bd7aa58273f9548c5d13d0b934e84d6d0f73d490425456b38737",
- "Source": "/var/lib/docker/volumes/da1b1b391fb4bd7aa58273f9548c5d13d0b934e84d6d0f73d490425456b38737/_data",
- "Destination": "/var/lib/mysql",
- "Driver": "local",
- "Mode": "",
- "RW": true,
- "Propagation": ""
- }
- ],
- "Config": {
- "Hostname": "eb31302470a4",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "3306/tcp": {},
- "33060/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "MYSQL_ROOT_PASSWORD=000000",
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
- "GOSU_VERSION=1.12",
- "MYSQL_MAJOR=8.0",
- "MYSQL_VERSION=8.0.20-1debian10"
- ],
- "Cmd": [
- "mysqld"
- ],
- "ArgsEscaped": true,
- "Image": "mysql",
- "Volumes": {
- "/var/lib/mysql": {}
- },
- "WorkingDir": "",
- "Entrypoint": [
- "docker-entrypoint.sh"
- ],
- "OnBuild": null,
- "Labels": {}
- },
- "NetworkSettings": {
- "Bridge": "",
- "SandboxID": "64f77b452c68c6e77564ddae9e1259cd5407d3e88e02eaca0992703d13da45b5",
- "HairpinMode": false,
- "LinkLocalIPv6Address": "",
- "LinkLocalIPv6PrefixLen": 0,
- "Ports": {
- "3306/tcp": [
- {
- "HostIp": "0.0.0.0",
- "HostPort": "3306"
- }
- ],
- "33060/tcp": null
- },
- "SandboxKey": "/var/run/docker/netns/64f77b452c68",
- "SecondaryIPAddresses": null,
- "SecondaryIPv6Addresses": null,
- "EndpointID": "79f7bc65f7db15a7d1b5639771d0e3ad212755df49ac58ea67ae8aed6151265e",
- "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": {
- "IPAMConfig": null,
- "Links": null,
- "Aliases": null,
- "NetworkID": "2c8318a19c78a634950d6a1b364604cdcf91f817ab76d3de3125159de17b527f",
- "EndpointID": "79f7bc65f7db15a7d1b5639771d0e3ad212755df49ac58ea67ae8aed6151265e",
- "Gateway": "172.17.0.1",
- "IPAddress": "172.17.0.2",
- "IPPrefixLen": 16,
- "IPv6Gateway": "",
- "GlobalIPv6Address": "",
- "GlobalIPv6PrefixLen": 0,
- "MacAddress": "02:42:ac:11:00:02"
- }
- }
- }
- }
- ]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。