文章目录

  • 一、查看容器 docker ps
  • 二、创建容器
  • (一)新建容器 docker create
  • (二)启动容器
  • 1. docker start
  • 2. docker restart
  • (三)新建并启动容器 docker run
  • 1. 守护态运行
  • 2. 前台交互式运行
  • 3. 指定Docker端口
  • 三、进入容器
  • (一)docker attach
  • (二)docker exec
  • 四、Docker日志命令
  • (一)docker events
  • (二)docker history
  • (三)docker logs
  • 五、文件拷贝 docker cp
  • 六、终止容器
  • (一)docker stop
  • (二)docker kill
  • 七、删除容器 docker rm
  • 八、导入和导出容器
  • (一)docker export命令导出容器
  • (二)docker import命令导入容器



容器是Docker的另一个核心概念。简单来说,容器是镜像的一个运行实例。


容器内设置密码 容器的使用要求_centos

所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层。如果认为虚拟机是模拟运行的一整套操作系统(包括内核、应用运行态环境和其他系统环境)和跑在上面的应用,那么Docker容器就是独立运行的一个(或一组)应用,以及它们必需的运行环境。

容器是直接提供应用服务的组件,也是Docker实现快速启停和高效服务性能的基础。

容器和虚拟机

容器和虚拟机都依赖于宿主机才能运行。宿主机可以是笔记本,是数据中心的物理服务器,也可以是公有云的某个实例。

在下面的示例中,假设宿主机是一台需要运行 4 个业务应用的物理服务器。

在虚拟机模型中,首先要开启物理机并启动 Hypervisor 引导程序。一旦 Hypervisor 启动,就会占有机器上的全部物理资源,如 CPU、RAM、存储和 NIC。

Hypervisor 接下来就会将这些物理资源划分为虚拟资源,并且看起来与真实物理资源完全一致。

然后 Hypervisor 会将这些资源打包进一个叫作虚拟机(VM)的软件结构当中。这样用户就可以使用这些虚拟机,并在其中安装操作系统和应用。

前面提到需要在物理机上运行 4 个应用,所以在 Hypervisor 之上需要创建 4 个虚拟机并安装 4 个操作系统,然后安装 4 个应用。当操作完成后,结构如下图所示。

容器内设置密码 容器的使用要求_docker_02


而容器模型则略有不同。

服务器启动之后,所选择的操作系统会启动。在 Docker 世界中可以选择 Linux,或者内核支持内核中的容器原语的新版本 Windows。

与虚拟机模型相同,OS 也占用了全部硬件资源。在 OS 层之上,需要安装容器引擎(如 Docker)。

容器引擎可以获取系统资源,比如进程树、文件系统以及网络栈,接着将资源分割为安全的互相隔离的资源结构,称之为容器。

每个容器看起来就像一个真实的操作系统,在其内部可以运行应用。按照前面的假设,需要在物理机上运行 4 个应用。

因此,需要划分出 4 个容器并在每个容器中运行一个应用,如下图所示。

容器内设置密码 容器的使用要求_centos_03


从更高层面上来讲,Hypervisor 是硬件虚拟化(Hardware Virtualization)——Hypervisor 将硬件物理资源划分为虚拟资源。

容器是操作系统虚拟化(OS Virtualization)——容器将系统资源划分为虚拟资源。

一、查看容器 docker ps

docker ps 命令可以用来列出 Docker容器 相关信息。

用法:

docker ps [OPTIONS]

OPTIONS:
	无参	默认显示正在运行的容器。
	-a		显示所有的容器,包括未运行的。
	-f, --filter filter		根据条件过滤显示的内容。
	--format	 指定返回值的模板文件。
	-l		显示最近创建的容器。
	-n		列出指定数目的容器。
	--no-trunc	不截断输出容器ID信息(即显示完整的容器ID信息)。
	-q		静默模式,只显示容器编号。
	-s		显示总的文件大小。

容器状态

created

已创建

restarting

重启中

running

运行中

removing

迁移中

paused

暂停

exited

退出

dead

僵死

显示正在运行的容器

[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS      NAMES
61a6293bc3d4   tomcat    "catalina.sh run"   3 seconds ago   Up 2 seconds   8080/tcp   upbeat_lovelace

# CONTAINER ID	容器 ID 的意思,可以通过这 id 找到唯一的对应容器。
# IMAGE	该容器所使用的镜像。
# COMMAND	启动容器时运行的命令。
# CREATED	容器的创建时间,显示格式为 ”**时间之前创建“。
# STATUS	容器现在的状态。
# PORTS	容器的端口信息和使用的连接类型(tcp\udp)。
# NAMES	镜像自动为容器创建的名字,也唯一代表一个容器。

显示所有状态的容器

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS                          PORTS      NAMES
61a6293bc3d4   tomcat           "catalina.sh run"        42 seconds ago   Up 40 seconds                   8080/tcp   upbeat_lovelace
bc8083164d40   nginx:1.17.1     "nginx -g 'daemon of…"   4 minutes ago    Exited (0) About a minute ago              optimistic_allen
bced87c3f8b4   busybox:1.31.1   "sh"                     8 minutes ago    Exited (0) 7 minutes ago                   compassionate_bhaskara
2e1a60b14662   centos:7         "/bin/bash"              35 minutes ago   Created                                    upbeat_hugle

显示指定个数的(所有状态)容器

[root@docker ~]# docker ps -n 3
CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS                          PORTS      NAMES
61a6293bc3d4   tomcat           "catalina.sh run"        About a minute ago   Up About a minute               8080/tcp   upbeat_lovelace
bc8083164d40   nginx:1.17.1     "nginx -g 'daemon of…"   4 minutes ago        Exited (0) About a minute ago              optimistic_allen
bced87c3f8b4   busybox:1.31.1   "sh"                     8 minutes ago        Exited (0) 8 minutes ago                   compassionate_bhaskara

仅显示容器 ID

# 显示正在运行的容器ID
docker ps -q 
# 显示所有状态的容器的ID
docker ps -aq

同时显示容器大小

docker ps -s
docker ps -as

显示容器ID的完整信息

docker ps --no-trunc

如果容器数量过多,或者想排除干扰容器,可以通过docker ps --filterdocker ps -f,过滤需要显示的容器。

docker ps过滤规则

选项后跟的都是键值对 key=value (可不带引号),如果有多个过滤条件,就多次使用 filter 选项

docker ps --filter id=a1b2c3 --filter name=test
# 以上过滤条件会找出 name 包含 test 且 ID 包含 a1b2c3的容器

# 相同条件之间的关系是或,不同条件之间的关系是与关系
docker ps --filter name=test --filter name=daemon --filter status=running
# 以上过滤条件会找出 name 包含 test 或 daemon 并且 status 为 running 的容器。

# id 和 name,支持正则表达式,使用起来非常灵活
docker ps --filter name=^/test$

二、创建容器

对容器进行操作就跟直接操作应用一样简单、快速。Docker容器实在太轻量级了,用户可以随时创建或删除容器。

(一)新建容器 docker create

docker create命令用于创建一个新的 Docker 容器,类似 docker run -d 命令。

但是与 docker run -d 不同的是,docker create 创建的容器并未实际启动,还需要执行 docker start 命令或 docker run 命令以启动容器。

事实上,docker create命令在指定的映像上创建一个可写容器层,并准备它运行指定的命令。 然后将容器ID打印到STDOUT,容器的状态为:created。 docker create 命令常用于在启动容器之前进行必要的设置容器配置

用法:

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

常用选项:
-i,-interactive 	交互式
-t,-tty 			分配一个伪终端
-d,-detach 		运行容器到后台
--name string 		指定容器名称

创建容器

[root@docker ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
centos        7         8652b9f0cb4c   6 months ago    204MB

# 即为 centos:7 这个镜像创建一个容器,启动前的配置为: -i和-t这两个参数的作用是,为该docker创建一个伪终端,这样就可以进入到容器的交互模
# 式(也就是直接进入到容器里面)后面的/bin/bash的作用是表示载入容器后运行bash ,docker中必须要保持一个进程的运行,要不然整个容器启动后就
# 会马上kill itself,这样当你使用docker ps 查看启动的容器时,就会发现你刚刚创建的那个容器并不在已启动的容器队列中。这个/bin/bash
# 就表示启动容器后启动bash。
[root@docker ~]# docker create --name mycentos -it centos:7
7c44d80cf66494a7d491f31b00f9448c9b63177a86b6d426a010c986fa927c4e

# 使用 docker ps 命令,查看当前正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# 即没有任何正在运行的容器,我们使用 docker ps -a 命令,查看当前所有的容器列表
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS                   PORTS      NAMES
7c44d80cf664   centos:7         "/bin/bash"              7 seconds ago   Created                             mycentos
# 创建的容器,此时已经存在,只是没有运行,状态为 Created ,只是为容器启动前做了相应的设置

(二)启动容器

1. docker start

使用docker start命令来启动一个或多个已经创建的容器或者启动一个或多个已经被停止的容器

用法:

docker start [OPTIONS] CONTAINER [CONTAINER...]

启动上面使用 docker create 创建的容器

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED       STATUS                   
7c44d80cf664   centos:7         "/bin/bash"              About a minute ago   Created                             mycentos

[root@docker ~]# docker start mycentos	# 也可以使用docker start 7c44d80cf664
mycentos
[root@docker ~]# docker ps 
CONTAINER ID   IMAGE      COMMAND             CREATED              STATUS         PORTS      NAMES
7c44d80cf664   centos:7   "/bin/bash"         About a minute ago   Up 4 seconds              mycentos
#此时查看该容器处于运行状态

处于终止状态的容器,可以通过docker start命令来重新启动

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS                       PORTS     NAMES
61a6293bc3d4   tomcat           "catalina.sh run"        2 hours ago     Exited (143) 3 seconds ago             upbeat_lovelace
# 该容器状态为退出

[root@docker ~]# docker start 61a6293bc3d4
61a6293bc3d4
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND             CREATED         STATUS         PORTS      NAMES
61a6293bc3d4   tomcat     "catalina.sh run"   2 hours ago     Up 2 seconds   8080/tcp   upbeat_lovelace	
# 此时为启动状态

但是不能使用该命令直接将镜像运行为容器,必须是使用docker create创建的容器或者是处停止状态的容器才可以使用该命令启动

2. docker restart

docker restart 命令可以用来重新启动一个或者多个 Docker容器。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。

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

用法:

docker restart [OPTIONS] CONTAINER [CONTAINER...]

OPTIONS:
	-t, --time int	在终止容器之前等待停止的秒数

(三)新建并启动容器 docker run

除了创建容器后通过start命令来启动,也可以直接新建并启动容器。所需要的命令主要为docker run,等价于先执行docker create命令,再执行docker start命令。

docker run 流程图:

容器内设置密码 容器的使用要求_Docker_04

用法:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用语法: docker run --name "CONTAINER_NAME" [OPTIONS] IMAGE [COMMAND] [ARG...]
# --name=""	指定容器名字,后续可以通过名字进行容器管理
# 如果不使用 --name 属性指定 Docker 容器运行的名字,则每次运行的名字为随机名字,这给我们管理带来了很大的不便。

OPTIONS:

	-d, --detach=false	指定容器运行于前台还是后台,默认为 false。
	-i, --interactive=false	打开 STDIN,用于控制台交互。
	-t, --tty=false	分配 tty 设备,该可以支持终端登录,默认为 false。
	-u, --user=""	指定容器的用户。
	-a, --attach=[]	登录容器(必须是以 docker run -d 启动的容器)。
	-w, --workdir=""	指定容器的工作目录。
	-c, --cpu-shares=0	设置容器 CPU 权重,在 CPU 共享场景使用。
	-e, --env=[]	指定环境变量,容器中可以使用该环境变量。
	-m, --memory=""	指定容器的内存上限。
	-P, --publish-all=false	随机指定容器暴露的端口。
	-p, --publish=[]	指定容器暴露的端口。
		-p IP:主机端口有:容器端口
		-p 主机端口有:容器端口
		-p 容器端口
	-h, --hostname=""	指定容器的主机名。
	-v, --volume=[]	给容器挂载存储卷,挂载到容器的某个目录。
	--volumes-from=[]	给容器挂载其他容器上的卷,挂载到容器的某个目录。
	--cap-add=[]	添加权限。
	--cap-drop=[]	删除权限。
	--cidfile=""	运行容器后,在指定文件中写入容器 PID 值,一种典型的监控系统用法。
	--cpuset=""	设置容器可以使用哪些 CPU,此参数可以用来容器独占 CPU。
	--device=[]	添加主机设备给容器,相当于设备直通。
	--dns=[]	指定容器的 dns 服务器。
	--dns-search=[]	指定容器的 dns 搜索域名,写入到容器的 /etc/resolv.conf 文件。
	--entrypoint=""	覆盖 image 的入口点。
	--env-file=[]	指定环境变量文件,文件格式为每行一个环境变量。
	--expose=[]	指定容器暴露的端口,即修改镜像的暴露端口。
	--link=[]	指定容器间的关联,使用其他容器的 IP、env 等信息。
	--lxc-conf=[]	指定容器的配置文件,只有在指定 --exec-driver=lxc 时使用。
	--name=""	指定容器名字,后续可以通过名字进行容器管理,links 特性需要使用名字。
	--net=“bridge”	器网络设置:
		1. bridge 使用 docker daemon 指定的网桥。
		2. host //容器使用主机的网络。
		3. container:NAME_or_ID >//使用其他容器的网路,共享 IP 和 PORT 等网络资源。
		4. none 容器使用自己的网络(类似–net=bridge),但是不进行配置。
	--privileged=false	指定容器是否为特权容器,特权容器拥有所有的 capabilities。
	--restart=“no”	指定容器停止后的重启策略:
		1. no:容器退出时不重启。
		2. on-failure:容器故障退出(返回值非零)时重启。
		3. always:容器退出时总是重启。
	--rm=false	指定容器停止后自动删除容器(不支持以 docker run -d 启动的容器)。
	--sig-proxy=true	设置由代理接受并处理信号,但是 SIGCHLD、SIGSTOP 和 SIGKILL 不能被代理。

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

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

1. 守护态运行

第一种:指定容器后台运行后直接退出

[root@docker ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
centos        7         8652b9f0cb4c   6 months ago    204MB

[root@docker ~]# docker run -d centos:7
cf56a1165723997e90fc50193e1d84dc9dac77d0329e50ed628d45f3ee6dcc84
# 使用 docker run -d 命令以后台方式运行 Docker,此时终端输出了一长串的容器 ID。

# 使用 docker ps 命令,查看正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 此时我们发现并没有任何在运行的容器。因为,虽然我们指定了 Docker 容器的后台运行,但是容器中并没有运行任何的程序,所以容器直接就退出了,
# 因此没有任何正在运行的 Docker 容器。

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS                     PORTS     NAMES
cf56a1165723   centos:7   "/bin/bash"   6 seconds ago   Exited (0) 6 seconds ago             crazy_chandrasekhar
# 可以看到为退出状态

第二种:指定容器后台运行后继续在后台运行

[root@docker ~]# docker run -d centos:7 tail -f /dev/null
2fb7afde7bab2b857930d66e72835e612ff1bf07bed2312581ea668903a600d5

# 使用 docker ps 命令,查看正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED          STATUS          PORTS     NAMES
2fb7afde7bab   centos:7   "tail -f /dev/null"   12 seconds ago   Up 11 seconds             dazzling_golick
# 此时发现终端输出了正在运行的容器,以及容器的基本信息(容器Id,镜像名,运行的命令,创建时间等)。
# 这次运行 Docker 容器,因为我们使用了 tail -f 命令,此命令会一直在后台执行,因此此时的 Docker 容器是有正在运行的进程,因此容器并没有退出,而是一直在后台运行。

第三种:交互式后台运行

[root@docker ~]# docker run -it -d centos:7 /bin/bash
3396f9d0f3a9f86b047fae1795498abd3772b5b73f69980abc5573a0c6f04590

# 使用 docker ps 命令,查看正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED         STATUS         PORTS     NAMES
3396f9d0f3a9   centos:7   "/bin/bash"           2 seconds ago   Up 2 seconds             optimistic_nightingale
# 这次运行 Docker 容器,因为使用了 docker run -it -d 命令,其中 -it 参数是以交互式方式运行容器,因此容器并没有退出,而是一直在后台运行。

2. 前台交互式运行

[root@docker ~]# docker run --name test -it centos:7 /bin/bash
# 其中,-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。

# 在交互模式下,用户可以通过所创建的终端来输入命令
[root@42d730983a37 /]# cd /etc
[root@42d730983a37 etc]# pwd
/etc
[root@42d730983a37 etc]# ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.2  0.0  11828  1892 pts/0    Ss   06:36   0:00 /bin/bash
root         17  0.0  0.0  51732  1704 pts/0    R+   06:36   0:00 ps -aux                                                                                                                  
# 在容器内用ps命令查看进程,可以看到,只运行了bash应用,并没有运行其他无关的进程。
[root@42d730983a37 etc]# exit
exit
# 可以通过使用 【Ctrl + d 】组合键或输入 exit 命令来退出容器:
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED         STATUS         PORTS     NAMES
3396f9d0f3a9   centos:7   "/bin/bash"           5 minutes ago   Up 5 minutes             optimistic_nightingale
2fb7afde7bab   centos:7   "tail -f /dev/null"   8 minutes ago   Up 8 minutes             dazzling_golick
# 对于所创建的bash容器,当使用exit命令退出之后,容器就自动处于退出(Exited)状态了。这是因为对Docker容器来说,当运行的应用退出后,容器也就没有继续运行的必要了。

某些时候,执行docker run会出错,因为命令无法正常执行容器会直接退出,此时可以查看退出的错误代码。

默认情况下,常见错误代码包括:
	125: Docker daemon执行出错,例如指定了不支持的Docker命令参数;
	126:所指定命令无法执行,例如权限出错;
	127:容器内命令无法找到。
命令执行后出错,会默认返回错误码。

3. 指定Docker端口

指定 Docker 容器运行时暴露的端口

用法:

docker run -p PORT1:PORT2 IMAGE [COMMAND] [ARG]
# 使用 -p 运行参数,将容器内部的端口 PORT2 暴露为宿主机的端口为 PORT1。

指定nginx容器暴露端口

[root@docker ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
nginx         1.17.1    98ebf73aba75   23 months ago   109MB

# 创建启动nginx容器并将容器内部的80端口暴露暴露为宿主机的9999端口
[root@docker ~]# docker run --name mynginx -it -d -p 9999:80 nginx:1.17.1
229b70ba2a76bb053b1a5debaee4317ccc7ac6890bca285eb300869e13223e0b
# 也指定 Docker 映射指定主机和端口 -p HOST_ZIP:PORT

[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                   NAMES
229b70ba2a76   nginx:1.17.1   "nginx -g 'daemon of…"   4 seconds ago    Up 3 seconds    0.0.0.0:9999->80/tcp, :::9999->80/tcp   mynginx
# PORTS字段下显示了内部的 80 端口被导出为了宿主机的 9999 端口。

# 使用 docker port 命令查看 Docker 容器的端口映射
[root@docker ~]# docker port mynginx
80/tcp -> 0.0.0.0:9999
80/tcp -> :::9999
# 同样显示了内部的 80 端口被导出为了宿主机的 9999 端口。

# 同时查看宿主机的 9999 端口是否被监听
[root@docker ~]# ss -anp | grep 9999
tcp    LISTEN     0      128       *:9999                  *:*                   users:(("docker-proxy",pid=4055,fd=4))
tcp    LISTEN     0      128    [::]:9999               [::]:*                   users:(("docker-proxy",pid=4060,fd=4))

# 宿主机的 9999 端口被 docker 容器在监听

容器内设置密码 容器的使用要求_docker_05

三、进入容器

在使用 -d 参数时,容器启动后会进入后台,用户无法看到容器中的信息,也无法进行操作。这个时候如果需要进入容器进行操作,有多种方法,包括使用官方的attach或exec命令等。

(一)docker attach

使用 docker attach 命令可以用来进入到一个正在运行的 Docker容器。docker attach 命令后面的 CONTAINER 可以是容器Id,或者是容器名。

用法:

docker attach [OPTIONS] CONTAINER

OPTIONS:
	--detach-keys[=[]]:指定退出attach模式的快捷键序列,默认是CTRL-p;
	--no-stdin=true|false:是否关闭标准输入,默认是保持打开;
	--sig-proxy=true|false:是否代理收到的系统信号给应用进程,默认为true。

进入容器后容器退出

在容器内使用 exit 命令或者 ctrl + d 退出容器后,原来正在运行的容器会退出

# 创建后台运行的容器
[root@docker ~]# docker run --name mycentos -itd centos:7
7c22ca255369669baead5755b205fa598c5104e320d5b511120d60f9168d2eb9

# 查看
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
7c22ca255369   centos:7   "/bin/bash"   3 seconds ago   Up 2 seconds             mycentos

# 进入
[root@docker ~]# docker attach mycentos
[root@7c22ca255369 /]# 
# 此时,终端的命令行提示符变成了 docker containerId,即我们已经进入了 docker容器的内部。
# 我们可以在 dokcer 容器的内部,执行任何的 linux 命令,使用 exit 命令或者 Ctrl+d,退出 docker attach 的容器。
[root@7c22ca255369 /]# exit
exit
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 此时没有任何正在运行的容器,说明我们使用 docker attach 命令,进入容器后,
# 再使用 exit 命令或者 Ctrl+d 退出容器后,原来正在运行的容器也会停止。

进入容器不退出

使用 Ctrl+p+q,退出 docker attach 的容器,容器不会退出

创建后台运行容器
[root@docker ~]# docker run --name mycentos -itd centos:7
deabcdbe07d87a2bcca8d854fe748d2d05fdbf19af6e0d813c6e11e4f55f87da

[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
deabcdbe07d8   centos:7   "/bin/bash"   4 minutes ago   Up 4 minutes             mycentos

# 进入容器
[root@docker ~]# docker attach mycentos
[root@deabcdbe07d8 /]# pwd
/
[root@deabcdbe07d8 /]# read escape sequence # 此时是使用 使用 Ctrl+p+q,退出 docker attach 的容器。


[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
deabcdbe07d8   centos:7   "/bin/bash"   6 minutes ago   Up 6 minutes             mycentos
# 此时容器还是正在运行的状态。

(二)docker exec

使用 docker exec 命令,进入正在运行的 docker容器后,再次使用 exit 命令或者 Ctrl+d 退出容器后,原来正在运行的容器不会停止,这是 docker exec 命令进入容器与 docker attach 进入容器的区别。

用法:

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

OPTIONS:
	-d	在后台运行命令
	-i	--interactive=true|false:打开标准输入接受用户输入命令,默认为false;
	--privileged=true|false:是否给执行命令以高权限,默认为false;
	-t,--tty=true|false:分配伪终端,默认为false;
	-e	设置环境变量
	-w	需要执行命令的目录
	-u,--user="":执行命令的用户名或ID。
[root@docker ~]# docker run --name mycentos -itd centos:7
d537aab49227ec7d9e083dd9e7240c4a3580a0aa734e5d3a50d73db972fcb1e3
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS         PORTS     NAMES
d537aab49227   centos:7   "/bin/bash"   10 seconds ago   Up 9 seconds             mycentos

# 进入到刚创建的容器中,并启动一个bash
[root@docker ~]# docker exec -it mycentos /bin/bash
[root@d537aab49227 /]# 
# 可以看到,一个bash终端打开了,在不影响容器内其他应用的前提下,用户可以很容易与容器进行交互。

# 使用 exit 命令或者 Ctrl+d 或者 Ctrl+p+q 退出容器,再次使用 docker ps 命令,查看当前正在运行的容器
[root@d537aab49227 /]# exit
exit
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
d537aab49227   centos:7   "/bin/bash"   3 minutes ago   Up 3 minutes             mycentos
# 原来正在运行的容器还在继续运行。这里如果使用 docker attach 进入容器后,使用 exit 命令或者 Ctrl+d 退出容器那么运行的容器会退出。

注意:
通过指定- it参数来保持标准输入打开,并且分配一个伪终端。通过 exec 命令对容器执行操作是最为推荐的方式。

四、Docker日志命令

(一)docker events

docker events 命令用于打印出实时的系统事件。

用法:

docker events [OPTIONS]

OPTIONS:
	-f	根据条件过滤事件。
	--since	从指定的时间戳后显示所有事件。
	--until	流水时间显示到指定的时间为止。

显示某个时间段的事件

显示 docker 从 2021-5-1 之后的事件
[root@docker ~]# date -d "2021-5-1" +%s
1619798400
[root@docker ~]# docker events  --since="1619798400"

显示指定镜像的事件

# 显示 centos 镜像从 2021-5-1 之后的事件。
[root@docker ~]# docker events -f "image"="centos"  --since="1619798400"

(二)docker history

docker history 命令用于打印出指定的Docker镜像的历史版本信息。

用法:

docker history [OPTIONS] IMAGE

OPTIONS:
	-H, --human	以可读的格式打印镜像大小和日期,默认为 true。
	--no-trunc	显示完整的提交记录。
	-q, --quiet	仅列出提交记录 ID。

查看镜像的提交历史

[root@docker ~]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
centos             7         8652b9f0cb4c   7 months ago    204MB
[root@docker ~]# docker history centos:7
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
8652b9f0cb4c   7 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      7 months ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      7 months ago   /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB

仅显示镜像的提交历史 ID

[root@docker ~]# docker history -q centos:7
8652b9f0cb4c
<missing>
<missing>

(三)docker logs

docker logs 命令用于获取Docker容器的日志(在控制台的标准输出信息)

用法:

docker logs [OPTIONS] CONTAINER

OPTIONS:
	--details		 显示 log 信息的额外的详细信息。
	-f, --follow	 跟踪日志输出。
	--since	string	 显示某个开始时间的所有日志。
	--tail	string	 仅列出最新 N 条容器日志。
	-t, --timestamps	显示时间戳。

查看容器日志

# 使用 docker run 命令,运行 docker 容器,并且不停的在后台输出日志。
[root@docker ~]# docker run --name mycentos -d centos:7 /bin/sh -c "while true; do echo hello world; sleep 2; done"
c0438b7f20d7bce721084a910bddef845f6cbb893879c0f5d6ef179511767548
[root@docker ~]# docker logs mycentos
hello world
hello world
hello world

跟踪容器日志

[root@docker ~]# docker logs -f mycentos

同时显示容器日志的时间

[root@docker ~]# docker logs -t mycentos
2021-06-18T08:02:37.153502097Z hello world
2021-06-18T08:02:38.156463485Z hello world

显示最后指定数目的日志信息

[root@docker ~]# docker logs --tail 4 mycentos

五、文件拷贝 docker cp

docker cp 命令用于在本地文件系统与 Dokcer容器之间复制文件或者文件夹。

用法:

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

说明:
1. docker cp 命令类似于 Linux 中的 cp -a 命令,递归复制目录下的所有子目录和文件。
2. docker cp 命令中的 - 表示通过标准输入/输出设备以流的方式读取或写入 tar 文件。
3. 本地文件系统中的路径可以是绝对路径,也可以是相对路径,相对于当前命令执行的路径。
4. 容器中的路径都是相对容器的 / 根路径。
5. docker cp 命令操作的容器可以是在运行状态,也可以是停止状态。
6. docker cp 命令不能复制 /proc、 /sys、 /dev、 tmpfs 和容器中 mount 的路径下的文件。

OPTIONS:
	-a, --archive	归档模式(复制所有UID / GID信息)
	-L, --follow-link	总是跟在源地址符号链接

将文件从宿主机复制到容器

# 在宿主机创建文件
[root@docker ~]# echo "hello" > test.txt

# 创建并启动一个容器
[root@docker ~]# docker run --name mycentos -itd centos:7 
9edfb6dc4374a478441c0f059cbc2476db722ef44b8c24089c2668e6a00d1541
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
9edfb6dc4374   centos:7   "/bin/bash"   6 seconds ago   Up 3 seconds             mycentos

# 将刚在宿主机创建的文件,复制到 docker容器内部
[root@docker ~]# docker cp ./test.txt mycentos:/tmp

# 使用 docker attach 命令,进入到 docker 容器内部
[root@docker ~]# docker attach mycentos

# 查看容器的 /tmp 目录,是否有刚复制的文件存在,并查看文件内容
[root@9edfb6dc4374 /]# cd tmp
[root@9edfb6dc4374 tmp]# ll test.txt 
-rw-r--r--. 1 root root 6 Jun 19 02:47 test.txt
[root@9edfb6dc4374 tmp]# cat test.txt
hello
# 在容器内部的 /tmp 目录存在复制的文件,并且文件的内容为我们在宿主机写入的内容。

将容器内的文件复制到宿主机上

# 创建并运行容器
[root@docker ~]# docker run --name mycentos1 -it centos:7 
# 在容器内创建文件
[root@ec1fd58664c7 /]# echo "this file is from container" > test1.txt
[root@ec1fd58664c7 /]# exit
exit

# 使用 docker cp 命令,将刚在容器内部创建的文件,复制到宿主机
[root@docker ~]# docker cp mycentos1:/test1.txt ./

# 查看宿主机是否有刚复制的文件存在,并查看文件内容
[root@docker ~]# ll test1.txt 
-rw-r--r--. 1 root root 28 Jun 19 10:53 test1.txt
[root@docker ~]# cat test1.txt
this file is from container

六、终止容器

(一)docker stop

docker stop 命令可以用来停止一个运行中的 Docker容器。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。

停止过程为:首先向容器发送SIGTERM信号,等待一段超时时间(默认为10秒)后,再发送SIGKILL信号来终止容器

用法:

docker stop [OPTIONS] CONTAINER [CONTAINER...]
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS             PORTS                                   NAMES
229b70ba2a76   nginx:1.17.1   "nginx -g 'daemon of…"   38 minutes ago      Up 2 seconds       0.0.0.0:9999->80/tcp, :::9999->80/tcp   mynginx
3396f9d0f3a9   centos:7       "/bin/bash"              About an hour ago   Up About an hour                                           optimistic_nightingale

# 使用容器名停止容器
[root@docker ~]# docker stop mynginx
mynginx
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED             STATUS             PORTS     NAMES
3396f9d0f3a9   centos:7   "/bin/bash"           About an hour ago   Up About an hour             optimistic_nightingale

# 使用容器 ID 停止容器
[root@docker ~]# docker stop 3396f9d0f3a9
3396f9d0f3a9
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED             STATUS             PORTS     NAMES

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

(二)docker kill

docker kill 命令可以用来强制终止一个或者多个正在运行的 Docker容器。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。

docker kill命令会直接发送SIGKILL信号来强行终止容器。

用法:

docker kill [OPTIONS] CONTAINER [CONTAINER...]

OPTIONS:
	-s	向容器发送一个信号。
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED       STATUS        PORTS                                   NAMES
229b70ba2a76   nginx:1.17.1   "nginx -g 'daemon of…"   2 hours ago   Up 1 second   0.0.0.0:9999->80/tcp, :::9999->80/tcp   mynginx
2fb7afde7bab   centos:7       "tail -f /dev/null"      2 hours ago   Up 2 hours                                            dazzling_golick

# 使用容器名强制终止容器
[root@docker ~]# docker kill mynginx
mynginx
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED       STATUS       PORTS     NAMES
2fb7afde7bab   centos:7   "tail -f /dev/null"   2 hours ago   Up 2 hours             dazzling_golick

# 使用容器 ID 强制终止容器
[root@docker ~]# docker kill 2fb7afde7bab
2fb7afde7bab
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# 杀死所有容器
docker kill `docker ps -q`

kill 和 stop 区别:

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

docker kill,发送SIGKILL信号,应用程序直接退出。

线上应用优雅退出十分必要。docker stop也不是docker独有的设计,lxc和google borg系统都有类似设计,即在发送SIGKILL之前,发送SIGTERM信号通知任务。

七、删除容器 docker rm

可以使用docker rm命令来删除处于终止或退出状态的容器,

用法:

docker rm [OPTIONS] CONTAINER [CONTAINER...]
# 默认情况下,docker rm命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器。
# 如果要直接删除一个运行中的容器,可以添加-f参数。Docker会先发送SIGKILL信号给容器,终止其中的应用,之后强行删除

OPTIONS:
-f,--force	通过 SIGKILL 信号强制删除一个运行中的容器。
-l,--link	移除容器间的网络连接,而非容器本身。
-v:-v	删除与容器关联的卷。

# 删除所有容器
docker rm -f `docker ps -aq` 或 docker rm -f $(docker ps -aq) 或 docker rm -f `docker ps -a | awk 'NR!=1 {print $1}'` 或 docker ps -aq | xargs docker rm -f

删除已停止的容器

[root@docker ~]# docker run --name mycentos -itd centos:7
b05de44eb02fc80752446d5e9f43a212fde4436859ca24412ebaf4dd66ce8475
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
b05de44eb02f   centos:7   "/bin/bash"   5 seconds ago   Up 4 seconds             mycentos

# 杀掉刚创建的容器
[root@docker ~]# docker kill mycentos
mycentos
# 查看正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 使用 docker ps -a 命令,查看所有的容器
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS                       PORTS     NAMES
b05de44eb02f   centos:7   "/bin/bash"   21 seconds ago   Exited (137) 2 seconds ago             mycentos

# 使用 docker rm 命令,删除 docker容器
[root@docker ~]# docker rm mycentos
mycentos

# 再次使用 docker ps -a 命令,查看所有的容器
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 此时已经没有任何容器,即刚才创建的容器已经被删除。

删除正在运行的容器

[root@docker ~]# docker run --name mycentos1 -itd centos:7
2be43a0eae72d5054aa58e6eebde306e762dfa954fa33c601e2c999cf37bdae1
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
2be43a0eae72   centos:7   "/bin/bash"   4 seconds ago   Up 3 seconds             mycentos1

# 使用 docker rm 命令,杀掉正在运行的 docker 容器
[root@docker ~]# docker rm mycentos1
Error response from daemon: You cannot remove a running container 2be43a0eae72d5054aa58e6eebde306e762dfa954fa33c601e2c999cf37bdae1. Stop the container before attempting removal or force remove
# 此时命令行直接报错,提示我们使用 docker rm -f 命令,我们使用 docker rm -f 命令,删除一个正在运行的 docker 容器。

[root@docker ~]# docker rm -f mycentos1
mycentos1

# 再次使用 docker ps -a 命令,查看所有的容器
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 此时已经没有任何容器,即刚才创建的且正在运行的 docker 容器已经被 docker rm -f 命令强制删除了

八、导入和导出容器

某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用Docker的导入和导出功能。这也是Docker自身提供的一个重要特性。

(一)docker export命令导出容器

docker export 命令可以用于将 Docker容器里的文件系统作为一个 tar 归档文件导出到标准输出。注意,docker save 命令是用于将 Docker 镜像保存成 tar 包

导出容器是指导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态

用法:

docker export [OPTIONS] CONTAINER

OPTIONS:
-o,--output string	将输出内容写到文件。
# docker export [-o|--output[=""]] CONTAINER  其中,可以通过-o选项来指定导出的tar文件名,也可以直接通过重定向来实现。
# 或者 docker export CONTAINER > filename

导出运行状态的容器

[root@docker ~]# docker run --name mycentos2 -itd centos:7
e9d23cd091cccb6264f6277f324e56ee1025601a3af4431838c9aaa511aef899
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS         PORTS     NAMES
e9d23cd091cc   centos:7   "/bin/bash"   3 seconds ago   Up 2 seconds             mycentos2
[root@docker ~]# docker export -o centos_v1.tar mycentos2
# 或者 docker export mycentos2 > centos_v1.tar
[root@docker ~]# file centos_v1.tar 
centos_v1.tar: POSIX tar archive

导出未运行的容器

[root@docker ~]# docker create -it --name mycentos3 centos:7
1ade9b48f4c68b833f3d41b6280f080586d694c3f175091b902876d63fb87b7b
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED         STATUS    PORTS     NAMES
1ade9b48f4c6   centos:7   "/bin/bash"   8 seconds ago   Created             mycentos3
[root@docker ~]# docker export -o centos_v2.tar mycentos3
# 或者 docker export mycentos3 > centos_v2.tar
[root@docker ~]# file centos_v2.tar 
centos_v2.tar: POSIX tar archive

之后,可将导出的tar文件传输到其他机器上,然后再通过导入命令导入到系统中,从而实现容器的迁移。

(二)docker import命令导入容器

导出容器的文件又可以使用docker import命令导入变成镜像

用法:

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

OPTIONS:
	-c, --change	应用 docker 指令创建镜像。
	-m, --message	提交时的说明文字。

将使用容器导出的文件导入为镜像

[root@docker ~]# docker import centos_v2.tar import/centos_v2
sha256:bb4615fa52115aaec35d9ae7b8da556bd6f79b8c9325a970602ddfef646abaa1
[root@docker ~]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
import/centos_v2   latest    bb4615fa5211   4 seconds ago   204MB
# 此时的镜像列表的 import/centos_v2 镜像,即为使用 docker import 命令导入的镜像

使用 docker load 命令来导入一个镜像文件,与 docker import 命令十分类似。实际上,既可以使用docker load 命令来导入镜像存储文件到本地镜像库,也可以使用 docker import 命令来导入一个容器快照到本地镜像库。

这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。