• docker 使用总结


    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/OpenMPIC++/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来关闭网络接口,此时将关闭所有网络数据的输入输出,你只能通过STDINSTDOUT或者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>.
    比如当前有一个绑定了本地地址localhostRedis容器。

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

    $ 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启动了C0C1C2三个容器,使用-c=512启动了C3容器。

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

    如果这个主机的操作系统是时序调度类型的,每个CPU时间片是100微秒,那么C0C1 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-driverdocker -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
    • 当然这样会很痛苦,所以一般是采用Dockerfilebuild得到最终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服务器去搜寻主机AIP地址。

    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

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

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

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

    FROM ubuntu/testa     #这是基础镜像

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

     

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

     

    6docker参数详解
        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     
    默认是空,使用提供的CIDRClasslessInter-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 "
    "}'

    第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/vmlinuzlinux的内核文件,以及/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放置系统管理员使用的可执行命令,如fdiskshutdownmount等。与/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存放在该目录下。

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

  • 相关阅读:
    C#中将结构类型数据存储到二进制文件中方法
    常用的20个在线工具类网站清单
    PyQt:开发小工具
    PyQt:使用QtDesigner设计界面
    经营策略
    Xmind 8 update 9 破解
    AI: 百度AI实战教学
    DRF:djangorestframework从入门到精通
    python:requests库发送参数+文件
    python:关于postman中生成的基于requests库的接口代码
  • 原文地址:https://www.cnblogs.com/asnjudy/p/4687272.html
Copyright © 2020-2023  润新知