Docker run参考(5) – UTS(–uts)和IPC (–ipc)设置

UTS设置(–uts)

  1. –uts=""  : Set the UTS namespace mode for the container,
  2.        ‘host’: use the host’s UTS namespace inside the container

UTS命名空间用于设置主机名和对该命名空间中正在运行的进程可见的域。默认下,所有的容器,包括那么以–network=host运行的容器,有它们自己的UTS命名空间。设置UTS为host将使容器使用与主机相同的U
TS命名空间。注意–hostname在host UTS模式是无效的。
当你想在主机更改hostname之后,同时也更改同样的hostname到容器, 这就需要与主机共享UTS命名空间。一个更高级的用例是从容器更改主机的hostname。

IPC设置(–ipc)

  1. –ipc=""  : Set the IPC mode for the container,
  2.              ‘container:<name|id>’: reuses another container’s IPC namespace
  3.              ‘host’: use the host’s IPC namespace inside the container

默认下,所有的容器都启用了IPC命名空间。
IPC(POSIX / SysV IPC)命名空间提供命名的共享内存段,信号量和消息队列的分离。
共享内存段用来加速内部进程以内存速度通信,而不是通过管道或网络。共享内存通常由数据库和定制(通常是C / OpenMPI,C ++ /使用boost库)的高性能应用程序用于科学计算和金融服务行业。如果这些类型的应用程序分成多个容器,可能需要共享容器的IPC机制。

Docker run参考(4) – PID设置(–pid)

  1. –pid=""  : Set the PID (Process) Namespace mode for the container,
  2.              ‘container:<name|id>’: joins another container’s PID namespace
  3.              ‘host’: use the host’s PID namespace inside the container

默认下,所有的容器都启用了PID命名空间。
PID命名空间提供了进程的分离。PID命名空间删除系统进程视图,允许进程ID可重用,包括pid 1。
在一些情况下需要容器共享主机进程命名空间,基本上允许容器内的进程可以查看主机的所有进程。例如,构建了一个带调试工具如strace或gdb的容器,想在容器使用这些工具来调试主机的进程。

示例:容器内运行htop

创建这个Dockerfile:

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

构建Dockerfile并tag镜像为myhtop:

  1. $ docker build -t myhtop .

使用如下命令在容器内运行htop命令:

  1. $ docker run -it –rm –pid=host myhtop

这样htop就能看到宿主机上的所有进程。

示例:加入其它容器pid命令空间

启动一个容器运行redis服务器:

  1. $ docker run –name my-redis -d redis

通过运行一个带strace的容器来debug这个redis容器:

  1. $ docker run -it –pid=container:my-redis my_strace_docker_image bash
  2. $ strace -p 1

Docker run参考(3) – 容器标识

Name (–name)

此参数有三种方式识别一个容器:

标识类型 示例值
UUID long identifier “f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”
UUID short identifier “f78375b1c487”
Name “evil_ptolemy”

UUID标识符来自docker daemon。如果不使用–name参数指定一个容器名称,那么daemon将生成一个随机的名称。定义一个有意义容器名称方便识别容器。此名称可以用来把容器关联在一个指定的网络内。

PID

最后,为了方便自动化,可以让docker把容器ID写到一个你指定的文件。这个与一些程序把它们的进程id写到一个文件类似。

  1. –cidfile="": Write the container ID to the file

Image[:tag]

这个虽然不是严格识别一个容器的方法,不过可以使用image[:tag]来指定一个特定版本的镜像来运行一个容器。例如docker run ubuntu:14.04。

Image[@digest]

使用v2镜像或之后镜像的格式有一个称为digest的内容可寻址标识符。只要用来生成镜像的内容输入没有更改,这个digest值是可预测和可引用的。
下面的示例使用sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 digest来从alpine镜像运行一个容器:

  1. $ docker run alpine@sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 date

Docker run参考(2) – Detached vs foreground模式

当要启动一个docker容器时,首先必须决定是以detached模式在后台运行容器还是以默认的foreground模式运行:

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

Detached (-d)

要在detached模式启动一个容器,必须使用-d=true或仅-d选项。docker是这样设计的,当运行在容器的根进程退出时,以detached模式启动的容器也退出。以detached模式运行的容器当它停止时无法自动删除,因此–rm选项和-d选项不能一起使用。
不要传递一个service x start命令到deatched的容器。例如,下面的命令是尝试启动nginx服务。

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

这个命令会成功启动nginx服务。不过在detached的容器会失败。根进程service nginx start启动后立即返回,导致detached容器按照设计停止。因此,nginx服务虽然启动了,不过无法使用。所以要按如下命令启动nginx服务:

  1. $ docker run -d -p 80:80 my_image nginx -g ‘daemon off;’

要对一个detached容器输入/输出,使用网络连接或共享数据卷。
要重新附着到一个detached容器,使用docker attach命令。

Foreground

在forgroud模式[当-d不指定时],docker run能够在容器启动进程并附着控制台到进程的标准输入,输出和标准错误。它甚至可以伪装为一个TTY(这是大多数命令行可执行程序所需要的)并传递信号。有配置的选项有:

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

如果你没有指定-a,那么docker将附着所有标准流。可以从三个标准流(STDIN, STDOUT, STDERR)指定你想连接的标准流。如:

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

对于交互的进程[如shell],为了给容器进程分配一个tty,必须-i -t一起使用。-i -t经常写为-it。当客户端标准输出重定向或管道传递时,不能指定-t:

  1. $ echo test | docker run -i busybox cat

Linux对运行在容器PID 1的进程特别对待:它会忽略任何信号的默认行为。所以,进程不会收到SIGINT或SIGTERM时停止,除非它要这么做。

Docker run参考(1) – 一般格式

基本的docker run命令格式为:

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

docker run命令必须指定创建容器的镜像。镜像开发者可以定义镜像默认的关于:

  • 后台或前台运行
  • 容器标识
  • 网络设置
  • CPU和内存运行时限制
  • 使用docker run [OPTIONS],镜像用户能够添加或覆盖镜像开发者设置的默认参数。并且,镜像用户几乎能够覆盖docker运行时的默认参数。之所以docker run命令有这么多选项设置是因为它能够覆盖镜像和docker运行默认参数。