docker run

asn@hadoop1:~/Desktop$ docker run --help

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

-a, --attach=[] Attach to STDIN, STDOUT or STDERR

--add-host=[] Add a custom host-to-IP mapping (host:ip) 增加一个定制的'主机-IP'映射

--blkio-weight=0 Block IO (relative weight), between 10 and 1000

-c, --cpu-shares=0 CPU shares (relative weight)

--cap-add=[] Add Linux capabilities 增加linux能力

--cap-drop=[] Drop Linux capabilities

--cgroup-parent= Optional parent cgroup for the container

--cidfile= Write the container ID to the file 把容器的ID写入文件

--cpu-period=0 Limit CPU CFS (Completely Fair Scheduler) period

--cpu-quota=0 Limit the CPU CFS quota

--cpuset-cpus= CPUs in which to allow execution (0-3, 0,1)

--cpuset-mems= MEMs in which to allow execution (0-3, 0,1)

-d, --detach=false Run container in background and print container ID         在后台运行容器并打印容器ID

--device=[] Add a host device to the container 把一个主机设备添加到容器

--dns=[] Set custom DNS servers 设置定制的域名服务器

--dns-search=[] Set custom DNS search domains 设置定制的域名服务器的搜索域

-e, --env=[] Set environment variables 设置环境变量

--entrypoint= Overwrite the default ENTRYPOINT of the image 覆盖镜像的默认进入点

--env-file=[] Read in a file of environment variables 读入一个包含环境变量的文件

--expose=[] Expose a port or a range of ports 暴露一个端口、端口范围

-h, --hostname= Container host name 容器的主机名

-i, --interactive=false Keep STDIN标准输入 open even if not attached

--ipc= IPC namespace to use 使用的IPC命名空间

--pid= PID namespace to use 使用的PID命名空间

--uts= UTS namespace to use

-l, --label=[] Set meta data on a container 在容器上,设置元数据

--label-file=[] Read in a line delimited file of labels

--link=[] Add link to another container 添加一个到另一个容器的连接

--log-driver= Logging driver for container 容器的日志驱动

--log-opt=[] Log driver options

--lxc-conf=[] Add custom lxc options 添加定制的lxc选项

-m, --memory= Memory limit 内存限制

--mac-address= Container MAC address (e.g. 92:d0:c6:0a:29:33) 容器的MAC地址

--memory-swap= Total memory (memory + swap), '-1' to disable swap 容器的总内存(物理内容+交换区)

--name= Assign a name to the container 为容器分配一个名字

--net=bridge Set the Network mode for the container 为容器设置网络模式

--oom-kill-disable=false Disable OOM Killer

-P, --publish-all=false Publish all exposed ports to random ports

-p, --publish=[] Publish a container's port(s) to the host 把容器的端口发布到主机

--privileged=false Give extended privileges to this container 赋予容器扩展权限

--read-only=false Mount the container's root filesystem as read only 以只读的方式装载容器的根文件系统

--restart=no Restart policy to apply when a container exits

--rm=false Automatically remove the container when it exits 当容器存在时,自动移除容器

--security-opt=[] Security Options 安全选项

--sig-proxy=true Proxy received signals to the process

-t, --tty=false Allocate a pseudo-TTY 分配一个伪终端

-u, --u-user= Username or UID (format: <name|uid>[:<group|gid>])

--ulimit=[] Ulimit options

-v, --volume=[] Bind mount a volume

--volumes-from=[] Mount volumes from the specified container(s)

-w, --workdir= Working directory inside the container

Docker会在隔离的容器中运行进程。

当运行docker run命令时,Docker会启动一个进程,并为这个进程分配其独占的文件系统、网络资源和以此进程为根进程的进程组。

在容器启动时,镜像可能已经定义了要运行的二进制文件、暴露的网络端口等,但是用户可以通过docker run命令重新定义(译者注:docker run可以控制一个容器运行时的行为,它可以覆盖docker build在构建镜像时的一些默认配置),这也是为什么run命令相比于其它命令有如此多的参数的原因。

使用方法:

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

OPTIONS总起来说可以分为两类:

  • 设置运行方式:
    • 决定容器的运行方式,前台执行还是后台执行;
    • 设置containerID;
    • 设置网络参数;
    • 设置容器的CPU和内存参数;

      - 设置权限和LXC参数;

  • 设置镜像的默认资源,也就是说用户可以使用该命令来覆盖在镜像构建时的一些默认配置。

docker run [OPTIONS]可以让用户完全控制容器的生命周期,并允许用户覆盖执行docker build时所设定的参数,甚至也可以修改本身由Docker所控制的内核级参数。

Operator exclusive options

当执行docker run时可以设置以下参数:

  • Detached vs Foreground
    • Detached (-d)

      - Foreground

  • Container Identification
    • Name (--name)

      - PID Equivalent

  • IPC Setting
  • Network Settings
  • Clean Up (--rm)
  • Runtime Constraints on CPU and Memory
  • Runtime Privilege, Linux Capabilities, and LXC Configuration

======================================================

Detached vs foreground

当我们启动一个容器时,首先需要确定这个容器是运行在前台还是运行在后台。

-d=false, 没有附加标准输入、输出、错误 ---- 运行在后台

Detached (-d)

docker run    -d

-d=false

--detach=false

那么容器将会运行在后台模式。

此时所有I/O数据只能通过网络资源或者共享卷组来进行交互,因为容器不再监听你执行docker run的这个终端命令行窗口。

但你可以通过执行docker attach来重新附着到该容器的回话中。

需要注意的是,容器运行在后台模式下,是不能使用--rm选项的。

Foregroud

不指定-d参数(为明确给-d选项指定值,取默认值false) --在前台模式下

Docker会在容器中启动进程,同时将当前的命令行窗口附着到容器的标准输入、标准输出和标准错误中
--- 把当前的命令行窗口附着到容器的标准输入、输出、错误上

也就是说容器中所有的输出都可以在当前窗口中看到。

甚至它都可以虚拟出一个TTY窗口,来执行信号中断。这一切都是可以配置的:

-a=[], --attach=[]            把容器的标准输入、输出、错误附着到当前的命令行窗口

-t=false, --tty=false        分配一个伪终端

-i=false, --interactive=false    附着标准输入到当前命令行

注意:

-i选项取默认值(false)

docker run 没有-i选项,相当于docker run -i=false,即非交互式运行

docker run -i, 指定-i选项,即以交互式运行

如果在执行run命令时没有指定-a参数,那么Docker默认会挂载所有标准数据流,包括输入输出和错误,你可以单独指定挂载哪个标准流。

$ sudo docker run -a=[stdin, stdout] -i -t ubuntu /bin/bash

如果要进行交互式操作(例如Shell脚本),那我们必须使用-i -t参数同容器进行数据交互。

但是当通过管道同容器进行交互时,就不需要使用-t参数,例如下面的命令:

echo test | docker run -i busybox cat

=====================

容器识别

Name(--name)

可以通过三种方式为容器命名

1. 使用UUID长命名("f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778")
2. 使用UUID短命令("f78375b1c487")
3. 使用Name("evil_ptolemy")

这个UUID标示是由Docker deamon生成的。

如果你在执行docker run时没有指定--name,那么deamon会自动生成一个随机字符串UUID。

但是对于一个容器来说有个name会非常方便,当你需要连接其它容器时或者类似需要区分其它容器时,使用容器名称可以简化操作。无论容器运行在前台或者后台,这个名字都是有效的。

PID equivalent

如果在使用Docker时有自动化的需求,你可以将containerID输出到指定的文件中(PIDfile),类似于某些应用程序将自身ID输出到文件中,方便后续脚本操作。

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

Image[:tag]

当一个镜像的名称不足以分辨这个镜像所代表的含义时,你可以通过tag将版本信息添加到run命令中,以执行特定版本的镜像。例如:docker run ubuntu:14.04
asn@hadoop1:~$ docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

ubuntu jdk8 ed479b562041 28 hours ago 799.3 MB

ubuntu 14.04 d2a0ecffe6fa 10 days ago 188.4 MB

IPC Settings

默认情况下,所有容器都开启了IPC命名空间。

--ipc=""  : Set the IPC mode for the container,

'container:<name|id>': reuses another container's IPC namespace

'host': use the host's IPC namespace inside the container

IPC(POSIX/SysV IPC)命名空间提供了相互隔离的命名共享内存、信号灯变量和消息队列。

共享内存可以提高进程数据的交互速度。

共享内存一般用在数据库和高性能应用(C/OpenMPI、C++/using boost libraries)上或者金融服务上。

如果需要容器中部署上述类型的应用,那么就应该在多个容器直接使用共享内存了。

================

Network settings

默认情况下,所有的容器都开启了网络接口,同时可以接受任何外部的数据请求。

--dns=[]      : Set custom dns servers for the container

--net="bridge"   : Set the Network mode for the container

##在docker桥接上,为容器创建一个新的网络栈

'bridge'                 :     creates a new network stack for the container on the docker bridge

'none'                 :     no networking for this container 没有为该容器配置网络

'container:<name|id>'    :     reuses another container network stack 重用另一个容器的网络栈

'host'                    :     use the host network stack inside the container      在容器内使用主机的网络栈

--add-host=""    : Add a line to /etc/hosts (host:IP) 向容器/etc/hosts的文件中增加一行

--mac-address=""  : Sets the container's Ethernet device's MAC address 设置容器网卡的MAC地址

你可以通过docker run --net=none来关闭网络接口,此时将关闭所有网络数据的输入输出,你只能通过STDIN、STDOUT或者files来完成I/O操作。

默认情况下,容器使用主机的DNS设置,你也可以通过--dns来覆盖容器内的DNS设置。

同时Docker为容器默认生成一个MAC地址,你可以通过--mac-address 12:34:56:78:9a:bc来设置你自己的MAC地址。

Docker支持的网络模式有:

  • none        关闭容器内的网络连接
  • bridge    通过veth接口来连接容器,默认配置
  • host        允许容器使用host的网络堆栈信息。注意:这种方式将允许容器访问host中类似D-BUS之类的系统服务,所以认为是不安全的。
  • container    使用另外一个容器的网络堆栈信息。 

None模式
将网络模式设置为none时,这个容器将不允许访问任何外部router。

这个容器内部只会有一个loopback接口,而且不存在任何可以访问外部网络的router。

Bridge模式
Docker默认会将容器设置为bridge模式。

此时在主机上面将会存在一个docker0的网络接口,同时会针对容器创建一对veth接口。

其中一个veth接口是在主机充当网卡桥接作用,另外一个veth接口存在于容器的命名空间中,并且指向容器的loopback。

Docker会自动给这个容器分配一个IP,并且将容器内的数据通过桥接转发到外部。

Host模式
当网络模式设置为host时,这个容器将完全共享host的网络堆栈。

host所有的网络接口将完全对容器开放。

容器的主机名也会存在于主机的hostname中。

这时,容器所有对外暴露的端口和对其它容器的连接,将完全失效。

Container模式
当网络模式设置为Container时,这个容器将完全复用另外一个容器的网络堆栈。同时使用时这个容器的名称必须要符合下面的格式:--net container:<name|id>.
比如当前有一个绑定了本地地址localhost的Redis容器。

如果另外一个容器需要复用这个网络堆栈, 则需要如下操作:

$ sudo docker run -d --name redis example/redis --bind 127.0.0.1

#use the redis container's network stack to access localhost

$ sudo docker run --rm -ti --net container:redis example/redis-cli -h 127.0.0.1

管理/etc/hosts
/etc/hosts文件中会包含容器的hostname信息,我们也可以使用--add-host这个参数来动态添加/etc/hosts中的数据。

$ /docker run -ti --add-host db-static:86.75.30.9 ubuntu cat /etc/hosts

172.17.0.22      09d03f76bf2c

fe00::0         ip6-localnet

ff00::0         ip6-mcastprefix

ff02::1         ip6-allnodes

ff02::2         ip6-allrouters

127.0.0.1        localhost

::1           localhost ip6-localhost ip6-loopback

86.75.30.9           db-static ##容器启动时添加进来的 地址到主机名映射

=================

Clean up (--rm)

默认情况下,每个容器在退出时,它的文件系统也会保存下来,这样一方面调试会方便些,因为你可以通过查看日志等方式来确定最终状态。

另外一方面,你也可以保存容器所产生的数据。

但是当你仅仅需要短暂的运行一个容器,并且这些数据不需要保存,你可能就希望Docker能在容器结束时自动清理其所产生的数据。

这个时候你就需要--rm这个参数了。 注意:--rm 和 -d不能共用!

--rm=false: Automatically remove the container when it exits (incompatible with -d)

Security configuration

--security-opt="label:user:USER"   : Set the label user for the container

--security-opt="label:role:ROLE"   : Set the label role for the container

--security-opt="label:type:TYPE"   : Set the label type for the container

--security-opt="label:level:LEVEL"  : Set the label level for the container

--security-opt="label:disable"    : Turn off label confinement for the container 关闭容器的标签限制

--secutity-opt="apparmor:PROFILE"   : Set the apparmor profile to be applied  to the container

你可以通过--security-opt修改容器默认的schema标签。

比如说,对于一个MLS系统来说(译者注:MLS应该是指Multiple Listing System),你可以指定MCS/MLS级别。

使用下面的命令可以在不同的容器间分享内容:

#docker run --security-opt=label:level:s0:c100,c200 -i -t fedora bash

如果是MLS系统,则使用下面的命令:

#docker run --security-opt=label:level:TopSecret -i -t rhel7 bash

使用下面的命令可以在容器内禁用安全策略:

#docker run --security-opt=label:disable -i -t fedora bash

如果你需要在容器内执行更为严格的安全策略,那么你可以为这个容器指定一个策略替代,比如你可以使用下面的命令来指定容器只监听Apache端口:

#docker run --security-opt=label:type:svirt_apache_t -i -t centos bash

注意:此时,你的主机环境中必须存在一个名为svirt_apache_t的安全策略。

Runtime constraints on CPU and memory
下面的参数可以用来调整容器内的性能。

-m="" : Memory limit (format: <number><optional unit>, where unit = b, k, m or g)

-c=0 : CPU shares (relative weight)

通过docker run -m可以调整容器所使用的内存资源。

如果主机支持swap内存,那么使用-m可以设定比主机物理内存还大的值。

同样,通过-c可以调整容器的CPU优先级。

默认情况下,所有的容器拥有相同的CPU优先级和CPU调度周期,但你可以通过Docker来通知内核给予某个或某几个容器更多的CPU计算周期。

比如,我们使用-c或者--cpu-shares =0启动了C0、C1、C2三个容器,使用-c=512启动了C3容器。

这时,C0、C1、C2可以100%的使用CPU资源(1024),但C3只能使用50%的CPU资源(512)

如果这个主机的操作系统是时序调度类型的,每个CPU时间片是100微秒,那么C0、C1、 C2将完全使用掉这100微秒,而C3只能使用50微秒。

Runtime privilege, Linux capabilities, and LXC configuration

--cap-add : Add Linux capabilities

--cap-drop : Drop Linux capabilities

--privileged=false : Give extended privileges to this container

--device=[] : Allows you to run devices inside the container without the --privileged flag.

--lxc-conf=[] : (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"

默认情况下,Docker的容器是没有特权的,例如不能在容器中再启动一个容器。这是因为默认情况下容器是不能访问任何其它设备的。但是通过"privileged",容器就拥有了访问任何其它设备的权限。

当操作者执行docker run --privileged时,Docker将拥有访问主机所有设备的权限,同时Docker也会在apparmor或者selinux做一些设置,使容器可以容易的访问那些运行在容器外部的设备。你可以访问Docker博客来获取更多关于--privileged的用法。

同时,你也可以限制容器只能访问一些指定的设备。下面的命令将允许容器只访问一些特定设备:

sudo docker run --device=/dev/snd:/dev/snd ...

默认情况下,容器拥有对设备的读、写、创建设备文件的权限。使用:rwm来配合--device,你可以控制这些权限。

$sudo docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q

$sudo docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk  /dev/xvdc

You will not be able to write the partition table.

Command (m for help): q

$sudo docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk  /dev/xvdc

crash....

$sudo docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk  /dev/xvdc

fdisk: unable to open /dev/xvdc: Operation not permitted

使用--cap-add和--cap-drop,配合--privileged,你可以更细致的控制人哦怒气。

默认使用这两个参数的情况下,容器拥有一系列的内核修改权限,这两个参数都支持all值,如果你想让某个容器拥有除了MKNOD之外的所有内核权限,那么可以执行下面的命令:

$ sudo docker run --cap-add=ALL --cap-drop=MKNOD ...

如果需要修改网络接口数据,那么就建议使用--cap-add=NET_ADMIN,而不是使用--privileged。

$ docker run -t -i --rm  ubuntu:14.04 ip link add dummy0 type dummy

RTNETLINK answers: Operation not permitted

$ docker run -t -i --rm --cap-add=NET_ADMIN ubuntu:14.04 ip link add dummy0 type dummy

如果要挂载一个FUSE文件系统,那么就需要--cap-add和--device了。

如果Docker守护进程在启动时选择了lxclxc-driver(docker -d --exec-driver=lxc),那么就可以使用--lxc-conf来设定LXC参数。

但需要注意的是,未来主机上的Docker deamon有可能不会使用LXC,所以这些参数有可能会包含一些没有实现的配置功能。

这意味着,用户在操作这些参数时必须要十分熟悉LXC。

特别注意:当你使用--lxc-conf修改容器参数后,Docker deamon将不再管理这些参数,那么用户必须自行进行管理。

比如说,你使用--lxc-conf修改了容器的IP地址,那么在/etc/hosts里面是不会自动体现的,需要你自行维护。

##把当前用户加入到docker用户组中

sudo usermod -a -G docker $USER

===============================

asn@hadoop1:~/Desktop$ docker commit -h

Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes ##从一个容器的改变创建一个新的镜像

-a, --author= Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")

-c, --change=[] Apply Dockerfile instruction to the created image

--help=false Print usage

-m, --message= Commit message

-p, --pause=true Pause container during commit

============================

asn@hadoop1:~/hadoop-2.6.0-cdh5.4.4$ docker tag -h

Usage: docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]

Tag an image into a repository ##给镜像打标签入库

-f, --force=false Force

--help=false Print usage

给容器打标签

docker tag 11662b14f5e0 ubuntu:jdk1.7

以用户grid_hd登录容器

asn@hadoop1:~/hadoop-2.6.0-cdh5.4.4$ docker run -it -u grid_hd ubuntu:hd-salve1

grid_hd@c6af61c80d27:/$

查看目录的大小

root@hadoop1:~# sudo du -sh /var/lib/docker

3.7G    /var/lib/docker

给目录下的所有子目录增加执行权限

#!/bin/bash

find /mnt/sda4/docker/aufs -type d | while read dir

do

chmod +rx "$dir"

done

find 目录 -type f -name "docker*" ##在指定目录下,查找名字模式为"docker*"的文件

find 目录 -type d -name "sac*"     ##在指定目录下,查找名字模式为"sac*"的子目录

启动一个docker容器在后台运行

docker run -d IMAGE[:TAG] 命令

docker logs container_id ##打印该容器的输出

docker attach container_id ##附加该容器的标准输出到当前命令行

此时,Ctrl+C退出container(容器消失),按ctrl-p ctrl-q可以退出到宿主机,而保持container仍然在运行

发布容器的一个端口到主机

docker run -p

-p, --publish=[] Publish a container's port(s) to the host

-v, --volume=[] Bind mount a volume

docker images显示镜像

grid_hd@hadoop1:~/Desktop$ docker images --help

Usage: docker images [OPTIONS] [REPOSITORY]

List images

-a, --all=false Show all images (default hides intermediate images)

--digests=false Show digests

-f, --filter=[] Filter output based on conditions provided ##基于的条件过滤输出

--help=false Print usage

--no-trunc=false Don't truncate output

-q, --quiet=false Only show numeric IDs ##仅显示镜像ID

docker rmi删除镜像

grid_hd@hadoop1:~/Desktop$ docker rmi --help

Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

-f, --force=false Force removal of the image

--help=false Print usage

--no-prune=false Do not delete untagged parents

docker rm 删除正在运行的容器

grid_hd@hadoop1:~/Desktop$ docker rm --help

Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

-f, --force=false Force the removal of a running container (uses SIGKILL)

--help=false Print usage

-l, --link=false Remove the specified link

-v, --volumes=false Remove the volumes associated with the container

清除系统中正在运行的容器脚本

docker ps 显示所有和刚运行的容器

grid_hd@hadoop1:~/Desktop$ docker ps --help

Usage: docker ps [OPTIONS]

List containers

-a, --all=false Show all containers (default shows just running)

--before= Show only container created before Id or Name

-f, --filter=[] Filter output based on conditions provided

--help=false Print usage

-l, --latest=false Show the latest created container, include non-running ##显示最近创建的容器(包括未运行的)

-n=-1 Show n last created containers, include non-running         ##显示最近创建的n个容器(包括未运行的)

--no-trunc=false Don't truncate output

-q, --quiet=false Only display numeric IDs

-s, --size=false Display total file sizes

--since= Show created since Id or Name, include non-running

映射host到container的端口和目录

映射主机到容器的端口是很有用的,比如在container中运行memcached,端口为11211,运行容器的host可以连接container的 internel_ip:11211 访问,如果有从其他主机访问memcached需求那就可以通过-p选项,形如-p <host_port:contain_port>,存在以下几种写法:

-p 11211:11211这个即是默认情况下,绑定主机所有网卡(0.0.0.0)的11211端口到容器的11211端口上
-p 127.0.0.1:11211:11211只绑定localhost这个接口的11211端口
-p 127.0.0.1::5000
-p 127.0.0.1:80:8080

目录映射其实是"绑定挂载"host的路径到container的目录,这对于内外传送文件比较方便,在搭建私服那一节,为了避免私服container停止以后保存的images不被删除,就要把提交的images保存到挂载的主机目录下。使用比较简单,-v <host_path:container_path>,绑定多个目录时再加-v。

-v /tmp/docker:/tmp/docker

另外在两个container之间建立联系可用--link,详见高级部分或官方文档
下面是一个例子:

# docker run --name nginx_test \
> -v /tmp/docker:/usr/share/nginx/html:ro \
> -p 80:80 -d \
> nginx:1.7.6

在主机的/tmp/docker下建立index.html,就可以通过http://localhost:80/或http://host-ip:80访问了。

将一个container固化为一个新的image(commit)

当我们在制作自己的镜像的时候,会在container中安装一些工具、修改配置,如果不做commit保存起来,那么container停止以后再启动,这些更改就消失了。
docker commit <container> [repo:tag]
后面的repo:tag可选
只能提交正在运行的container,即通过docker ps可以看见的容器,

查看刚运行过的容器
# docker ps -l
CONTAINER ID   IMAGE     COMMAND      CREATED       STATUS        PORTS   NAMES
c9fdf26326c9   nginx:1   nginx -g..   3 hours ago   Exited (0)..     nginx_test
启动一个已存在的容器(run是从image新建容器后再启动),以下也可以使用docker start nginx_test代替
[root@hostname docker]# docker start c9fdf26326c9
c9fdf26326c9
docker run -i -t --sig-proxy=false 21ffe545748baf /bin/bash
nginx服务没有启动
# docker commit -m "some tools installed" fcbd0a5348ca seanlook/ubuntu:14.10_tutorial
fe022762070b09866eaab47bc943ccb796e53f3f416abf3f2327481b446a9503

-a "seanlook7@gmail.com"
请注意,当你反复去commit一个容器的时候,每次都会得到一个新的IMAGE ID,假如后面的repository:tag没有变,通过docker images可以看到,之前提交的那份镜像的repository:tag就会变成<none>:<none>,所以尽量避免反复提交。
另外,观察以下几点:

commit container只会pause住容器,这是为了保证容器文件系统的一致性,但不会stop。如果你要对这个容器继续做其他修改:

  • 你可以重新提交得到新image2,删除次新的image1
  • 也可以关闭容器用新image1启动,继续修改,提交image2后删除image1
  • 当然这样会很痛苦,所以一般是采用Dockerfile来build得到最终image,参考[]

虽然产生了一个新的image,并且你可以看到大小有100MB,但从commit过程很快就可以知道实际上它并没有独立占用100MB的硬盘空间,而只是在旧镜像的基础上修改,它们共享大部分公共的"片"。

root@1ed046828345:/# mount

none on / type aufs (rw,relatime,si=20f4f613261c7d1d,dio,dirperm1)

proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

tmpfs on /dev type tmpfs (rw,nosuid,mode=755)

devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)

shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)

mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)

sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)

/dev/disk/by-uuid/cb3e8593-916d-40e3-8614-24741433f32f on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)

/dev/disk/by-uuid/cb3e8593-916d-40e3-8614-24741433f32f on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)

/dev/disk/by-uuid/cb3e8593-916d-40e3-8614-24741433f32f on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)

devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)

proc on /proc/asound type proc (ro,nosuid,nodev,noexec,relatime)

proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime)

proc on /proc/fs type proc (ro,nosuid,nodev,noexec,relatime)

proc on /proc/irq type proc (ro,nosuid,nodev,noexec,relatime)

proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime)

proc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime)

tmpfs on /proc/kcore type tmpfs (rw,nosuid,mode=755)

tmpfs on /proc/timer_stats type tmpfs (rw,nosuid,mode=755)

有四种不同的选项会影响容器守护进程的服务名称。

  1. -h HOSTNAME 或者 --hostname=HOSTNAME  --设置容器的主机名,仅本机可见。

这种方式是写到/etc/hostname ,以及/etc/hosts 文件中,作为容器主机IP的别名,并且将显示在容器的bash中。

不过这种方式设置的主机名将不容易被容器之外可见。这将不会出现在 docker ps 或者 其他的容器的/etc/hosts 文件中。

  1. --link=CONTAINER_NAME:ALIAS  --使用这个选项去run一个容器, 将在此容器的/etc/hosts文件中增加一个主机名ALIAS这个主机名是名为CONTAINER_NAME 的容器的IP地址的别名。

这使得新容器的内部进程可以访问主机名为ALIAS的容器而不用知道它的IP。

--link= 关于这个选项的详细讨论请看:    Communication between containers.

3. --dns=IP_ADDRESS --设置DNS服务器的IP地址,写入到容器的/etc/resolv.conf文件中。当容器中的进程尝试访问不在/etc/hosts文件中的主机A 时,容器将以53端口连接到IP_ADDRESS这个DNS服务器去搜寻主机A的IP地址。

4. --dns-search=DOMAIN --设置DNS服务器的搜索域,以防容器尝试访问不完整的主机名时从中检索相应的IP。这是写入到容器的 /etc/resolv.conf文件中的。当容器尝试访问主机 host,而DNS搜索域被设置为 example.com ,那么DNS将不仅去查寻host主机的IP,还去查询host.example.com的 IP。

在docker中,如果启动容器时缺少以上最后两种选项设置时,将使得容器的/etc/resolv.conf文件看起来和宿主主机的/etc/resolv.conf文件一致。这些选项将修改默认的设置。

=================================

3、关于docker容器的端口映射

由于docker容器的IP地址每次启动都会变,所以不适用于手动添加端口映射(难道每次重启都来查看容器的IP么?),

所以需要每次启动容器时, 由docker程序自动添加NAT规则,前期尽可能的把需要映射的端口在创建容器时配置好,如下:

#此处我把mysql,redis,nginx,ssh都进行了映射

docker run -h="activemq" --name activemq -d -p 51000:22 -p 51001:3306-p 51003:6379 -p 51004:6381 -p 51005:80-p 51006:8000 -p 51007:8888 debian/base/etc/rc.local

后续对于docker容器的管理,记住容器的名称,如上述名称是activemq,则使用

docker stop,start来控制容器进程。

docker stop activemq  
    docker start activemq

4、关于docker容器的多程序开机自动运行docker容器每次启动时,开机自启动的命令都要在启动容器前指定。

docker run -I -t debian /bin/bash命令,只会运行/bin/bash程序,其它的程序都不会运行,对于要跑多个程序的容器特别纠结。

多程序开机自动运行方法:
可把前面所说的启动命令换成dockerrun -I -t debian /etc/rc.local,在容器中把所有需要开机自的启动命令放在/etc/rc.local中,就可以达到多程序开机自启动了。

后台运行则是:docker run -d -p 50001:22 debian /etc/rc.local。

注意:run命令是创建一个新的容器,如果要启动一个曾经运行过的容器,则用命令docker ps -a中找对应的容器ID,然后使用docker start <容器ID>即可。

5、关于docker容器和镜像的关系

无论容器里做什么操作,写文件,删文件。该容器的基本镜像都不会有任何改变。

这是因为Docker从父镜像建立增量镜像,只存储每个容器的更改。

因此,如果你有一个300MB的父镜像,如果你在容器中安装了50MB的额外应用或服务,你的容器只有50MB,父镜像还是300MB。

但是可以使用Dockfile或commit命令来,把增量镜像和父镜像一起生成一个新的镜像。

commit使用:
    docker commit <容器id> <新镜像名称>

Dockfile使用:
    root@yangrong:/data# cat Dockerfile

FROM ubuntu/testa     #这是基础镜像

CMD["/root/start.sh"]     #这是启动命令

root@yangrong:/data# docker build -t <新镜像名> ./

6、docker参数详解
    docker  
    useage of docker  
    -D 默认false 允许调试模式(debugmode)  
    -H 默认是unix:///var/run/docker.sock tcp://[host[:port]]来绑定或者

unix://[/path/to/socket]来使用(二进制文件的时候),当主机ip host=[0.0.0.0],(端口)port=[4243] 或者 path=[/var/run/docker.sock]是缺省值,做为默认值来使用  
    -api-enable-cors 默认flase 允许CORS header远程api  
    -b     默认是空,附加在已存在的网桥上,如果是用'none'参数,就禁用了容器的网络  
    -bip     默认是空,使用提供的CIDR(ClasslessInter-Domain Routing-无类型域间选路)标记地址动态创建网桥(dcoker0),和-b参数冲突  
    -d     默认false 允许进程模式(daemonmode)  
    -dns     默认是空,使docker使用指定的DNS服务器  
    -g     默认是"/var/lib/docker":作为docker使用的根路径  
    -icc     默认true,允许inter-container来通信  
    -ip     默认"0.0.0.0":绑定容器端口的默认Ip地址  
    -iptables     默认true 禁用docker添加iptables规则  
    -mtu     默认1500 : 设置容器网络传输的最大单元(mtu)  
    -p         默认是/var/run/docker.pid进程pid使用的文件路径  
    -r         默认是true 重启之前运行的容器  
    -s         默认是空,这个是docker运行是使用一个指定的存储驱动器  
    -v         默认false 打印版本信息和退出

7、docker run命令详解
    Usage: docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]  
    Run a command in a new container  
    -a=map[]: 附加标准输入、输出或者错误输出  
    -c=0: 共享CPU格式(相对重要)  
    -cidfile="": 将容器的ID标识写入文件  
    -d=false: 分离模式,在后台运行容器,并且打印出容器ID  
    -e=[]:设置环境变量  
    -h="": 容器的主机名称  
    -i=false: 保持输入流开放即使没有附加输入流  
    -privileged=false: 给容器扩展的权限  
    -m="": 内存限制 (格式:<number><optional unit>, unit单位 = b, k, m or g)  
    -n=true: 允许镜像使用网络
    -p=[]: 匹配镜像内的网络端口号
    -rm=false:当容器退出时自动删除容器 (不能跟-d一起使用)  
    -t=false: 分配一个伪造的终端输入
    -u="": 用户名或者ID  
    -dns=[]: 自定义容器的DNS服务器
    -v=[]: 创建一个挂载绑定:[host-dir]:[container-dir]:[rw|ro].如果容器目录丢失,docker会创建一个新的卷  
    -volumes-from="": 挂载容器所有的卷
    -entrypoint="": 覆盖镜像设置默认的入口点  
    -w="": 工作目录内的容器  
    -lxc-conf=[]: 添加自定义-lxc-conf="lxc.cgroup.cpuset.cpus = 0,1" 
    -sig-proxy=true: 代理接收所有进程信号(even in non-tty mode)  
    -expose=[]: 让你主机没有开放的端口  
    -link="": 连接到另一个容器(name:alias)  
    -name="": 分配容器的名称,如果没有指定就会随机生成一个  
    -P=false: Publish all exposed ports to the host interfaces 公布所有显示的端口主机接口

8、docker常用命令总结
    docker pull <镜像名:tag> #从官网拉取镜像  
    docker search <镜像名> #搜索在线可用镜像名

8.1查询容器、镜像、日志
    docker top <container> #显示容器内运行的进程  
    docker images #查询所有的镜像,默认是最近创建的排在最上。  
    docker ps #查看正在运行的容器  
    docker ps -l #查看最后退出的容器的ID  
    docker ps -a #查看所有的容器,包括退出的。  
    docker logs {容器ID|容器名称} #查询某个容器的所有操作记录。  
    docker logs -f {容器ID|容器名称} #实时查看容易的操作记录。

8.2删除容器与镜像
    docker rm $(docker ps -a -q) #删除所有容器  
    docker rm <容器名or ID> #删除单个容器  
    docker rmi <ID> #删除单个镜像  
    docker rmi $(docker images | grep none | awk '{print $3}' | sort -r)  #删除所有镜像

8.3启动停止容器
    docker stop <容器名or ID> #停止某个容器  
    docker start <容器名or ID> #启动某个容器  
    docker kill <容器名or ID> #杀掉某个容器

8.4容器迁器
    docker export <CONTAINER ID> > /home/export.tar #导出  
    cat /home/export.tar | sudo docker import - busybox-1-export:latest  # 导入export.tar文件  
    docker save debian> /home/save.tar #将debian容器打包  
    docker load< /home/save.tar #在另一台服务器上加载打包文件

save和export的对比参考地址:

http://www.fanli7.net/a/bianchengyuyan/C__/20140423/452256.html

8.5运行一个新容器
#运行一个新容器,同时为它命名、端口映射。以debian02镜像为例  
docker run -h="redis-test" --name redis-test -d -p 51000:22 -p51001:3306 -p 51003:6379 -p 51004:6381 -p 51005:80 -p 51006:8000 -p 51007:8888 debian02 /etc/rc.local

#从container中拷贝文件,当container已经关闭后,在里面的文件还可以拷贝出来。  
sudo docker cp 7bb0e258aefe:/etc/debian_version . #把容器中的/etc/debian_version拷贝到当前目录下。

8.6 docker Dockfile镜像制作
    root@yangrong:/data# cat Dockerfile  
    FROM ubuntu/testa #这是基础镜像  
    CMD ["/root/start.sh"] #这是启动命令

root@yangrong:/data# docker build -t <新镜像名> ./ #生成新的镜像

一些网络配置命令选项只能在启动时提供给Docker服务器,并且在运行中不能改变:

  • -b BRIDGE或--bridge=BRIDGE— see    建立自己的网桥
  • --bip=CIDR— see    定制docker0
  • -H SOCKET...或--host=SOCKET...—   它看起来像是在设置容器的网络,但实际却恰恰相反:它告诉Docker服务器要接收命令的通道,例如"run container"和"stop container"。
  • --icc=true|false— see    容器间通信
  • --ip=IP_ADDRESS— see    绑定容器端口
  • --ip-forward=true|false— see    容器间通信
  • --iptables=true|false— see   容器间通信
  • --mtu=BYTES— see    定制docker0

有两个网络配置选项可以在启动时或调用docker run时设置。当在启动时设置它会成为docker run的默认值:

  • --dns=IP_ADDRESS...— see    配置DNS
  • --dns-search=DOMAIN...— see    配置DNS

最后,一些网络配置选项只能在调用docker run时指出,因为它们要为每个容器做特定的配置:

  • -h HOSTNAME或--hostname=HOSTNAME— see    配置DNS 和  Docker与容器连接原理
  • --link=CONTAINER_NAME:ALIAS— see   配置DNS and    容器间通信
  • --net=bridge|none|container:NAME_or_ID|host— see   Docker与容器连接原理
  • -p SPECor--publish=SPEC— see    绑定容器端口
  • -P或--publish-all=true|false— see    绑定容器端口

接下来的部分会对以上话题从易到难做出逐一解答。

【Shell脚本】逐行处理文本文件

经常会对文体文件进行逐行处理,在Shell里面如何获取每行数据,然后处理该行数据,最后读取下一行数据,循环处理.有多种解决方法如下:

1.通过read命令完成.

read命令接收标准输入,或其他文件描述符的输入,得到输入后,read命令将数据放入一个标准变量中.

利用read读取文件时,每次调用read命令都会读取文件中的"一行"文本.

当文件没有可读的行时,read命令将以非零状态退出.

1 cat data.dat | while read line
2 do
3     echo "File:${line}"
4 done
5 
6 while read line
7 do 
8     echo "File:${line}"
9 done < data.dat

2.使用awk命令完成

awk是一种优良的文本处理工具,提供了极其强大的功能.

利用awk读取文件中的每行数据,并且可以对每行数据做一些处理,还可以单独处理每行数据里的每列数据.

1 cat data.dat | awk '{print $0}'
2 cat data.dat | awk 'for(i=2;i<NF;i++) {printf $i} printf "\n"}'

第1行代码输出data.dat里的每行数据,第2代码输出每行中从第2列之后的数据.

如果是单纯的数据或文本文件的按行读取和显示的话,使用awk命令比较方便.

3.使用for var in file 命令完成

for var in file 表示变量var在file中循环取值.取值的分隔符由$IFS确定.

1 for line in $(cat data.dat)
2 do 
3     echo "File:${line}"
4 done
5 
6 for line in `cat data.dat`
7 do 
8     echo "File:${line}"
9 done

如果输入文本每行中没有空格,则line在输入文本中按换行符分隔符循环取值.

如果输入文本中包括空格或制表符,则不是换行读取,line在输入文本中按空格分隔符或制表符或换行符特环取值.

可以通过把IFS设置为换行符来达到逐行读取的功能.

IFS的默认值为:空白(包括:空格,制表符,换行符)

ubuntu目录结构

本文引自:cup

/根目录,一般根目录下只存放目录,不要存放文件,/etc、/bin、/dev、/lib、/sbin应该和根目录放置在一个分区中

/bin:

/usr/bin:    可执行二进制文件的目录,如常用的命令ls、tar、mv、cat等。

/boot:    放置linux系统启动时用到的一些文件。/boot/vmlinuz为linux的内核文件,以及/boot/gurb。建议单独分区,分区大小100M即可

/dev:    存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,常用的是挂载光驱mount /dev/cdrom /mnt。

/etc:    系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有/etc/inittab、/etc/fstab、/etc/init.d、/etc/X11、/etc/sysconfig、/etc/xinetd.d修改配置文件之前记得备份。

注:/etc/X11存放与x windows有关的设置。

/home系统默认的用户家目录,新增用户账号时,用户的家目录都存放在此目录下,~表示当前用户的家目录,~test表示用户test的家目录。

建议单独分区,并设置较大的磁盘空间,方便用户存放数据

/lib:

/usr/lib:

/usr/local/lib:    系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助,比较重要的目录为/lib/modules。

/lost+fount:    系统异常产生错误时,会将一些遗失的片段放置于此目录下,通常这个目录会自动出现在装置目录下。如加载硬盘于/disk 中,此目录下就会自动产生目录/disk/lost+found

/mnt:/media:    光盘默认挂载点,通常光盘挂载于/mnt/cdrom下,也不一定,可以选择任意位置进行挂载。

/opt:    给主机额外安装软件所摆放的目录。

如:FC4使用的Fedora 社群开发软件,如果想要自行安装新的KDE 桌面软件,可以将该软件安装在该目录下。以前的 Linux 系统中,习惯放置在 /usr/local 目录下

/proc:    此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的目录有/proc/cpuinfo、/proc/interrupts、/proc/dma、/proc/ioports、/proc/net/*等

/root:    系统管理员root的家目录,系统第一个启动的分区为/,所以最好将/root和/放置在一个分区下。

/sbin:

/usr/sbin:

/usr/local/sbin放置系统管理员使用的可执行命令,如fdisk、shutdown、mount等。与/bin不同的是,这几个目录是给系统管理员root使用的命令,一般用户只能"查看"而不能设置和使用。

/tmp:    一般用户或正在执行的程序临时存放文件的目录,任何人都可以访问,重要数据不可放置在此目录下

/srv:    服务启动之后需要访问的数据目录,如www服务需要访问的网页数据存放在/srv/www内

/usr应用程序存放目录

/usr/bin    存放应用程序

/usr/share    存放共享数据

/usr/lib        存放不能直接运行的,却是许多程序运行所必需的一些函数库文件。

          /usr/local:    存放软件升级包

/usr/share/doc:        系统说明文件存放目录。

/usr/share/man:         程序说明文件存放目录,使用 man ls时会查询/usr/share/man/man1/ls.1.gz的内容

建议单独分区,设置较大的磁盘空间

/var:    放置系统执行过程中经常变化的文件,如随时更改的日志文件/var/log

/var/log/message    所有的登录文件存放目录

/var/spool/mail:    邮件存放的目录

/var/run:            程序或服务启动后,PID存放在该目录下。

建议单独分区,设置较大的磁盘空间

docker 使用总结的更多相关文章

  1. docker——容器安装tomcat

    写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...

  2. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  3. Docker 第一篇--初识docker

    已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...

  4. 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)

    环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...

  5. docker for mac 学习记录

    docker基本命令 docker run -d -p 80:80 --name webserver nginx 运行容器并起别名 docker ps 展示目前启动的容器 docker ps -a 展 ...

  6. scrapy爬虫docker部署

    spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...

  7. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

  8. 开发者的利器:Docker 理解与使用

    困扰写代码的机器难免会被我们安装上各种各样的开发工具.语言运行环境和引用库等一大堆的东西,长久以来不仅机器乱七八糟,而且有些相同的软件还有可能会安装不同的版本,这样又会导致一个项目正常运行了,却不小心 ...

  9. 使用python自动生成docker nginx反向代理配置

    由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...

  10. 微服务与Docker介绍

    什么是微服务 微服务应用的一个最大的优点是,它们往往比传统的应用程序更有效地利用计算资源.这是因为它们通过扩展组件来处理功能瓶颈问题.这样一来,开发人员只需要为额外的组件部署计算资源,而不需要部署一个 ...

随机推荐

  1. Java开发中的Memcache原理及实现

    Memcached 客户端程序 Memcached的java客户端已经存在三种了: ?  官方提供的基于传统阻塞io由Greg Whalin维护的客户端 ?  Dustin Sallings实现的基于 ...

  2. TypeScript高级类型

    交叉类型 将多个类型合并成一个类型,去两个类型的并集.与继承的区别是,继承可以有自己的属性,而交叉没有. interface DogInterface { run():void } interface ...

  3. DOM,jquery,vue

    DOM 部分引用自引用自七色花的姐姐 1.DOM全称 Document Object Model,即文档对象模型,它允许脚本(js)控制Web页面.窗口和文档 2.DOM的作用 做网页的都知道,想要做 ...

  4. Gradle基本操作入手

    Gradle本身的领域对象主要由Project和Task.Project为Task提供了执行上下文,所有的Plugin要么向Project中添加用于配置Property,要么向Project中添加不同 ...

  5. MySQL——自定义[存储]函数、触发器

    一. 编程基础 1)        结束符 2)        代码块 Begin 相当于 { end;  相当于 } 1.    变量 系统变量 Show variables; 查看系统变量sql_ ...

  6. Web.xml详解(转)(Filter,context,listener)

    web.xml 详细解释!!(链接) web.xml加载过程(步骤) 首先简单说一下,web.xml的加载过程. 当我们去启动一个WEB项目时,容器包括(JBoss.Tomcat等)首先会读取项目we ...

  7. Redis → 下载安装及启动

    一.Window 下安装 下载地址:https://github.com/MSOpenTech/redis/releases Redis 支持 32 位和 64 位.这个需要根据你系统平台的实际情况选 ...

  8. mysql自定义function 写递归查询子节点

    #存储文本信息表 CREATE TABLE WordInfoEntity( word_id ) PRIMARY KEY NOT NULL, # 主键ID UUID word_greda :正文文本 , ...

  9. 洛谷 P2146 [NOI2015]软件包管理器 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 输出样例#1: 输入样例#2: 输出样例#2: 说明 说明 思路 AC代码 总结 题面 题目链接 P ...

  10. 洛谷P2051 中国象棋

    题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...