docker run 命令学习

Docker run 命令学习

Docker 是运行在隔离的容器中运行的,容器是在主机上运行的进程,主机可以是本地的也可以是远程的。当运行docker run 命令时,运行的容器是独立的,因为它有自己的文件系统,自己的网络,以及独立于主机的进程树。

一般的语法格式

基础的docker run 命令如下面的格式:

$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

docker run 命令必须指定一个镜像,来指定运行容器派生于哪个镜像。镜像的开发人员可以定义镜像相关的默认值:

  • 独立运行或前端运行
  • 容器识别
  • 网络设置
  • CPU和内存的运行时限制

你可以使用 docker run 的选项参数来覆盖镜像的默认值,此外,你还可以覆盖Dcoker运行时本身所有的默认设置。由于使用 docker run 命令可以覆盖镜像和Docker运行时的默认设置,所以 run 的参数要比其他的docker 命令有更多的选项设置。

注意: 依赖于你的Docker操作系统设置的问题,所以你可能要在docker run 命令前加上sudo。如果你不想总是加上sudo指令,用系统管理员创建一个Unix群组docker,把用户加进去。更多配置,可以参照和你系统相关的 Docker 安装文档。

操作人员专有的选项设置

只有运行 docker run 命令的人才能设置以下选项:

  • 独立模式(detached) vs 前台模式(默认模式)
    • 独立模式 (-d)
    • 前台模式
  • 容器识图  
    • PID当量 ( --cidfile)
    • 名称 (--name)
  • IPC 设置(--ipc)
  • 网络设置
  • 重启策略(--restart)
  • 移除(--rm)
  • 资源的运行时限制
  • 运行时特权和Linux功能

独立模式 vs 前台模式

启动Docker容器时,必须首先确定是在后台以"detached"模式运行,还是默认的前台模式。

-d=false: Detached mode: Run container in the background, print new container id

独立模式 (-d)

以独立模式启动容器,使用 -d=true 或是 -d 选项,根据设计,容器以独立模式运行时,容器只会在运行容器的根进程退出时退出,除非你指定了 --rm 选项。如果 -d 和 --rm 一起使用,容器会在它退出或是容器的守护进程退出时(以先退出的为准)退出,

独立模式启动容器时,不要将 service xx start 命令传递给容器,例如下面的命令会尝试启动nginx服务。

$ docker run -d -p 80:80 my_image service nginx start

这成功启动了容器内容的nginx服务,但是,它破坏了独立容器的范式。因为根进程(service nginx start)返回,并且独立容器按照设计那样停止。结果,nginx 服务启动了,但不能使用。可以用下面的代码来替代nginx web 服务进程的启动。

$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'

要使用独立容器进行输入/输出,请使用网络连接或共享卷,这些是必需的,因为容器不再监听 docker run 所在的命令行。

要重新附加到独立的容器,请使用docker attach命令。

前台模式

前台模式(不指定 -d 时默认的模式),docker run 可以在容器中启动进程,将控制台转换为容器启动后的控制台信息。它甚至可以假装为TTY(这是大多数命令行可执行文件所期望的)并传递信号。所有这些都是可配置的:

-a=[]           : Attach to `STDIN`, `STDOUT` and/or `STDERR`
-t              : Allocate a pseudo-tty
--sig-proxy=true: Proxy all received signals to the process (non-TTY mode only)
-i              : Keep STDIN open even if not attached

如果不指定 -a ,那么Docker就会附加stdout和stderr。你可以像下面这样,任何指定三个标准流中的任意一个或几个。

$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash

对于交互进程(比如shell),必须一起使用 -i -t,才能为容器进程分配一个TTY。-i -t 经常写成-it 。如果只写 -t ,那么客户端就不能接收到管道的输入信息。如下:

For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it as you’ll see in later examples. Specifying -t is forbidden when the client is receiving its standard input from a pipe, as in:

$ echo test | docker run -i busybox cat

注意: Linux会特别处理在容器内以PID 1运行的进程:它会忽略具有默认操作的任何信号。因此,该过程将不会终止,SIGINT或者SIGTERM除非经过编码才能终止。

容器识别

名称 (--name)

有三种方式可以识别一个容器:

识别类型 示例值
UUID long 标识符 “f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”
UUID short 标识符 “f78375b1c487”
名称 “evil_ptolemy”

UUID标识符来自Docker守护进程,如果你没有使用 --name 给容器分配名称,那么守护进程就会为容器生成随机的名称。为容器取一个有意义的名字,将会对后续的操作提供便利。你可以在Docker的网络中使用名称定位容器。这对前台和后台的Docker容器都有效。

注意: 默认的桥接网络容器必须通过名称连接进行通信

PID 当量

最后,为了帮助自动化,可以让Docker将容器ID写入到你选择文件当中。这类似于某些程序将进程ID写入到文件当中的方式(视为PID文件):

--cidfile="": Write the container ID to the file

镜像[:标签]

虽然不是一种严格标识容器的方法,但是你可以通过添加 镜像[:标签] 命令来指定版本的镜像运行容器。例如:

docker run ubuntu:14.04

镜像[@digest]

使用v2或更高版本镜像格式的镜像具有称为摘要的内容可寻址标识符。只要用于生成镜像的输入不变,摘要值就可以预测和参考。

以下示例从带有sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0摘要的alpine镜像中运行容器:

$ docker run alpine@sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 date

PID 设置 (--pid)

--pid=""  : Set the PID (Process) Namespace mode for the container,
             'container:<name|id>': joins another container's PID namespace
             'host': use the host's PID namespace inside the container

所有容器都有默认的PID,PID命名空间提供进程分离,PID命名空间可删除系统进程的视图,允许重用进程id,包括 PID 1。

在某些情况下,你想让容器共享主机的进程命名空间,主要是让容器上的进程查看系统上的所有进程。例如,你可以通过诸如strace 或 gdb 的调试工具,但是要在容器的调试进程中使用这些工具。

示例:  容器内部运行htop

创建Dockerfile:

FROM alpine:latest
RUN apk add --update htop && rm -rf /var/cache/apk/*
CMD ["htop"]

构建Dockerfile,将镜像标记为myhtop

$ docker build -t myhtop .

使用下面的命令在容器内使用htop:

$ docker run -it --rm --pid=host myhtop

加入另一个容器的pid名称空间可用于调试该容器。

原创文章 22 获赞 20 访问量 18万+

猜你喜欢

转载自blog.csdn.net/lw001x/article/details/103716403