docker常用命令
将常用的一些命令记录下,方便以后查阅。
配置文件
服务配置文件
docker 服务的配置文件(可以配置各项启动参数):
/etc/systemd/system/docker.service
内容类似这样:
1 | |
daemon.json
/etc/docker/daemon.json
可以配置私有仓库信息(比如内网需要用到 http 协议的私有仓库),内容类似这样:
1 | |
注意该文件修改后,必须重启 docker 进程才会生效。
docker 服务
启动
systemctl start docker
重启
systemctl restart docker
关闭
systemctl stop docker
查看 docker 信息
docker info
加入自启动
systemctl enable docker
镜像
搜索镜像
docker search [options] imageName
※ -s num :可以查找多少星以上的镜像
※ –automated:默认 false,显示 automated build 镜像
※ –no-trunk :默认 false ,不以截断方式查找镜像
还可以去https://hub.docker.com/ 网站进行搜索;如果你想看某个镜像具体有哪些标签,也是在这个网站上查询,比如查询 centos 的 tag 列表:https://hub.docker.com/_/centos/
查看镜像的所有标签
需要自己写脚本,参考这个文章:https://blog.csdn.net/kongxx/article/details/86558328
1 | |
通过镜像 ID 拉取镜像
查看本地镜像
docker images
拉取镜像
docker pull [options] 镜像名称[:tags]
※ -a :下载所有该 tags 的镜像
※ 忽略 tags 下载最新版本的镜像
比如:docker pull hub.hexin.cn/imageName
拉取并启动镜像
docker run -d hub.hexin.cn/imageName
启动镜像
docker run -t -i a6cd10f85c07 /bin/sh
cannot execute binary file
这个一般是 Dockerfile 中使用了 ENTRYPOINT 来启动某些程序,但是参数设置有误导致的,参考这个文章。
需要给你的 ENTRYPOINT 命令加上-c 参数,比如这样:
1 | |
启动镜像(后台):
docker run -d -t -i a6cd10f85c07 /bin/sh
注意:不加/bin/bash,启动后执行完 Dockerfile 中指定的命令,就会关闭容器
启动镜像并添加 host 映射:
docker run -d –add-host this-is-domain1:10.0.6.29 –add-host this-is-domain2:10.0.6.30 -t -i a6cd10f85c07 /bin/sh
启动镜像并随机映射端口:
sudo docker run -d -t -i -P 镜像 ID
启动镜像并映射端口:
sudo docker run -d -t -i -p 10001:22 镜像 ID
启动镜像并映射多个端口:
sudo docker run -d -p 10022:22 -p 13306:3306 -p 10080:80 -p 18080:8080 镜像 ID
1 | |
将镜像保存为压缩包
docker save -o nginx.tar nginx:latest
或:
docker save > nginx.tar nginx:latest
导入压缩包,还原镜像
docker load -i nginx.tar
或:
docker load < nginx.tar
删除镜像
docker rmi
unable to delete fc6c02e0c01c (cannot be forced) - image has dependent child images
参考这个回答:
https://stackoverflow.com/questions/38118791/can-t-delete-docker-image-with-dependent-child-images
通过指定镜像:tag 名称来删除:
1 | |
通过 Dockfile 生成镜像
docker build -f Dockerfile.local -t resource:local .
如果 dockerfile 中需要连接网络,比如下载安装包,那么一般需要制定网络信息,比如指定代理,或者通过--network=host选择使用宿主机的网络:
1 | |
重命名镜像和 tag
1 | |
将镜像推送到仓库
首先我们在官网上创建一个仓库(repository),假设名为 zhouchangju/micro-video
然后修改本地的镜像名和 tag,使其和仓库中的名称一致,比如仓库是 zhouchangju/micro-video,则要命名为这种格式:
1 | |
然后通过 docker login 登录仓库:
1 | |
在推送上去即可:
1 | |
容器
查看全部容器(包括停止的):
docker ps -a
查看所有已启动的容器:
docker ps
查看某个已启动的容器:
docker inspect 容器 id
进入 docker 容器:
docker exec -ti 54c6395feb62 /bin/bash
停止容器
docker stop 容器 ID
停止所有容器
docker stop $(docker ps -q)
重启容器
docker restart 容器 ID
启动容器
docker start 容器 ID
(有时候容器意外停止了,可以重新启动下,里面修改的内容还在的)
查看容器日志
docker logs 容器 ID
完全删除容器(得先停止再删除):
docker stop 容器 ID && docker rm 容器 ID
将容器保存为镜像(注意,镜像名称只能取字符[a-z]和数字[0-9]):
docker commit 容器 ID 新的 j 镜像名称
如何在保存镜像的时候添加说明信息?
可以通过-a 添加作者,-m 添加说明信息,比如:
1 | |
然后通过 inspect 就可以看到这些信息了:
1 | |
为什么 docker commit 生成的镜像,没有保存/etc/hosts 的修改信息?
参考这个文章:
一、原因
/etc/hosts, /etc/resolv.conf 和/etc/hostname,容器中的这三个文件不存在于镜像,在启动容器的时候,通过 mount 的形式将这些文件挂载到容器内部。因此,如果在容器中修改这些文件的话,修改部分不会存在于容器的 top layer,而是直接写入这三个物理文件中。为什么重启后修改内容不存在了?原因是:每次 Docker 在启动容器的时候,通过重新构建新的/etc/hosts 文件,这又是为什么呢?原因是:容器重启,IP 地址为改变,hosts 文件中原来的 IP 地址无效,因此理应修改 hosts 文件,否则会产生脏数据。
二、解决办法
在每次启动容器的时候指定 IP、hostname、往/etc/hosts 里添加 hosts,命令如下:docker run -itd –name hadoop0 –hostname hadoop0 –net network_my –ip 192.168.10.30 –add-host hadoop1:192.168.10.31 –add-host hadoop2:192.168.10.32 -d -P -p 50070:50070 -p 8088:8088 hadoop:master
Docker 系列(四)Docker 网络模式及配置
–hostname :指定 hostname;
–net : 指定网络模式
–ip:指定 IP
–add-host :指定往/etc/hosts 添加的 host
解决容器命令行界面(TTY 窗口)太小的问题
docker exec -it -e LINES=$(tput lines) -e COLUMNS=$(tput cols) 镜像 bash
解决容器不能联网的问题
http://cloud.51cto.com/art/201502/465958.htm
将容器保存为压缩包
docker export -o nginx.tar container
导入压缩包,还原镜像
docker import nginx.tar nginx:tagName
export 命令是从容器(container)中导出 tar 文件,而 save 命令则是从镜像(images)中导出
基于第二点,export 导出的文件再 import 回去时,无法保留镜像所有历史(即每一层 layer 信息,不熟悉的可以去看 Dockerfile),不能进行回滚操作;而 save 是依据镜像来的,所以导入时可以完整保留下每一层 layer 信息。
查看容器的文件/目录变更情况
docker diff container
报错:error: “Read-only file system” setting key “kernel.msgmnb”
error: “Read-only file system” setting key “kernel.msgmnb”
error: “Read-only file system” setting key “kernel.msgmni”
解决方案:加入–privileged 参数,注意要加在前面,不能追加到末尾
docker run -ti –privileged 0705b9e24c78 /bin/bash
启动参数
挂载
简写:docker run -ti -v 宿主机目录:容器内目录
完整:docker run -ti –volume 宿主机目录:容器内目录
比如:
docker run -ti -v /data/dir1:/data1/dir1 -v /data/dir2:/data1/dir2
这一篇文章很详细:https://www.cnblogs.com/ivictor/p/4834864.html
修改挂载的宿主机的文件,docker 里面是可以马上生效的。
MySQL 数据持久化到宿主机
1 | |
参考:https://blog.csdn.net/lvbian/article/details/83030308
容器退出时自动重启
docker run -ti –restart=[always|on-failure:10|unless-stopped|no]
no,默认策略,在容器退出时不重启容器
on-failure,在容器非正常退出时(退出状态非 0),才会重启容器
on-failure:3,在容器非正常退出时重启容器,最多重启 3 次
always,在容器退出时总是重启容器
unless-stopped,在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器
容器与主机之间的数据拷贝-docker cp
1 | |
OPTIONS 说明:
1 | |
存储
查看硬盘信息
1 | |
修改 docker 存储目录
参考这个文章:https://blog.csdn.net/kevinsingapore/article/details/89175398
优化镜像大小
可以使用 docker-squash 这个工具:
https://github.com/jwilder/docker-squash
http://jasonwilder.com/blog/2014/08/19/squashing-docker-images/
1 | |
如果 docker 宿主机内存较小,建议手动设置 TMPDIR:
1 | |
很奇怪,我通过 docker-squash 对镜像进行精简后,发现最终导入的镜像大小并没有改变,是我哪里弄错了么?
PS:docker build 有个–squash 参数,可以将多个 layer 整合为一个,以实现精简镜像大小的目的,这个待尝试。
另外合并 RUN 命令也是一个方案,待尝试。
DEBUG
获取容器/镜像的元信息
docker inspect [OPTIONS] NAME|ID [NAME|ID…]
OPTIONS 说明:
-f :指定返回值的模板文件。
-s :显示总的文件大小。
–type :为指定类型返回 JSON。
关于 Go 模板的应用:https://88250.b3log.org/docker-inspect-template-magic-chinese
常见报错
内核版本问题
我遇到过这个问题:制作的 docker 镜像,在有的机器上能跑起来,但是有的机器上,docker run 报如下错误:
1 | |
问了下云平台的同事,反馈可能是内核版本的问题,需要升级内核。
RUN 执行 source 命令报错
docker 默认应该是用的/bin/sh,和/bin/bash 有些差异,我们改为明确指定使用/bin/bash 即可:
1 | |
网上的说法:
sh 不支持 source
bash 支持 source
1 | |
或
1 | |
另外注意:对于环境变量文件/etc/profile 不起作用。
容器启动日志报错:unable to exec import: Argument list too long
(误)一般是内存不足导致的,申请容器扩容。
内存扩容了还是出现这个问题。后来发现,是因为这个报错才导致内存不停增长的,并不是因为内存增长才报错的。
后来尝试给容器加上 read 检查,期望通过自动重启修复,无效。
联系运维,反馈可能是文件多的缘故,他删除了 core.113 文件/目录,再手动重启,就 OK 了。但是我感觉应该和文件数没关系。
Mac 系统
在 M 芯片的 Mac 电脑上,使用 docker pull 拉取镜像时,会默认拉取 arm 架构的镜像,而不是 x86 或 amd64 架构的镜像。
https://zhuanlan.zhihu.com/p/713118127
有 2 个解决方案:
方案一:设置环境变量DOCKER_DEFAULT_PLATFORM
1 | |
方案二:docker pull 时指定 platform
1 | |
教训
直接将新镜像存为现有镜像的名称
修改了一点东西,以为没问题,结果出问题了。然后因为我直接覆盖了老镜像,导致无法回滚。
没有弄清楚 s6、Dockerfile 命令、CMD 命令的执行顺序
导致的问题就是一些脚本命令没有执行,比如 nginx 的配置没有拷贝。
执行顺序如下:
1 | |
几个知识点:
1、init 是在 Dockerfile 中常规命令之后、非 CMD 命令之前执行的,因为这是在新构建的容器起来之后执行的
2、CMD 命令是最后执行的
所以:
1、init 中不能执行挂起操作,否则会导致 nginx 配置拷贝不执行
2、CMD 的 bootstrap 中执行挂起操作