开源应用容器引擎,基于Go语言
打包应用以及依赖包到一个轻量级、可移植的容器中,然后发布。
容器是完全使用沙箱机制,容器性能开销极低。
客户端-服务器 C/S架构

对比传统VM

  • 容器启动快,秒级启停
  • 节约系统资源,一台主机可同时运行上千容器
  • 类git命令操作,学习成本低
  • Dockerfile配置文件,灵活自动化创建和部署
  • 防护机制,严格可靠的隔离

三要素

  • 容器——提供服务,由镜像创建
  • 镜像——容器工厂,生产容器的原材料
  • 仓库——存储镜像的地方

    容器与镜像的关系: 镜像创建容器,类似于类创建对象

  • docker Client 客户端

向docker服务器进程发起请求,如:创建、停止、销毁容器等操作

  • docker Server 服务器进程

处理所有docker的请求,管理所有容器

  • docker Registry 镜像仓库

镜像存放的中央仓库,可看作是存放二进制的scm

底层技术

  • namespace

容器隔离的基础,保证容器间隔离。六个名空间:User、Mnt、Network、UTS、IPC、Pid

  • cgroups

容器资源统计和隔离。子系统:cpu、blkio、device、freezer、memory

  • unionfs

分层镜像实现的基础。典型:aufs、overlayfs

安装

yum安装

  1. yum install docker -y #安装
  2. systemctl start docker #启动
  3. systemctl enable docker #设置开机自启动

配置加速

官网文档

  1. #该脚本可以将 --registry-mirror 加入到你的 Docker 配置文件中
  2. curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://xxxxxxxx.m.daocloud.io
  3. #脚本写入
  4. echo "{\"registry-mirrors\": [\"http://xxxxxxxx.m.daocloud.io\"]}" > /etc/docker/daemon.json
  5. #重启生效
  6. systemctl restart docker
  1. #阿里云镜像加速配置
  2. $ docker info
  3. # Registry Mirrors: https://hox7ap74.mirror.aliyuncs.com/

相关命令

  1. #用于显示全部系统信息
  2. $ uname -a
  3. #查看centos版本
  4. $ cat /etc/redhat-release

命令

基本命令

镜像类

  1. #镜像类操作
  2. $ docker images # 显示本地所有的镜像列表
  3. $ docker import # 从一个tar包创建一个镜像,往往和export结合使用
  4. $ docker build # 使用Dockerfile创建镜像(推荐)
  5. $ docker commit # 从容器创建镜像
  6. $ docker rmi # 删除一个镜像
  7. $ docker load # 从一个tar包创建一个镜像,和save配合使用
  8. $ docker save # 将一个镜像保存为一个tar包,带layers和tag信息
  9. $ docker history # 显示生成一个镜像的历史命令
  10. $ docker tag # 为镜像起一个别名
  11. #镜像仓库操作
  12. $ docker login # 登录到一个registry
  13. $ docker search # 从registry仓库搜索镜像
  14. $ docker pull # 从仓库下载镜像到本地
  15. $ docker push # 将一个镜像push到registry仓库中
  16. #拉取镜像
  17. $ docker pull centos7-ansible
  18. #循环拉取全部镜像
  19. $ for i in `docker search centos|awk '!/NAME/{print $2}'`;do docker pull $i;done

容器类

  1. $ docker create # 创建一个容器但是不启动它
  2. $ docker run # 创建并启动一个容器
  3. $ docker stop # 停止容器运行,发送信号SIGTERM
  4. $ docker start # 启动一个停止状态的容器
  5. $ docker restart # 重启一个容器
  6. $ docker rm # 删除一个容器
  7. $ docker kill # 发送信号给容器,默认SIGKILL
  8. $ docker attach # 连接(进入)到一个正在运行的容器
  9. $ docker wait # 阻塞一个容器,直到容器停止运行
  10. #获取容器信息
  11. $ docker ps # 显示状态为运行(Up)的容器
  12. $ docker ps -a # 显示所有容器,包括运行中(Up)的和退出的(Exited)
  13. $ docker inspect # 深入容器内部获取容器所有信息
  14. $ docker logs # 查看容器的日志(stdout/stderr)
  15. $ docker events # 得到docker服务器的实时的事件
  16. $ docker port # 显示容器的端口映射
  17. $ docker top # 显示容器的进程信息
  18. $ docker diff # 显示容器文件系统的前后变化
  19. #导出容器
  20. $ docker cp # 从容器里向外拷贝文件或目录
  21. $ docker export # 将容器整个文件系统导出为一个tar包,不带layers、tag等信息
  22. #执行
  23. $ docker exec # 在容器里执行一个命令,可以执行bash进入交互式

Docker 命令总览

  1. $ docker 或者 $ docker --help
  2. # Commands:
  3. # attach Attach local standard input, output, and error streams to a running container
  4. # build Build an image from a Dockerfile
  5. # commit Create a new image from a container's changes
  6. # cp Copy files/folders between a container and the local filesystem
  7. # create Create a new container
  8. # diff Inspect changes to files or directories on a container's filesystem
  9. # events Get real time events from the server
  10. # exec Run a command in a running container
  11. # export Export a container's filesystem as a tar archive
  12. # history Show the history of an image
  13. # images List images
  14. # import Import the contents from a tarball to create a filesystem image
  15. # info Display system-wide information
  16. # inspect Return low-level information on Docker objects
  17. # kill Kill one or more running containers
  18. # load Load an image from a tar archive or STDIN
  19. # login Log in to a Docker registry
  20. # logout Log out from a Docker registry
  21. # logs Fetch the logs of a container
  22. # pause Pause all processes within one or more containers
  23. # port List port mappings or a specific mapping for the container
  24. # ps List containers
  25. # pull Pull an image or a repository from a registry
  26. # push Push an image or a repository to a registry
  27. # rename Rename a container
  28. # restart Restart one or more containers
  29. # rm Remove one or more containers
  30. # rmi Remove one or more images
  31. # run Run a command in a new container
  32. # save Save one or more images to a tar archive (streamed to STDOUT by default)
  33. # search Search the Docker Hub for images
  34. # start Start one or more stopped containers
  35. # stats Display a live stream of container(s) resource usage statistics
  36. # stop Stop one or more running containers
  37. # tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  38. # top Display the running processes of a container
  39. # unpause Unpause all processes within one or more containers
  40. # update Update configuration of one or more containers
  41. # version Show the Docker version information
  42. # wait Block until one or more containers stop, then print their exit codes

镜像

轻量级、可执行的独立软件包
联合文件系统UnionFS,分层镜像,共享资源
bootfs——共用
rootfs——定制
镜像的实现原理
Docker 镜像是怎么实现增量的修改和维护的? 每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去。
通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。 Docker 在 AUFS 上构建的容器也是利用了类似的原理。

命令一览

  1. $ docker image --help
  2. build Build an image from a Dockerfile
  3. history Show the history of an image
  4. import Import the contents from a tarball to create a filesystem image
  5. inspect Display detailed information on one or more images
  6. load Load an image from a tar archive or STDIN
  7. ls List images
  8. prune Remove unused images
  9. pull Pull an image or a repository from a registry
  10. push Push an image or a repository to a registry
  11. rm Remove one or more images
  12. save Save one or more images to a tar archive (streamed to STDOUT by default)
  13. tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

获取镜像

  1. $ docker pull [dl.dockerpool.com:5000/]ubuntu:12.04
  2. # 该命令实际上相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04 命令,
  3. # 即从注册服务器registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。
  4. `docker pull [imageName]`
  5. $ docker pull ubuntu
  6. # 获取镜像
  7. $ docker pull ubuntu:13.10
  8. # 指定版本用 :[TAG]

列出本地主机上的镜像

  1. $ docker images
  2. $ docker images -a
  3. $ docker images -q
  4. $ docker images --digests 描述
  5. $ docker images --digests --no-trunc 不截取

查找镜像

  1. $ docker search [-s 30] httpd
  2. # -s --stars
  3. # --filter=stars=30
  4. $ docker search --filter=stars=30 tomcat

删除镜像

  1. $ docker rmi [-f] [name/image Id]
  2. # 批量删除镜像
  3. $ docker rmi -f $(docker images -qa)

创建镜像

当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

  • 从已经创建的容器中更新镜像,并且提交这个镜像
  • 使用 Dockerfile 指令来创建一个新的镜像

制作自己的镜像

  1. # 在运行的容器中安装vim和net-tools
  2. yum -y install vim
  3. yum -y install net-tools
  4. $ docker commit -m "add vim & net tool" -a "gnkevin" [id] biubiu/gn-centos:v1
  5. $ docker images
  6. #REPOSITORY TAG IMAGE ID CREATED SIZE
  7. #biubiu/gn-centos v1 0b16d97ef358 3 minutes ago 298MB

提交容器副本

  1. $ docker commit -m="has update" -a="kevin" e218edb10161 kevin/ubuntu:v2
  2. # -m描述 -a作者 ID 目标镜像名
  3. # 构建镜像
  4. $ docker build

容器

创建容器

  1. $ docker run -it centos /bin/bash
  2. # 创建一个容器,让其中运行 bash 应用
  3. # TAG信息用来标记来自同一个仓库的不同镜像。
  4. # 如果不指定具体的标记,则默认使用 latest 标记信息。
  5. # -i: 交互式操作
  6. # -t: 终端
  7. # --name: 自定义命名
  8. # -P: 随机映射端口
  9. # -p: 指定端口号映射
  10. # ubuntu: ubuntu 镜像
  11. # /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

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

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止
  1. #运行
  2. $ docker run hello-world
  3. # To generate this message, Docker took the following steps:
  4. # 1. The Docker client contacted the Docker daemon.
  5. # 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.(amd64)
  6. # 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
  7. # 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
  8. # 查看正在运行的容器
  9. $ docker [container] ps
  10. # 停止运行的容器
  11. $ docker stop [id]
  12. # 查看容器内的标准输出
  13. $ docker logs [id]
  14. # -i 标准输入 -t 伪终端或终端
  15. # 可以在伪终端中利用 ps 或 top 来查看进程信息
  16. $ docker run [-i -t] [image]
  17. # 指定端口映射, python app.py 为执行的命令
  18. $ docker run -d -p 5000:5000 training/webapp python app.py
  19. # 进入容器
  20. $ docker exec
  21. # 退出终端
  22. exit
  23. ctrl + P + Q 关闭不退出
  24. # 后台运行 守护态
  25. $ docker run -d [image]

查看容器

  1. // 查看所有(含终止状态)的容器
  2. $ docker ps -a
  3. // last
  4. $ docker ps -l
  5. // 最近3
  6. $ docker ps -n 3
  7. // 只显示id
  8. $ docker ps -q


启动容器

  1. # 通过 docker start 命令来重新启动处于终止状态的容器
  2. $ docker start [name]


重启容器

  1. # 将一个运行态的容器终止,然后再重新启动它
  2. $ docker restart [name]

停止容器

  1. docker stop [containerId] # 温柔
  2. docker kill [containerId] # 暴力

导入导出容器

  1. docker export [containerId] > dir
  2. docker import [url/path] [target]

删除容器

  1. docker rm -f [containerId]
  2. docker rm -f $(docker ps -a -q)
  3. docker ps -a -q | xargs docker rm

清理终止态容器

  1. docker container prune


web应用容器

  1. PORTS
  2. 0.0.0.0:32769->5000/tcp
  3. Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。

映射所有接口地址

使用 hostPort:containerPort 格式本地的 5000 端口映射到容器的 5000 端口,可以执行

  1. $ docker run -d -p 5000:5000 training/webapp python app.py

python app.py 启动后执行的command
此时默认会绑定本地所有接口上的所有地址。
-p 参数来设置不一样的端口

  1. $ docker run -d -p 5000:5000 training/webapp python app.py

-p 主机端口: docker 容器端口
主机端口——浏览器地址栏填写的端口
查看指定容器的某个确定端口映射到宿主机的端口号

  1. $ docker port [containerId]

查看容器内标准输出

  1. $ docker run -d centos /bin/sh "while true; do echo hello kevin; sleep 2; done"
  2. $ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
  3. $ docker ps
  4. $ docker logs [-t -f --tail 3] [containerId]

查看容器内部运行的进程

  1. $ docker top [containerId]||[name]

查看 Docker 的底层信息

  1. $ docker inspect [containerId]||[name]
  2. $ docker inspect -f "{{ .Name }}" aed84ee21bde
  3. $ docker inspect centos
  4. [
  5. {
  6. "Id": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee",
  7. "RepoTags": [
  8. "centos:latest"
  9. ],
  10. "RepoDigests": [
  11. "centos@sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700"
  12. ],
  13. "Parent": "",
  14. "Comment": "",
  15. "Created": "2020-01-18T00:26:46.850750902Z",
  16. "Container": "57333b28d93d47fedc0cc5c995092b9266fa4b73b64f3f88d42a08e46f1aab48",
  17. "ContainerConfig": {
  18. "Hostname": "57333b28d93d",
  19. "Domainname": "",
  20. "User": "",
  21. "AttachStdin": false,
  22. "AttachStdout": false,
  23. "AttachStderr": false,
  24. "Tty": false,
  25. "OpenStdin": false,
  26. "StdinOnce": false,
  27. "Env": [
  28. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  29. ],
  30. "Cmd": [
  31. "/bin/sh",
  32. "-c",
  33. "#(nop) ",
  34. "CMD [\"/bin/bash\"]"
  35. ],
  36. "ArgsEscaped": true,
  37. "Image": "sha256:0fff7846fd29d8959680f5c1ed8ee2f30197a479c0f73a88dedc0f0755d3277d",
  38. "Volumes": null,
  39. "WorkingDir": "",
  40. "Entrypoint": null,
  41. "OnBuild": null,
  42. "Labels": {
  43. "org.label-schema.build-date": "20200114",
  44. "org.label-schema.license": "GPLv2",
  45. "org.label-schema.name": "CentOS Base Image",
  46. "org.label-schema.schema-version": "1.0",
  47. "org.label-schema.vendor": "CentOS",
  48. "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
  49. "org.opencontainers.image.licenses": "GPL-2.0-only",
  50. "org.opencontainers.image.title": "CentOS Base Image",
  51. "org.opencontainers.image.vendor": "CentOS"
  52. }
  53. },
  54. "DockerVersion": "18.06.1-ce",
  55. "Author": "",
  56. "Config": {
  57. "Hostname": "",
  58. "Domainname": "",
  59. "User": "",
  60. "AttachStdin": false,
  61. "AttachStdout": false,
  62. "AttachStderr": false,
  63. "Tty": false,
  64. "OpenStdin": false,
  65. "StdinOnce": false,
  66. "Env": [
  67. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  68. ],
  69. "Cmd": [
  70. "/bin/bash"
  71. ],
  72. "ArgsEscaped": true,
  73. "Image": "sha256:0fff7846fd29d8959680f5c1ed8ee2f30197a479c0f73a88dedc0f0755d3277d",
  74. "Volumes": null,
  75. "WorkingDir": "",
  76. "Entrypoint": null,
  77. "OnBuild": null,
  78. "Labels": {
  79. "org.label-schema.build-date": "20200114",
  80. "org.label-schema.license": "GPLv2",
  81. "org.label-schema.name": "CentOS Base Image",
  82. "org.label-schema.schema-version": "1.0",
  83. "org.label-schema.vendor": "CentOS",
  84. "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
  85. "org.opencontainers.image.licenses": "GPL-2.0-only",
  86. "org.opencontainers.image.title": "CentOS Base Image",
  87. "org.opencontainers.image.vendor": "CentOS"
  88. }
  89. },
  90. "Architecture": "amd64",
  91. "Os": "linux",
  92. "Size": 237117212,
  93. "VirtualSize": 237117212,
  94. "GraphDriver": {
  95. "Data": {
  96. "MergedDir": "/var/lib/docker/overlay2/8cb423dcb279b20723cd5a92ee401a9463ab8fbb812b67b4cfa6ccdb922ef004/merged",
  97. "UpperDir": "/var/lib/docker/overlay2/8cb423dcb279b20723cd5a92ee401a9463ab8fbb812b67b4cfa6ccdb922ef004/diff",
  98. "WorkDir": "/var/lib/docker/overlay2/8cb423dcb279b20723cd5a92ee401a9463ab8fbb812b67b4cfa6ccdb922ef004/work"
  99. },
  100. "Name": "overlay2"
  101. },
  102. "RootFS": {
  103. "Type": "layers",
  104. "Layers": [
  105. "sha256:0683de2821778aa9546bf3d3e6944df779daba1582631b7ea3517bb36f9e4007"
  106. ]
  107. },
  108. "Metadata": {
  109. "LastTagTime": "0001-01-01T00:00:00Z"
  110. }
  111. }
  112. ]

信息下方的Layers,就是centos的文件,这些东西都是只读的不能去修改,我们基于这个镜像去创建的镜像和容器也会共享这些文件层,而docker会在这些层上面去添加一个可读写的文件层。如果需要修改一些文件层里面的东西的话,docker会复制一份到这个可读写的文件层里面,如果删除容器的话,那么也会删除它对应的可读写的文件层的文件。

进入容器

-d 后台运行,如需进入容器

  1. $ docker attach [containerId]
  2. $ docker exec -it [containerId][/bin/bash]||[ls -l /tmp]
  3. # 可以在容器外面操作容器,隔山打牛

退出 exit 后,使用 docker ps 查看容器运行状态


自定义命名容器

使用 --name 标记可以为容器自定义命名。
docker run -d -P --name web training/webapp python app.py
在执行 docker run 的时候如果添加 --rm 标记,则容器在终止后会立刻删除。注意,--rm-d 参数不能同时使用。

复制数据

  1. $ docker cp containerId:path name target

重启应用容器

  1. 通过 docker start 命令来重新启动处于终止状态的容器
  2. $ docker start [name]
  3. 将一个运行态的容器终止,然后再重新启动它
  4. $ docker restart [name]
  5. 查看最后一次创建的容器
  6. $ docker ps -l
  7. 查看终止状态的容器
  8. $ docker ps -a

停止web应用容器

  1. $ docker stop [containerId]||[name]

移除应用容器

  1. $ docker rm [name]
  2. # Note: 容器必须先stop

docker 容器数据卷

如果有些数据你想一直保存的话,比如:web服务器上面的日志,数据库管理系统里面的数据,那么我们可以把这些数据放到data volumes数据盘里面。它上面的数据,即使把容器删掉,也还是会永久保留。创建容器的时候,我们可以去指定数据盘。其实就是去指定一个特定的目录。

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 卷会一直存在,直到没有容器使用

数据卷的使用,类似于 Linux 下对目录或文件进行 mount。
数据持久化、数据共享

命令添加数据卷

创建一个 web 容器,并加载一个数据卷到容器的 /webapp 目录

  1. docker run -d -P
  2. --name web
  3. -v /src/webapp:/opt/webapp
  4. training/webapp python app.py

在用 docker run 命令的时候,使用 -v 标记来创建一个数据卷并挂载到容器里。

-v 宿主机目录:容器目录 将宿主机目录挂载在容器内

使用 -v 标记也可以指定挂载一个本地主机的目录到容器中去

docker run -it -v /宿主机绝对路径:/容器内目录[:ro] imageName
Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro 指定为只读。
加载主机的 /src/webapp 目录到容器的 /opt/webapp 目录

使用docker inspect 容器ID可以查看挂载目录对应于宿主机的物理文件路径

数据卷容器

如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

首先,创建一个命名的数据卷容器 dbdata:

  1. $ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
  2. $ docker create -v /mnt -it --name newnginx docker.io/nginx /bin/bash

然后,在其他容器中使用 --volumes-from 来挂载 dbdata 容器中的数据卷。

  1. $ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
  2. $ sudo docker run -d --volumes-from dbdata --name db2 training/postgres

还可以使用多个 --volumes-from 参数来从多个容器挂载多个数据卷。 也可以从其他已经挂载了数据卷的容器来挂载数据卷。

  1. $ sudo docker run -d --name db3 --volumes-from db1 training/postgres

注意:使用 --volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态。

如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的容器。

volumes-from 容器间传递共享

  1. $ docker run -it --name dc04 --volumns-from dc03 zzyy/centos_dc

备份

首先使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从本地主机挂载当前到容器的 /backup 目录。命令如下:

  1. $ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

容器启动后,使用了 tar 命令来将 dbdata 卷备份为本地的 /backup/backup.tar

恢复

如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 dbdata2。

  1. $ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后创建另一个容器,挂载 dbdata2 的容器,并使用 untar 解压备份文件到挂载的容器卷中。

  1. $ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf
  2. /backup/backup.tar
  1. $ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
  2. $ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
  3. $ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
  4. $ sudo docker run -d --name db3 --volumes-from db1 training/postgres
  5. $ sudo docker run -it --name dc04 --volumns-from dc03 zzyy/centos_dc
  6. $ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
  7. $ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
  8. $ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf
  9. /backup/backup.tar

数据盘管理

  1. #查看数据盘
  2. $ docker volume ls
  3. #查看未被容器使用的数据盘
  4. $ docker volume ls -f dangling=true
  5. #删除数据盘
  6. $ docker volume rm VOLUME NAME

如果想要删除容器时,同时删除掉其数据盘,那么可以使用-v参数。

  1. $ docker rm -v newnginx

Dockerfile

包含一组指令来告诉 Docker 如何构建我们的镜像

  1. // 第一条FROM,指定使用哪个镜像源
  2. FROM centos:6.7
  3. MAINTAINER Fisher "fisher@sudops.com"
  4. // RUN 指令告诉docker 在镜像内执行命令,安装了什么
  5. RUN /bin/echo 'root:123456' |chpasswd
  6. RUN useradd runoob
  7. RUN /bin/echo 'runoob:123456' |chpasswd
  8. RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
  9. EXPOSE 22
  10. EXPOSE 80
  11. CMD /usr/sbin/sshd -D

每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。 …… 注意一个镜像不能超过 127 层 然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。 docker build -t runoob/centos:6.7 .

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

为镜像添加一个新的标签

  1. $ docker tag [containerId] 用户名/镜像源名:新标签名

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
一般的,Dockerfile 分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令

Dockerfile的指令是忽略大小写的,建议使用大写,使用 # 作为注释,每一行只支持一条指令,每条指令可以携带多个参数。
Dockerfile的指令根据作用可以分为两种,构建指令和设置指令。
构建指令:用于构建image,其指定的操作不会在运行image的容器上执行;
设置指令:用于设置image的属性,其指定的操作将在运行image的容器中执行。

其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。
后面则是镜像操作指令,例如 RUN 指令,RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令,镜像添加新的一层,并提交。
最后是 CMD 指令,来指定运行容器时的操作命令。

每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。
ENV 格式为 ENV <key> <value>。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。WORKDIR 为后续的 RUNCMDENTRYPOINT 指令配置工作目录。

基本的格式为 docker build [选项] 路径,该命令将读取指定路径下(包括子目录)的 Dockerfile,并将该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置 Dockerfile 的目录为空目录。也可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文件。

要指定镜像的标签信息,可以通过 -t 选项

步骤:

  1. 手动编写dockerfile文件
  2. docker build,得到一个新镜像
  3. docker run
  1. FROM centos
  2. MAINTAINER kevin<gnkevin@126.com>
  3. ENV MYPATH /usr/local
  4. WORKDIR $MYPATH
  5. RUN yum -y install vim
  6. RUN yum -y install net-tools
  7. EXPOSE 80
  8. CMD echo $MYPATH
  9. CMD echo "success...ok"
  10. CMD /bin/bash
  1. FROM centos:latest
  2. MAINTAINER gnkevin <gnkevin@126.com>
  3. ENV DEFAULTPATH /usr/local
  4. WORKDIR $DEFAULTPATH
  5. RUN yum -y install vim
  6. RUN yum -y install net-tools
  7. EXPOSE 80
  8. CMD echo "exec done"
  9. CMD /bin/bash
  1. FROM centos
  2. MAINTAINER kevin<gnkevin@126.com>
  3. ENV MYPATH /usr/local
  4. WORKDIR $MYPATH
  5. RUN yum -y install vim
  6. RUN yum -y install net-tools
  7. EXPOSE 80
  8. CMD echo $MYPATH
  9. CMD echo "success...ok"
  10. CMD /bin/bash
  11. FROM centos:latest
  12. MAINTAINER gnkevin <gnkevin@126.com>
  13. ENV DEFAULTPATH /usr/local
  14. WORKDIR $DEFAULTPATH
  15. RUN yum -y install vim
  16. RUN yum -y install net-tools
  17. EXPOSE 80
  18. CMD echo "exec done"
  19. CMD /bin/bash

命令详解

  • FROM(指定基础image)

构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的image。FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库。
该指令有两种格式:

  1. FROM <image> #指定基础image为该image的最后修改的版本
  2. FROM <image>:<tag> #指定基础image为该image的一个tag版本。
  • MAINTAINER(用来指定镜像创建者信息)

构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。建议使用LABEL指令代替

  1. MAINTAINER <name>
  • RUN(安装软件用)

构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。

  1. RUN <command> (the command is run in a shell - `/bin/sh -c`)
  2. RUN ["executable", "param1", "param2" ... ] (exec form)
  • CMD(设置container启动时执行的操作)

设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。

  1. CMD ["executable","param1","param2"] (like an exec, this is the preferred form)
  2. CMD command param1 param2 (as a shell)

ENTRYPOINT指定的是一个可执行的脚本或者程序的路径,该指定的脚本或者程序将会以param1和param2作为参数执行。所以如果CMD指令使用上面的形式,那么Dockerfile中必须要有配套的ENTRYPOINT。当Dockerfile指定了ENTRYPOINT,那么使用下面的格式:

  1. CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
  • ENTRYPOINT(设置container启动时执行的操作)

设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。

  1. ENTRYPOINT ["executable", "param1", "param2"] (like an exec, the preferred form)
  2. ENTRYPOINT command param1 param2 (as a shell)

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。
当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。

  1. # CMD指令将不会被执行,只有ENTRYPOINT指令被执行
  2. CMD echo Hello, World!”
  3. ENTRYPOINT ls -l

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。

  1. FROM ubuntu
  2. CMD ["-l"]
  3. ENTRYPOINT ["/usr/bin/ls"]
  • USER(设置container容器的用户)

设置指令,设置启动容器的用户,默认是root用户

  1. # 指定memcached的运行用户
  2. ENTRYPOINT ["memcached"]
  3. USER daemon
  4. ENTRYPOINT ["memcached", "-u", "daemon"]
  • EXPOSE(指定容器需要映射到宿主机器的端口)

设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。

  1. # 映射一个端口
  2. EXPOSE port1
  3. # 相应的运行容器使用的命令 (主机(宿主)端口:容器端口)
  4. docker run -p port1 image
  5. # 映射多个端口
  6. EXPOSE port1 port2 port3
  7. # 相应的运行容器使用的命令
  8. docker run -p port1 -p port2 -p port3 image
  9. # 还可以指定需要映射到宿主机器上的某个端口号
  10. docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image

端口映射是docker比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不能指定而是在桥接网卡的地址范围内随机生成的。宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。对于一个运行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID来查看该端口号在宿主机器上的映射端口。

  • ENV(用于设置环境变量)

构建指令,在image中设置一个环境变量。

  1. ENV <key> <value>

设置了后,后续的RUN命令都可以使用,container启动后,可以通过docker inspect查看这个环境变量,也可以通过在docker run —env key=value时设置或修改环境变量。
假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写:

  1. ENV JAVA_HOME /path/to/java/dirent
  • ADD(从src复制文件到container的dest路径)

构建指令,所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;如果是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);如果是文件且中不使用斜杠结束,则会将视为文件,的内容会写入;如果是文件且中使用斜杠结束,则会文件拷贝到目录下。

  1. ADD <src> <dest>

是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;
是container中的绝对路径

  • VOLUME(指定挂载点)

设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。

  1. FROM base
  2. VOLUME ["/tmp/data"]
  • WORKDIR(切换目录)

设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。

  1. # 在 /p1/p2 下执行 vim a.txt
  2. WORKDIR /p1 WORKDIR p2 RUN vim a.txt

构建

  1. $ docker build -f /docker/Dockerfile -t mycentos:0.2 .
  2. # -f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
  3. # -t, --tag list Name and optionally a tag in the 'name:tag' format

其中 -t 标记来添加 tag,指定新的镜像的用户信息。 “.” 是 Dockerfile 所在的路径(当前目录),也可以替换为一个具体的 Dockerfile 的路径。

更改tag

  1. $ docker tag d2c05474342b biubiu/gn-centos:v2

上传镜像

  1. $ docker push REPOSITORY:TAG

导出镜像

  1. $ docker save -o path REPOSITORY:TAG
  2. $ docker save -o centos7.0.tar centos7.0
  3. $ docker export f1c33062063c >centos7.0.tar

载入镜像

  1. $ docker load -i centos7.0.tar
  2. $ docker load < centos7.0.tar
  3. # -i, --input string Read from tar archive file, instead of STDIN
  4. # -q, --quiet Suppress the load output

移除镜像

  1. $ docker rmi xxx
  2. 在删除镜像之前要先用 docker rm 删掉依赖于这个镜像的所有容器。

ONBUILD

父子镜像间,创建子镜像时,执行父镜像ONBUILD的指令

  1. 例如,Dockerfile 使用如下的内容创建了镜像 image-A
  2. [...]
  3. ONBUILD ADD . /app/src
  4. ONBUILD RUN /usr/local/bin/python-build --dir /app/src
  5. [...]
  6. 如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A指定基础镜像时,会自动执行ONBUILD 指令内容,等价于在后面添加了两条指令。

安装常用软件

tomcat

  1. docker run -d -p 9080:8080 --name myt9
  2. -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test
  3. -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs
  4. --privileged=true
  5. zzyytomcat9

mysql

  1. docker run -p 12345:3306 --name mysql
  2. -v /zzyyuse/mysql/conf:/etc/mysql/conf.d
  3. -v /zzyyuse/mysql/logs:logs
  4. -v /zzyyuse/mysql/data:/var/lib/mysql
  5. -e MYSQL_ROOT_PASSWORD=123456
  6. -d mysql:5.6

redis

  1. $ docker run -p 6379:6379
  2. -v /zzyyuse/myredis/data:/data
  3. -v /zzyyuse/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf
  4. -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf
  5. --appendonly yes

docker-compose

  1. biubiu:selfmk bubu$ docker-compose -h
  2. Define and run multi-container applications with Docker.
  3. Usage:
  4. docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  5. docker-compose -h|--help
  6. Options:
  7. -f, --file FILE Specify an alternate compose file
  8. (default: docker-compose.yml)
  9. -p, --project-name NAME Specify an alternate project name
  10. (default: directory name)
  11. --verbose Show more output
  12. --log-level LEVEL Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  13. --no-ansi Do not print ANSI control characters
  14. -v, --version Print version and exit
  15. -H, --host HOST Daemon socket to connect to
  16. --tls Use TLS; implied by --tlsverify
  17. --tlscacert CA_PATH Trust certs signed only by this CA
  18. --tlscert CLIENT_CERT_PATH Path to TLS certificate file
  19. --tlskey TLS_KEY_PATH Path to TLS key file
  20. --tlsverify Use TLS and verify the remote
  21. --skip-hostname-check Don't check the daemon's hostname against the
  22. name specified in the client certificate
  23. --project-directory PATH Specify an alternate working directory
  24. (default: the path of the Compose file)
  25. --compatibility If set, Compose will attempt to convert keys
  26. in v3 files to their non-Swarm equivalent
  27. --env-file PATH Specify an alternate environment file
  28. Commands:
  29. build Build or rebuild services
  30. bundle Generate a Docker bundle from the Compose file
  31. config Validate and view the Compose file
  32. create Create services
  33. down Stop and remove containers, networks, images, and volumes
  34. events Receive real time events from containers
  35. exec Execute a command in a running container
  36. help Get help on a command
  37. images List images
  38. kill Kill containers
  39. logs View output from containers
  40. pause Pause services
  41. port Print the public port for a port binding
  42. ps List containers
  43. pull Pull service images
  44. push Push service images
  45. restart Restart services
  46. rm Remove stopped containers
  47. run Run a one-off command
  48. scale Set number of containers for a service
  49. start Start services
  50. stop Stop services
  51. top Display the running processes
  52. unpause Unpause services
  53. up Create and start containers
  54. version Show the Docker-Compose version information

理论

Docker provides a way to run applications securely isolated in a container, packaged with all its dependencies and libraries. Docker提供了一种将应用程序安全地隔离在容器中运行的方法,容器中打包了所有依赖项和库。

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production. Docker是一个用于开发、发布和运行应用程序的开放平台。Docker使您能够将应用程序与基础设施分离,以便能够快速交付软件。使用Docker,您可以像管理应用程序一样管理基础设施。通过利用Docker的方法论哲学来快速地交付、测试和部署代码,您可以显著地减少编写代码和在生产环境中运行代码之间的延迟。

Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. Containers are lightweight because they don’t need the extra load of a hypervisor, but run directly within the host machine’s kernel. This means you can run more containers on a given hardware combination than if you were using virtual machines. You can even run Docker containers within host machines that are actually virtual machines! Docker提供了在称为容器的松散隔离环境中打包和运行应用程序的能力。隔离和安全性允许您在给定的主机上同时运行多个容器。容器是轻量级的,因为它们不需要管理程序的额外负载,而是直接在主机的内核中运行。这意味着与使用虚拟机相比,您可以在给定的硬件组合上运行更多的容器。您甚至可以在实际上是虚拟机的主机中运行Docker容器!

Fast, consistent delivery of your applications 快速、一致地交付应用程序

Docker streamlines the development lifecycle by allowing developers to work in standardized environments using local containers which provide your applications and services. Containers are great for continuous integration and continuous delivery (CI/CD) workflows. Docker简化了开发生命周期,允许开发人员使用提供应用程序和服务的本地容器在标准化环境中工作。容器对于持续集成和持续交付(CI/CD)工作流非常有用。

Consider the following example scenario: 考虑以下示例场景:

  • Your developers write code locally and share their work with their colleagues using Docker containers.

您的开发人员在本地编写代码,并使用Docker容器与同事共享工作。

  • They use Docker to push their applications into a test environment and execute automated and manual tests.

他们使用Docker将应用程序推入测试环境,并执行自动化和手动测试。

  • When developers find bugs, they can fix them in the development environment and redeploy them to the test environment for testing and validation.

当开发人员发现bug时,他们可以在开发环境中修复它们,并将它们重新部署到测试环境中进行测试和验证。

  • When testing is complete, getting the fix to the customer is as simple as pushing the updated image to the production environment.

测试完成后,修复客户端只需将更新后的映像推入生产环境即可。 Responsive deployment and scaling** 响应式部署和扩展

Docker’s container-based platform allows for highly portable workloads. Docker containers can run on a developer’s local laptop, on physical or virtual machines in a data center, on cloud providers, or in a mixture of environments. Docker的基于容器的平台允许高度可移植的工作负载。Docker容器可以在开发人员的本地膝上型电脑、数据中心的物理或虚拟机、云提供商或混合环境中运行。

Docker’s portability and lightweight nature also make it easy to dynamically manage workloads, scaling up or tearing down applications and services as business needs dictate, in near real time. Docker的可移植性和轻量级特性也使得动态管理工作负载变得很容易,可以根据业务需求实时扩展或分解应用程序和服务。

Running more workloads on the same hardware 在相同的硬件上运行更多的工作负载

Docker is lightweight and fast. It provides a viable, cost-effective alternative to hypervisor-based virtual machines, so you can use more of your compute capacity to achieve your business goals. Docker is perfect for high density environments and for small and medium deployments where you need to do more with fewer resources. Docker是轻量级和快速的。它为基于管理程序的虚拟机提供了一种可行的、经济有效的替代方案,因此您可以使用更多的计算能力来实现业务目标。Docker非常适合于高密度环境和需要使用较少资源完成更多工作的中小型部署。

Images and containers

Fundamentally, a container is nothing but a running process, with some added encapsulation features applied to it in order to keep it isolated from the host and from other containers. One of the most important aspects of container isolation is that each container interacts with its own, private filesystem; this filesystem is provided by a Docker image. An image includes everything needed to run an application — the code or binary, runtimes, dependencies, and any other filesystem objects required. 从根本上说,容器只是一个正在运行的进程,为了使它与主机和其他容器隔离,在其上应用了一些附加的封装特性。容器隔离最重要的方面之一是每个容器都与自己的私有文件系统进行交互;此文件系统由Docker镜像提供。镜像包含运行应用程序所需的所有内容——代码或二进制、运行时、依赖项和任何其他文件系统对象。

Containers and virtual machines

A container runs natively on Linux and shares the kernel of the host machine with other containers. It runs a discrete process, taking no more memory than any other executable, making it lightweight. By contrast, a virtual machine (VM) runs a full-blown “guest” operating system with virtual access to host resources through a hypervisor. In general, VMs incur a lot of overhead beyond what is being consumed by your application logic. 容器在Linux上本地运行,并与其他容器共享主机的内核。它运行一个独立的进程,不占用比其他任何可执行程序更多的内存,使其轻量级。 相比之下,虚拟机(VM)运行一个成熟的“guest”操作系统,通过虚拟机监控程序对主机资源进行虚拟访问。通常,vm会产生大量开销,超出应用程序逻辑所消耗的开销。

虚拟机——带环境安装的解决方案
docker,容器虚拟化技术,将应用与运行环境打包成镜像,实现一次打包,处处运行。

Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。
Docker 的基础是 Linux 容器(LXC)等技术。
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。
用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
Docker 会尽可能的缩短从代码测试到产品部署的时间。
Docker 可以让你像使用集装箱一样快速的组合成应用,并且可以像运输标准集装箱一样,尽可能的屏蔽代码层面的差异。
Docker容器能够帮助开发人员、系统管理员、QA和版本控制工程师在一个生产环节中一起协同工作。

我们制定了一套容器标准,而这套容器标准能够使系统管理员更改容器的时候,程序员不需要关心容器的变化,而更专注自己的应用程序代码。从而隔离开了开发和管理,简化了开发和部署的成本。
我们使应用的构建方式更加简单,可以快速的迭代你的应用,并且可以可视化的来查看应用的细微更改。这能够帮助组织里边的成员来更好的理解一个应用从构建到运行的过程。
Docker 是一个轻量级的容器,所以它的速度是非常快的,而容器的启动时间只需要一秒钟,从而大大的减少了开发、测试和部署的时间。轻松部署和扩展。
Docker 容器可以运行在大多数的环境中,你可以在桌面环境、物理主机、虚拟主机再到数据中,私有或者公有云中部署。
因为 Docker 可以从多平台下运行。你可以很容易的迁移你的应用程序。如果需要,你可以非常简单的将应用程序从测试环境迁移到云,或者从云迁移到测试环境。
Docker 是一个轻量级的容器,因此它可以在很短的时间内启动和关闭。当你需要的时候,你可以启动多个容器引擎,并且在不需要使用他们的时候,可以将他们全部关闭。
Docker的容器本身不需要额外创建虚拟机管理系统,因此你可以启动多套Docker容器,这样就可以充分发挥主机服务器的物理资源,也可以降低因为采购服务器licenses而带来的额外成本。
在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。
由于 Docker 使用一个统一文件系统,Docker 进程认为整个文件系统是以读写方式挂载的。 但是所有的变更都发生顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不可写,所以镜像是无状态的
每一个镜像都可能依赖于由一个或多个下层的组成的另一个镜像。我们有时说,下层那个镜像是上层镜像的父镜像。
一个没有任何父镜像的镜像,谓之基础镜像。
所有镜像都是通过一个 64 位十六进制字符串(内部是一个 256 bit 的值)来标识的。为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的碰撞机率,所以服务器总是返回长ID。