通过Docker
命令行客户端使用Docker
的一些例子
Docker
安装过程参考官网, 安装成功后我们可以通过命令行接口(CLI)来使用Docker
, 每个命令都可能会包含一些标记(flags
)和参数(arguments
), 命令的格式大致如下:
$ [sudo] docker [subcommand] [flags] [arguments] ..
比如刚安装完成可以查看Docker
的版本信息:
$ docker version
我们可以通过--help
标记来获取帮助, 比如列出docker
命令的所有选项(子命令)和用法、查看子命令的用法
$ docker --help
# 查看 attach 子命令的用法
$ docker attach --help
常用的命令使用方式示例以及一些解释
镜像好比类, 容器好比实例, 镜像被run
就形成了容器, 运行容器可以通过docker run
命令
先来个简单例子:
$ docker run hello-world
当运行镜像hello-world
时, 会先检查本地是否有这个镜像, 没有则会去仓库(默认是docker hub)下载
其他例子:
$ docker run ubuntu /bin/echo 'Hello world'
Hello world
$ docker run -t -i ubuntu /bin/bash
root@a98895ac1616:/#
-t
flag: 给容器分配一个tty终端-i
flag: 可通过STDIN
与容器交互/bin/bash
: 在容器里运行的bash shell
, 可用shell命令exit
退出容器$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
28f3adccbae408573bbe6ecc03ad621d4257fbf1a79c672cc8d83ad327266807
-d
flag: 后台运行容器(daemonize)container ID
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28f3adccbae4 ubuntu "/bin/sh -c 'while tr" 4 minutes ago Up 4 minutes zen_curran
container ID
: 前面那一长串的缩写NAMES
: 自动给容器起的名字, 每个容器的名字都是不一样的
另外:
docker ps
: 仅查看运行中的容器docker ps -l
: 查看最后一次运行的容器(last)docker ps -a
: 查看所有运行过的容器$ docker run --name hello ubuntu /bin/echo 'Hello world'
Hello world
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4c79c82eb6c ubuntu "/bin/echo 'Hello wor" 48 minutes ago Exited (0) 2 seconds ago hello
hello
而不再是自动起的名$ docker logs zen_curran
hello world
hello world
...
$ docker stop zen_curran
可以再次运行某个容器
$ docker start zen_curran
$ docker rm zen_curran
新下载一个镜像training/webapp
, 运行python app.py
可运行python写的web程序, 通过下面的命令运行容器
$ docker run -d -P training/webapp python app.py
查看该容器的信息:
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b32553a8272 training/webapp "python app.py" 12 minutes ago Up 12 minutes 0.0.0.0:32768->5000/tcp admiring_mayer
其中有个与其他程序不一样的地方:
PORTS
0.0.0.0:32768->5000/tcp
这就是-P
的作用, 上面描述的意思是Dcoker
容器里的端口是5000(Python Flask的默认端口)
暴露到了属主机的32768
端口.
上面-P
的作用等同于-p 5000
, 将暴露容器中的端口5000
到一个更大的宿主机端口上(临时端口映射范围一般为32768~61000
).
也可以自己指定使用某个具体的端口:
$ docker run -d -p 80:5000 training/webapp python app.py
访问容器运行起来的web程序地址为:127.0.0.1:80
上面的docker ps
可以看到容器的端口信息, 还有个更简单的命令docker port
, 指定要查看的容器的name
或ID
即可:
$ docker port 9b32553a8272
5000/tcp -> 0.0.0.0:32768
$ docker port admiring_mayer 5000
0.0.0.0:32768
$ docker logs -f admiring_mayer
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
172.17.0.1 - - [19/Jul/2016 09:10:49] "GET / HTTP/1.1" 200 -
172.17.0.1 - - [19/Jul/2016 09:10:49] "GET /favicon.ico HTTP/1.1" 404 -
-f
: 类似与tail -f
的形式查看使用docker inspect
命令可以获取一些信息, 如:
$ docker inspect admiring_mayer
可以看到一些json格式的信息:
[
{
"Id": "9b32553a82729a012b33b157abefb7639f1a59007042454f7ea543982a888466",
"Created": "2016-07-19T08:40:01.882402323Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
...
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest cf62323fa025 11 days ago 125 MB
hello-world latest c54a2cc56cbb 2 weeks ago 1.848 kB
REPOSITORY
: 镜像来自哪个仓库, 如ubuntu
TAG
: 镜像的版本, 如14.04
, latest
表示最新版本IMAGE ID
: 镜像的id每个镜像都有很多版本, 你可以指定某个版本, 如$ docker run -t -i ubuntu:14.04 /bin/bash
, 当不指定时, 默认都是latest
.
之前都是直接run
的, 会自动获取镜像, 也可以仅获取, 不运行:
$ docker pull ubuntu:14.04
$ docker pull centos
可以去Docker Hub搜索镜像, 也可以在命令行搜索
$ docker search ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating s... 4293 [OK]
ubuntu-upstart Upstart is an event-based replacement for ... 65 [OK]
rastasheep/ubuntu-sshd Dockerized SSH service, built on top of of... 29 [OK]
STARS
: 表示该镜像的受欢迎程度OFFICIAL
: 表示是官方制作的镜像AUTOMATED
: 表示是用户制作的镜像,/
前面就是用户名我们可以通过两种方式来制作镜像
Dockerfile
来指定具体如何创建某个镜像.先来看看第一种方法.
通过training/sinatra
镜像运行起来一个容器:
$ docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/#
记住这个容器的id:0b2616b0e5a8
,一会儿会用. 然后通过bash在容器中安装json
gem
root@0b2616b0e5a8:/# gem install json
完成之后退出容器就可以了
最后我们用docker commit
命令, 把刚才已经改变了的容器提交一个副本制作成镜像
$ docker commit -m "Added json gem" -a "Kate Smith" 0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
-m
: 添加描述信息, 类似于git commit -m
-a
: 作者信息0b2616b0e5a8
: 要制作成镜像的拿个容器的idouruser/sinatra:v2
: 目标镜像, 用户为ouruser
, 镜像名为sinatra
, 版本(tag)为v2
第一种方法比较麻烦而且不利于团队间的合作分享, 下面看看第二种方法:
通过docker build
命令编译Dockerfile
来制作镜像, 首先创建一个目录和一个Dockerfile
文件:
$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile
然后在Dockerfile
文件里添加类似于下面的内容:
# This is a comment
FROM ubuntu:14.04
MAINTAINER Kate Smith <ksmith@example.com>
RUN apt-get update && apt-get install -y ruby ruby-dev
RUN gem install sinatra
上面#
开头的是注释, 下面是指令, 指令的格式类似于INSTRUCTION statement
, 每条指令都会创建镜像的一层
FROM
: 告诉Docker
源镜像, 即我们是基于哪个镜像进行修改的MAINTAINER
: 用来说明是谁维护的这个镜像RUN
: 要在源镜像上做那些修改最后我们编译Dockerfile
$ docker build -t ouruser/sinatra:v2 .
-t
: 来指定一个新的tag
, 形式为:name:tag
.
: 注意后面有个.
, 用来表示编译当前目录里的Dockerfile
文件, 也可以自己指定Dockerfile
文件的位置我们可以给已经存在的镜像添加新的tag
docker tag ubuntu:14.04 rgkjhshi/ubuntu:newtag
docker tag b2f1fdd93175 rgkjhshi/ubuntu:newtag2
$ docker push rgkjhshi/ubuntu:newtag
# 提交所有tag
$ docker push rgkjhshi/ubuntu
$ docker rmi rgkjhshi/ubuntu:newtag2
# 不写tag 默认删除 latest
$ docker rmi rgkjhshi/ubuntu
v2
或之后的格式的镜像, 有个唯一标识符叫做digest
, 如果用于生成镜像的输入没有变,则digest
值也是一样的
$ docker images --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
rgkjhshi/ubuntu newtag sha256:8d0f6d13291273ad6271c3c55b222ad08e28ff71a40c27487c79dbe80cce184f b2f1fdd93175 40 hours ago 188.4 MB
rgkjhshi/ubuntu newtag2 sha256:8d0f6d13291273ad6271c3c55b222ad08e28ff71a40c27487c79dbe80cce184f b2f1fdd93175 40 hours ago 188.4 MB
ubuntu 14.04 sha256:b2c8a4d46473ab082200880391ddf8c06f2a67da4fa905ce2747dcd95d8d7af7 b2f1fdd93175 40 hours ago 188.4 MB
ubuntu latest sha256:ba1688fec34f66d8a7ff5b42e6971625d8232c72bf0e38ad06dda10cad157293 cf62323fa025 11 days ago 125 MB
在2.0
的仓库使用push
或pull
命令时都会显示镜像的digest
, 我们也可以直接像这样使用digest
:
$ docker pull rgkjhshi/ubuntu@sha256:8d0f6d13291273ad6271c3c55b222ad08e28ff71a40c27487c79dbe80cce184f
digest
有不同的tag
, 则pull
下来的镜像没有tag
(显示的是<none>
)create
, run
, rmi
命令甚至Dockerfile
中的FROM
都可以使用digest
.