15.docker:容器

文章目录

Docker:容器

如何运行容器?

docker run=docker create + docker start

docker run 是启动容器的方法。在讨论 Dockerfile 时我们已经学习到,可用三种方式指定容器启动时执行的命令:

  1. CMD 指令。
  2. ENTRYPOINT 指令。
  3. docker run 命令行中指定。

比如:

bash 复制代码
[root@docker ~]# docker create ubuntu
# 没有ubuntu镜像则自动拉取
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
20043066d3d5: Already exists 
Digest: sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54
Status: Downloaded newer image for ubuntu:latest
7efb831754fec235549691afba678fcbc8be92855978dfc89a5abdd3a70e873b

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS    PORTS     NAMES
7efb831754fe   ubuntu    "/bin/bash"   50 seconds ago   Created             stoic_banzai
# 可以看见此时的容器状态时created

[root@docker ~]# docker start 7efb831754fe
7efb831754fe
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS                     PORTS     NAMES
7efb831754fe   ubuntu    "/bin/bash"   About a minute ago   Exited (0) 2 seconds ago             stoic_banzai
# 启动容器使用容器ID,查看容器状态发现是启动了又退出了

-a 会显示所有状态的容器,可以看到,之前的容器已经退出了,状态为Exited

这种"一闪而过"的容器通常不是我们想要的结果,我们希望容器能够保持 runing 状态,这样才能被我们使用。

让容器长期运行

如何让容器保存运行呢?

因为容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出。

理解了这个原理,我们就可以通过执行一个长期运行的命令来保持容器的运行状态。例如执行下面的命令:

bash 复制代码
[root@docker ~]# docker run ubuntu /bin/bash -c "while true ; do sleep 1 ; echo hahaha; done"
hahaha
hahaha
hahaha
hahaha

可见容器仍处于运行状态。不过这种方法有个缺点:它占用了一个终端。

再开一个窗口,我们加上一个选项-d让容器以后台方式运行

bash 复制代码
[root@docker ~]# docker run -d ubuntu /bin/bash -c "while true ; do sleep 1 ; echo hahaha; done"
291d41dd7aff2e0d15ebf226c0a45826a267888c7389ddb0a05ec9aaefba0bc6
# 这一长串是容器的ID,可以通过docker ps 看见正在运行的容器
[root@docker ~]# 

[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS     NAMES
291d41dd7aff   ubuntu    "/bin/bash -c 'while..."   17 seconds ago       Up 17 seconds                 elated_keldysh
18bafa5e60ec   ubuntu    "/bin/bash -c 'while..."   About a minute ago   Up About a minute             elegant_goodall

现在我们有了两个正在运行的容器。这里注意一下容器的 CONTAINER IDNAMES 这两个字段。

CONTAINER ID 是容器的 "短ID",前面启动容器时返回的是 "长ID"。短ID是长ID的前12个字符。

NAMES 字段显示容器的名字,在启动容器时可以通过 --name 参数显示地为容器命名,如果不指定,docker 会自动为容器分配名字。

对于容器的后续操作,我们需要通过 "长ID"、"短ID" 或者 "名称" 来指定要操作的容器。比如下面停止一个容器:

bash 复制代码
# 根据容器创建的时间我们将之前占用终端的容器停止运行
[root@docker ~]# docker stop 18bafa5e60ec
18bafa5e60ec

这里我们就是通过 "短ID" 指定了要停止的容器。

回到之前的终端查看,也确实停止占用了

进入容器的方法

我们经常需要进到容器里去做一些工作,比如查看日志、调试、启动其他进程等。有两种方法进入容器:attach 和 exec。

docker attach

bash 复制代码
# 连接到容器的主进程(如果退出,容器可能会停止)
docker attach my-container

比如

bash 复制代码
[root@docker ~]# docker run -d ubuntu /bin/bash -c "while true ; do sleep 1 ; echo I_am_in_container ; done"
f371f37a2e215501ed15b7ca66ce7399c80b0b91ac1bf0c5dc9c245a18288993
[root@docker ~]# docker attach f371f37a2e215501ed15b7ca66ce7399c80b0b91ac1bf0c5dc9c245a18288993
I_am_in_container
I_am_in_container
I_am_in_container

这次我们通过 "长ID" attach 到了容器的启动命令终端,之后看到的是echo 每隔一秒打印的信息。

注:可通过 Ctrl+p 然后 Ctrl+q 组合键退出 attach 终端。若没有反应或无法退出可能是因为终端兼容性的问题,开启另外一个窗口输出stop给该容器停止

docker exec

bash 复制代码
# 进入正在运行的容器(打开bash终端)
docker exec -it my-nginx /bin/bash

# 进入容器并执行单个命令
docker exec my-nginx ls /etc/nginx

比如

bash 复制代码
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
291d41dd7aff   ubuntu    "/bin/bash -c 'while..."   10 minutes ago   Up 10 minutes             elated_keldysh
[root@docker ~]# docker exec -it 291d41dd7aff bash
root@291d41dd7aff:/# 

说明如下:

-it 以交互模式打开 pseudo-TTY,执行 bash,其结果就是打开了一个 bash 终端。

② 进入到容器中,容器的 hostname 就是其 "短ID"。可以像在普通 Linux 中一样执行命令。ps -elf 显示了容器启动进程while 以及当前的 bash 进程。

③ 执行 exit 退出容器,回到 docker host。

docker exec -it <container> bash|sh 是执行 exec 最常用的方式。

两者区别

attach 与 exec 主要区别如下:

  1. attach 直接进入容器 启动命令 的终端,不会启动新的进程。
  2. exec 则是在容器中打开新的终端,并且可以启动新的进程。
  3. 如果想直接在终端中查看启动命令的输出,用 attach;其他情况使用 exec。

当然,如果只是为了查看启动命令的输出,可以使用 docker logs 命令:

bash 复制代码
[root@docker ~]# docker logs -f 291d41dd7aff
I_am_in_container
I_am_in_container
I_am_in_container

-f 的作用与 tail -f 类似,能够持续打印输出。

运行容器的最佳实践

按用途容器大致可分为两类:服务类容器和工具类的容器。

  1. 服务类容器以 daemon 的形式运行,对外提供服务。比如 web server,数据库等。通过 -d 以后台方式启动这类容器是非常合适的。如果要排查问题,可以通过 exec -it 进入容器。

  2. 工具类容器通常给能我们提供一个临时的工作环境,通常以 run -it 方式运行,比如:

    bash 复制代码
    [root@docker ~]# docker run -it busybox
    / # 
    / # wget www.baidu.com
    Connecting to www.baidu.com (36.152.44.132:80)
    saving to 'index.html'
    index.html           100% |************************************************************************************|  2381  0:00:00 ETA
    'index.html' saved
    / # 
    / # exit

运行 busybox,run -it 的作用是在容器启动后就直接进入。我们这里通过 wget 验证了在容器中访问 internet 的能力。执行 exit 退出终端,同时容器停止。

工具类容器多使用基础镜像,例如 busybox、debian、ubuntu 等。

一个容器一个进程

bash 复制代码
# ✅ 正确:每个容器只运行一个主要进程
docker run -d --name db mysql
docker run -d --name web nginx
docker run -d --name app myapp

# ❌ 避免:在一个容器里运行多个服务
# (除非使用supervisord等进程管理工具,但不推荐新手)

容器在 docker host 中实际上是一个进程,docker stop 命令本质上是向该进程发送一个 SIGTERM 信号。如果想快速停止容器,可使用 docker kill 命令,其作用是向容器进程发送 SIGKILL 信号。

容器常用操作

生命周期管理

bash 复制代码
# 启动/停止/重启
docker start my-container
docker stop my-container
docker restart my-container

# 暂停/恢复
docker pause my-container
docker unpause my-container

# 删除容器
docker rm my-container
docker rm -f my-container  # 强制删除运行中的容器

容器可能会因某种错误而停止运行。对于服务类容器,我们通常希望在这种情况下容器能够自动重启。启动容器时设置 --restart 就可以达到这个效果。

比如:

一般我们进入容器后exit出来容器会自动停止,加--restart=always参数,attach进去ctrl_c(终止进程)会自动重启。

bash 复制代码
[root@docker ~]# docker run -d --restart=always httpd
7fb00d6d5aceb690cbd08f61cff45d8d33f14e38a53417983a12ac4da33fe7be

[root@docker ~]# docker attach 7fb
# 这里容器ID只写前几位也是可以的,只要前几位不是重复的
^C[Sun Dec 07 13:13:35.752911 2025] [mpm_event:notice] [pid 1:tid 1] AH00491: caught SIGTERM, shutting down
[root@docker ~]# 
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
7fb00d6d5ace   httpd     "httpd-foreground"       44 seconds ago   Up 12 seconds   80/tcp    stupefied_kare
291d41dd7aff   ubuntu    "/bin/bash -c 'while..."   23 minutes ago   Up 23 minutes             elated_keldysh

--restart=always 意味着无论容器因何种原因退出(包括正常退出),就立即重启。该参数的形式还可以是 --restart=on-failure:3,意思是如果启动进程退出代码非0,则重启容器,最多重启3次。

删除容器

使用 docker 一段时间后,host 上可能会有大量已经退出了的容器。

这些容器依然会占用 host 的文件系统资源,如果确认不会再重启此类容器,可以通过 docker rm 删除。

docker rm 一次可以指定多个容器,如果希望批量删除所有已经退出的容器,可以执行如下命令:

docker rm -v $(docker ps -aq -f status=exited)

bash 复制代码
# !!!慎用,删除所有状态容器
[root@docker ~]# docker rm -f $(docker ps -aq)

顺便说一句:docker rm 是删除容器,而 docker rmi 是删除镜像。

查看信息

bash 复制代码
# 查看正在运行的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 查看容器日志
docker logs my-container
docker logs -f my-container  # 实时查看

# 查看容器资源使用
docker stats

# 查看容器详细信息
docker inspect my-container

文件操作

bash 复制代码
# 从主机复制文件到容器
docker cp file.txt my-container:/path/

# 从容器复制文件到主机
docker cp my-container:/path/file.txt ./

# 查看容器内进程
docker top my-container

容器运行小结

容器运行相关的知识点:

  1. 当 CMD 或 Entrypoint 或 docker run 命令行指定的命令运行结束时,容器停止。
  2. 通过 -d 参数在后台启动容器。
  3. 通过 exec -it 可进入容器并执行命令。

指定容器的三种方法:

  1. 短ID。
  2. 长ID。
  3. 容器名称。 可通过 --name 为容器命名。重命名容器可执行docker rename

容器按用途可分为两类:

  1. 服务类的容器。
  2. 工具类的容器。

一张图搞懂容器所有操作

前面我们已经讨论了容器的各种操作,对容器的生命周期有了大致的理解,下面这张状态机很好地总结了容器各种状态之间是如何转换的。

命名空间和控制组的作用

Cgroup 控制组------ "资源管理"

docker 通过 cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制

Cgroup管理的资源包括:

  • CPU使用率
  • 内存使用量
  • 磁盘I/O
  • 网络带宽
bash 复制代码
# 查看容器的cgroup配置
docker inspect my-container | grep -i cgroup

# 实际cgroup文件位置(Linux系统)
/sys/fs/cgroup/memory/docker/容器ID/
/sys/fs/cgroup/cpu/docker/容器ID/

stress是什么?

是模拟压力测试的工具

在机器上模拟cpu、内存等使用率

来检测不同状态下的运行情况

目前 docker 只是用了其中一部分子系统,实现对资源配额和使用的控制。

可以使用 stress 工具来测试 CPU 和内存。使用下面的 Dockerfile 来创建一个基于 Ubuntu 的 stress 工具镜像。

Dockerfile

bash 复制代码
[root@docker ~]# mkdir dockerfile
[root@docker ~]# cd dockerfile/
[root@docker dockerfile]# vim Dockerfile
[root@docker dockerfile]# cat Dockerfile 
# Version 1
FROM ubuntu
MAINTAINER aabbcc
RUN apt-get -y update && apt-get -y install stress
ENTRYPOINT ["/usr/bin/stress"]       # 以服务或进程的形式运行

# 使用Dockerfile 构建镜像 ubuntu-with-stress
[root@docker dockerfile]# docker build -t ubuntu-with-stress .
[root@docker dockerfile]# docker images                                                                                             
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE                                                                 
ubuntu-with-stress   latest    16c75b683121   53 seconds ago   136MB

一个 docker host 上会运行若干容器,每个容器都需要 CPU、内存和 IO 资源。对于 KVM,VMware 等虚拟化技术,用户可以控制分配多少 CPU、内存资源给每个虚拟机。对于容器,Docker 也提供了类似的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能。

内存限额

和操作系统类似,容器可使用的内存包括两部分:物理内存和 swap。 Docker 通过下面两组参数来控制容器内存的使用量。

  1. -m--memory:设置内存的使用限额,例如 100M, 2G。
  2. --memory-swap:设置 内存+swap 的使用限额。

比如:

docker run -m 200M --memory-swap=300M ubuntu,这条命令的意思就是允许该容器最多使用 200M 的内存和 100M 的 swap。

如果--memory-swap 设置为0 或者不设置,则容器可以使用的swap大小为-m值的两倍。

如果 --memory-swap 的值和-m 值相同,则容器不能使用swap

如果 --memory-swap值为-1。它表示容器程序使用的内存受限,而可以使用的swap空间不受限制(宿主机有多少swap空间该容器就可以使用多少)

下面我们使用ubuntu-with-stress镜像来学习如何为容器分配内存。

该镜像可用于对容器执行压力测试

bash 复制代码
[root@docker ~]# docker run -it -m 200M --memory-swap=300M ubuntu-with-stress --vm 1 --vm-bytes 280M -v

--vm 1:启动 1 个内存工作线程。

--vm-bytes 280M:每个线程分配 280M 内存。

运行结果:

因为 280M 在可分配的范围(300M)内,所以工作线程能够正常工作,其过程是:

  1. 分配 280M 内存。
  2. 释放 280M 内存。
  3. 再分配 280M 内存。
  4. 再释放 280M 内存。
  5. 一直循环...

如果让工作线程分配的内存超过300M,结果如下:

超过限额就会报错,并且容器退出

CPU限额

默认设置下,所有容器可以平等地使用 host CPU 资源并且没有限制。

Docker 可以通过 -c--cpu-shares 设置容器使用 CPU 的权重。如果不指定,默认值为 1024。

--cpu-shares的值不能保证可以获得1个 vcpu 或者多少 GHz 的 CPU 资源,仅仅只是一个弹性的加权值。

默认情况下,每一个docker容器的cpu份额都是1024,但是单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器cpu加权的效果才能体现出来。

例如,两个容器A、B的 CPU 份额分别为1000和500,在 CPU 进行时间片分配的时候,容器 A 比容器 B 多一倍的机会获得 CPU 的时间片,但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器A一定能获得 CPU 时间片。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的 CPU 时间片的。极端情况下,比如说主机上只运行了一个容器,即使它的 CPU 份额只有 50,它也可以独占整个主机的 CPU 资源。

cgroups 只在容器分配的资源紧缺时,也就是说在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的 CPU 份额来确定有多少 CPU 资源分配给它,资源分配结果取决于同时运行的其他容器的 CPU 分配和容器中进程运行情况。

你可以理解为,通过cpu shares 设置容器使用CPU的优先级

下面我们还是用 ubuntu-with-stress 来做个实验

  1. 启动容器 container_A,cpu share 为1024:

    bash 复制代码
    [root@docker ~]# docker run --name "container_A" -it -c 1024 ubuntu-with-stress --cpu 4 -v
    stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 12000us
    stress: dbug: [1] --> hogcpu worker 4 [6] forked
    stress: dbug: [1] using backoff sleep of 9000us
    stress: dbug: [1] --> hogcpu worker 3 [7] forked
    stress: dbug: [1] using backoff sleep of 6000us
    stress: dbug: [1] --> hogcpu worker 2 [8] forked
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogcpu worker 1 [9] forked
    
    # 再开一个窗口
    # 使用下面命令,创建容器,则最终生成的cgroup的cpu份额配置可以在下面文件中找到
    # cat /sys/fs/cgroup/cpu/docker/<容器长ID>/cpu.shares
    
    # 查看容器的长id命令 
    # docker inspect --format='{{.Id}}' <container_name>/短id
    
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS     NAMES
    9e67c6ede5d1   ubuntu-with-stress   "/usr/bin/stress --c..."   2 minutes ago   Up 2 minutes             container_A
    [root@docker ~]# docker inspect --format={{'.Id'}} 9e67c6ede5d1
    9e67c6ede5d15de3bb73bbf2ad1eaf409312dfa3733ca450621f19a80dec2b50
    [root@docker ~]# docker inspect --format={{'.Id'}} container_A
    9e67c6ede5d15de3bb73bbf2ad1eaf409312dfa3733ca450621f19a80dec2b50
    [root@docker ~]# cat /sys/fs/cgroup/cpu/docker/9e67c6ede5d15de3bb73bbf2ad1eaf409312dfa3733ca450621f19a80dec2b50/cpu.shares 
    1024

    /sys/fs/cgroup/cpu/docker 目录中,Linux 会为每个容器创建一个 cgroup 目录,以容器长ID 命名

    同样的,/sys/fs/cgroup/memory/docker/sys/fs/cgroup/blkio/docker 中保存的是内存 以及 Block IO 的 cgroup 配置。

    --cpu 用来设置工作线程的数量。因为当前 host 有 4颗 CPU,所以要4个工作线程才能将 CPU 压满。如果 host 有多颗 CPU,则需要相应增加 --cpu 的数量。

  2. 再开一个窗口,启动 container_B,cpu share 为512:

    bash 复制代码
    [root@docker ~]# docker run --name 'container_B' -it -c 512 ubuntu-with-stress --cpu 4 -v
    stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
    stress: dbug: [1] using backoff sleep of 12000us
    stress: dbug: [1] --> hogcpu worker 4 [6] forked
    stress: dbug: [1] using backoff sleep of 9000us
    stress: dbug: [1] --> hogcpu worker 3 [7] forked
    stress: dbug: [1] using backoff sleep of 6000us
    stress: dbug: [1] --> hogcpu worker 2 [8] forked
    stress: dbug: [1] using backoff sleep of 3000us
    stress: dbug: [1] --> hogcpu worker 1 [9] forked
    
    [root@docker ~]# docker inspect --format={{'.Id'}} container_B
    4e76e2bcc2a9c6b75d49a5afef2459c70fca27e93389b0b1feb8ade2597a24bc 
    [root@docker ~]# cat /sys/fs/cgroup/cpu/docker/4e76e2bcc2a9c6b75d49a5afef2459c70fca27e93389b0b1feb8ade2597a24bc/cpu.shares 
    512
  3. 在host 中执行 top命令,查看容器对cpu的使用情况

    因为我们host是4核所以开启了4个进程,为的就是充分让系统资源变得紧张,只有这样竞争资源,我们设定的资源比例才可以显现出来,如果只运行一个进程,他们会自动分配到空闲的CPU,这样比例就无法看出来。目前可以看到总比例是2:1。

    container_A 消耗的 CPU 是 container_B 的两倍

    再开一个窗口

    bash 复制代码
    [root@docker ~]# docker stats
  4. 现在暂停 container_A

    bash 复制代码
    [root@docker ~]# docker pause container_A
    container_A
  5. top 中显示 container_B 在 container_A 空闲的时候能够用满整颗cpu

Namespace 命名空间------ "隔离墙"

命名空间类型 隔离内容
PID 进程ID
Network 网络接口
Mount 文件系统挂载点
UTS 主机名
IPC 进程间通信
User 用户和组ID

在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。拿网卡来说,每个容器都会认为自己有一块独立的网卡,即使 host 上只有一块物理网卡。这种方式非常好,它使得容器更像一个独立的计算机。

Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离

PID namespace

容器在 host 中以进程的形式运行

这里运行两个容器

bash 复制代码
[root@docker ~]# docker run -d -it httpd
0e9b39878f9abc5c1b706868749ebeb0196c9ece0a8fc9d69dc6b0a2cda67e13
[root@docker ~]# docker run -d -it ubuntu
e949e19402fccf0c415868702a8efac848db0ba0fc71d25a5ded5ca07bcf4b2e
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS              PORTS     NAMES
e949e19402fc   ubuntu    "/bin/bash"          10 seconds ago       Up 9 seconds                  dreamy_wu
0e9b39878f9a   httpd     "httpd-foreground"   About a minute ago   Up About a minute   80/tcp    stoic_bohr

通过ps axf查看容器进程

所有容器的进程都挂在 docker 进程下,同时也可以看到容器自己的子进程。 如果我们进入到某个容器,ps 就只能看到自己的进程了:

bash 复制代码
[root@docker ~]# docker exec -it e949e19402fc bash
root@e949e19402fc:/# 
root@e949e19402fc:/# ps axf
    PID TTY      STAT   TIME COMMAND
      8 pts/1    Ss     0:00 bash
     16 pts/1    R+     0:00  \_ ps axf
      1 pts/0    Ss+    0:00 /bin/bash

而且进程的 PID 不同于 host 中对应进程的 PID,容器中 PID=1 的进程当然也不是 host 的 init 进程。也就是说:容器拥有自己独立的一套 PID,这就是 PID namespace 提供的功能。

Network namespace

Network namespace 让容器拥有自己独立的网卡、IP、路由等资源

Mount namespace

Mount namespace 让容器看上去拥有整个文件系统。

容器有自己的 / 目录,可以执行 mountumount 命令。当然我们知道这些操作只在当前容器中生效,不会影响到 host 和其他容器。

UTS namespace

简单的说,UTS namespace 让容器有自己的 hostname。 默认情况下,容器的 hostname 是它的短ID,可以通过 -h--hostname 参数设置。

比如:

IPC namespace

IPC namespace 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。

User namespace

User namespace 让容器能够管理自己的用户,host 不能看到容器中创建的用户。

bash 复制代码
[root@docker ~]# docker exec -it e949e19402fc bash
root@e949e19402fc:/#               
root@e949e19402fc:/# useradd aabbcc
root@e949e19402fc:/# 
root@e949e19402fc:/# exit
exit
[root@docker ~]# su - aabbcc
su: user aabbcc does not exist

在容器中创建了用户 gaoqd,但 host 中并不会创建相应的用户。

容器的导入和导出

导出容器(容器 → tar文件)

bash 复制代码
# 将容器导出为tar文件(包含文件系统)
docker export my-container > my-container.tar

导入容器(tar文件 → 镜像)

bash 复制代码
# 直接指定文件
docker import my-container.tar my-new-image:tag

例如:

bash 复制代码
[root@docker ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS     NAMES
e949e19402fc   ubuntu    "/bin/bash"          11 minutes ago   Up 11 minutes             dreamy_wu
0e9b39878f9a   httpd     "httpd-foreground"   12 minutes ago   Up 12 minutes   80/tcp    stoic_bohr
[root@docker ~]# docker export stoic_bohr -o myhttpd.tar
[root@docker ~]# ls
dockerfile  myhttpd.tar

[root@docker ~]# docker import myhttpd.tar 
sha256:39c145ca634b45822700cbd49b1284a050bbd8a06a8e4c2cca115b0a95b1d73f
[root@docker ~]# docker import myhttpd.tar myweb:v1
sha256:ea9a2811a11122b274ab71ddcb3e9e3b8325be82f3e3b1f2b45c09439c3a58d4
[root@docker ~]# docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
myweb                v1        ea9a2811a111   4 seconds ago    115MB
<none>               <none>    39c145ca634b   13 seconds ago   115MB
ubuntu-with-stress   latest    16c75b683121   46 hours ago     136MB
httpd                latest    9e0cccc06e8d   5 days ago       117MB
ubuntu               latest    c3a134f2ace4   7 weeks ago      78.1MB

可以见看见不指定名称,导出的镜像也没有名称和tag

和上一章镜像的中学习的 save 做比较:

  • export:只导出容器当前的文件系统
  • save:导出整个镜像(包括历史层)
相关推荐
农夫山泉2号2 小时前
【docker】——不启用docker的启动命令,使用自己的
docker·容器·eureka
风123456789~2 小时前
【健康管理】第14章 健康保险与健康管理
笔记·考证·健康管理
celeste03102 小时前
shell脚本综合练习
运维·服务器·网络
飞函安全2 小时前
私有化一站式办公平台,协同办公更高效
运维·安全·信息与通信
2301_801387292 小时前
网络、API 连接和 pod 启动的问题
运维·网络·kubernetes
凯子坚持 c3 小时前
Docker实战指南:MySQL、Redis与C++环境的深度容器化部署
redis·mysql·docker
渡我白衣3 小时前
计算机组成原理(4):计算机的层次结构与工作原理
运维·c语言·网络·c++·人工智能·笔记·硬件架构
Mr_sun.3 小时前
Docker中安装软件汇总(留存版)
运维·docker·容器
YJlio3 小时前
Active Directory 工具学习笔记(10.9):AdInsight——命令行选项与自动化采集模板
笔记·学习·自动化