上节学习了镜像(image),本节学习容器(container)。

一、基本概念

容器是 Docker 的三个基本概念中的又一核心概念。容器是镜像的运行时实例。可以从单个镜像上启动一个或多个容器。简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。

再来温习一下虚拟机和容器的差异:

虚拟机和容器最大的区别是容器更快并且更轻量级——与虚拟机运行在完整的操作系统之上相比,容器会共享其所在主机的操作系统/内核。

docker容器unhealth Docker容器详解_docker

二、基本操作 

1、启动容器

基于一个镜像启动容器的命令:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

 下面以操作镜像 centos 为例,来启动一个centos 应用的容器。

docker run -it centos

docker容器unhealth Docker容器详解_docker_02

参数说明:

  • -i: 交互式操作,让容器的标准输入保持打开。
  • -t: 终端,Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上。
  • centos: centos 镜像。

在交互模式下,用户可以通过所创建的终端来输入命令。

仔细观察,就会发现 Shell 提示符发生了变化,说明目前已经位于容器内部了。在上面的示例中,Shell 提示符已经变为 root@12e7a7b65fea:/#。@ 之后的一长串数字就是容器唯一 ID 的前 12 个字符。若尝试在容器内执行一些基础命令,可能会发现某些指令无法正常工作。这是因为大部分容器镜像都是经过高度优化的。这意味着某些命令或者包可能没有安装。

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止

要退出终端,直接输入 exit:

exit

docker容器unhealth Docker容器详解_docker容器unhealth_03

启动已终止容器

可以利用 docker start

容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 pstop 来查看进程信息。

docker容器unhealth Docker容器详解_docker_04

可见,容器中仅运行了指定的 bash 应用。这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。

docker容器unhealth Docker容器详解_docker容器unhealth_05

2、守护态运行

更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。

下面举两个例子来说明一下。

如果不使用 -d 参数运行容器。

docker run centos:latest /bin/sh -c  "while true; do echo hello world; sleep 1; done"

docker容器unhealth Docker容器详解_docker容器unhealth_06

容器会把输出的结果 (STDOUT) 打印到宿主机上面

如果使用了 -d 参数运行容器。

docker run centos:latest /bin/sh -c  "while true; do echo hello world; sleep 1; done"

docker容器unhealth Docker容器详解_Docker_07

此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面。

输出结果可以用 docker logs 查看:

docker logs [OPTIONS] CONTAINER

参数说明:

CONTAINER:容器ID 或容器name

注: 容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。

使用 -d 参数启动后会返回一个唯一的 id,也可以通过 docker container ls  或 docker ps  命令来查看容器信息。

docker容器unhealth Docker容器详解_3d_08

要获取容器的输出信息,可以通过 docker container logs 命令。

:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec(下面会介绍到)。

 

3、终止容器

可以使用 docker stop 来终止一个运行中的容器。

docker stop <容器 ID>

此外,当 Docker 容器中指定的应用终结时,容器也自动终止。

例如对于上一章节中只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。

终止状态的容器可以用 docker ps -a 命令看到。例如

处于终止状态的容器,可以通过 docker start

docker restart <容器 ID>

此外,docker restart  命令会将一个运行态的容器终止,然后再重新启动它。

docker restart <容器 ID>

 

4、进入容器

在使用 -d 参数时,容器启动后会进入后台,以守护态运行。此时想要进入容器,可以通过以下指令进入:

  • docker attach [容器ID]
  • docker exec   [容器ID]

推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。

attach 命令

下面演示了使用 docker attach 命令。

docker容器unhealth Docker容器详解_docker容器unhealth_09

:如果从这个容器退出,会导致容器的停止。

docker容器unhealth Docker容器详解_Docker_10

exec 命令

下面演示了使用 docker exec 命令。

docker容器unhealth Docker容器详解_3d_11

可以看到我使用进入命令进入容器,报错提示这个容器未运行,验证了之前的说法,我重启后再次进入即可

注意:如果从这个容器退出,不会导致容器的停止,这就是为什么推荐大家使用 docker exec 的原因。

docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。

只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。

-i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。

更多参数说明请使用  docker exec --help 命令查看。

5、导出容器

如果要导出本地某个容器,可以使用 docker export

docker容器unhealth Docker容器详解_docker容器unhealth_12

这样将导出容器快照到本地文件。

6、导入容器

可以使用 docker import 从容器快照文件中再导入为镜像,

Usage:    docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

例如:

docker容器unhealth Docker容器详解_docker容器unhealth_13


此外,也可以通过指定 URL 或者某个目录来导入,例如

[root@iZ8vbdmp7p7nu6o38oalgoZ ~]# docker import http://example.com/exampleimage.tgz example/imagerepo

:用户既可以使用 docker load  来导入镜像存储文件到本地镜像库,也可以使用 docker import

 

7、删除容器

可以使用 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

8、查看容器详情

显示容器的配置细节和运行时信息。该命令接收容器名称和容器 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"
                }
            }
        }
    }
]