常用命令
获取镜像
下载镜像
docker pull name:tag
PS:如果不显示指定tag,默认选择latest标签,即下载仓库中最新版本的镜像
指定注册服务器下载镜像
docker pull registry.hub.docker.com/ubuntu:latest
查看镜像信息
查看本地仓库中所有的镜像信息
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest ef8893942c44 4 weeks ago 64.2MB
ubuntu latest ccc6e87d482b 4 weeks ago 64.2MB
PS:镜像id信息唯一标识了镜像。
给镜像添加新的标签
docker tag ubuntu:latest ubuntu:12.2
执行docker images 列出本地主机镜像信息,发现多了一个ubuntu:12.2
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest ef8893942c44 4 weeks ago 64.2MB
ubuntu 12.2 ccc6e87d482b 4 weeks ago 64.2MB
ubuntu latest ccc6e87d482b 4 weeks ago 64.2MB
获取镜像的详细信息
docker inspect ef8893942c44
只获取其中一项内容
docker inspect -f {{".Architecture"}} ef8893942c44
amd64
搜寻镜像
搜索远端仓库的镜像
docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9137 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3235 [OK]
DESCROPTION:描述信息
STARS:星级
OFFICAIAL:是否官方创建
AUTOMATED:是否自动创建
删除镜像
使用镜像的标签删除镜像
docker rmi IMAGE #image 可以为镜像:标签
PS:当同一个镜像拥有多个标签的时候,docker rmi命令只是删除了该镜像多个标签中的指定标签,并不影响镜像文件。
使用镜像ID删除镜像
docker rmi 镜像ID
如果想要强行删除镜像,可以使用-f参数
PS:删除镜像的时候要删除依赖该镜像的所有容器,再来删除镜像。
删除容器
docker rm 容器ID
创建镜像
创建镜像的方法有三种:基于已有的容器创建、基于本地模板导入、基于Dockerfile创建。
基于已有镜像的容器创建
docker commit options container repository:tag
常用选项
-a "作者信息"
-m "提交信息"
-p 提交时暂停容器运行
[root@localhost ~]# docker commit -m "mkdir /test" -a "root" 84ca8dc76ae8 unbuntu:test
sha256:3b476008c14be363fa4aeaa80dea073d6b81180eeb96ce5718383b48cd0aa6a1
基于本地模板导入
Open VZ 模板下载url https://wiki.openvz.org/Download/template/precreated
[root@107 ~]# cat centos-7-x86_64-minimal.tar.gz | docker import - centos:daoru
sha256:6979b02b848c0d861046fc27bd3743b9320a2f3bcc4dc00b2e593d6ac95a2940
存出载入镜像
存出镜像
docker save -o 本地文件名字.tar 镜像名字:标签
载入镜像
docker load < 载入的文件
上传镜像
可以使用docker push命令上传镜像到仓库,默认上传到DockerHub官方仓库(需要登录)docker push name:tag
用户在DockerHub网站注册后,即可上传自制的镜像。例如用户上传本地的test:latest镜像,可以先添加新的标签user/test:latest,然后容docker push上传镜像(上传类似git hub):
[root@107 ~]# docker tag centos:daoru 2312398095/ymy:centos
[root@107 ~]# docker push 2312398095/ymy:centos
The push refers to repository [docker.io/2312398095/ymy]
788edba9eaa8: Pushed
centos: digest: sha256:10e785549811d2f582e4a92ca84445ec80bcf20ce240663b389cecbd59cb56cb size: 529
登录DockerHub账号
[root@107 ~]# docker login
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
容器操作
新建并启动容器
docker run options imageid command arg
常用option
--name="容器新名字": 为容器指定一个名称;
-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,让容器的标准输入保持打开,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,并绑定到容器的标准输入上方,通常与 -i 同时使用;
-P: 随机端口映射;
-p: 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
启动一个交互式容器
[root@localhost ~]# docker run -it --name centos3 4706
[root@f09fa51ca9d4 /]# ps -elf
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 3003 do_wai 01:21 pts/0 00:00:00 /bin/bash
4 R root 14 1 0 80 0 - 10987 - 01:21 pts/0 00:00:00 ps -elf
查看容器
docker ps option
常用option
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
--no-trunc :不截断输出。
[root@localhost ~]# docker ps -q
f09fa51ca9d4
d9c82841eab1
0b7aaf489fb2
退出容器
ctrl + d #容器停止退出
exit #容器停止退出
ctrl + P + Q #容器不停止退出
启动容器
docker start 容器id 或者 容器名
重启容器
docker restart 容器id 或者 容器名
停止容器
docker stop 容器id 或者 容器名
强制停止容器
docker kill 容器id 或者 容器名
删除容器
docker rm 容器id
常用选项
-f #强行终止并删除一个运行中的容器。
-l #删除容器的连接,但保留容器。
-v #删除容器挂载的数据卷。
一次性删除多个容器
docker rm $(docker ps -q )
docekr ps -q | xargs docker rm
启动守护式容器
docker run -d 容器名
docker run -d centos
问题:然后docker ps 进行查看, 会发现容器已经退出
很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。
这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如
service nginx start
但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.
所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行
docker run -itd 容器名
或者
docker run -d centos /bin/sh -c "while true;do echo hello;sleep 2;done"
查看容器日志
docker logs -f -t --tail 容器id
常用选项
-t 加入时间戳
-f 更新最新的日志
--tail 数字显示最后多少条
[root@localhost ~]# docker logs -f -t --tail 9005a
2020-02-18T02:31:32.383336558Z hello
2020-02-18T02:31:34.385152926Z hello
2020-02-18T02:31:36.387717883Z hello
查看容器内运行的进程
docker top 容器id
查看容器内部细节
docker inspect 容器id
进入正在运行的容器,并以命令行交互
docker exec -it 容器id bashshell
[root@localhost ~]# docker exec -it 9005a /bin/bash
[root@9005aecba009 /]#
这条命令是进入了一个新的终端
docker attach 容器id
docker attach 9005a
这条命令是进入容器运行的那个终端,不会开启一个新的终端。
也可以通过exec不进入交互在外面执行容器里面命令
nsenter 进入容器(不常用)
6a为容器id
通过下面这条命令获取对应容器的pid
[root@107 ~]# PID=`docker inspect --format "{{ .State.Pid }}" 6a`
[root@107 ~]# echo $PID
32310
通过nsenter工具进入容器
[root@107 ~]# nsenter --target 32310 --mount --uts --ipc --net --pid
[root@localhost ~]# docker exec -it 9005a ls /root
anaconda-ks.cfg anaconda-post.log original-ks.cfg
拷贝容器内的文件到本地主机
docker cp 容器id:容器内路径 目地主机路径
[root@localhost ~]# docker cp 9005a:/etc/passwd /
[root@localhost ~]# ls /
bin boot dev etc home lib lib64 media mnt opt passwd proc root run sbin srv sys tmp usr var
导出容器
docker export container
PS:不管容器是否处于运行状态,都可以使用这个命令。
[root@107 ~]# docker export 6a > test_ubuntu.tar
导入容器
将导出的容器文件,导入为一个镜像。
[root@107 ~]# cat test_ubuntu.tar | docker import - ubuntu:test2
sha256:ac5c4c7427a92b9c0c698d67b637d085dc93d0401909fcfad318ea707deefe4f
[root@107 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu test2 ac5c4c7427a9 7 seconds ago 64.2MB
PS: docker load 命令和 docker import 导入的容器快照的区别
-
docker Import 使用的容器快照会丢弃所有的历史数据和元数据(即仅保存容器当时的快照状态)。
-
docker laod 使用的镜像存储文件保存完整记录,体积也比较大。
-
容器快照文件导入的时候可以重新指定标签等元数据信息。
数据卷操作
数据卷的特性
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 卷会一直存在,知道没有容器使用
- 数据卷的使用类似Linux下对目录或文件进行mount操作
在容器内创建一个数据卷
使用training/webapp镜像创建一个名字叫web的容器,并创建一个数据卷挂载到容器的/webapp目录,并随机暴漏容器内端口
docker run -d -P --name web -v /webapp training/webapp python app.py
挂载一个主机目录作为数据卷
使用 -v 标记也可以指定挂载一个本地的已有目录到容器去作为数据卷
[root@107 volumes]# docker run -itd -v /data:/etc/data ubuntu
394a53949b6007e39e578ca2a804b233692377e7990fe23f74dbaedc3f46ca99
将本地主机的/data目录挂载到容器内部的/etc/data目录,本地目录必须是绝对路径,如果目录不存在Docker会自动创建。
docker挂载数据卷的默认权限是是(rw),也可以通过,ro指定为只读。
[root@107 volumes]# docker run -itd -v /data:/data:ro ubuntu:latest
45d09a627173cd5b1672739d6fe821a5242b9fb5e5f82a5d41d2ad8f156f6c93
挂载一个本地主机文件作为数据卷
不推荐挂载文件到容器中,如果挂载文件到容器中后,在对文件进行修改会产生报错。
[root@107 volumes]# docker run --rm -it -v /data/2:/.bash_history ubuntu /bin/bash
删除数据卷
如果删除了挂载的容器,数据卷并不会自动删除,如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显示使用 docekr rm -v 命令来指定同时删除关联的容器。
创建数据卷容器
1.首先创建一个容器dbdata,并在其中创建一个数据卷挂载到/dbdata
docker run -it -v /dbdata --name dbdata ubuntu
2.通过在其他容器中使用–volumes-from挂载dbdata容器中的数据卷。
docker run -it --volumes-from dbdata --name db1 ubuntu
这个时候在db1容器里面的/dbdata目录里面写入文件,dbdata里面的/dbdata目录里面也能看到该文件
可以多次使用–volumes-from参数来从多个容器挂载多个数据卷,还可以从其他已经挂载了容器卷的容器来挂载数据卷。
使用用数据卷容器迁移数据
- 备份
docker run --volumes-form dbdata -v $(pwd):/backup --name worker ubuntu tar -zcf /backup/backup.tar /dbdata
使用Ubuntu镜像创建了一个叫worker的容器,让worker容器挂载了dbdata容器的数据卷 使用-v把本地目录挂载载worker容器的/backup目录
容器启动后使用tar 命令将/dbdata下达内容备份为/backup/backup.tar,即宿主机主机当前目录下的backup.tar
- 恢复
先创建一个带有数据卷的容器dadata2
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
创建一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂在的容器卷中即可
通过端口映射访问容器
随机映射一个端口到容器内(-P)
[root@localhost ~]# docker run -d -P training/webapp
使用docker ps 看到本地的32768端口被映射到了容器内部的5000端口
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5fc70cafff1f training/webapp "python app.py" 8 seconds ago Up 6 seconds 0.0.0.0:32768->5000/tcp sad_gates
指定要映射的端口
- -p小写的 三种映射格式
ip:hostport:containerport
ip::containerport
hostport:containerport
- 映射主机的所有接口地址(多张网卡)到容器指定端口
hostport:containerport
将本地所有接口的3000端口映射到容器内部5000
[root@localhost ~]# docker run -itd -p 3000:5000 ubuntu:latest
44f66c85e01847c5e1ea975df9f47d2f21d9a71808befd0e7407f58227089224
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44f66c85e018 ubuntu:latest "/bin/bash" 7 seconds ago Up 6 seconds 0.0.0.0:3000->5000/tcp elegant_knuth
- 映射到指定地址的指定端口
ip:hostport:containerport
将127.0.0.1的3001端口映射到容器的5000端口
[root@localhost ~]# docker run -itd -p 127.0.0.1:3001:5000 ubuntu:latest
7e453b2a02482d850c582222f1febbe52985b1047b482cc7d98304170ad09a51
[root@localhost ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e453b2a0248 ubuntu:latest "/bin/bash" 17 seconds ago Up 16 seconds 127.0.0.1:3001->5000/tcp magical_hugle
- 映射到指定地址的任意端口
ip::containerport
绑定127.0.0.1的任意端口到容器的5000端口,本地主机会自动飞配一个端口
[root@localhost ~]# docker run -itd -p 127.0.0.1::5000 ubuntu:latest
e681c8a91cd3465550293935dceaf7065e38f51673de2c3e5c9fabbc3a873342
[root@localhost ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e681c8a91cd3 ubuntu:latest "/bin/bash" 6 seconds ago Up 4 seconds 127.0.0.1:32769->5000/tcp goofy_franklin
- 映射一个udp端口
[root@localhost ~]# docker run -itd -p 127.0.0.1::5000/udp ubuntu:latest
d1ded802a05719f800db150c79aec22ad0d1d5857cb72ffbfc82165cfb27f29a
[root@localhost ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1ded802a057 ubuntu:latest "/bin/bash" 6 seconds ago Up 4 seconds 127.0.0.1:32768->5000/udp loving_goldwasser
查看映射端口配置
docker port name
容器互联
–link参数可以让容器之间进行安全的交互
创建一个容器busybox1
[root@localhost ~]# docker run -itd --name busybox1 -p 3005:3000 busybox
884afcabb80816bb7e0ddc5c49aa5d7bed4061f162301959fa8eccfa42e35655
创建一个容器busybox2连接到busybox1
–link参数格式 --link name:alias
name 要链接的容器名字
alias 这个链接的别名(/etc/hosts里面写入的主机名,也就是后期可以通过这个别名来进行通信)
[root@localhost ~]# docker run -itd --name busybox2 -p 3006:3005 --link busybox1:busybox1 busybox
71e108d6b228f4cfb19ed380302acead6f7001fd7718ce94484dde0dad4c9588
/ # ping busybox1
PING busybox1 (172.17.0.7): 56 data bytes
64 bytes from 172.17.0.7: seq=0 ttl=64 time=0.156 ms
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:08
inet addr:172.17.0.8 Bcast:172.17.255.255
docker 通过两种方式公开容器连接信息
- /etc/hosts
- 环境变量
hosts信息,第一个是busybox1 的容器id 和 主机名 第二个是busybox2的容器id和主机名
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.7 busybox1 884afcabb808
172.17.0.8 6f9f491bdd2b
env里面大写的busybox1的环境变量是供busybox2连接1使用到的
/ # env
HOSTNAME=6f9f491bdd2b
SHLVL=1
BUSYBOX1_PORT_3000_TCP=tcp://172.17.0.7:3000
HOME=/root
BUSYBOX1_PORT=tcp://172.17.0.7:3000
BUSYBOX1_NAME=/busybox2/busybox1
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
BUSYBOX1_PORT_3000_TCP_ADDR=172.17.0.7
PWD=/
BUSYBOX1_PORT_3000_TCP_PORT=3000
BUSYBOX1_PORT_3000_TCP_PROTO=tcp
用户可以链接多个子容器到父容器,比如链接多个busybox2到1上
PS:当启动容器busybox2的时候使用–link命令去连接busybox1容器的时候,实际上连接是单向的,只能busybox2去ping busybox1,而不能在busybox1容器内ping busybox2。