美文网首页
3 Docker 入门

3 Docker 入门

作者: 这样的昵称没问题么 | 来源:发表于2019-03-12 00:37 被阅读0次

    首先,确保 Docker 就绪。在命令行运行 docker info ,看看 Docker 是否存在和正常。

    运行第一个容器

    docker run -i -t ubuntu /bin/bash
    

    对命令产生疑问,可以使用docker help命令来查看命令说明

    在第一条命令中,我们先告诉了 Docker 执行 docker run 命令,并指定了 -i -t 两个命令行参数。其中 -i 表示开启 STDIN,-t 表示 Docker 要为创建的容器分配一个伪 tty 终端。这样新创建的容器才能提供一个交互式 shell。

    接下来,我们指明了使用 ubuntu 镜像来创建容器。ubuntu 镜像是一个常备镜像,可作为“基础(base)”镜像,类似的镜像还有 fedora、debian、centos,它们都是由 Docker 官方提供的,保存在 Docker Hub Registry 上。

    实际上发生了什么?

    • 首先,Docker 在本地查找 ubuntu 镜像(由于我们没有指明镜像的版本,默认为最新版镜像 ubuntu:latest ),如果没有找到,就连接官方 Docker Hub Registry 查看 Docker Hub 中有没有 ubuntu 镜像。一旦找到就会下载到本地宿主机中。
    • 随后,Docker 在文件系统内用这个镜像创建了一个容器。容器拥有自己的网络、IP,以及一个用来和宿主机进行通信的桥接网络接口。
    • 最后,我们告诉 Docker 在新容器中要执行什么命令,例中我们执行了 /bin/bash 。当容器创建完毕,Docker 就会执行容器中的 /bin/bash 命令,就可以看到容器中的 shell 了。
    root@10871b426af0:/#
    

    容器命名

    docker run --name my_ubuntu -i -t ubuntu /bin/bash
    

    上述命令将会创建名为 my_ubuntu 的容器。一个合法的容器名只能包含以下字符:a-z、A-Z、0-9、下划线、句号、减号,用正则表达式表示为 [a-zA-Z0-9-_.](因为句号在正则表达式中为通配字符,所以请把 . 理解为转义后的句号)。

    在 Docker 中可以用容器名、UUID 缩写、UUID 来唯一指定一个容器。但是推荐为容器命名,这样更加方便理解与管理。

    容器的命名不可重复,如果试图创建和已有容器相同名称的新容器,命令会执行失败。可以先执行 docker rm 命令删除已有容器,再创建新容器。

    查看容器

    docker ps 命令可以显示当前正在运行的容器;如果指定参数 -a ,则可以显示所有容器;指定参数 -l ,则只显示最后一个启动的容器。还可以使用 docker ps -n x命令,它会显示最后x个容器,不论这些容器的运行状态如何。

    启动停止的容器

    docker startdocker restart 这两个命令,前者可以启动已经停止的容器,后者无论容器处于运行还是停止状态都可以重新启动容器。

    类似地,docker create 命令可以创建一个容器,但不运行它。

    附着到容器上

    执行 docker attach 命令,可以附着到处于运行状态容器的会话上。如果用在上面的 ubuntu 容器,则会进入 shell,此时如果退出 shell,容器也将停止。

    创建守护式容器

    除了上述的交互式容器(interactive container),也可以创建长期运行的容器。守护式容器(daemonized container)没有交互式会话,适合运行应用程序和服务。

    docker run 命令中指定 -d 参数,Docker 便会创建守护式容器放到后台运行。

    docker run --name daemon_hello_world -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done" 
    

    该命令创建了一个守护式容器,并于后台运行,运行后执行了循环打印 hello world 的命令。

    看看容器内部在做什么

    针对上面的例子,我们知道容器正在每隔1秒打印一条 hello world 日志。使用以下命令可以参看容器的日志:

    docker logs daemon_hello_world
    

    它将获取到最后的一些日志并返回。我们还可以对 docker logs 命令指定 -f 参数来跟踪打印日志,-t 参数用于显示日志的打印时间。可以这样指定参数 -ft

    docker logs 命令还可以指定参数 --tail 7 表示只打印最后的7条日志。 下面我们结合使用一下:

    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
    

    执行结果:

    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统计信息

    docker stats
    

    该命令可以显示一个或多个容器的统计信息。输出样式如下:

    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
    

    在容器内运行进程

    使用 docker exec 命令在新容器内额外启动新进程。容器内运行的进程有两种:后台任务和交互式任务(须保持在前台)。

    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 容器中创建一个新的 bash 会话。

    停止守护式容器

    可以使用 docker stop 停止正在运行的容器。如果想快速停止容器,还可以使用 docker kill 命令。

    docker stop 向容器进程发送 SIGTERM 新号。而 docker kill 向容器发送 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 标志被设置为 always 。表示无论容器的退出代码是什么,Docker 都会自动重启该容器。还可以设置为 on-failure ,如此只有当退出码不为 0 的时候,才会重启;同时 on-failure 还接受一个重启次数可选参数,--restart=on-failure:5,没错这条命令表示当异常退出容器时,最多重启5次。

    删除容器

    可以使用 docker rm 来删除不用的容器。默认执行是不可以删除运行中的容器的,但是可以使用 -f 标志来强制删除正在运行的容器。
    如果你想一次性删除所有的容器,可以使用以下命令

    docker rm `docker ps -a -q`
    

    注意:命令中的符号 ` 不是单引号,而是Tab键上方的那个反单引号,我第一次看的时候就看错了。
    上面的命令中的 -q 表示只列出容器的 ID,如果对命令参数有什么疑问,可以使用help命令查看。比如上面这个命令中,我对-q标志有疑问,可以使用 docker help ps 来查看详细的命令说明。

    深入容器

    除了通过 docker ps 获取获取容器信息,还可以用 docker inspect 来获得更多的容器信息。

    执行:docker inspect daemon_hello_world
    结果:
    [
        {
            "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 标志选定查看结果,以及也可以同时指定多个容器。

    执行:docker inspect -f '{{.NetworkSettings.IPAddress}}' daemon_hello_world redis mysql
    结果:
    172.17.0.5
    172.17.0.2
    172.17.0.3
    

    至此,你学会了一些基本的 docker 命令,但是还没到能实用的地步,让我们继续下一篇吧。

    相关文章

      网友评论

          本文标题:3 Docker 入门

          本文链接:https://www.haomeiwen.com/subject/uopbpqtx.html