[关闭]
@cdmonkey 2017-08-01T03:04:17.000000Z 字数 7894 阅读 1260

Docker-常用管理命令

Container


http://seanlook.com/2014/10/31/docker-command-best-use-1
http://seanlook.com/2014/11/05/docker-command-best-use-2

分类 说明
容器生命周期管理 docker [run|start|stop|restart|kill|rm|pause|unpause]
容器操作运维 docker [ps|inspect|top|attach|events|logs|wait|export|port]
容器rootfs命令 docker [commit|cp|diff]
镜像仓库 docker [login|pull|push|search]
本地镜像管理 docker [images|rmi|tag|build|history|save|import]
其他命令 docker [info|version]

列出机器上的镜像

  1. [root@hidocker ~]# docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. httpd latest ef0aca83ba5a 2 weeks ago 177 MB
  4. centos latest a8493f5f50ff 4 weeks ago 192 MB
  5. hello-world latest 48b5124b2768 3 months ago 1.84 kB

可根据“REPOSITORY”来判断这个镜像是来自哪个服务器:

上面的 IMAGE ID 列其实是缩写,显示的是短 UUID,要显示完整则带上 --no-trunc 选项。

搜索镜像

Usage:  docker search [OPTIONS] TERM

其搜索范围是官方镜像及所有个人公共镜像。其中“NAME”列 / 后面是仓库的名字。

  1. [root@hidocker ~]# docker search centos
  2. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
  3. centos The official build of CentOS. 2076 [OK]
  4. jdeathe/centos-ssh CentOS-6 6.7 x86_64 / CentOS-7 7.2.... 18 [OK]
  5. jdeathe/centos-ssh-apache-php CentOS-6 6.7 x86_64 / Apache / PHP ... 14 [OK]
  6. million12/centos-supervisor Base CentOS-7 with supervisord laun... 10 [OK]
  7. blalor/centos Bare-bones base CentOS 6.5 image 8 [OK]
  8. nimmis/java-centos This is docker images of CentOS 7 ... 8 [OK]
  9. ...

注意:如果想知道镜像都有哪些 tag,还是得浏览访问 Docker Hub 这个官方站点。

拉取镜像及仓库

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]
  1. [root@docker-node1 ~]# docker pull centos
  2. latest: Pulling from centos
  3. 6fdebd7b0eb5: Pull complete
  4. a63aae4d216f: Pull complete
  5. bb3d629a7cbc: Pull complete
  6. 47d44cb6f252: Already exists
  7. Digest: sha256:381f21e4c7b3724c6f420b2bcfa6e13e47ed155192869a2a04fa10f944c78476
  8. Status: Downloaded newer image for centos:latest

上面的命令需要注意:于“Docker 1.2”版本之前,会下载官方镜像的对应仓库里的全部镜像,而从“1.3”开始就只会下载标签为 latest 的镜像,以及同一 IMAGE ID 的打上其他标签的镜像。

可明确指定具体的镜像,这也是推荐的做法:

  1. [root@hidocker ~]# docker pull centos:centos7

Daocloud 拉取镜像:

  1. [root@hidocker ~]# docker pull daocloud.io/centos:7
  2. 7: Pulling from centos
  3. 343b09361036: Pull complete
  4. Digest: sha256:ddd3cb191f642246e04255927f3c4abdb44dc83b403ba2a63bbbef12c52506d1
  5. Status: Downloaded newer image for daocloud.io/centos:7

推送镜像及仓库

同上面的拉操作相对应,能够推送至“Docker Hub”及私有仓库,但不能推送至官方仓库。

  1. docker push seanlook/mongo
  2. docker push registry.tp-link.net:5000/mongo:2017-03-27

若仓库名不存在,则命令行下推送上去的会自动创建为私有库,然而通过浏览器创建的默认为公共库。

移除镜像:

  1. docker rmi

注意:如果一个镜像对应了多个 tag,只有当最后一个 tag 被删除时,镜像才被真正删除。

启动容器

  1. [root@docker-node1 ~]# docker run centos /bin/echo "Hello world"
  2. Hello world

注意:启动容器的方法有两种,用户可选择运行另外指定的命令,也可选择运行 Docker 镜像内部指定的命令。

能够看到,该容器已经退出了,因为你指定执行的应用(指令)执行完毕,因而容器也就完成了其使命,也就退出了。但是由上面的指令能够看到,容器虽然退出了,但容器仍然是存在的。

注意:这种一闪而过的容器通常不是我们想要的,我们希望容器能够保持 runing 状态,这样才能被我们使用。

  1. # 我们需要使用如下指令查看当前系统中容器的列表:
  2. [root@docker-node1 ~]# docker ps
  3. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  4. d1838e7fb7f5 centos "/bin/bash" 2 weeks ago Up 2 weeks mydocker
  5. # 使用-a选项能够看到所有的,包括正在运行的及已经停止的容器:
  6. [root@docker-node1 ~]# docker ps -a
  7. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  8. 486ac0d172c6 centos "/bin/echo 'Hello" About a minute ago Exited (0) About a minute ago agitated_mcclintock

启动容器时可通过使用 --name 参数显示地为容器命名,如果不为容器指定名称,则会被随机的从名字库内分配一个名字。

说明:对于容器的后续操作,我们可通过 Long IDShrt ID 或者 NAME 来指定要操作的容器。

  1. # Create a container an in it
  2. [root@docker-node1 ~]# docker run --name mydocker -it centos /bin/bash
  3. [root@d1838e7fb7f5 /]# # 表示我们已经进入到容器内部。

我们运行一个 Docker 容器时,会运行一个指定的应用(当然也可以是一个脚本文件),而当该应用退出时,容器也就随之退出了。

启动一个已经退出的容器:

  1. [root@docker-node1 ~]# docker start 486ac0d172c6
  2. 486ac0d172c6

移除一个容器(只能够移除已经退出的容器,移除正在运行的容器时会报错):

  1. # Remove a running container:
  2. [root@docker-node1 ~]# docker rm mydocker
  3. Error response from daemon: Cannot destroy container mydocker: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
  4. Error: failed to remove containers: [mydocker]
  5. --------------
  6. [root@docker-node1 ~]# docker rm fadb19dfed0d
  7. fadb19dfed0d

停掉一个正在运行的容器:

  1. [root@docker-node1 ~]# docker stop mydocker
  2. mydocker

启动一个于后台运行的容器:

  1. [root@docker-node1 ~]# docker run -d --name mydocker-2 centos
  2. a997e52879dda3b79bd5cc4d98a80c8eb41723d569e3e1237e15ed06e9f97cc3
  3. ------------------
  4. [root@docker-node1 ~]# docker run -d --name mynginx nginx
  5. 6292b9f84bf1f5a8f27514885a8aa72d9d64d859edb3cd8d04594bff3cf5c34d
  6. [root@docker-node1 ~]# docker ps -a|grep nginx
  7. 6292b9f84bf1 nginx "nginx -g "daemon of About a minute ago Up About a minute 80/tcp, 443/tcp mynginx

让容器长期运行

如何让容器一直保持运行状态呢?因为容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出。理解了这个原理,我们就能够通过执行一个长期运行的命令来使得容器保持运行的状态。例如执行下面的命令:

  1. docker run centos7 /bin/bash -c "while true; do sleep 1; done"

由于 while 语句让 bash 不会退出,因而容器会始终保持运行的状态。不过这种方法有个缺点:它占用了一个终端。可加上参数 -d 从而以后台方式启动容器。

  1. [root@hidocker ~]# docker run -d cdmonkey/centos6.7:test /bin/bash -c "while true; do sleep 1; done"
  2. e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e

容器启动后回到了 docker host 的终端。这里看到 docker 返回了一串字符,这是容器 ID

进入容器

我们经常需要进到容器里去进行一些工作,比如查看日志、问题调试、启动其他服务进程等。有两种方法能够进入正在运行的容器内:attachexec

docker attach

我们能够使 docker attach 指令重新附着到一个正在运行的容器内:

  1. docker attach e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e

注意:一定不要用 Ctrl+c,那样就会使容器停止。可通过 Ctrl+p 然后 Ctrl+q 组合键退出 attach 终端。

  1. # 但是当我们试图重新附着到Nginx容器内时,会出现问题(无法附着,只能强行退出):
  2. [root@docker-node1 ~]# docker attach mynginx
  3. ^C[root@docker-node1 ~]#
  4. [root@docker-node1 ~]# docker ps -a|grep nginx
  5. # 强行退出后该容器也同时退出,这是附着指令的一个问题。
  6. 6292b9f84bf1 nginx "nginx -g "daemon of 31 minutes ago Exited (0) About a minute ago mynginx

要想进入 Nginx 容器的话,我们以访问指定进程的名字空间的方法进行:

  1. [root@docker-node1 ~]# yum install util-linux
  2. ---------------
  3. [root@docker-node1 ~]# docker start mynginx
  4. mynginx
  5. # Get the PID:
  6. [root@docker-node1 ~]# docker inspect --format "{{.State.Pid}}" mynginx
  7. 9539
  8. [root@docker-node1 ~]# nsenter --target 9539 --mount --uts --ipc --net --pid
  9. root@6292b9f84bf1:/# # This is a way of producing a more recommended entry into the container.
  10. root@6292b9f84bf1:/# exit
  11. logout
  1. [root@docker-node1 ~]# cat in.sh
  2. #!/bin/bash
  3. CNAME=$1
  4. CPID=$(docker inspect --format "{{.State.Pid}}" $CNAME)
  5. nsenter --target $CPID --mount --uts --ipc --net --pid

docker exec

使用 docker exec 进入相同的容器:

  1. docker exec -it e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e bash
  2. [root@e492aa059fa8 /]#

说明:同样要通过 Ctrl+p 然后 Ctrl+q 组合键退出容器终端,回到宿主机。

说明如下:

说明:docker exec -it <container> bash|sh 是执行 exec 最常使用的方式。

上面两种方法之区别:

当然,如果只是为了查看启动命令的输出,可使用 docker logs 命令:

  1. docker log -f e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e

其中 -f 的作用同 tail -f 类似,能够持续打印输出。

Access the Container

  1. [root@docker-node1 ~]# brctl show
  2. bridge name bridge id STP enabled interfaces
  3. docker0 8000.0aad0749e040 no veth01f2e67

由于我们运行了容器服务,因而会自动创建一个网桥,而每运行一个容器,就会相应的于该网桥上创建一个接口。并且容器于默认情况下是能够上网的。我们可以查看下容器的网卡信息:

  1. root@6292b9f84bf1:/# ip ad li
  2. 28: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
  3. link/ether 02:42:ac:11:00:09 brd ff:ff:ff:ff:ff:ff
  4. inet 172.17.0.9/16 scope global eth0
  5. inet6 fe80::42:acff:fe11:9/64 scope link
  6. valid_lft forever preferred_lft forever
  7. ...
  8. # View the route info:
  9. root@6292b9f84bf1:/# ip ro li
  10. 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.9
  11. default via 172.17.42.1 dev eth0
  12. ----------------
  13. [root@docker-node1 ~]# ifconfig
  14. docker0 Link encap:Ethernet HWaddr 0A:AD:07:49:E0:40
  15. inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0
  16. inet6 addr: fe80::5807:c8ff:fe78:3fbe/64 Scope:Link
  17. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  18. RX packets:2659 errors:0 dropped:0 overruns:0 frame:0
  19. TX packets:4684 errors:0 dropped:0 overruns:0 carrier:0
  20. collisions:0 txqueuelen:0
  21. RX bytes:146551 (143.1 KiB) TX bytes:10409698 (9.9 MiB)
  22. ...

能够看到,宿主机的网桥地址就是容器的网关。如果我们需要访问容器,最直接的方法就是将容器内的端口映射出来。包括随机映射及指定映射。

Random mapping

随机映射的好处端口不会冲突。

  1. [root@docker-node1 ~]# docker run -d -P --name mynginx-2 nginx
  2. bedef258a583f0819ed251c873254b95c2f09c22ad6dcf04993dc733933a361f
  3. [root@docker-node1 ~]# docker ps -a|grep mynginx-2
  4. bedef258a583 nginx "nginx -g "daemon of 47 seconds ago Up 45 seconds
  5. 0.0.0.0:4001->80/tcp, 0.0.0.0:4000->443/tcp mynginx-2

我们可以使用浏览器来访问宿主机的地址及映射出来的端口:http://192.168.120.251:4001

Specified mapping

  1. # 第一种方式是直接指定映射对,适用于宿主机只有一个网络地址的情况。
  2. [root@docker-node1 ~]# docker run -d -p 90:80 --name mynginx-3 nginx
  3. 31e1b92682941346f12d4fd8930c2bca7f6d1ffde167fd38da7f8ab047a5d935
  4. [root@docker-node1 ~]# docker ps -a|grep mynginx-3
  5. 31e1b9268294 nginx "nginx -g "daemon of 38 seconds ago Up 36 seconds
  6. 443/tcp, 0.0.0.0:90->80/tcp mynginx-3

其中冒号前面是映射出来的端口,而冒号后面的是容器内部的端口。如果宿主机存在多个网络地址的话,这需要写成如下形式:

  1. -p ip:hostPort:containerPort
  2. -p ip::containerPort # Random mapping
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注