发表于 2018-5-30 11:07:31

docker使用入门

      这段时间在看docker,想弄明白它究竟有什么功能,能用在什么地方,然后就去官网上看了下它的用户指南,按照其内容自己整理了一份笔记,其中可能会有错误,望大家多多指教。
      docker用户指南网址:http://docs.docker.com/userguide/
  =====1.在一个docker容器中运行应用=====
  1)在容器中运行一次输出“Hello world”
docker run ubuntu:14.04 /bin/echo 'Hello world'     #docker run 就是运行容器
     #之后需要指定一个image,这里是ubuntu:14.04
     #若本地有image就直接用,若docker找不到就到Docker Hub上下载一个。
     #之后就是在容器里运行的命令了,输出Hello world
  

  2)交互式的容器
docker run -t -i ubuntu:14.04 /bin/bash         #进入容器的bash     #-t   表示在新的容器里分配一个虚拟终端
     #-i   表示允许我们用一个交互式的连接
     
  3)后台运行容器
docker run -d ubuntu:14.04 /bin/sh -c
"while true; do echo hello world; sleep 1; done"     1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147    #返回该容器的id。
     #-d   表示让docker运行一个容器并放到后台执行。
docker ps          #返回正在运行的容器以及其运行的应用等信息   CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1e5535038e28 ubuntu:14.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage

  #container id就是容器的短id;ports name是自动生成的该容器的名字,只要开启一个容器,docker就会给它去一个名字。
docker logs insane_babbage    #查看容器里面的标准输出,后面跟上容器名     hello world
     hello world
     hello world
     . . .   
docker stop insan_babbage    #停止运行的docker容器,成功的话会返回该容器的名字  

  

  

  ===========2.docker容器============
  

  1)docker命令
     命令格式: docker ..
     eg.
docker run -i -t ubuntu /bin/bash     查看docker版本
docker version    #docker client和docker server都会有,还有go语言版本,以及git的版本     

  2)查看docker客户端的功能
docker   Usage: docker COMMAND
   -H=: tcp://host:port to bind/connect to or unix://path/to/socket to use
  

  A self-sufficient runtime for linux containers.
  

  Commands:
      attach    Attach to a running container
      build   Build an image from a Dockerfile
      commit    Create a new image from a container's changes
      cp      Copy files/folders from the containers filesystem to the host path
      diff      Inspect changes on a container's filesystem
      events    Get real time events from the server
      export    Stream the contents of a container as a tar archive
      history   Show the history of an image
      images    List images
      import    Create a new filesystem image from the contents of a tarball
      info      Display system-wide information
      inspect   Return low-level information on a container
      kill      Kill a running container
      load      Load an image from a tar archive
      login   Register or Login to the docker registry server
      logs      Fetch the logs of a container
      port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
      pause   Pause all processes within a container
      ps      List containers
      pull      Pull an image or a repository from the docker registry server
      push      Push an image or a repository to the docker registry server
      restart   Restart a running container
      rm      Remove one or more containers
      rmi       Remove one or more images
      run       Run a command in a new container
      save      Save an image to a tar archive
      search    Search for an image in the docker index
      start   Start a stopped container
      stop      Stop a running container
      tag       Tag an image into a repository
      top       Lookup the running processes of a container
      unpause   Unpause a paused container
      version   Show the docker version information
      wait      Block until a container stops, then print its exit code
  

  3)查看docker命令的用法
dicker command [--help]  

  4)在docker里面运行一个网页应用
docker run -d -P training/webapp python app.py     -d   后台运行一个容器
     -P   从容器映射所有需要的端口到宿主机
     #training/webapp是一个已经创建好的包含一个简单的python flask web 应用的容器,其开放5000端口供客户端访问
     #由于本地没有,自行从docker hub上下载,所以执行这条命令需要保证能够联网
  

  5)查看web应用容器
docker ps -l  CONTAINER ID      IMAGE                  COMMAND             CREATED             STATUS            PORTS                     NAMES
2a2243aabeef      training/webapp:latest   python app.py       9 seconds ago       Up 8 seconds      0.0.0.0:49154->5000/tcp   trusting_archimedes
     -l   返回最近一个容器的详细信息
     -a   查看已经停止的容器的信息
  

     其中ports部分,是在我们通过docker run的-P选项来映射image中开启的端口到宿主机上。这里是将docker容器中的开放端口(5000端口)映射到了宿主机的49154端口。
   
     网络端口映射在docker中是可配置的。-P在这里其实等价于-p 5000(这个应用就是开放5000端口),使得容器中的5000端口映射到宿主机上的49000~49900端口上。在run的时候也可以直接使用-p选项来映射:
docker run -d -p 5001:5000 training/webapp python app.py     这里就是将另一个容器的5000端口映射到宿主机的5001端口。

                  注:访问的是另一个容器的5000端口

  

     
  6)快速查看网络端口
     docker port 容器端口
     eg.
docker port jolly_fermi 5000            0.0.0.0:49200
  

  7)查看web应用的日志
     docker logs [-f]
     -f   查看容器的标准输出
docker logs -f jolly_fermi     * Running on http://0.0.0.0:5000/
   192.168.125.1 - - "GET /favicon.ico HTTP/1.1" 404 -
   192.168.125.1 - - "GET / HTTP/1.1" 200 -
   192.168.125.1 - - "GET / HTTP/1.1" 200 -
  

  8)查看web应用容器的进程
     docker top
     eg.
docker top jolly_fermi  UID               PID               PPID                C                   STIME               TTY               TIME                CMD
root                2338                1173                0                   19:50               ?                   00:00:02            python app.py
  

  9)检查web应用容器配置
docker inspect jolly_fermi[{
    "Args": [
      "app.py"
    ],
    "Config": {
      "AttachStderr": false,
      "AttachStdin": false,
      "AttachStdout": false,
      "Cmd": [
            "python",
            "app.py"            ...
     也可以指定一个元素来查看
docker inspect -f '{{ .Config.Cmd }}' jolly_fermi     
  

  10)停止web应用容器
docker stop jolly_fermi  

  11)重启web应用容器
docker start jolly_fermi     #docker attach jolly_fermi,若该容器可以进入的话,这句就是连到容器里面。
  

  12)删除web应用容器
   docker rm jolly_fermi  

  =======3.docker镜像(images)=======
  

  管理和使用本地的docker镜像
  创建一个基本的镜像
  上传镜像到docker hub
  

  1)列出本地镜像
docker images     REPOSITORY          TAG               IMAGE ID            CREATED             VIRTUAL SIZE
         centos                  latest            0c752394b855      4 weeks ago         124.1 MB
       training/webapp      latest            31fa814ba25a      5 weeks ago         278.6 MB
     这些都是从docker hub上下载的
     每个repository都可能有多个不同的镜像,如centos:6.5,centos:6.4。这些都是取决于在pull镜像的时候所下载的镜像。
     所以在运行一个镜像的时候需要加上后面的TAG标签,如:
docker run -t -u ubuntu:14.04 /bin/bash     若不添加这个标签,docker就是用latest这个标签的镜像。
  

  2)获取一个新的镜像
     docker pull 镜像名
     eg.
docker pull ubuntu  

  3)找镜像
     (1)可以直接上官网找

     (2)通过命令行来找
     docker search 镜像名
     eg.
docker search sinatraNAME                                 DESCRIPTION                                     STARS   OFFICIAL   AUTOMATED
training/sinatra                     Sinatra training image                        0                  
marceldegraaf/sinatra                  Sinatra test app                              0
mattwarren/docker-sinatra-demo                                                         0                  
luisbebop/docker-sinatra-hello-world                                                   0                  
bmorearty/handson-sinatra            handson-ruby + Sinatra for Hands on with D...   0
subwiz/sinatra                                                                         0
bmorearty/sinatra                                                                      0. . .
  #列表中有名字、描述、星值(类似“赞”)、官方、自动创建(可以去扩充)。
  

  4)从docker hub上拖“我们”的镜像
docker pull training/sinatra     然后团队就可以用自己的镜像了
docker run -t -i training/sinatra  

  5)创建我们自己的镜像
     下载的镜像可能不能完全满足自身的需要,需要做一些改动。有两个方法可以更新和创建镜像
     (1)通过更新容器并同步到一个镜像中
     (2)通过Dockerfile来指定创建镜像
  

  6)更新并提交一个镜像(5)的方法一)
     (1)通过该镜像创建一个容器      
docker run -t -i centos /bin/bash    bash-4.1#            在这个镜像没有标出其容器的ID,可以通过docker ps查看到是08b6d2e3c87e

     (2)在容器里通过yum安装vim和httpd并退出容器
    yum -y install httpd vim
    exit  #这里通过centos的base的repo成功联网安装。
  很好奇docker 的容器网络设置,后来发现,docker的容器使用的是nat的方法,docker生成容器的同时,宿主机上会创建与容器联通的一个虚拟网卡,然后docker 的容器就可以通过这个网卡来联网了。类似于vmware的nat。
                 宿主机上的操作:
                 # ifconfig
            docker0   Link encap:EthernetHWaddr 46:D4:FB:67:3B:36            
            inet addr:172.17.42.1Bcast:0.0.0.0Mask:255.255.0.0
            inet6 addr: fe80::5817:1ff:fe25:615d/64 Scope:Link
            UP BROADCAST RUNNING MULTICASTMTU:1500Metric:1
            RX packets:13852 errors:0 dropped:0 overruns:0 frame:0
            TX packets:23720 errors:0 dropped:0 overruns:0 carrier:0
            collisions:0 txqueuelen:0
            RX bytes:565006 (551.7 KiB)TX bytes:28907343 (27.5 MiB)
            ...
                 docker容器:
                 bash-4.1# traceroute www.baidu.com
            bash-4.1# traceroute www.baidu.com
traceroute to www.baidu.com (180.97.33.71), 30 hops max, 60 byte packets1172.17.42.1 (172.17.42.1)0.040 ms0.012 ms0.010 ms2192.168.125.2 (192.168.125.2)0.108 ms0.080 ms0.077 ms3* * *4* * *         (3)现在已经有了这个与基本的镜像不同的容器,通过commit来创建镜像
docker commit -m="Added vim and httpd" -a="liuling"
08b6d2e3c87e myown/centos:v1            -m   描述信息
            -a      操作者
            后面跟容器的id,以及镜像的标签。
            其中myown是只用户,centos是镜像名,后面的v2是版本
        (4)查看刚才建立的镜像
docker imagesREPOSITORY          TAG               IMAGE ID            CREATED             VIRTUAL SIZEmyown/centos      v1                  1ab425143ef8      3 minutes ago       260.3 MB           
  7)通过Dockerfile创建镜像(从头做一个新的镜像)
mkdir centos
cd centos
vi Dockerfile  # make /data directory and yum install vsftpd
  FROM myown/centos:v1
  MAINTAINER liuling
  RUN mkdir /data
  RUN yum -y install vsftpd
        
     
docker build -t="myown/centos:v2" .    #docker build -t=“镜像名” dockerfile的路径,注意这里有一个“.”  Sending build context to Docker daemon2.56 kB
  Sending build context to Docker daemon
  Step 0 : FROM myown/centos:v1
   ---> 1ab425143ef8
  Step 1 : MAINTAINER liuling
   ---> Using cache
   ---> b977f42fb08c
  Step 2 : RUN mkdir /data
   ---> Using cache
   ---> 80d492289b95
  Step 3 : RUN yum -y install vsftpd
   ---> Running in a742917e9b67
  Loaded plugins: fastestmirror
  Loading mirror speeds from cached hostfile
   * base: centos.ustc.edu.cn
  ...
  Complete!
   ---> 14f9e7b5be23
  Removing intermediate container a742917e9b67
  Successfully built 14f9e7b5be23
        这里是使用build命令,-t指定镜像归属/名:标签,后面通过"."来指定Dockerfile的所在路径。
     通过Dockerfile创建文件,首先发送给docker daemon。其实就是建立一个容器,执行一条命令,然后commit出一个镜像,再使用这个镜像建立一个容器,再执行一条命令,再commint出一个镜像。最后命令执行完毕,commit出最后一个镜像,就将前面所有过渡用的容器删除。
docker images  REPOSITORY          TAG               IMAGE ID            CREATED             VIRTUAL SIZE
  myown/centos      v2                  14f9e7b5be23      2 minutes ago       292.8 MB
  

  8)设置镜像的标签(版本)
     docker tag /:
     eg.
   docker tag 14f9e7b5be23 myown/centos:v3
   docker imagesREPOSITORY          TAG               IMAGE ID            CREATED             VIRTUAL SIZE
myown/centos      v2                  14f9e7b5be23      36 minutes ago      292.8 MB
myown/centos      v3                  14f9e7b5be23      36 minutes ago      292.8 MB     这里就给myown/centos:v2添加了一个新的标签。(个人有点觉得像一个不同标签名的快捷方式0.0)
  

  9)将镜像上传到Docker Hub,分享给其他人
    docker push myown/centos  

  10)删除本地的镜像
docker rmi myown/centos:v3     Untagged: myown/centos:v3
     #由于这个是添加的标签,因此会有untagged,即取消标签
docker rmi myown/centos:v2Error: Conflict, cannot delete d47258e47dc3 because the container bae61e4726e4 is using it (docker untagged the image), use -f to force
2014/07/10 18:47:59 Error: failed to remove one or more images        #若该镜像上面已经创建了容器,是不能够直接删除的,需要先删除容器
docker rm bae61e4726e4  bae61e4726e4
  #由于第一次删除的时候虽然没有成功,但是名字和tag已经没了,就只有通过id来删除了。
docker rmi 14f9e7b5be2         Deleted: d47258e47dc3310ab857c44a818c0112a2784674b5dc9f3dbd3075db141322a1
  Deleted: c8d2bc86f41e11e529e204af5f47876d5a7f72cbcfd8af00a6910af375858e02
  Deleted: eaee52520045a1e3d39f260bd5d7fe40fa750fab5e541269deae6bdea4a40d73
  

  

  

  =======4.将容器连接在一起=======
  

  1)网络端口映射
docker run -d -P training/webapp pyton app.py     #使用-P则表示将容器内的端口随机映射到宿主机端口(49000~49900)。
     注:容器中是有一个内网以及内网端口(可以通过docker inspect来查看容器的ip地址)。
     可以通过docker ps 来查看端口映射“宿主机端口->容器端口”
docker ps training/webapp  CONTAINER ID      IMAGE                  COMMAND             CREATED             STATUS            PORTS                     NAMES
  b7b1263fa1f7      training/webapp:latest   python app.py       10 seconds ago      Up 8 seconds      0.0.0.0:49153->5000/tcp   sick_nobel
     
     通过-p指定端口映射规则

docker run -d -p 49000:5000 training/webapp python app.py     #将容器的5000端口与宿主机的49000端口映射出去,但这并不是一个好方法,因为一个-p只能让一个容器使用一个端口,而-P则是使用将容器的所有开放端口映射出去。
  

     上面两种方法都是开发端口给所有用户(所有能连到该host的用户都可以访问),通过-p还可以指定只允许本地(宿主host)访问端口49000来访问web应用。
docker run -d -p 127.0.0.1:49000:5000 training/webapp python app.py     #这里的127.0.0.1也可以改成localhost
elinks --dump 127.0.0.1:49000#宿主机上测试        Hello world!
  

     也可以不指定宿主机的端口让其随机选择
   docker run -d -p 127.0.0.1::5000 training/webapp python app.py
   docker psCONTAINER ID      IMAGE                  COMMAND             CREATED             STATUS            PORTS                     NAMES
ad644d473938      training/webapp:latest   python app.py       4 seconds ago       Up 3 seconds      127.0.0.1:49155->5000/tcp   determined_samme  

     还可以指定使用udp端口
   docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
   docker psCONTAINER ID      IMAGE                  COMMAND             CREATED             STATUS            PORTS                              NAMES
33a5ce0d825e      training/webapp:latest   python app.py       3 seconds ago       Up 3 seconds      5000/tcp, 127.0.0.1:5000->5000/udp   naughty_yonath     
     查看该容器5000端口映射到宿主机的端口
docker port naughty_yonath 5000/udp            127.0.0.1:5000   
            Note: The -p flag can be used multiple times to configure multiple ports.
            #官网上的一句话,不过不知道怎样实现。
  

  2)docker容器连接
  

     网络端口映射不是唯一的方法让容器连接到其他。docker也有一个连接系统可以
  

  3)容器命名
  

     创建一个容器的时候docker会自动为容器命令,也可以自定义名字。
     eg.
docker run -d -P --name web training/webapp python app.py     查看容器名字
docker ps -l
docker inspect -f "``.`Name`" 容器id     容器名必须唯一。
     若想只用一次容器,可以再docker run 的选项中加上--rm,退出容器之后就会删除该容器了。
  

  4)容器连接
     创建一个名为db的容器(包含PostgreSQL数据库)
docker run -d --name db training/postgres     创建一个新的网页容器并且link到db容器   
docker run -d -P --name web --link db:db training/webapp python app.py     其中,--link name:alias,name是连接到得容器名,alias是连接的别名。   
docker ps$ docker ps
CONTAINER IDIMAGE                     COMMAND               CREATED             STATUS             PORTS                  NAMES
6d3af77b76eb      training/webapp:latest   python app.py          3 seconds ago       Up 2 seconds      0.0.0.0:49153->5000/tcp   web               
cfad1bb78495      training/postgres:latest   su postgres -c '/usr   27 seconds ago      Up 27 seconds       5432/tcp                  db,web/db     我们可以发现连接给db和web这两个容器创建了一个父-子关系。父容器(db)可以再子容器中连接信息。容器建立了一个安全的通道而不是一个公开一个端口。
     docker在子容器里通过两种方法为父容器公开一个连接的信息:
     a)环境变量
     b)更新/etc/hosts文件
  

      可以看docker的初始化环境变量的设置。通过env命令来列出容器的环境变量
docker run --rm --name web2 --link db:db training/webapp env    DB_NAME=/web2/db
    DB_PORT=tcp://172.17.0.5:5432
    DB_PORT_5000_TCP=tcp://172.17.0.5:5432
    DB_PORT_5000_TCP_PROTO=tcp
    DB_PORT_5000_TCP_PORT=5432
    DB_PORT_5000_TCP_ADDR=172.17.0.5
    . . .      注意:这些环境变量只是在容器的第一个进程中使用。一些进程(sshd)为了连接而生成新的shell将会清除掉这些环境变量。
  

     上面的变量都是DB_开头的,这个是连接的alias,连接的名字是什么,上面变量就是以什么来开头的。我们可以使用这些环境变量来配置应用去连接在db容器中的数据库。这个连接时安全、私有并且只有web容器才能够与db容器通信。
     
     除了环境变量之外,docker在子容器中为连接父节点而在/etc/hosts添加一个入口。(不能够随意修改/etc/hosts这个文件。)

docker run -t -i --name web1 --link db:db training/webapp /bin/bash  root@6148503e55de:/opt/webapp# cat /etc/hosts
  172.17.0.11   6148503e55de
  ...
  172.17.0.9      db
  

     尝试ping一下db(由于python的webapp这个容器没有ping命令,需要安装)
root@6148503e55de:/opt/webapp#apt-get install -yqq inetutils-ping
   root@6148503e55de:/opt/webapp# ping db  PING db (172.17.0.9): 48 data bytes
  56 bytes from 172.17.0.9: icmp_seq=0 ttl=64 time=2.884 ms
  56 bytes from 172.17.0.9: icmp_seq=1 ttl=64 time=0.068 ms
  56 bytes from 172.17.0.9: icmp_seq=2 ttl=64 time=0.069 ms
  56 bytes from 172.17.0.9: icmp_seq=3 ttl=64 time=0.069 ms
           
  

  =======5.在容器中管理数据=======
  

  1)data volumes(数据卷)
  

     数据卷是一个在一个活多个容器里特别设计的目录,围绕union file system来提供多个持久的或共享数据的特性:
     a)data volumes可以被多个容器共享和重用
     b)可以直接修改在dota volumes进行变动
     c)变动data volumes不包括更新一个镜像
     d)volumes将一直存在知道没有容器使用它们
  

  2)添加一个data volumes
   docker run -t -i --name centos1 -v /mingchao centos /bin/bash
   bash-4.1# df  Filesystem         1K-blocks    Used Available Use% Mounted on
  rootfs                10321208300112   9496808   4% /
  /dev/mapper/docker-253:0-132071-7020c1bf4840f24a984f12587a08f9bb2f5ec0f40e8fe0b1e8ded18c3b631c17
                        10321208300112   9496808   4% /
  tmpfs                   957244       0    957244   0% /dev
  shm                      65536       0   65536   0% /dev/shm
  /dev/mapper/VolGroup-lv_root
                        36744792 43330843054516413% /.dockerinit
  /dev/mapper/VolGroup-lv_root
                        36744792 43330843054516413% /etc/resolv.conf
  /dev/mapper/VolGroup-lv_root
                        36744792 43330843054516413% /etc/hostname
  /dev/mapper/VolGroup-lv_root
                        36744792 43330843054516413% /etc/hosts
  /dev/mapper/VolGroup-lv_root
                        36744792 43330843054516413% /mingchao
  tmpfs                   957244       0    957244   0% /proc/kcore
     这里是创建了一个新的volume在容器的/mingchao下。
       注:也可以通过在Dockerfile文件中使用VOLUME这个命令来添加一个或多个volumes使得所有用该镜像创建的容器都可以使用。
  

  3)挂载一个宿主机目录当做data volumes
docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py     这里是将本地的/src/webapp目录挂载到容器的/opt/webapp目录中。
     注:这个不能通过Dockerfile来使用。
  

     docker默认是实现可读可写的volume,不过我们也可以自定义为只读
docker run -d -P --name web -v /src/webapp:/opt/webapp:ro tra
ining/webapp python app.py  

  4)创建和挂载一个data volume 容器(容器挂载另一个容器的data volume)
  

     如果有需要保存的数据并且在容器中共享,或者被一些不长久使用的容器使用,最好是创建一个data volume的容器,然后再使用它的时候采取挂载。
     
     #创建一个容器,并且里面创建一个data volume。   
docker run -i -t -v /dbdata --name dbdata centos /bin/bash     

     #创建另一个容器,挂载dbdata的data volume----/dbdata
docker run -i -t --volumes-from dbdata(容器名) --name db1 centos /bin/bash  

     #创建第二个容器来挂载dbdata的data volume
docker run -i -t --volumes-from dbdata --name db2 centos /bin/bash  

     这种挂载可以继续传递下去:
docker run -i -t --volumes-from db1 --name db3 centos /bin/bash     如果删除了其中的一些容器,甚至是一开始创建的dbdata这个容器,该volume都会存在,直到所有挂载volume的容器都删除掉,这个volume才会被删除掉。
  

  5)data volumes备份、恢复或迁移   
docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata     这里我们启动一个新的容器然后挂载dbdata容器的volume。接着挂载一个当前host的路径到/backup。最后,我们使用tar来将dbdata的volume备份到backup.tar(在/backup目录中,即是宿主机的当前目录)。当命令结束且容器停止了之后我们就获得了dbdata的volume的备份。
  

     可以将它恢复到相同的容器中,或者其他的任何地方。
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
docker run --volumes-from dbdata2 -v $(pwd):/backup centos tar xvf /backup/backup.tar  
页: [1]
查看完整版本: docker使用入门