Docker容器學習梳理 - 日常操作總結

散盡浮華發表於2016-07-28

 

使用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

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指令

[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 a 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,表示容器埠對映到宿主機的具體埠上,比如 -p 8080:80
-P, --publish=[] Publish a container's port(s) to the host      大寫P,表示容器埠對映到宿主機的任意一個埠上,比如 -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.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)從地址池配置一個 ip 地址給容器
6)執行使用者指定的應用程式
7)執行完畢後容器被終止

簡單補充下.......

在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的檔案拷貝出來

列出當前所有正在執行的容器

# 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標識。如下:

[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必須放在映象名稱的後面:

[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)當使用-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

刪除容器和映象

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)將本機的/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/
例項如下:
[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)如果要匯出映象到本地檔案,可以使用 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)匯出容器
如果要匯出本地某個容器,可以使用 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)將A機器上將nginx容器提交為新的映象(docker commit),然後將這個映象匯出並上傳到B機器上,最後在B機器上匯入這個新映象並依據這個映象啟動容器,這個就和A機器上的nginx容器一樣了。
2)將A機器上的nginx容器做快照,然後從這個快照檔案中匯入為映象,將這個映象上傳到B機器上,最後在B機器上匯入這個新映象並依據它啟動容器。

在執行狀態中的容器內再次啟動新的程式(docker exec)

雖然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)建立容器時使用"-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

命令格式: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容器的ip地址

[root@docker-test1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b5c97379265a        centos              "/bin/bash"         12 minutes ago      Up 11 minutes                           kevinmy

[root@docker-test1 ~]# docker inspect kevinmy
......

            "MacAddress": "02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "df0c8465aeb4663aa0abcaddc9c7ea205a7bbaa075e46db7476c85589471cfbc",
                    "EndpointID": "3d504eb397a27696857750bc2f5919faf4be8bb1947b10375bee55439f2d7ce4",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04"
                }
            }
        }
    }
]

[root@docker-test1 ~]# docker inspect kevinmy|grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.4",
                    "IPAddress": "172.17.0.4",

[root@docker-test1 ~]# docker inspect kevinmy|grep IPAddress|grep [1-9]
            "IPAddress": "172.17.0.4",
                    "IPAddress": "172.17.0.4",

[root@docker-test1 ~]# docker inspect kevinmy|grep IPAddress|grep [1-9]|awk '{print $2}'
"172.17.0.4",
"172.17.0.4",

[root@docker-test1 ~]# docker inspect kevinmy|grep IPAddress|grep [1-9]|awk '{print $2}'|sort|uniq
"172.17.0.4",

[root@docker-test1 ~]# docker inspect kevinmy|grep IPAddress|grep [1-9]|awk '{print $2}'|sort|uniq|awk -F'"' '{print $2}'
172.17.0.4

docker inspect 命令:顯示更底層的容器或image資訊(docker inspect images_id/container_id 檢視映象或容器資訊)

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)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給刪除了)

[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---------------------------------------------------

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---------------------------------------------------

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不能使用--------------------------------------------------

容器啟動後登陸進去,發現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容器和映象以及檔案的幾個轉化關係==============

容器轉成映象:
# 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--------------------------------------

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

相關文章