Docker 使用

Docker 是一个开源的应用容器引擎, 基于 Go 语言 并遵从 Apache2.0 协议开源.

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级, 可移植的容器中, 然后发布到任何流行的 Linux 机器上, 也可以实现虚拟化.

容器是完全使用沙箱机制, 相互之间不会有任何接口 (类似 iPhone 的 app), 更重要的是容器性能开销极低.

安装

Linux

  1. 卸载旧版本
        $ sudo yum remove docker \
                         docker-client \
                         docker-client-latest \
                         docker-common \
                         docker-latest \
                         docker-latest-logrotate \
                         docker-logrotate \
                         docker-engine
      
    
  2. 安装依赖
        $ sudo yum install -y yum-utils \
         device-mapper-persistent-data \
         lvm2
      
    
  3. 设置仓库
        # 官方
       $ sudo yum-config-manager \
           --add-repo \
           https://download.docker.com/linux/centos/docker-ce.repo
       # 或者选择 阿里源
       # sudo yum-config-manager \
       # --add-repo \
       # http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
      
    
  4. 安装 Docker Engine-Community
        sudo yum install docker-ce docker-ce-cli containerd.io
      
    

    默认安装的 docker-ce 是最新版, 如果想要安装其他版本的话可以:

    1. 先使用 yum list docker-ce --showduplicates | sort -r 命令找出所有可用版本
    2. 然后使用 sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io 安装具体版本
  5. 启动 Docker
        sudo systemctl start docker
      
    
  6. 运行 hello-world 来验证是否正确安装了 Docker Engine-Community
        sudo docker run hello-world
      
    

MacOS

brew cask install docker

命令使用

  • sudo service docker status
  • sudo service docker start
  • docker network: 管理 docker 网络
  • docker image: 管理 docker 镜像
  • docker container: 管理 docker 容器

  • docker login: 登录 docker 账户, 需在 Hub Docker 提前注册账户, 登录后能拉取账号下的所有镜像
  • docker logout:: 退出登录
  • docker run [options] <id/name> [command]: 运行一个镜像 (也是创建一个新的容器)
    • -b:
    • -d: 在后台运行
    • -i: 进入交互式操作
    • -t: 终端
    • -P: 将容器内部使用的网络端口以随机方式映射到我们使用的主机上
           $ docker run -d -P training/webapp python app.py
          $ docker ps
          
          2a8df02af645  training/webapp "python app.py"  2 hours ago    Up 2 hours       0.0.0.0:32768->5000/tcp    hanley
         
      
    • -p: 将容器内部使用的网络端口指定映射到我们使用的主机上
           $ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
          $ docker ps
          
          2e8a12599649  training/webapp  "python app.py" 2 hours ago   Up 2 hours      127.0.0.1:5001->5000/tcp   kind_bassi
         
      
       docker run -i -t ubuntu:15.10 /bin/bash # 进入 ubuntun 的 15.10 版本镜像 (需提前 pull), 并指定 shell 为 /bin/bash, 并进入交互模式
      docker run -itd --name ubuntu-hanley ubuntu:15.10 /bin/bash # 以后台, 终端, 交互式方式运行 ubuntu 这个镜像的 15.10 版本, 并将其命名为 ubuntu-hanley
     
    
  • exit: 在既然怒容器后的环境中执行, 退出一个容器
  • docker stop <id/name>: 停止一个正在运行的容器
  • docker start <id/name>: 启动一个已停止的容器
  • docker restart <id/name>: 重启一个容器
  • docker kill <id/name>: 停止一个容器
  • docker ps: 查看当前正在运行的容器, 如果需要列出所有的 (含已经被 exit 的) 容器需要使用
       $ docker ps
      
      CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                      NAMES
      31e46c0aad34        ubuntu              "/bin/bash"         2 hours ago         Up 2 hours                                     test1
      2e8a12599649        training/webapp     "python app.py"     2 hours ago         Up 2 hours          127.0.0.1:5001->5000/tcp   kind_bassi
      
      $ docker ps -a
      
      CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                      NAMES
      31e46c0aad34        ubuntu              "/bin/bash"         2 hours ago         Up 2 hours                                            test1
      2e8a12599649        training/webapp     "python app.py"     2 hours ago         Up 2 hours                 127.0.0.1:5001->5000/tcp   kind_bassi
      62b13f6c9b2f        training/webapp     "python app.py"     2 hours ago         Exited (137) 2 hours ago                              keen_jackson
      
      $ docker ps -l
      
      CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
      31e46c0aad34        ubuntu              "/bin/bash"         2 hours ago         Up 2 hours                                     test1
     
    
  • docker images: 列出所有的位于本地的镜像
  • docker attach <id/name>: 运行容器使用 -d 参数后会在后台运行, 使用 attach 可以进入此容器
  • docker exec: 与 attach 类似, 但是在此命令下使用 exit 并不会导致容器停止运行, 因此这种方式更好.
       docker exec -it
     
    
  • docker rm <id/name>: 删除某个容器, docker rm -f 1e560fca3906
  • docker container prune: 删除所有不在运行的容器
  • docker rmi <image name>: 删除某个镜像
  • docker port <id/name>: 查看某个容器的映射端口详情
       $ docker port 1e560fca3906
      5000/tcp -> 0.0.0.0:5000
      
      $ docker port wizardly_chandrasekhar
      5000/tcp -> 0.0.0.0:5000
     
    
  • docker logs <id/name>: 查看某个容器的内部标准输出, -f 像使用 tail -f 一样来输出容器内部的标准输出
  • docker top <id/name>: 查看某个容器的内部运行的进程信息
       $docker top 1e560fca3906
      UID    PID        PPID     C     STIME     TTY  TIME       CMD
      root   14019      14002    0     May23?    00:00:01   python app.py
     
    
  • docker inspect <id/name>: 查看容器的底层信息, 会返回一个 json 文件记录 docker 容器的配置与状态信息
  • docker export <id/name> > <name>: 导出一个容器快照到本地, docker export 1e560fca3906 > ubuntu.tar
  • docker import: 从本地导入容器快照, cat docker/ubuntu.tar | docker import - test/ubuntu:v1, 另外也可以通过指定 URL 或者某个目录来导入
    • docker import http://example.com/exampleimage.tgz example/imagerepo
  • docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]: 将容器的改变更新到镜像
    • -a: Author (e.g., “John Hannibal Smith hannibal@a-team.com”)
    • -c: Apply Dockerfile instruction to the created image
    • -m: Commit message
    • -p: Pause container during commit (default true)
    • docker commit -m="has update" -a="hanleylee" e218edb10161 hanleylee/ubuntu:v2
  • docker tag <id/name> <new name>: 为镜像添加一个新的标签, new name 格式为 用户名 / 镜像名:tag
       $ docker tag 860c279d2fec hanleylee/ubuntu:v3
      
      $ docker images
      REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      hanleylee/ubuntu    6.7                 860c279d2fec        5 hours ago         190.6 MB
      hanleylee/ubuntu    dev                 860c279d2fec        5 hours ago         190.6 MB
     
    
  • docker rename
  • docker search <image name>: 根据 name 搜索一个镜像
  • docker pull <image name>: 从远程仓库载入镜像, docker pull ubuntu; 也可以指定版本: docker pull ubuntu:15.10
  • docker push <image name>: 推送本地创建或更新的镜像到远程自己的仓库中, docker push hanlyelee/ubuntu:18.04
  • docker history
  • --help: 使用帮助查看具体命令的使用, docker image --help
  • --name: 以现有镜像创建自定义名称的容器, docker run -itd --name test1 --network test-net ubuntu /bin/bash
  • --network: 以现有镜像创建使用自定义网络的容器

容器属性

使用 docker ps -a 可列出所有存在的容器

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                      NAMES
8e7f63c63e6b        ubuntu              "/bin/bash"         2 hours ago         Up 2 hours                                            test2
31e46c0aad34        ubuntu              "/bin/bash"         2 hours ago         Up 2 hours                                            test1
2a8df02af645        training/webapp     "python app.py"     2 hours ago         Up 2 hours                 0.0.0.0:32768->5000/tcp    hanley
2e8a12599649        training/webapp     "python app.py"     2 hours ago         Up 2 hours                 127.0.0.1:5001->5000/tcp   kind_bassi
dc33b04b866b        training/webapp     "python app.py"     2 hours ago         Created                                               cranky_hawking
62b13f6c9b2f        training/webapp     "python app.py"     2 hours ago         Exited (137) 2 hours ago                              keen_jackson

容器有以下属性:

  • CONTAINER ID: 容器 ID.
  • IMAGE: 使用的镜像.
  • COMMAND: 启动容器时运行的命令.
  • CREATED: 容器的创建时间.
  • STATUS: 容器状态.
    • created: 已创建
    • restarting: 重启中
    • running: 运行中
    • removing: 迁移中
    • paused: 暂停
    • exited: 停止
    • dead: 死亡
  • PORTS: 容器的端口信息和使用的连接类型 (tcp\udp).
  • NAMES: 自动分配的容器名称.

镜像属性

使用 docker images 可列出所有存在的镜像

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              14.04               90d5884b1ee0        5 days ago          188 MB
php                 5.6                 f40e9e0f10c8        9 days ago          444.8 MB
nginx               latest              6f8d099c3adc        12 days ago         182.7 MB
mysql               5.6                 f2e8d6c772c0        3 weeks ago         324.6 MB
httpd               latest              02ef73cf1bc0        3 weeks ago         194.4 MB
ubuntu              15.10               4e3b13c8a266        4 weeks ago         136.3 MB
hello-world         latest              690ed74de00f        6 months ago        960 B
training/webapp     latest              6fae60ef3446        11 months ago       348.8 MB

镜像有以下属性:

  • REPOSITORY: 表示镜像的仓库源
  • TAG: 镜像的标签

    在一个仓库源中, 可能有多个 tag, tag 不同则代表不同的版本, 表示不同的镜像, 哪怕两个镜像完全一致, 只有 tag 不一致, 那也是不同的镜像

  • IMAGE ID: 镜像 ID
  • CREATED: 镜像创建时间
  • SIZE: 镜像大小

实际使用

更新镜像

$ docker run -t -i ubuntu:15.10 /bin/bash # 首先创建一个容器
root@e218edb10161 apt-get update # 更新此容器
root@e218edb10161 exit
$ docker commit -m="has update" -a="hanleylee" e218edb10161 hanleylee/ubuntu:v2 # 根据更新后的容器创建新镜像 hanleylee/ubuntu:v2
$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hanleylee/ubuntu    v2                  70bf1840fd7c        15 seconds ago      158.5 MB
ubuntu              15.10               4e3b13c8a266        4 weeks ago         136.3 MB
mysql               5.6                 f2e8d6c772c0        3 weeks ago         324.6 MB
httpd               latest              02ef73cf1bc0        3 weeks ago         194.4 MB
hello-world         latest              690ed74de00f        6 months ago        960 B
training/webapp     latest              6fae60ef3446        12 months ago       348.8 MB

容器互联

$ docker run -d -P --name hanley training/webapp python app.py
$ docker ps -l
CONTAINER ID     IMAGE            COMMAND...     PORTS                     NAMES
43780a6eabaa     training/webapp   "python app.py"...     0.0.0.0:32769->5000/tcp   hanley

$ docker network create -d bridge test-net # 创建网络, -d: 参数指定 Docker 网络类型, 有 bridge, overlay.
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash # 运行一个容器并连接到新建的 test-net 网络
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash # 打开新的终端, 再运行一个容器并加入到 test-net 网络

$ docker exec -it test1 /bin/bash
root@ed123dfvcxd: ping test2

64 bytes from test2. test-net...... # 正确接收到来自 test2 的信息

root@ed123dfvcxd: exit

$ docker exec -it test2 /bin/bash
root@1sdaf124232: ping test1

64 bytes from test1. test-net...... # 正确接收到来自 test1 的信息

参考

本博客文章采用 CC 4.0 协议,转载需注明出处和作者。

鼓励作者