Docker容器学习梳理--日常操作总结

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

使用Docker已有一段时间了,今天正好有空梳理下自己平时操作Docker时的一些命令和注意细节:

Docker 命令帮助

复制代码
$ sudo docker 
Commands:
    attach    Attach to a running container  
              --将终端依附到容器上
              1> 运行一个交互型容器
                 [root@localhost ~]# docker run -i -t centos /bin/bash
                 [root@f0a02b473067 /]# 
              2> 在另一个窗口上查看该容器的状态
                 [root@localhost ~]# docker ps -a
                 CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS      PORTS       NAMES
                 d4a75f165ce6        centos              "/bin/bash"         5 seconds ago       Up 5 seconds            cranky_mahavira
              3> 退出第一步中运行的容器
                 [root@d4a75f165ce6 /]# exit
                  exit
              4> 查看该容器的状态
                 [root@localhost ~]# docker ps -a
                 CONTAINER ID        IMAGE           COMMAND           CREATED             STATUS                  PORTS    NAMES
                 d4a75f165ce6        centos          "/bin/bash"       2 minutes ago       Exited (0) 23 seconds ago        cranky_mahavira
                 可见此时容器的状态是Exited,那么,如何再次运行这个容器呢?可以使用docker start命令
              5> 再次运行该容器
                 [root@localhost ~]# docker start cranky_mahavira
                 cranky_mahavira
              6> 再次查看该容器的状态
                 [root@localhost ~]# docker ps -a
                 CONTAINER ID        IMAGE          COMMAND             CREATED             STATUS              PORTS      NAMES
                 d4a75f165ce6        centos         "/bin/bash"         6 minutes ago       Up 29 seconds                  cranky_mahavira
                 因为该容器是交互型的,但此刻我们发现没有具体的终端可以与之交互,这时可使用attach命令。
              7> 通过attach命令进行交互
                 [root@localhost ~]# docker attach cranky_mahavira
                 [root@d4a75f165ce6 /]# 

    build     Build an image from a Dockerfile
              --通过Dockerfile创建镜像

    commit    Create a new image from a container's changes
              --通过容器创建本地镜像
              注意:如果是要push到docker hub中,注意生成镜像的命名
               [root@localhost ~]# docker commit centos_v1 centos:v1
               68ad49c999496cff25fdda58f0521530a143d3884e61bce7ada09bdc22337638
               [root@localhost ~]# docker push centos:v1
               You cannot push a "root" repository. Please rename your repository to <user>/<repo> (ex: <user>/centos)
               用centos:v1就不行,因为它push到docker hub中时,是推送到相应用户下,必须指定用户名。譬如我的用户名是ivictor,则新生成的本地镜像命名为:
               docker push victor/centos:v1,其中v1是tag,可不写,默认是latest 
              
    cp        Copy files/folders from a container to a HOSTDIR or to STDOUT
              --在宿主机和容器之间相互COPY文件
              cp的用法如下:
              Usage:    docker cp [OPTIONS] CONTAINER:PATH LOCALPATH|-
                        docker cp [OPTIONS] LOCALPATH|- CONTAINER:PATH
              如:容器mysql中/usr/local/bin/存在docker-entrypoint.sh文件,可如下方式copy到宿主机
              #  docker cp mysql:/usr/local/bin/docker-entrypoint.sh /root
              修改完毕后,将该文件重新copy回容器
              # docker cp /root/docker-entrypoint.sh mysql:/usr/local/bin/     

    create    Create a new container  
              --创建一个新的容器,注意,此时,容器的status只是Created

    diff      Inspect changes on a container's filesystem
              --查看容器内发生改变的文件,以我的mysql容器为例
               [root@localhost ~]# docker diff mysqldb
               C /root
               A /root/.bash_history
               A /test1.txt
               A /test.tar
               A /test.txt
               C /run
               C /run/mysqld
               A /run/mysqld/mysqld.pid
               A /run/mysqld/mysqld.sock
               不难看出,C对应的均是目录,A对应的均是文件

    events    Get real time events from the server
              --实时输出Docker服务器端的事件,包括容器的创建,启动,关闭等。
              譬如:
              [root@localhost ~]# docker events
              2015-09-08T17:40:13.000000000+08:00 d2a2ef5ddb90b505acaf6b59ab43eecf7eddbd3e71f36572436c34dc0763db79: (from wordpress) create
              2015-09-08T17:40:14.000000000+08:00 d2a2ef5ddb90b505acaf6b59ab43eecf7eddbd3e71f36572436c34dc0763db79: (from wordpress) die
              2015-09-08T17:42:10.000000000+08:00 839866a338db6dd626fa8eabeef53a839e4d2e2eb16ebd89679aa722c4caa5f7: (from mysql) start

    exec      Run a command in a running container
              --用于容器启动之后,执行其它的任务
              通过exec命令可以创建两种任务:后台型任务和交互型任务
              后台型任务:docker exec -d cc touch 123  其中cc是容器名
              交互型任务:
              [root@localhost ~]# docker exec -i -t cc /bin/bash
              root@1e5bb46d801b:/# ls
              123  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

    export    Export a container's filesystem as a tar archive
              --将容器的文件系统打包成tar文件
              有两种方式(mysqldb为容器名):
              docker export -o mysqldb1.tar mysqldb
              docker export mysqldb > mysqldb.tar

    history   Show the history of an image
              --显示镜像制作的过程,相当于dockfile

    images    List images   
              --列出本机的所有镜像

    import    Import the contents from a tarball to create a filesystem image
              --根据tar文件的内容新建一个镜像,与之前的export命令相对应
             [root@localhost ~]# docker import mysqldb.tar mysql:v1
             eb81de183cd94fd6f0231de4ff29969db822afd3a25841d2dc9cf3562d135a10
             [root@localhost ~]# docker images
             REPOSITORY                 TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
             mysql                      v1                  eb81de183cd9        21 seconds ago       281.9 MB

              譬如下面一例:
              [root@localhost volume2]# docker ps
              CONTAINER ID   IMAGE               COMMAND      CREATED        STATUS      PORTS     NAMES
              9cb07559cc17   docker.io/ubuntu    "/bin/bash"  22 hours ago   Up 22 hours           naughty_bartik
              [root@localhost volume2]# docker export gigantic_goldwasser > wanghui.tar
              [root@localhost volume2]# docker import wanghui.tar wanghui:v1
              sha256:b6cbbaf69a58149f337dcc439a21ed185dcdf96fd7f72ddf45e102d27f47c4ae
              [root@localhost volume2]# docker images
              REPOSITORY    TAG   IMAGE ID        CREATED           SIZE
              wanghui       v1    b6cbbaf69a58    5 seconds ago     450.9 MB
              [root@localhost volume2]# docker run -i -t wanghui:v1 /bin/bash
              [root@78f4ac39972d /]# ps -ef

    info      Display system-wide information
              --查看docker的系统信息
              [root@localhost ~]# docker info
              Containers: 3              --当前有3个容器
              Images: 298      
              Storage Driver: devicemapper
               Pool Name: docker-253:0-34402623-pool
               Pool Blocksize: 65.54 kB
               Backing Filesystem: xfs
               Data file: /dev/loop0
               Metadata file: /dev/loop1
               Data Space Used: 8.677 GB          --对应的是下面Data loop file大小
               Data Space Total: 107.4 GB
               Data Space Available: 5.737 GB
               Metadata Space Used: 13.4 MB       --对应的是下面Metadata loop file大小
               Metadata Space Total: 2.147 GB
               Metadata Space Available: 2.134 GB
               Udev Sync Supported: true
               Deferred Removal Enabled: false
               Data loop file: /var/lib/docker/devicemapper/devicemapper/data
               Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
               Library Version: 1.02.93-RHEL7 (2015-01-28)
              Execution Driver: native-0.2
              Logging Driver: json-file
              Kernel Version: 3.10.0-229.el7.x86_64
              Operating System: CentOS Linux 7 (Core)
              CPUs: 2
              Total Memory: 979.7 MiB
              Name: localhost.localdomain
              ID: TFVB:BXGQ:VVOC:K2DJ:LECE:2HNK:23B2:LEVF:P3IQ:L7D5:NG2V:UKNL
              WARNING: bridge-nf-call-iptables is disabled
              WARNING: bridge-nf-call-ip6tables is disabled

    inspect   Return low-level information on a container or image
              --用于查看容器的配置信息,包含容器名、环境变量、运行命令、主机配置、网络配置和数据卷配置等。

    kill      Kill a running container 
              --强制终止容器
              关于stop和kill的区别,docker stop命令给容器中的进程发送SIGTERM信号,默认行为是会导致容器退出,当然,
              容器内程序可以捕获该信号并自行处理,例如可以选择忽略。而docker kill则是给容器的进程发送SIGKILL信号,该信号将会使容器必然退出。

    load      Load an image from a tar archive or STDIN
              --与下面的save命令相对应,将下面sava命令打包的镜像通过load命令导入

    login     Register or log in to a Docker registry
              --登录到自己的Docker register,需有Docker Hub的注册账号
              [root@localhost ~]# docker login
              Username: ivictor
              Password: 
              Email: xxxx@foxmail.com
              WARNING: login credentials saved in /root/.docker/config.json
              Login Succeeded

    logout    Log out from a Docker registry
              --退出登录
              [root@localhost ~]# docker logout
              Remove login credentials for https://index.docker.io/v1/

    logs      Fetch the logs of a container
              --用于查看容器的日志,它将输出到标准输出的数据作为日志输出到docker logs命令的终端上。常用于后台型容器

    pause     Pause all processes within a container
              --暂停容器内的所有进程,
              此时,通过docker stats可以观察到此时的资源使用情况是固定不变的,
              通过docker logs -f也观察不到日志的进一步输出。

    port      List port mappings or a specific mapping for the CONTAINER
              --输出容器端口与宿主机端口的映射情况
              譬如:
              [root@localhost ~]# docker port blog
              80/tcp -> 0.0.0.0:80
              容器blog的内部端口80映射到宿主机的80端口,这样可通过宿主机的80端口查看容器blog提供的服务

    ps        List containers  
              --列出所有容器,其中docker ps用于查看正在运行的容器,ps -a则用于查看所有容器。

    pull      Pull an image or a repository from a registry
              --从docker hub中下载镜像

    push      Push an image or a repository to a registry
              --将本地的镜像上传到docker hub中
              前提是你要先用docker login登录上,不然会报以下错误
              [root@localhost ~]# docker push ivictor/centos:v1
              The push refers to a repository [docker.io/ivictor/centos] (len: 1)
              unauthorized: access to the requested resource is not authorized

    rename    Rename a container
              --更改容器的名字

    restart   Restart a running container 
              --重启容器

    rm        Remove one or more containers 
              --删除容器,注意,不可以删除一个运行中的容器,必须先用docker stop或docker kill使其停止。
              当然可以强制删除,必须加-f参数
              如果要一次性删除所有容器,可使用 docker rm -f `docker ps -a -q`,其中,-q指的是只列出容器的ID

    rmi       Remove one or more images   
              --删除镜像

    run       Run a command in a new container   
              --让创建的容器立刻进入运行状态,该命令等同于docker create创建容器后再使用docker start启动容器

    save      Save an image(s) to a tar archive
              --将镜像打包,与上面的load命令相对应
              譬如:
              docker save -o nginx.tar nginx

    search    Search the Docker Hub for images   
              --从Docker Hub中搜索镜像

    start     Start one or more stopped containers
              --启动容器

    stats     Display a live stream of container(s) resource usage statistics
              --动态显示容器的资源消耗情况,包括:CPU、内存、网络I/O

    stop      Stop a running container 
              --停止一个运行的容器

    tag       Tag an image into a repository
              --对镜像进行重命名

    top       Display the running processes of a container
              --查看容器中正在运行的进程

    unpause   Unpause all processes within a container
              --恢复容器内暂停的进程,与pause参数相对应

    version   Show the Docker version information 
              --查看docker的版本

    wait      Block until a container stops, then print its exit code
              --捕捉容器停止时的退出码
              执行此命令后,该命令会“hang”在当前终端,直到容器停止,此时,会打印出容器的退出码。
复制代码

Docker option

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Usage of docker:
   --api- enable -cors= false                 Enable CORS headers  in  the remote API                       # 远程 API 中开启 CORS 头
   -b, --bridge= ""                         Attach containers to a pre-existing network bridge          # 桥接网络
                                            use  'none'  to disable container networking
   --bip= ""                                Use this CIDR notation address  for  the network bridge's IP, not compatible with -b
                                          # 和 -b 选项不兼容,具体没有测试过
   -d, --daemon= false                      Enable daemon mode                                          # daemon 模式
   -D, --debug= false                       Enable debug mode                                           # debug 模式
   --dns=[]                               Force docker to use specific DNS servers                    # 强制 docker 使用指定 dns 服务器
   --dns-search=[]                        Force Docker to use specific DNS search domains             # 强制 docker 使用指定 dns 搜索域
   -e, -- exec -driver= "native"              Force the docker runtime to use a specific  exec  driver      # 强制 docker 运行时使用指定执行驱动器
   --fixed-cidr= ""                         IPv4 subnet  for  fixed IPs (ex: 10.20.0.0 /16 )
                                            this subnet must be nested  in  the bridge subnet ( which  is defined by -b or --bip)
   -G, --group= "docker"                    Group to assign the unix socket specified by -H when running  in  daemon mode
                                            use  ''  (the empty string) to disable setting of a group
   -g, --graph= "/var/lib/docker"           Path to use as the root of the docker runtime               # 容器运行的根目录路径
   -H, --host=[]                          The socket(s) to bind to  in  daemon mode                     # daemon 模式下 docker 指定绑定方式[tcp or 本地 socket]
                                            specified using one or  more  tcp: //host :port, unix: ///path/to/socket , fd: // * or fd: //socketfd .
   --icc= true                              Enable inter-container communication                        # 跨容器通信
   --insecure-registry=[]                 Enable insecure communication with specified registries (no certificate verification  for  HTTPS and  enable  HTTP fallback) (e.g., localhost:5000 or 10.20.0.0 /16 )
   --ip= "0.0.0.0"                          Default IP address to use when binding container ports      # 指定监听地址,默认所有 ip
   --ip-forward= true                       Enable net.ipv4.ip_forward                                  # 开启转发
   --ip-masq= true                          Enable IP masquerading  for  bridge's IP range
   --iptables= true                         Enable Docker's addition of iptables rules                  # 添加对应 iptables 规则
   --mtu=0                                Set the containers network MTU                              # 设置网络 mtu
                                            if  no value is provided: default to the default route MTU or 1500  if  no default route is available
   -p, --pidfile= "/var/run/docker.pid"     Path to use  for  daemon PID  file                             # 指定 pid 文件位置
   --registry-mirror=[]                   Specify a preferred Docker registry mirror                 
   -s, --storage-driver= ""                 Force the docker runtime to use a specific storage driver   # 强制 docker 运行时使用指定存储驱动
   --selinux-enabled= false                 Enable selinux support                                      # 开启 selinux 支持
   --storage-opt=[]                       Set storage driver options                                  # 设置存储驱动选项
   --tls= false                             Use TLS; implied by tls-verify flags                        # 开启 tls
   --tlscacert= "/root/.docker/ca.pem"      Trust only remotes providing a certificate signed by the CA given here
   --tlscert= "/root/.docker/cert.pem"      Path to TLS certificate  file                                # tls 证书文件位置
   --tlskey= "/root/.docker/key.pem"        Path to TLS key  file                                        # tls key 文件位置
   --tlsverify= false                       Use TLS and verify the remote (daemon: verify client, client: verify daemon)  # 使用 tls 并确认远程控制主机
   - v , --version= false                     Print version information and quit

Docker run指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
[root@localhost ~] # docker run --help
  
: 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  file  of environment variables    读入一个包含环境变量的文件
--expose=[] Expose a port or a range of ports    暴露一个端口、端口范围
-h, -- hostname = Container host name      容器的主机名
-i, --interactive= false  Keep STDIN    标准输入
--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      把容器的端口发布到主机,即容器端口映射到宿主机的具体端口上。可加上多个-p
--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 run命令时,Docker会启动一个进程,并为这个进程分配其独占的文件系统、网络资源和以此进程为根进程的进程组。
  
在容器启动时,镜像可能已经定义了要运行的二进制文件、暴露的网络端口等,但是用户可以通过docker run命令重新定义(docker run可以控制一个容器运行时的行为,它可以覆盖docker build在构建镜像时的一些默认配置),这也是为什么run命令相比于其它命令有如此多的参数的原因。
使用方法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  
OPTIONS总起来说可以分为两类:
a)设置运行方式:
    决定容器的运行方式,前台执行还是后台执行;
    设置containerID;
    设置网络参数;
    设置容器的CPU和内存参数;
    设置权限和LXC参数;
b)设置镜像的默认资源,也就是说用户可以使用该命令来覆盖在镜像构建时的一些默认配置。
  
docker run [OPTIONS]可以让用户完全控制容器的生命周期,并允许用户覆盖执行docker build时所设定的参数,甚至也可以修改本身由Docker所控制的内核级参数。
  
Operator exclusive options
当执行docker run时可以设置以下参数:
   1.Detached vs Foreground
      Detached (-d)
        - Foreground
  
   2.Container Identification
      Name (--name)
        - PID Equivalent
  
   3.IPC Setting
    
   4.Network Settings
  
   5.Clean Up (-- rm )
  
   6.Runtime Constraints on CPU and Memory
  
   7.Runtime Privilege, Linux Capabilities, and LXC Configuration
  
----------------------------------------------------------------------------------------------
1.Detached vs foreground
当我们启动一个容器时,首先需要确定这个容器是运行在前台还是运行在后台。
  
-d= false , 没有附加标准输入、输出、错误 ---- 运行在后台
  
Detached (-d)
docker run    -d
    -d= false
    --detach= false
  
那么容器将会运行在后台模式。
此时所有I /O 数据只能通过网络资源或者共享卷组来进行交互,因为容器不再监听你执行docker run的这个终端命令行窗口。
但你可以通过执行docker attach来重新附着到该容器的回话中。
需要注意的是,容器运行在后台模式下,是不能使用-- rm 选项的。
  
  
2.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默认会挂载所有标准数据流,包括输入输出和错误,你可以单独指定挂载哪个标准流。
# docker run -a=[stdin, stdout] -i -t ubuntu /bin/bash
  
如果要进行交互式操作(例如Shell脚本),那我们必须使用-i -t参数同容器进行数据交互。
但是当通过管道同容器进行交互时,就不需要使用-t参数,例如下面的命令:
# echo test | docker run -i busybox cat

Docker容器识别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
1.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
  
  
2.Image[:tag]
当一个镜像的名称不足以分辨这个镜像所代表的含义时,你可以通过tag将版本信息添加到run命令中,以执行特定版本的镜像。例如:docker run ubuntu:14.04
[root@localhost ~] # docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
docker.io /uifd/ui-for-docker    latest              312812aadc64        34 hours ago        8.096 MB
docker.io /nginx                 latest              5e69fe4b3c31        5 days ago          182.5 MB
192.168.1.23:5000 /tomcat7       latest              47c5123914a1        6 days ago          562.3 MB
docker.io /ubuntu                latest              0ef2e08ed3fa        4 weeks ago         130 MB
docker.io /centos                latest              67591570dd29        3 months ago        191.8 MB
docker.io /tomcat                latest              ebb17717bed4        5 months ago        355.4 MB
  
  
3.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容器。
如果另外一个容器需要复用这个网络堆栈, 则需要如下操作:
# docker run -d --name redis example/redis --bind 127.0.0.1
  
//use  the redis container's network stack to access localhost
# 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
默认情况下,每个容器在退出时,它的文件系统也会保存下来,这样一方面调试会方便些,因为你可以通过查看日志等方式来确定最终状态。
另外一方面,你也可以保存容器所产生的数据。
但是当你仅仅需要短暂的运行一个容器,并且这些数据不需要保存,你可能就希望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,你可以控制这些权限。
# docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc
Command (m  for  help): q
  
# 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
  
# docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk  /dev/xvdc
crash....
  
# 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之外的所有内核权限,那么可以执行下面的命令:
# docker run --cap-add=ALL --cap-drop=MKNOD ...
  
如果需要修改网络接口数据,那么就建议使用--cap-add=NET_ADMIN,而不是使用--privileged。
# run -t -i --rm  ubuntu:14.04 ip link add dummy0 type dummy
RTNETLINK answers: Operation not permitted
# 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用户组中
usermod  -a -G docker $USER
===============================
# 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
============================
  
# 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登录容器
# docker run -it -u grid_hd ubuntu:hd-salve1
  
给目录下的所有子目录增加执行权限的脚本
#!/bin/bash
find  /mnt/sda4/docker/aufs  - type  d |  while  read  dir
do
     chmod  +rx  "$dir"
done
  
启动一个docker容器在后台运行
docker run -d IMAGE[:TAG] 命令
docker logs container_id  ##打印该容器的输出
[root@localhost ~] # docker run -d --name mytest docker.io/centos /bin/sh -c "while true; do echo hello world; sleep 2; done"
37738fe3d6f9ef26152cb25018df9528a89e7a07355493020e72f147a291cd17
[root@localhost ~] # docker logs mytest
hello world
hello world
hello world
hello world
  
docker attach container_id  ##附加该容器的标准输出到当前命令行
[root@localhost ~] # docker attach mytest
hello world
hello world
hello world
.......
此时,Ctrl+C退出container(容器消失),按ctrl-p ctrl-q可以退出到宿主机,而保持container仍然在运行
 
---------------------------------------------------------------
另外,观察以下几点:
commit container只会pause住容器,这是为了保证容器文件系统的一致性,但不会stop。如果你要对这个容器继续做其他修改:
     你可以重新提交得到新image2,删除次新的image1
     也可以关闭容器用新image1启动,继续修改,提交image2后删除image1
     当然这样会很痛苦,所以一般是采用Dockerfile来build得到最终image,参考[]
虽然产生了一个新的image,并且你可以看到大小有100MB,但从commit过程很快就可以知道实际上它并没有独立占用100MB的硬盘空间,而只是在旧镜像的基础上修改,它们共享大部分公共的 "片"
  
有四种不同的选项会影响容器守护进程的服务名称:
1)-h HOSTNAME 或者 -- hostname =HOSTNAME  --设置容器的主机名,仅本机可见。
这种方式是写到 /etc/hostname  ,以及 /etc/hosts  文件中,作为容器主机IP的别名,并且将显示在容器的 bash 中。
不过这种方式设置的主机名将不容易被容器之外可见。这将不会出现在 docker  ps  或者 其他的容器的 /etc/hosts  文件中。
  
2)--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文件一致。这些选项将修改默认的设置。

注意一点:当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

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

简单补充下.......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
在ubuntu中安装docker
# sudo apt-get install docker.io
   
查看docker的版本信息
# docker version
   
查看安装docker的信息
# docker info
   
查看本机Docker中存在哪些镜像
# docker images
 
-------------------------------------------------------
docker pull 拉取镜像
docker push 推送指定镜像
  
示例:
下载官方 ubuntu docker 镜像,默认下载所有 ubuntu 官方库镜像
[root@localhost ~] # docker pull ubuntu
  
下载指定版本 ubuntu 官方镜像
[root@localhost ~] # docker pull ubuntu:14.04
  
推送镜像库到私有源(可注册 docker 官方账户,推送到官方自有账户)
[root@localhost ~] # docker push 192.168.0.100:5000/ubuntu
  
推送指定镜像到私有源
[root@localhost ~] # docker push 192.168.0.100:5000/ubuntu:14.04
 
------------------------------------------------------
从 Docker Hub 搜索镜像
# docker search ubuntu:14.04
示例:
查找star数至少为10的ubuntu镜像(默认是不加-s选项)
[root@localhost ~] # docker search -s 10 ubuntu
INDEX       NAME                                 DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io /ubuntu                      Ubuntu is a Debian-based Linux operating s...   5682      [OK]     
docker.io   docker.io /rastasheep/ubuntu-sshd      Dockerized SSH service, built on  top  of of...   75                   [OK]
docker.io   docker.io /ubuntu-upstart              Upstart is an event-based replacement  for  ...   70        [OK]     
docker.io   docker.io /consol/ubuntu-xfce-vnc      Ubuntu container with  "headless"  VNC sessi...   45                   [OK]
docker.io   docker.io /ubuntu-debootstrap          debootstrap --variant=minbase --components...   28        [OK]     
docker.io   docker.io /torusware/speedus-ubuntu    Always updated official Ubuntu docker imag...   27                   [OK]
docker.io   docker.io /nickistre/ubuntu-lamp       LAMP server on Ubuntu                           16                   [OK]
docker.io   docker.io /nuagebec/ubuntu             Simple always updated Ubuntu docker images...   16                   [OK]
-------------------------------------------------------
  
显示一个镜像的历史
# docker history birdben/ubuntu:v1
   
列出一个容器里面被改变的文件或者目
# docker diff birdben/ubuntu:v1
   
从一个容器中取日志
# docker logs birdben/ubuntu:v1
   
显示一个运行的容器里面的进程信息
# docker top birdben/ubuntu:v1
   
从容器里面拷贝文件/目录到本地一个路径
# docker cp ID:/container_path to_path
--------------------------------------------------------------------------------------------
查看容器的root用户密码
# docker logs <容器名orID> 2>&1 | grep '^User: ' | tail -n1
因为Docker容器启动时的root用户的密码是随机分配的。所以,通过这种方式就可以得到redmine容器的root用户的密码了。
   
查看容器日志
# docker logs -f <容器名orID>
-----------------------------------------------------------------------------------
运行一个新容器,同时为它命名、端口映射、文件夹映射。以redmine镜像为例
# docker run --name redmine -p 9003:80 -p 9023:22 -d -v /var/redmine/files:/redmine/files -v /var/redmine/mysql:/var/lib/mysql sameersbn/redmine
   
一个容器连接到另一个容器
# docker run -i -t --name sonar -d -link mmysql:db   tpires/sonar-server sonar
容器连接到mmysql容器,并将mmysql容器重命名为db。这样,sonar容器就可以使用db的相关的环境变量了。
 
检查某一特定容器可以使用docker inspect命令,后面跟容器的名称或唯一ID。
Docker自动创建的容器名称同样是不方便记忆的,所以最好在运行容器时使用--name参数为其指定一个名称,命令格式为docker run --name=<yourname>。
# docker inspect App_Container
 
使用logs命令查看守护式容器
可以通过使用docker logs命令来查看容器的运行日志,其中-- tail 选项可以指定查看最后几条日志,而-t选项则可以对日志条目附加时间戳。使用-f选项可以跟踪日志的输出,直到手动停止。
docker logs [OPTIONS] CONTAINER
# docker logs App_Container
 
查看运行中容器内的进程
docker  top  CONTAINER [ ps  OPTIONS]
# docker top App_Container
 
构建自己的镜像
# docker build -t <镜像名> <Dockerfile路径>
如Dockerfile在当前路径:
# docker build -t xx/gitlab .
   
重新查看container的stdout
# 启动top命令,后台运行
$ ID=$( sudo  docker run -d ubuntu  /usr/bin/top  -b)
# 获取正在running的container的输出
sudo  docker attach $ID
top  - 02:05:52 up  3:05,  0  users ,  load average: 0.01, 0.02, 0.05
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.1%us,  0.2%sy,  0.0%ni, 99.7% id ,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    373572k total,   355560k used,    18012k  free ,    27872k buffers
Swap:   786428k total,        0k used,   786428k  free ,   221740k cached
^C$
sudo  docker stop $ID
   
后台运行(-d)、并暴露端口(-p)
# docker run -d -p 127.0.0.1:33301:22 centos6-ssh
   
从Container中拷贝文件出来
# sudo docker cp 7bb0e258aefe:/etc/debian_version .
拷贝7bb0e258aefe中的 /etc/debian_version 到当前目录下。
注意:只要7bb0e258aefe没有被删除,文件命名空间就还在,可以放心的把 exit 状态的container的文件拷贝出来

列出当前所有正在运行的容器

1
2
3
4
5
# docker ps
# docker ps -a   为查看所有的容器,包括已经停止的。
# docker ps -q   查找已运行的docker容器的ID
# docker ps -a -q  查找所有的docker容器的ID
# docker ps -l    列出最近一次启动的容器

查看容器的相关信息
# docker inspect CONTAINER_ID

显示容器IP地址和端口号,如果输出是空的说明没有配置IP地址(不同的Docker容器可以通过此IP地址互相访问)
# docker inspect --format='{{.NetworkSettings.IPAddress}}' CONTAINER_ID

保存对容器的修改 
# docker commit -m "Added ssh from ubuntu14.04" -a "birdben" 6s56d43f627f3 birdben/ubuntu:v1
参数:
-m参数用来来指定提交的说明信息;
-a可以指定用户信息的;
6s56d43f627f3代表的时容器的id;
birdben/ubuntu:v1指定目标镜像的用户名、仓库名和 tag 信息。

构建一个容器 
# docker build -t="birdben/ubuntu:v1" .
参数:
-t为构建的镜像制定一个标签,便于记忆/索引等
. 指定Dockerfile文件在当前目录下,也可以替换为一个具体的 Dockerfile 的路径。

在docker中运行ubuntu镜像
# docker run <相关参数> <镜像 ID> <初始命令>

守护模式启动
# docker run -it ubuntu:14.04

交互模式启动
# docker run -it ubuntu:14.04 /bin/bash

指定端口号启动
# docker run -p 80:80 birdben/ubuntu:v1

指定配置启动
# sudo docker run -d -p 10.211.55.4:9999:22 birdben/ubuntu:v1 '/usr/sbin/sshd' -D

参数:
-d:表示以“守护模式”执行,日志不会出现在输出终端上。
-i:表示以“交互模式”运行容器,-i 则让容器的标准输入保持打开
-t:表示容器启动后会进入其命令行,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
-v:表示需要将本地哪个目录挂载到容器中,格式:-v <宿主机目录>:<容器目录>,-v 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
-p:表示宿主机与容器的端口映射,此时将容器内部的 22 端口映射为宿主机的 9999 端口,这样就向外界暴露了 9999 端口,可通过 Docker 网桥来访问容器内部的 22 端口了。
注意:
这里使用的是宿主机的 IP 地址:10.211.55.4,与对外暴露的端口号 9999,它映射容器内部的端口号 22。ssh外部需要访问:ssh root@10.211.55.4 -p 9999
不一定要使用“镜像 ID”,也可以使用“仓库名:标签名”

根据镜像启动容器的时候,如果镜像的TAG是latest,那么就直接跟镜像名就行了;如果TAG不是latest,那么镜像后面要跟上这个TAG标识。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@linux-node2 ~] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              0ef2e08ed3fa        2 weeks ago         130 MB
centos7             7.3.1611            d5ebea14da54        3 weeks ago         311 MB
 
由于ubuntu镜像的TAG标识是latest,那么容器启动的时候,镜像后面的TAG信息可以省略。
[root@linux-node2 ~] # docker run -i -t ubuntu /bin/bash
 
但是centos7镜像的TAG标识不是latest,所以容器启动的时候必须要跟上这个TAG信息。
[root@linux-node2 ~] # docker run -i -t centos7:7.3.1611 /bin/bash
[root@2ba57568e836 /] # cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
 
不跟TAG的话,就会报错
[root@linux-node2 ~] # docker run -i -t centos7 /bin/bash
Unable to  find  image  'centos7:latest'  locally
Pulling repository docker.io /library/centos7
docker: Error: image library /centos7 :latest not found.
See  'docker run --help' .

docker运行一个容器必须是基于镜像来进行的,一旦容器启动了,我们就可以登录到容器中,安装自己所需的软件或应用程序。
启动容器的命令中必须跟一个镜像,启动容器后执行的命令必须放在镜像后面,如下,/bin/bash必须放在镜像名称的后面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@linux-node2 ~] # docker run -i -t daocloud.io/library/ubuntu /bin/bash
root@a7b997da8ba3:/ # cat /etc/issue
Ubuntu 16.04.1 LTS \n \l
  
root@a7b997da8ba3:/ # [root@linux-node2 ~]# docker run -i -t ubuntu /bin/bash
root@d96c6b85cace:/ # cat /etc/issue
Ubuntu 16.04.1 LTS \n \l
root@d96c6b85cace:/ #
  
[root@linux-node2 ~] # docker run -t -i -v /home/wangshibo/docker:/home/mycontainer:rw -p 8888:8080 centos /bin/bash
[root@8f65f826ad80 /] #
  
[root@linux-node2 ~] # docker run -i -t centos7:7.3.1611 /bin/bash
[root@4941394a1e92 /] # cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
  
[root@linux-node2 ~] # docker run -i -t centos:centos6 /bin/bash
[root@357eaa658c87 /] # cat /etc/redhat-release
CentOS release 6.8 (Final)

注意:创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用。可以通过-P或-p参数来指定端口映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
1)当使用-p标记时,可以指定端口映射,即容器端口映射到宿主机的对应端口。可以用多个-p指定多个端口映射关系。如下:
[root@localhost ~] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io /redis      latest              e4a35914679d        2 weeks ago         182.9 MB
 
[root@localhost ~] # docker run --name myredis -p 63799:6379 -d docker.io/redis
f5d5ff51ace01c5f26fcd65a6ca4853f8556a333c812576123ed71fd3d405737
 
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
f5d5ff51ace0        docker.io /redis      "docker-entrypoint.sh"    6 seconds ago       Up 5 seconds        0.0.0.0:63799->6379 /tcp    myredis
 
[root@localhost ~] # docker run --rm -it --name myredis2 --link myredis:redisdb docker.io/redis /bin/bash
root@16b660ff9f65: /data # redis-cli -h redisdb -p 6379
redisdb:6379>  ping
PONG
redisdb:6379>  set  test  linux
OK
redisdb:6379>
 
在别的机器上通过访问本机的63799端口连接这个容器的redis
[root@linux-node2 ~] # redis-cli -h 192.168.1.23 -p 63799
192.168.1.23:63799> get  test
"linux"
192.168.1.23:63799>
 
------------------------------------------------------------------------------------------
可以使用多个-p映射多个端口
[root@localhost ~] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos7             7.3.1611            d5ebea14da54        3 weeks ago         311 MB
  
[root@localhost ~] # docker run -i -t -p 20022:22 -p 8088:80 centos7:7.3.1611 /bin/bash
[root@1a7a949e2f41 /] #
------------------------------------------------------------------------------------------
 
2)当使用-P标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。如下:
[root@localhost ~] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io /redis      latest              e4a35914679d        2 weeks ago         182.9 MB
 
[root@localhost ~] # docker run --name myredis -P -d docker.io/redis
805d0e21e531885aad61d3e82395210b50621f1991ec4b7f9a0e25c815cc0272
 
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
805d0e21e531        docker.io /redis      "docker-entrypoint.sh"    4 seconds ago       Up 3 seconds        0.0.0.0:32768->6379 /tcp    myredis
 
从上面的结果中可以看出,本地主机的32768端口被映射到了redis容器的6379端口上,也就是说访问本机的32768端口即可访问容器内redis端口。
 
测试看下,登陆redis容器,随意写个数据
[root@localhost ~] # docker run --rm -it --name myredis2 --link myredis:redisdb docker.io/redis /bin/bash
root@be44d955d6f4: /data # redis-cli -h redisdb -p 6379
redisdb:6379>  set  wangshibo huanqiu
OK
redisdb:6379>
 
在别的机器上通过上面映射的端口32768连接这个容器的redis
[root@linux-node2 ~] # redis-cli -h 192.168.1.23 -p 32768
192.168.1.23:32768> get wangshibo
"huanqiu"

start 启动容器(多个容器,后面就跟多个容器id)
# docker start 117843ade696117843ade696

stop 停止正在运行的容器(多个容器,后面就跟多个容器id)(在容器里面按ctrl+d组合键,也会退出当前容器)
# docker stop 117843ade696117843ade696

restart 重启容器(多个容器,后面就跟多个容器id)
# docker restart 117843ade696117843ade696

删除容器和镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
rm  删除容器(删除一个或多个,多个之间用空格隔开)
# docker rm 117843ade696117843ade696
 
杀死所有running状态的容器
# docker kill $(docker ps -a -q)
# docker rm $(docker ps -a -q)
-----------------------------------------------------------------------------------
rmi 删除镜像(删除一个或多个,多个之间用空格隔开)
# docker rmi ed9c93747fe1Deleted
 
删除所有未打tag的镜像
# docker rmi $(docker images -q | awk '/^<none>/ { print $3 }')
 
删除所有镜像
# docker rmi $(docker images -q)
 
根据格式删除所有镜像
# docker rm $(docker ps -qf status=exited)

登录Docker Hub中心
# docker login

发布上传image(push)
# docker push birdben/ubuntu:v1

Docker本机和容器之间的文件拷贝:

1
2
3
4
5
1)将本机的 /root/test . file 文件传输到ID为7bb0e258aefe的容器里的 /mnt/wang 目录下
# docker cp /root/test.file 7bb0e258aefe:/mnt/wang/
 
2)拷贝ID为7bb0e258aefe的容器里的 /var/id .list文件到本机的 /opt
# docker cp  7bb0e258aefe:/var/id.list /opt/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
实例如下:
[root@linux-node2 ~] # docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
c7bd050b0a23        centos               "/bin/bash"          2 hours ago         Up 2 hours                                   small_almeida
eaf66f1e43ab        centos               "/sbin/init"         7 weeks ago         Up 7 weeks          0.0.0.0:8888->8080 /tcp    hungry_khorana
  
[root@linux-node2 ~] # docker exec -it eaf66f1e43ab /bin/bash
[root@eaf66f1e43ab /] # cd /mnt/
[root@eaf66f1e43ab mnt] # ls
[root@eaf66f1e43ab mnt] # mkdir test-haha
[root@eaf66f1e43ab mnt] # cd test-haha
[root@eaf66f1e43ab  test -haha] # touch a b c
[root@eaf66f1e43ab  test -haha] # pwd
/mnt/test-haha
[root@eaf66f1e43ab  test -haha] # ls
a  b  c
[root@eaf66f1e43ab  test -haha] #
  
然后拷贝容器文件出来
[root@linux-node2 ~] # docker cp eaf66f1e43ab:/mnt/test-haha /opt/
[root@linux-node2 ~] # ls /opt/test-haha/
a  b  c

镜像的存出和载入(可以将本机下载的镜像导出,然后将导出文件上传到别的机器上,在别的机器上进行镜像导入)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1)如果要导出镜像到本地文件,可以使用 docker save命令。
拉取镜像
[root@linux-node2 ~] # docker pull ubuntu:14.04
[root@linux-node2 ~] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              14.04               c4ff7513909d        5 weeks ago         225.4 MB
 
导出镜像
[root@linux-node2 ~] # docker save ubuntu:14.04 > /opt/ubuntu_14.04.tar.gz
或者:
[root@linux-node2 ~] # docker save -o /opt/ubuntu_14.04.tar.gz ubuntu:14.04
 
2)将上面的镜像导出文件上传到linux-node1机器上,然后在linux-node1机器上使用docker load命令载入这个镜像
[root@linux-node1 ~] # docker load < /opt/ubuntu_14.04.tar.gz
或者:
[root@linux-node1 ~] # docker load --input ubuntu_14.04.tar
 
实例如下:
[root@linux-node2 opt] # docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
centos7                      7.3.1611            1d7e06aab5db        24 hours ago        264.7 MB
nginx                        1.9                 c8c29d842c09        9 months ago        182.7 MB
[root@linux-node2 opt] # docker save nginx:1.9 > /opt/nginx:1.9.tar.gz
[root@linux-node2 opt] # ls
nginx:1.9. tar .gz
[root@linux-node2 opt] # rsync -e "ssh -p22" -avpgolr /opt/nginx:1.9.tar.gz 192.168.1.23:/opt/
   
登陆192.168.1.23
[root@localhost ~] # cd /opt/
[root@localhost opt] # ls
nginx:1.9. tar .gz
[root@localhost opt] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io /centos     latest              980e0e4c79ec        5 months ago        196.7 MB
docker.io /redis      2.8.19              dd9fe7db5236        22 months ago       110.7 MB
   
导入nginx镜像
[root@localhost opt] # docker load < /opt/nginx:1.9.tar.gz
[root@localhost opt] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io /centos     latest              980e0e4c79ec        5 months ago        196.7 MB
nginx               1.9                 c8c29d842c09        9 months ago        182.7 MB
docker.io /redis      2.8.19              dd9fe7db5236        22 months ago       110.7 MB

容器的导出和导入(可以依据导出的容器快照导入为镜像,在本地或将容器快照文件上传到别的机器上进行导入镜像操作都可以)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1)导出容器
如果要导出本地某个容器,可以使用 docker  export  命令。
[root@linux-node2 ~] # docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                    NAMES
5243af7921c5        centos               "/bin/bash"               2 days ago          Exited (0) 5 seconds ago                            sharp_saha
 
[root@linux-node2 ~] # docker export 5243af7921c5 > /opt/centos.tar.gz
[root@linux-node2 ~] # ls /opt/
centos. tar .gz
 
这样将导出上面的ID为5243af7921c5的容器快照到本地的 /opt/centos . tar .gz文件了。
 
2)导入容器快照
可以使用 docker  import  从容器快照文件中再导入为镜像
 
为了测试效果,先删除ID为5243af7921c5的容器,再导入
[root@linux-node2 ~] # docker rm 5243af7921c5
5243af7921c5
 
[root@linux-node2 ~] # cat /opt/centos.tar.gz | docker import - test/centos:v1.0
sha256:d84d758c5cda4aced7cd24a4efefedb3d56076ae127133dac8ac79ca0bab3f3d
或者使用下面命令导入
[root@linux-node2 ~] # docker import /opt/centos.tar.gz test/centos:v1.0
 
[root@linux-node2 ~] # docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
test /centos                   v1.0                d84d758c5cda        5 seconds ago       191.8 MB
 
[root@linux-node2 ~] # docker run -t -i test/centos:v1.0 /bin/bash
[root@5056db543cc2 /] #
 
[root@linux-node2 ~] # docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
5056db543cc2         test /centos :v1.0     "/bin/bash"          19 seconds ago      Up 18 seconds                                tiny_dijkstra
 
这个ID为5056db543cc2的新容器既是导入的上面的容器快照创建的
 
温馨提示:
用户既可以使用docker load来导入镜像存储文件到本地镜像库,也可以使用docker  import  来导入一个容器快照到本地镜像库。
这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。
此外,从容器快照文件导入时可以重新指定标签等元数据信息。

比如说我在A机器上有个nginx容器,现在要在B机器上启动一个一模一样的nginx容器(或者说将A机器上的nginx容器拿到B机器上),方法有下面两种:

1
2
1)将A机器上将nginx容器提交为新的镜像(docker commit),然后将这个镜像导出并上传到B机器上,最后在B机器上导入这个新镜像并依据这个镜像启动容器,这个就和A机器上的nginx容器一样了。
2)将A机器上的nginx容器做快照,然后从这个快照文件中导入为镜像,将这个镜像上传到B机器上,最后在B机器上导入这个新镜像并依据它启动容器。

在运行状态中的容器内再次启动新的进程(docker exec)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
虽然Docker鼓励我们一个容器只运行一个服务,但是当我们需要对运行中的容器进行监控、维护和管理时,通常需要为运行中的容器启动新进程。
# docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
这条命令与docker run极为相似,也可以使用-i、-t和-d等参数。
[root@linux-node2 ~] # docker exec -i -t App_Container /bin/bash
 
示例如下:
创建一个tomcat容器(创建容器后,启动容器的 /bin/bash 进程)
[root@localhost ~] # docker run -t -i -d --name=tomcat --hostname=wangshibo --dns=8.8.8.8 -p 8888:8080 tomcat7 /bin/bash
a5ab82945a88d16c51941c7fbc1e3f581823099835f96423c4fd19b44841b31c
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
a5ab82945a88        tomcat7              "/bin/bash"          3 seconds ago       Up 2 seconds        0.0.0.0:8888->8080 /tcp    tomcat
 
在上面tomcat容器已经启动的状态下,再在宿主机上启动该容器中新的进程。(当然也可以直接登陆容器内启动这个进程)
[root@localhost ~] # docker exec tomcat /usr/local/tomcat7/bin/startup.sh     //如果启动后出现卡的情况,就ctrl+c,不影响启动结果。
Tomcat started.
 
登陆到该容器内验证,发现tomcat进程已经通过上面的docker  exec 启动了
[root@localhost ~] # docker start tomcat
tomcat
[root@localhost ~] # docker attach tomcat
[root@wangshibo /] # ps -ef|grep tomcat
root        40     1 19 09:17 ?        00:00:08 java -Djava.util.logging.config. file = /usr/local/tomcat7/conf/logging .properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed. dirs = /usr/local/tomcat7/endorsed  -classpath  /usr/local/tomcat7/bin/bootstrap .jar: /usr/local/tomcat7/bin/tomcat-juli .jar -Dcatalina.base= /usr/local/tomcat7  -Dcatalina.home= /usr/local/tomcat7  -Djava.io.tmpdir= /usr/local/tomcat7/temp  org.apache.catalina.startup.Bootstrap start
root        77     1  0 09:17 ?        00:00:00  grep  --color=auto tomcat

-----------------------------------------------------------------------------------------------------------
一般来说,容器创建后的主机名都是随机生成的一串字符。DNS也是默认和宿主机一样的(/etc/resolv.conf)
容器创建后,登陆容器是无法修改主机名或DNS配置的,会报错说:需要root权限才能修改!
其实容器的主机名或DNS配置是可以在容器创建的时候手动指定的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
1)创建容器时使用 "-h HOSTNAME"  或者  "--hostname=HOSTNAME" 参数就可以指定容器的主机名。
    设定容器的主机名,它会被写到容器内的  /etc/hostname  和  /etc/hosts 。但它在容器外部看不到,既不会在 docker  ps  中显示,也不会在其他的容器的  /etc/hosts  看到。
2)创建容器时使用 "--dns=IP_ADDRESS" 参数就可以指定容器的DNS
    添加 DNS 服务器到容器的  /etc/resolv .conf 中,让容器用这个服务器来解析所有不在  /etc/hosts  中的主机名。
3)创建容器时使用 "--link=CONTAINER_NAME:ALIAS" 参数
    选项会在创建容器的时候,添加一个其他容器的主机名到  /etc/hosts  文件中,让新容器的进程可以使用主机名 ALIAS 就可以连接它。
 
实例:
手动设置主机名和DNS
[root@localhost ~] # docker run -t -i -d --name=tomcat --hostname=wangshibo --dns=8.8.8.8 -p 8888:8080 tomcat7 /bin/bash
4ccc7415aab8645fa2f76cac5b484c5e7195bec4da355069df4e7df62bd53e2f
[root@localhost ~] # docker attach tomcat
[root@wangshibo /] # cat /etc/hostname
wangshibo
[root@wangshibo /] # cat /etc/hosts  
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  wangshibo
[root@wangshibo /] # cat /etc/resolv.conf
search localdomain
nameserver 8.8.8.8
[root@wangshibo /] # ping www.baidu.com
PING www.a.shifen.com (14.215.177.38) 56(84) bytes of data.
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=51  time =36.0 ms
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=2 ttl=51  time =35.9 ms
......
[root@wangshibo /] # /usr/local/tomcat7/bin/startup.sh
Using CATALINA_BASE:    /usr/local/tomcat7
Using CATALINA_HOME:    /usr/local/tomcat7
Using CATALINA_TMPDIR:  /usr/local/tomcat7/temp
Using JRE_HOME:         /usr
Using CLASSPATH:        /usr/local/tomcat7/bin/bootstrap .jar: /usr/local/tomcat7/bin/tomcat-juli .jar
Tomcat started.
[root@wangshibo /] # yum install -y lsof
[root@wangshibo /] # yum install -y net-tools
[root@wangshibo /] # lsof -i:8080
COMMAND PID USER   FD   TYPE   DEVICE SIZE /OFF  NODE NAME
java     35 root   44u  IPv6 30851404      0t0  TCP *:webcache (LISTEN)
[root@wangshibo /] # ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
         inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>
         ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
         RX packets 149  bytes 660403 (644.9 KiB)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 108  bytes 7655 (7.4 KiB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
         inet 127.0.0.1  netmask 255.0.0.0
         inet6 ::1  prefixlen 128  scopeid 0x10<host>
         loop  txqueuelen 0  (Local Loopback)
         RX packets 0  bytes 0 (0.0 B)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 0  bytes 0 (0.0 B)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
 
做容器链接
[root@localhost ~] # docker run -t -i -d --name=my_tomcat --link tomcat:hahaha tomcat7 /bin/bash
996e16302d460c725f3685f98935fa3b61335ac19ccf2c4daf8615b492b1ac56
[root@localhost ~] # docker attach my_tomcat
[root@996e16302d46 /] # cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  hahaha wangshibo
172.17.0.3  996e16302d46
 
[root@996e16302d46 /] # yum install -y net-tools
[root@996e16302d46 /] # yum install -y telnet
[root@996e16302d46 /] # ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 172.17.0.3  netmask 255.255.0.0  broadcast 0.0.0.0
         inet6 fe80::42:acff:fe11:3  prefixlen 64  scopeid 0x20<link>
         ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
         RX packets 86  bytes 382330 (373.3 KiB)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 74  bytes 5338 (5.2 KiB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
 
在本容器链接tomcat容器的8080端口,则可以使用别名hahaha
[root@996e16302d46 /] # ping hahaha
PING hahaha (172.17.0.2) 56(84) bytes of data.
64 bytes from hahaha (172.17.0.2): icmp_seq=1 ttl=64  time =0.170 ms
64 bytes from hahaha (172.17.0.2): icmp_seq=2 ttl=64  time =0.053 ms
 
[root@996e16302d46 /] # telnet hahaha 8080
Trying 172.17.0.2...
Connected to hahaha.
Escape character is  '^]' .

Docker容器登陆的方法:
具体参考:Docker容器学习梳理--容器登陆方法梳理(attach、exec、nsenter)

查看docker中对应容器的IP

1
2
3
4
5
6
7
8
9
命令格式:docker inspect 容器ID | grep  IPAddress
   
比如查看ID为b220fabf815a的容器的ip
[root@localhost ~] # docker inspect b220fabf815a|grep IPAddress
             "SecondaryIPAddresses" : null,
             "IPAddress" "172.17.0.4" ,
                     "IPAddress" "172.17.0.4" ,
  
或者使用“yum  install  net-tools”,安装后就可以使用 ifconfig 命令查看ip了

docker inspect 命令:显示更底层的容器或image信息(docker inspect images_id/container_id 查看镜像或容器信息)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Usage: docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]Return low-level information on a container or image -f,-- format = "" Format the output using the given go template.
默认返回一个json字符串,更具结构自行提取信息即可
 
docker inspect命令用于获取容器/镜像的元数据,其中-f参数可以用于获取指定的数据。不过很多用户容易被该特性的语法搞晕,并很少有人能将它的优势发挥出来(大部分人都是通过  grep  来获取指定数据,虽然有效但比较零散混乱)。本文将详细介绍  -f 参数,并给出一些例子来说明如何使用它。
 
下面是针对ID为b220fabf815a的容器的相关inspect命令
[root@localhost ~] # docker inspect b220fabf815a
 
显示实例ip:
# docker inspect --format='{{.NetworkSettings.IPAddress}}' $INSTANCE_ID
[root@localhost ~] # docker inspect --format='{{.NetworkSettings.IPAddress}}' b220fabf815a
172.17.0.4
 
也可以通过 grep 来获取ip
[root@localhost ~] # docker inspect b220fabf815a|grep IPAddress
             "SecondaryIPAddresses" : null,
             "IPAddress" "172.17.0.4" ,
                     "IPAddress" "172.17.0.4" ,
                     
或者使用“yum  install  net-tools”,安装后就可以使用 ifconfig 命令查看ip了             
 
列出所有绑定的端口:
# docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' $INSTANCE_ID
[root@localhost ~] # docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' b220fabf815a
  22 /tcp  -> 20020
 
找出特殊的端口映射:
比如找出容器里22端口所映射的docker本机的端口:
# docker inspect --format='{{(index (index .NetworkSettings.Ports "22/tcp") 0).HostPort}}' $INSTANCE_ID
[root@localhost ~] # docker inspect --format='{{(index (index .NetworkSettings.Ports "22/tcp") 0).HostPort}}' b220fabf815a
20020

特别注意一个细节:

1
2
3
4
5
6
7
8
9
10
1)ubuntu14下的docker是没有service服务。去除每次 sudo 运行docker命令,需要添加组:
# Add the docker group if it doesn't already exist.
sudo  groupadd docker
#改完后需要重新登陆用户
sudo  gpasswd -a ${USER} docker
 
2)ubuntu14的febootstrap没有-i命令
 
3)Dockerfile中的EXPOSE、docker run --expose、docker run -p之间的区别
Dockerfile的EXPOSE相当于docker run --expose,提供container之间的端口访问。docker run -p允许container外部主机访问container的端口

---------------------------------------------------无法删除状态为Dead的容器---------------------------------------------------
docker中有两个status为dead的容器,删除时报错如下:
Error response from daemon: Driver devicemapper failed to remove root filesystem 33ddd2513fc3cb732fa02e912be1927929d8d028abefa945d8a3984d700a4d74: Device is Busy

解决办法:
1)看容器进程是否已经杀掉。没有的话,可以手动杀死。
2)mount -l看是不是该容器的路径还在挂载状态。是的话,umount掉。
3)然后再次尝试docker rm container_id
尽量不要手动去移除dm和docker里面container的相关文件,以免造成垃圾数据。
4)尝试docker rm -f <container-id>,强制删除
这样可以删除掉docker daemon中的container信息(但是已经创建的dm还是ACTIVE的,所以还要再去把dm给删除了)

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@linux-node2 ~] # docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
c7bd050b0a23        centos               "/bin/bash"          About an hour ago   Up About an hour                             small_almeida
33ddd2513fc3        centos               "/bin/bash"          7 weeks ago         Dead                                         App_Container
eaf66f1e43ab        centos               "/sbin/init"         7 weeks ago         Up 7 weeks          0.0.0.0:8888->8080 /tcp    hungry_khorana
[root@linux-node2 ~] # docker rm -f 33ddd2513fc3
Error response from daemon: Driver devicemapper failed to remove root filesystem 33ddd2513fc3cb732fa02e912be1927929d8d028abefa945d8a3984d700a4d74: Device is Busy
  
加上-f参数后,虽然删除时还是报错,然是container信息已经删除了
[root@linux-node2 ~] # docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
c7bd050b0a23        centos               "/bin/bash"          About an hour ago   Up About an hour                             small_almeida
eaf66f1e43ab        centos               "/sbin/init"         7 weeks ago         Up 7 weeks          0.0.0.0:8888->8080 /tcp    hungry_khorana

---------------------------------------------------容器启动失败错误1---------------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
docker: Error response from daemon: failed to create endpoint mosredis on network bridge: iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.6  -j ACCEPT: iptables: No chain /target/match  by that name.
  ( exit  status 1).
  
解决办法:
一般来说,重启docker服务,即可解决这个问题。
[root@localhost ~] # systemctl restart docker
[root@localhost ~] #
----------------------------------
如果重启docker服务解决不了,那么如下操作:
[root@localhost ~] # pkill docker
[root@localhost ~] # iptables -t nat -F
[root@localhost ~] # ifconfig docker0 down
[root@localhost ~] # brctl delbr docker0

---------------------------------------------------容器启动失败错误2---------------------------------------------------

1
2
3
4
5
docker: Error response from daemon: Cannot start container b0a845a3dedeac7b46002d1c8514077309d88dcc0667b7080bc1ab67d70eb167: [9] System error: SELinux policy denies access..
如上出现上面的报错,这是由于selinux造成的!需要关闭selinux,如下:
[root@localhost ~] # setenforce 0
[root@localhost ~] # getenforce
Permissive

---------------------------------------------------容器yum不能使用--------------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
容器启动后登陆进去,发现yum不能用,报错如下:
[root@5e91e12186e1 /] # yum list
........
yum-config-manager --disable <repoid>
........
yum-config-manager --save --setopt=<repoid>.skip_if_unavailable= true
 
解决办法:(再不行,就重启下docker服务,然后登陆容器试试)
先保证容器能正常联网( ping  www.baidu.com试试)
# yum clean all
# yum makecache

==============关于docker容器和镜像以及文件的几个转化关系==============

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
容器转成镜像:
# docker commit <CONTAINER ID> imagename01
 
容器转成文件:
# docker export <CONTAINER ID> > /home/export.tar
 
镜像转成文件:
# docker save imagename01 > /home/save.tar
 
注:一般情况下,save. tar export . tar 大一点点而已, export 比较小,因为它丢失了历史和数据元metadata
 
文件转成镜像:
# cat /home/export.tar | docker import - imagename02:latest
 
save. tar 文件转成镜像:
# docker load < /home/save.tar
 
查看转成的镜像:
# docker images
 
注意:这里一个镜像经过n次转化之后,可以用 sudo  docker images --tree查看历史,用docker tag <LAYER ID> <IMAGE NAME>可以回到某个层(只针对save命令可以回到某个层!)

-------------------------------------基于centos7的docker容器出现的一个bug--------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
centos7下部署的docker容器中启动服务,报错如下:
[root@a3c8baf6961e . ssh ] # systemctl restart sshd.service
Failed to get D-Bus connection: Operation not permitted
 
这是centos7容器里面出现的一个BUG!
即centos7镜像创建的容器里面安装服务后,不能用systemctl /service 启动服务,centos6的容器里没有这个坑!
可以通过使用其他的方式启动或者换用centos6的镜像来避免这个错误。
 
解决方案如下:
原因是dbus-daemon没能启动。其实systemctl并不是不可以使用,可以将你的CMD设置为 /usr/sbin/init 即可。
这样就会自动将dbus等服务启动起来。即采用  /usr/sbin/init 自动启动dbus daemon
 
即把之前的容器关闭并删除(docker stop container- id ),然后重新启动容器,注意:
启动时一定要加上参数--privileged和 /sbin/init ,如下:
 
[root@localhost ~] #  docker run --privileged -i -t centos7:7.3.1611 /sbin/init     
上面的容器启动后,会一直在卡着的状态中,先不用管,打开另一个终端窗口,查看容器
 
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
af40bd07fa0f        centos7:7.3.1611     "/sbin/init"         28 seconds ago      Up 28 seconds                                 nauseous_shirley
  
然后按照容器的ID进去,这个时候再根据 /bin/bash 进入容器(前面加 exec  -it参数),接着重启 ssh 服务就ok了
[root@localhost ~] # docker exec -it af40bd07fa0f /bin/bash
[root@af40bd07fa0f /] # systemctl restart sshd.service
***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************
本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/5715326.html ,如需转载请自行联系原作者
相关文章
|
8天前
|
运维 Cloud Native 虚拟化
一文吃透云原生 Docker 容器,建议收藏!
本文深入解析云原生Docker容器技术,涵盖容器与Docker的概念、优势、架构设计及应用场景等,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文吃透云原生 Docker 容器,建议收藏!
|
4天前
|
运维 Cloud Native 云计算
云原生之旅:Docker容器化实战
本文将带你走进云原生的世界,深入理解Docker技术如何改变应用部署与运维。我们将通过实际案例,展示如何利用Docker简化开发流程,提升应用的可移植性和伸缩性。文章不仅介绍基础概念,还提供操作指南和最佳实践,帮助你快速上手Docker,开启云原生的第一步。
|
2天前
|
关系型数据库 MySQL Java
【Docker最新版教程】一文带你快速入门Docker常见用法,实现容器编排和自动化部署上线项目
Docker快速入门到项目部署,MySQL部署+Nginx部署+docker自定义镜像+docker网络+DockerCompose项目实战一文搞定!
|
1天前
|
开发者 Docker Python
从零开始:使用Docker容器化你的Python Web应用
从零开始:使用Docker容器化你的Python Web应用
8 1
|
5天前
|
运维 持续交付 虚拟化
深入解析Docker容器化技术的核心原理
深入解析Docker容器化技术的核心原理
22 1
|
7天前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
7天前
|
JavaScript 开发者 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
7天前
|
持续交付 开发者 Docker
Docker容器化技术实战指南
Docker容器化技术实战指南
23 1
|
7天前
|
安全 Docker 微服务
深入理解Docker容器技术:从基础到实践
深入理解Docker容器技术:从基础到实践
|
9天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。