Docker使用笔记(二)Docker容器简单使用

在上一节讲了如何安装docker以及一些配置的更改,本节将会初步介绍docker容器的使用。

1、运行我们的第一个容器

现在, 让我们尝试启动第一个Docker容器。 我们可以使用docker run命令创建容器。docker run命令提供了Docker容
器的创建到启动的功能。

[05:37 shexuan@hulab ~]$ docker run --name bob_the_container -i -t ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
Trying to pull repository docker.io/library/ubuntu ...
latest: Pulling from docker.io/library/ubuntu
473ede7ed136: Pull complete
c46b5fa4d940: Pull complete
93ae3df89c92: Pull complete
6b1eed27cade: Pull complete
Digest: sha256:29934af957c53004d7fb6340139880d23fb1952505a15d69a03af0d1418878cb
Status: Downloaded newer image for docker.io/ubuntu:latest
root@9edcf79a4252:/#

上面命令启动运行了一个容器,并指定了多个参数:

  • run docker run用来启动一个容器;
  • --name 为我们运行的容器指定一个名字,不指定的话则系统会生成一个名称;
  • -i -i标志保证容器中STDIN是开启的, 尽管我们并没有附着到容器中。 持久的标准输入是交互式shell的“半边天”;
  • -t -t标志则是另外“半边天”, 它告诉Docker为要创建的容器分配一个伪tty终端;
  • /bin/bash 为运行的容器执行的第一个命令,这个命令启动了一个Bash shell。

在很多Docker命令中, 都可以用容器的名称来替代容器ID, 后面我们将会看到。 容器名称有助于分辨容器, 当构建容器和应用程序之间的逻辑连接时, 容器的名称也有助于从逻辑上理解连接关系。 具体的名称(如web、 db) 比容器ID和随机容器名好记多了。 我推荐大家都使用容器名
称, 以更加方便地管理容器。

容器的命名必须是唯一的。 如果试图创建两个名称相同的容器, 则命令将会失败。 如果要使用的容器名称已经存在, 可以先用docker rm命令删除已有的同名容器后, 再来创建新的容器。

最后,输入exit可以退出当前容器。
若想在退出容器后自动删除容器,还可以加上--rm参数。

如果由于某种错误而导致容器停止运行,还可以通过--restart标志,让Docker自动重新启动该容器。 --restart标志会检查容器的退出代码, 并据此来决定是否要重启容器。 默认的行为是Docker不会重启容器。

$ docker run --restart=always --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

在本例中, --restart标志被设置为always。 无论容器的退出代码是什么, Docker都会自动重启该容器。 除了always, 还可以将这个标志设为on-failure, 这样, 只有当容器的退出代码为非0值的时候, 才会自动重启。 另外, on-failure还接受一个可选的重启次数参数。

# 当容器退出代码为非0时, Docker会尝试自动重启该容器, 最多重启5次。
$ docker run --restart=on-failure:5 --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
2、重新启动已经停止的容器

在上面输入exit后bob_the_container容器已经停止了, 接下来我们能对它做些什么呢? 如果愿意, 我们可以用start命令重新启动一个已经停止的容器。

[21:03 shexuan@hulab ~]$ docker start bob_the_container
bob_the_container
# 也可以通过ID来指定容器
[21:09 shexuan@hulab ~]$ docker start 22e568aab98b
22e568aab98b

Docker容器重新启动的时候, 会沿用docker run命令时指定的参数来运行, 因此我们的容器重新启动后会运行一个交互式会话shell。 此外,也可以用docker attach命令, 重新附着到该容器的会话上。

# 先启动停止了的容器
[21:26 shexuan@hulab ~]$ docker start bob_the_container
bob_the_container
#  使用attach命令重新附着到该容器的会话上
[21:26 shexuan@hulab ~]$ docker attach bob_the_container
root@22e568aab98b:/#
3、创建守护式容器

除了这些交互式运行的容器(interactive container) , 也可以创建长期运行的容器。 守护式容器(daemonized container) 没有交互式会话, 非常适合运行应用程序和服务。
使用-d参数, Docker会将容器放到后台运行:

[21:33 shexuan@hulab ~]$ docker run --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
42b18316632c701e2ce266e49313cc274963b0bbb2241353da0f11526d403317

上面的命令创建了一个后台运行的容器,我们还在容器里运行了一个while 循环,该循环会一直打印hello world,知道该容器或进程停止运行。

使用docker ps我们可以看到一个正在运行的容器:

[21:33 shexuan@hulab ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
42b18316632c        ubuntu              "/bin/sh -c 'while..."   4 minutes ago       Up 4 minutes                            daemon_dave

使用docker logs可以查看该容器的内部运行情况,或称日志:

[21:40 shexuan@hulab ~]$ docker logs daemon_dave
hello world
hello world
hello world
...
# 加上-f 参数来监控最新日志,这个参数类似于tail -f 命令的作用
[21:40 shexuan@hulab ~]$ docker logs -f daemon_dave
hello world
hello world
hello world
...
# 还可以使用--tail 参数来指定获取日志最后指定行数
[21:45 shexuan@hulab ~]$ docker logs --tail 3 daemon_dave
hello world
hello world
hello world
# 最后你还可以组合使用--tail和-f命令来获取容器的最新日志而不必读取整个日志文件
[21:52 shexuan@hulab ~]$ docker logs --tail 3 -ft daemon_dave
2018-11-06T02:53:01.314952000Z hello world
2018-11-06T02:53:02.316191000Z hello world
2018-11-06T02:53:03.317513000Z hello world
2018-11-06T02:53:04.318959000Z hello world
# -t参数会输出时间戳使得看起来更方便

在上面我们简要介绍了如何使用docker logs来查看守护式容器的内部运行情况,获取其日志文件:

  • -f -f参数类似于tail -f,会不断刷新输出最新日志;
  • --tail输出日志的最后几行;
  • --tail number -f 输出最后指定行数日志并不断刷新输出最新日志;
  • -t 给日志加上时间戳。

最后,可以使用docker stop停止运行守护式容器:

[22:04 shexuan@hulab ~]$ docker stop daemon_dave
daemon_dave

docker stopdocker kill都可以停止运行守护式容器,但是略有区别:

  • docker stop,支持“优雅退出”。先发送SIGTERM信号,在一段时间之后(10s)再发送SIGKILL信号。Docker内部的应用程序可以接收SIGTERM信号,然后做一些“退出前工作”,比如保存状态、处理当前请求等;
  • docker kill,发送SIGKILL信号,应用程序直接退出。

更多docker日志配置可查看更改docker的日志引擎为 journald

4、查看容器内部进程及统计信息

除了容器的日志, 也可以查看容器内部运行的进程。 要做到这一点, 要使用docker top命令:

[22:31 shexuan@hulab ~]$ docker top daemon_dave
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                10317               10299               0                   22:31               ?                   00:00:00            /bin/sh -c while true; do echo hello world; sleep 1; done
root                10466               10317               0                   22:31               ?                   00:00:00            sleep 1

该命令执行后, 可以看到容器内的所有进程(主要还是我们的while循环) 、 运行进程的用户及进程ID。

除了查看进程信息外,还可以通过docker stats来查看一个或多个容器的统计信息:

[22:37 shexuan@hulab ~]$ docker stats daemon_dave
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
daemon_dave         0.13%               952 KiB / 251.6 GiB   0.00%               648 B / 648 B       0 B / 0 B           2

我们能看到一个守护式容器的列表, 以及它们的CPU、 内存、 网络I/O及存储I/O的性能和指标。 这对快速监控一台主机上的一组容器非常有用。

5、在容器中创建新的进程

通过docker exec命令可以在容器内部额外启动新进程。 可以在容器内运行的进程有两种类型: 后台任务和交互式任务。 后台任务在容器内运行且没有交互需求, 而交互式任务则保持在前台运行。

[22:55 shexuan@hulab ~]$ docker exec -d daemon_dave touch /etc/new_config_file

这里的-d标志表明需要运行一个后台进程, -d标志之后, 指定的是要在内部执行这个命令的容器的名字以及要执行的命令。 上面例子中的命令会在daemon_dave容器内创建了一个空文件, 文件名为/etc/new_config_file。 通过docker exec后台命令, 可以在正在运行的容器中进行维护、 监控及管理任务。

我们也可以在daemon_dave容器中新打开一个shell的交互式任务:

[22:55 shexuan@hulab ~]$ docker exec -t -i daemon_dave /bin/bash
root@42b18316632c:/#

和启动容器时候一样,这里的-i -t为我们执行的进程创建了TTY并捕捉STDIN。最后的/bin/bash为一个新创建的shell。

run, attach, exec的区别:

  • docker run通常是在新创建的容器中所使用的命令。 它适用于在没有其他容器运行的情况下,您想要创建一个容器,并且要启动它,然后在其上运行一个进程;
  • docker exec适用于在现有容器中运行命令的情况。如果您已经拥有了一个正在运行的容器,并希望更改该容器或从中获取某些内容,那么使用“docker exec”命令就非常合适了;
  • docker attach也是相当于继续运行已有的容器,但是并不会另外启动一个进程,而是以初始docker run启动命令的会话上。
6、深入了解容器信息

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

[00:49 shexuan@hulab ~]$ docker inspect daemon_dave
[
    {
        "Id": "42b18316632c701e2ce266e49313cc274963b0bbb2241353da0f11526d403317",
        "Created": "2018-11-06T02:33:42.333222931Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while\ntrue; do echo hello world; sleep 1; done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 10317,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2018-11-06T03:31:21.144011748Z",
            "FinishedAt": "2018-11-06T03:05:00.01247215Z"
        },
        "Image": "sha256:ea4c82dcd15a33e3e9c4c37050def20476856a08e59526fbe533cc4e98387e39",
...
]

docker inspect命令会对容器进行详细的检查, 然后返回其配置信息, 包括名称、命令、网络配置、基础镜像以及很多有用的数据。

也可以用-f或者--format标志来选定查看结果:

[00:53 shexuan@hulab ~]$ docker inspect --format='{{ .State.Running }}' daemon_dave
false

docker inspect支持同时指定多个容器, 并显示每个容器的输出结果。

7、删除容器

如果容器已经不再使用(已停止使用), 可以使用docker rm命令来删除它们。如果想删除正在运行的容器,可以加上-f参数。

[00:58 shexuan@hulab ~]$ docker rm daemon_dave
daemon_dave

目前, 还没有办法一次删除所有容器,但是可以通过下面的小技巧来一次性删除所有容器:

[01:02 shexuan@hulab ~]$ docker rm `sudo docker ps -a -q`
9f0b544d3573
22e568aab98b

上面的docker ps命令会列出现有的全部容器, -a标志代表列出所有容器, 而-q标志则表示只需要返回容器的ID而不会返回容器的其他信息。这样我们就得到了容器ID的列表, 并传给了docker rm命令, 从而达到删除所有容器的目的。

参考:
《第一本docker书》

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275

推荐阅读更多精彩内容