@cdmonkey
2017-08-01T11:04:17.000000Z
字数 7894
阅读 1342
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] |
[root@hidocker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest ef0aca83ba5a 2 weeks ago 177 MB
centos latest a8493f5f50ff 4 weeks ago 192 MB
hello-world latest 48b5124b2768 3 months ago 1.84 kB
可根据“REPOSITORY”来判断这个镜像是来自哪个服务器:
/
则表示官方镜像;username/repos_name
则表示“Github”的个人公共库;regsistory.example.com:5000/repos_name
则表示的是私服。上面的 IMAGE ID
列其实是缩写,显示的是短 UUID
,要显示完整则带上 --no-trunc
选项。
Usage: docker search [OPTIONS] TERM
其搜索范围是官方镜像及所有个人公共镜像。其中“NAME”列 /
后面是仓库的名字。
[root@hidocker ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 2076 [OK]
jdeathe/centos-ssh CentOS-6 6.7 x86_64 / CentOS-7 7.2.... 18 [OK]
jdeathe/centos-ssh-apache-php CentOS-6 6.7 x86_64 / Apache / PHP ... 14 [OK]
million12/centos-supervisor Base CentOS-7 with supervisord laun... 10 [OK]
blalor/centos Bare-bones base CentOS 6.5 image 8 [OK]
nimmis/java-centos This is docker images of CentOS 7 ... 8 [OK]
...
注意:如果想知道镜像都有哪些
tag
,还是得浏览访问Docker Hub
这个官方站点。
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
[root@docker-node1 ~]# docker pull centos
latest: Pulling from centos
6fdebd7b0eb5: Pull complete
a63aae4d216f: Pull complete
bb3d629a7cbc: Pull complete
47d44cb6f252: Already exists
Digest: sha256:381f21e4c7b3724c6f420b2bcfa6e13e47ed155192869a2a04fa10f944c78476
Status: Downloaded newer image for centos:latest
上面的命令需要注意:于“Docker 1.2”版本之前,会下载官方镜像的对应仓库里的全部镜像,而从“1.3”开始就只会下载标签为 latest
的镜像,以及同一 IMAGE ID
的打上其他标签的镜像。
可明确指定具体的镜像,这也是推荐的做法:
[root@hidocker ~]# docker pull centos:centos7
从 Daocloud
拉取镜像:
[root@hidocker ~]# docker pull daocloud.io/centos:7
7: Pulling from centos
343b09361036: Pull complete
Digest: sha256:ddd3cb191f642246e04255927f3c4abdb44dc83b403ba2a63bbbef12c52506d1
Status: Downloaded newer image for daocloud.io/centos:7
同上面的拉操作相对应,能够推送至“Docker Hub”及私有仓库,但不能推送至官方仓库。
docker push seanlook/mongo
docker push registry.tp-link.net:5000/mongo:2017-03-27
若仓库名不存在,则命令行下推送上去的会自动创建为私有库,然而通过浏览器创建的默认为公共库。
docker rmi
注意:如果一个镜像对应了多个
tag
,只有当最后一个tag
被删除时,镜像才被真正删除。
[root@docker-node1 ~]# docker run centos /bin/echo "Hello world"
Hello world
注意:启动容器的方法有两种,用户可选择运行另外指定的命令,也可选择运行
Docker
镜像内部指定的命令。
能够看到,该容器已经退出了,因为你指定执行的应用(指令)执行完毕,因而容器也就完成了其使命,也就退出了。但是由上面的指令能够看到,容器虽然退出了,但容器仍然是存在的。
注意:这种一闪而过的容器通常不是我们想要的,我们希望容器能够保持
runing
状态,这样才能被我们使用。
# 我们需要使用如下指令查看当前系统中容器的列表:
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1838e7fb7f5 centos "/bin/bash" 2 weeks ago Up 2 weeks mydocker
# 使用-a选项能够看到所有的,包括正在运行的及已经停止的容器:
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
486ac0d172c6 centos "/bin/echo 'Hello" About a minute ago Exited (0) About a minute ago agitated_mcclintock
启动容器时可通过使用 --name
参数显示地为容器命名,如果不为容器指定名称,则会被随机的从名字库内分配一个名字。
说明:对于容器的后续操作,我们可通过
Long ID
、Shrt ID
或者NAME
来指定要操作的容器。
# Create a container an in it
[root@docker-node1 ~]# docker run --name mydocker -it centos /bin/bash
[root@d1838e7fb7f5 /]# # 表示我们已经进入到容器内部。
我们运行一个 Docker
容器时,会运行一个指定的应用(当然也可以是一个脚本文件),而当该应用退出时,容器也就随之退出了。
启动一个已经退出的容器:
[root@docker-node1 ~]# docker start 486ac0d172c6
486ac0d172c6
移除一个容器(只能够移除已经退出的容器,移除正在运行的容器时会报错):
# Remove a running container:
[root@docker-node1 ~]# docker rm mydocker
Error response from daemon: Cannot destroy container mydocker: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
Error: failed to remove containers: [mydocker]
--------------
[root@docker-node1 ~]# docker rm fadb19dfed0d
fadb19dfed0d
停掉一个正在运行的容器:
[root@docker-node1 ~]# docker stop mydocker
mydocker
启动一个于后台运行的容器:
[root@docker-node1 ~]# docker run -d --name mydocker-2 centos
a997e52879dda3b79bd5cc4d98a80c8eb41723d569e3e1237e15ed06e9f97cc3
------------------
[root@docker-node1 ~]# docker run -d --name mynginx nginx
6292b9f84bf1f5a8f27514885a8aa72d9d64d859edb3cd8d04594bff3cf5c34d
[root@docker-node1 ~]# docker ps -a|grep nginx
6292b9f84bf1 nginx "nginx -g "daemon of About a minute ago Up About a minute 80/tcp, 443/tcp mynginx
如何让容器一直保持运行状态呢?因为容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出。理解了这个原理,我们就能够通过执行一个长期运行的命令来使得容器保持运行的状态。例如执行下面的命令:
docker run centos7 /bin/bash -c "while true; do sleep 1; done"
由于 while
语句让 bash
不会退出,因而容器会始终保持运行的状态。不过这种方法有个缺点:它占用了一个终端。可加上参数 -d
从而以后台方式启动容器。
[root@hidocker ~]# docker run -d cdmonkey/centos6.7:test /bin/bash -c "while true; do sleep 1; done"
e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e
容器启动后回到了 docker host
的终端。这里看到 docker
返回了一串字符,这是容器 ID
。
我们经常需要进到容器里去进行一些工作,比如查看日志、问题调试、启动其他服务进程等。有两种方法能够进入正在运行的容器内:attach
、exec
。
我们能够使 docker attach
指令重新附着到一个正在运行的容器内:
docker attach e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e
注意:一定不要用
Ctrl+c
,那样就会使容器停止。可通过Ctrl+p
然后Ctrl+q
组合键退出attach
终端。
# 但是当我们试图重新附着到Nginx容器内时,会出现问题(无法附着,只能强行退出):
[root@docker-node1 ~]# docker attach mynginx
^C[root@docker-node1 ~]#
[root@docker-node1 ~]# docker ps -a|grep nginx
# 强行退出后该容器也同时退出,这是附着指令的一个问题。
6292b9f84bf1 nginx "nginx -g "daemon of 31 minutes ago Exited (0) About a minute ago mynginx
要想进入 Nginx
容器的话,我们以访问指定进程的名字空间的方法进行:
[root@docker-node1 ~]# yum install util-linux
---------------
[root@docker-node1 ~]# docker start mynginx
mynginx
# Get the PID:
[root@docker-node1 ~]# docker inspect --format "{{.State.Pid}}" mynginx
9539
[root@docker-node1 ~]# nsenter --target 9539 --mount --uts --ipc --net --pid
root@6292b9f84bf1:/# # This is a way of producing a more recommended entry into the container.
root@6292b9f84bf1:/# exit
logout
[root@docker-node1 ~]# cat in.sh
#!/bin/bash
CNAME=$1
CPID=$(docker inspect --format "{{.State.Pid}}" $CNAME)
nsenter --target $CPID --mount --uts --ipc --net --pid
使用 docker exec
进入相同的容器:
docker exec -it e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e bash
[root@e492aa059fa8 /]#
说明:同样要通过
Ctrl+p
然后Ctrl+q
组合键退出容器终端,回到宿主机。
说明如下:
-it
用交互模式打开 pseudo-TTY
,执行 bash
,其结果就是打开了一个 bash
终端;hostname
就是其 “短ID”;exit
退出容器,回到 docker host
。说明:
docker exec -it <container> bash|sh
是执行exec
最常使用的方式。
上面两种方法之区别:
attach
指令直接进入容器启动命令 的终端,而不会启动新的进程。exec
则是于容器中打开新的终端,并且能够启动新的进程。attach
;其他情况使则使用 exec
。当然,如果只是为了查看启动命令的输出,可使用 docker logs
命令:
docker log -f e492aa059fa87a3a925d0fbe82b96174d3682b3d3ac7f0248d3bc14e108c586e
其中 -f
的作用同 tail -f
类似,能够持续打印输出。
[root@docker-node1 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0aad0749e040 no veth01f2e67
由于我们运行了容器服务,因而会自动创建一个网桥,而每运行一个容器,就会相应的于该网桥上创建一个接口。并且容器于默认情况下是能够上网的。我们可以查看下容器的网卡信息:
root@6292b9f84bf1:/# ip ad li
28: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:09 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.9/16 scope global eth0
inet6 fe80::42:acff:fe11:9/64 scope link
valid_lft forever preferred_lft forever
...
# View the route info:
root@6292b9f84bf1:/# ip ro li
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.9
default via 172.17.42.1 dev eth0
----------------
[root@docker-node1 ~]# ifconfig
docker0 Link encap:Ethernet HWaddr 0A:AD:07:49:E0:40
inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::5807:c8ff:fe78:3fbe/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2659 errors:0 dropped:0 overruns:0 frame:0
TX packets:4684 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:146551 (143.1 KiB) TX bytes:10409698 (9.9 MiB)
...
能够看到,宿主机的网桥地址就是容器的网关。如果我们需要访问容器,最直接的方法就是将容器内的端口映射出来。包括随机映射及指定映射。
随机映射的好处端口不会冲突。
[root@docker-node1 ~]# docker run -d -P --name mynginx-2 nginx
bedef258a583f0819ed251c873254b95c2f09c22ad6dcf04993dc733933a361f
[root@docker-node1 ~]# docker ps -a|grep mynginx-2
bedef258a583 nginx "nginx -g "daemon of 47 seconds ago Up 45 seconds
0.0.0.0:4001->80/tcp, 0.0.0.0:4000->443/tcp mynginx-2
我们可以使用浏览器来访问宿主机的地址及映射出来的端口:http://192.168.120.251:4001
# 第一种方式是直接指定映射对,适用于宿主机只有一个网络地址的情况。
[root@docker-node1 ~]# docker run -d -p 90:80 --name mynginx-3 nginx
31e1b92682941346f12d4fd8930c2bca7f6d1ffde167fd38da7f8ab047a5d935
[root@docker-node1 ~]# docker ps -a|grep mynginx-3
31e1b9268294 nginx "nginx -g "daemon of 38 seconds ago Up 36 seconds
443/tcp, 0.0.0.0:90->80/tcp mynginx-3
其中冒号前面是映射出来的端口,而冒号后面的是容器内部的端口。如果宿主机存在多个网络地址的话,这需要写成如下形式:
-p ip:hostPort:containerPort
-p ip::containerPort # Random mapping