一、常用命令
1、基础命令
查看 docker 信息:docker info
查看 docker 版本:docker version
查看 docker 镜像、容器、卷数量及大小:docker system df
删除无用的镜像、容器、网络、卷:docker system prune
2、镜像命令
2.1 查看镜像
docker images 语法:
docker images [OPTIONS] [REPOSITORY[:TAG]]
不指定标签,则默认latest
,如 docker images hello-world:latest
列出本地镜像:docker images
列出包含中间映像层的所有镜像:docker images -a显示完整摘要信息,完整的 image id:docker images --no-trunc
docker images 列出的信息有限,推荐用 docker hub 查看(请看后文扩展介绍)。
2.2 镜像搜索
搜索 mysql 镜像:docker search mysql
star 大于 600:docker search -f stars=600 mysql
只列出自动构建的镜像(automated=OK):docker search --filter=is-automated=true mysql显示完整描述:docker search --no-trunc mysql
上面提到的自动构建,指的是该镜像在 docker hub 上设置了自动构建(dockerfile),基于一个源代码仓库(如 Github),当代码发生变动时,docker hub 会自动拉去最新的代码并构建一个新的镜像。我们可以通过其 dockerfile 了解到里面包含的组件,是基于 ubantu 还是基于其他 unix-like 风格系统构建的。
不过我不关心这个,所以上面的命令用了删除线,表示不重要。
2.3 镜像下载
docker pull 语法:
docker pull [OPTIONS] [REPOSITORY[:TAG]]
下载 redis 最新镜像:docker pull redis
下载指定版本的 MySQL 镜像:docker pull mysql:5.7
2.4 镜像删除
删除 redis 镜像:docker rmi redis
强制删除(针对存在运行中的容器):docker rmi -f redis
一次删除多个:docker rmi -f redis tomcat nginx
删除本地所有镜像:docker rmi -f $(docker images -q)
2.5 镜像构建
很少用,一般用于 github 项目 dockerfile 构建的场景。
# 1、编写 dockerfile
vi /docker/dockerfile/mycentos
# 2、构建镜像(-f:文件路径 -t: tag)
docker build -f /docker/dockerfile/mycentos -t mycentos:1.1
三、容器命令
3.1 新建/创建容器
-p, --publish: 宿主机端口:容器端口
-d, --detach: 分离, 表示后台运行容器,并输出 container-id。和 -t 互斥
-v,--volumn:挂载卷,必备,用于容器内外共享数据
-e: 环境变量,常用于设置容器内的时区变量,一般也是需要的
--start=always:容器随着 docker 重启一起重启。推荐
--privileged=true: 当你不是使用 root 用户使用 docker,这很重要。让你在容器内的 root 拥有真正的 root 权限,否则容器内的 root 只是外部普通用户权限,进入容器内会发现一些 root 命令执行不了。还有一点 ls 看到文件的权限符号都是问号
?
。遇到 tomcat 某些版本不加此命令 docker run 跑不起来。--log-opt max-size=500m --log-opt max-file=3: 设置每个日志最大500M, 最多保留3个
--memory=4g,-m=4g:限定容器可以使用的总内存空间, 比如限定 gitlab 4G。
--memory-swap=4g:交换大小, 一般不设置。
--name:容器名,不指定会随机生成一个。下面示例,run 最后的 tomcat 是镜像名, 等价于 tomcat:latest
-it,--interactive, --tty:前者表示容器打开标准输入(STDIN),可以交互了,即使没有附加终端;后者表示用伪终端 tty 链接到容器,可以用过命令行进行交互。-it 必须同时存在,只有 -t 开了终端,没有 -i 输入命令不会有反应
-id,后台运行,常用于 ubuntu 等基础容器创建,没有 -i 容器启动立即停止。
1、-i 可以保证一些没有守护进程的容器不关闭,比如 tomcat 可以不用 -i,但是 ubuntu 不用 -i 容器跑起来马上就退出了。
2、-t 前台伪终端运行,和后台运行 -d 互斥。
3、-t 跑起来的容器,exit 退出后会停止容器,需要另外 docker start 才能实现 -d 效果后台运行。简单示例:
tomcat 后台运行:-d = -t + 终端 exit + docker start
ubuntu 后台运行:-id = -it + 终端 exit + docker start
示例一:创建 tomcat 容器:
$ docker run --name tomcat -p 8080:8080 -v /volume/tomcat/data/:/usr/local/tomcat/webapps -v /volume/tomcat/upload/:/usr/local/tomcat/upload -v /etc/localtime:/etc/localtime:ro -e TZ="Asia/Shanghai" --restart=always --privileged=true -d tomcat
# 这样也能创建容器。退出, docker start 保持后台运行(不推荐)
docker run -t tomcat
示例二:创建 ubuntu 容器:
docker run -id --name ubantu ubuntu:latest
// run 后会打开前台终端, exit 退出终端, 需要 docker start 才能保持后台运行
docker run -it --name ubantu ubuntu:latest
3.1.1 创建一次性的容器
用于一次性任务或者临时测试,--rm 表示退出删除容器
下面讲的 container-ip 的获取,请看 3.7 其他容器命令
# -it 开了一个伪终端, 使用当前终端, ctrl + c 退出. 当前终端效果等同 tail cata..log
# 使用 http://container-ip:8080 访问, 示例: http://172.17.0.2:8080
$ docker run -it --rm tomcat:8.0
# 使用 bash 新开一个伪终端, 并且登录进去 (推荐). exit 退出, 容器销毁.
$ docker run -it --rm tomcat:8.0 bash
# 一次性 ubuntu 容器
docker run -it --rm ubuntu
3.2 启、停、重启容器
docker start tomcat
docker stop tomcat
docker restart tomcat
3.3 查看容器
查看正在运行的容器:docker ps
查看所有容器:docker ps -a
查看完整的 container_id:docker ps --no-trunc
3.4 查看容器日志
# 1、查看日志(常用)
# 参数: -f, follow, 跟踪日志输出; -t, 显示时间戳; --tail, 从最后的n条数据开始列出
# 对于大日志 tail 很重要, 没有 tail 是从日志最开始往下刷屏, 刷半天都刷不到最新的日志
docker logs -f -t --tail=20 tomcat
# 查看指定时间段日志
docker logs --since="2022-01-01T09:00:37" --until "2022-01-05T16:23:37" tomcat
# 查看最近 30分钟日志
docker logs --since 30m tomcat
# 查看指定时间点后的10条数据
docker logs --since="2022-01-01" --tail=10 tomcat
3.5 进入容器
# -i, 保持 stdin 开放, 这允许您与容器交互; -t, terminal 表示分配一个伪终端
# 表示在名为 tomcat 的容器内部启动一个交互式的 bash 会话
docker exec -it tomcat /bin/bash
# 退出
exit
3.6 删除容器
删除一个已停止的容器:docker rm tomcat
删除一个运行中的容器:docker rm -f tomcat
删除多个容器:docker rm -f ${docker ps -a -q}
删除容器和挂载卷:docker rm -v tomcat
3.7 其他容器命令
# 获取容器元信息
docker inspect tomcat
# 获取容器 ip (如 127.17.0.2, 容器之间互通使用)
# --format, -f: 基于 docker inspect 对应 json 的数据提取
docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql
# 除了 volume, 宿主机通过 docker cp 命令实现容器内外数据传输
# 一般还是用 volume, 比较灵活, 特别是容器间数据共享必须用 volume
docker cp /home/1.sql mysql:/home/tmp/1.sql
docker cp mysql:/home/tmp/1.sql /home/1.sql
四、扩展
4.1 容器内部时间错误
date、date -R 验证服务器时间和时区,两个都 ok 才行。
时间错误,一般是没有指定时区导致的,针对容器创建前、创建后有不同的解决方案。主要有下面三种:
(1)推荐,创建容器时执行
一般创建容器后,验证时区发现错误,旧的镜像就没有必要存在了。重新创建,然后指定时区解决问题。
docker run --name tomcat -v /etc/localtime:/etc/localtime:ro -e TZ="Asia/Shanghai" ..
一般应用配置 TZ="Asia/Shanghai"
即可。
但是有些应用会读取 localtime,比如 crontab,所以最好加上 localtime 的挂载,ro 表示 read-only 容器内只读。阿里云的 localtime 默认是 CST+8,如果是自己虚拟机搭建的,会是默认的 UTC0,要用后面的指令设置时区为上海。
只设置 localtime 也是不行,比如 tomcat,必须配置 TZ="Asia/Shanghai"
,不然日志的时间还是错误的。
# timedatectl 是 systemd 的一个工具, 容器 linux 系统追求轻量化, 一般是不包含 systemd 的
timedatectl list-timezones
# 设置时区为上海
timedatectl set-timezone Asia/Shanghai
(2)容器运行中(补救)
1、docker cp /etc/localtime [容器ID或者NAME]:/etc/localtime
2、不存在则新建: echo "Asia/shanghai" > /etc/timezone
3、docker cp /etc/timezone tomcat:/etc/timezone
(3)针对 Dockerfile,镜像生成之前(用不上)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/TZ /etc/localtime && echo TZ > /etc/timezone
基于 ubuntu 容器的时间调整
上述方案,测试使用的容器都是基于 debain 的,实测 ubuntu 容器不生效。
安装 tzdata 可解决。
# 安装过程需要选择地区, 选择 Asia, 选择 Shanghai
apt-get install tzdata
4.2 容器日志过大
公司运行了 gitlab 容器,但是创建之初没有限制日志的大小,过了两年日志大小膨胀到了 30G+ 导致磁盘不足,docker 也随之宕机。
(1)删除日志(补救,临时解决)
使用命令:
du -sh /*
find / -type f -size +100M -print0 | xargs -0 du -h | sort -nr
逐个目录执行,最终定位到是/var/lib/docker/containers/{container_id}
下存在大日志文件*-json.log
,重置日志大小:
echo "" > xxx.log
cat /dev/null > xxx.log
(2)docker run 指定(个性化,针对单容器)
某些应用对日志需求高,全局配置的日志配置可能不适合,可使用此方案。
# max-size 单个文件大小 max-file 最大文件个数
docker run -it --log-opt max-size=500m --log-opt max-file=3 tomcat
(3)全局配置(推荐、已创建容器不生效)
注意:已创建容器不生效,要彻底解决只能销毁容器重新创建。不能销毁只能定期清除了。
创建或修改文件/etc/docker/daemon.json
,并增加以下配置:
vi /etc/docker/daemon.json
{"registry-mirrors": ["https://registry.docker-cn.com"],
"log-driver":"json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 创建容器后验证日志配置
docker inspect gitlab
docker inspect -f '{{.HostConfig.LogConfig}}' 容器名
4.3 docker hub
docker hub 是全世界最大的 docker 镜像仓库,地址:https://hub.docker.com/
需要魔法才能访问
如何使用:比如搜索我们常用的 tomcat,点击进入,切换 Tags,搜索框输入 9。
可见 tomcat 9 支持 java8 的版本有:
9.0.89-jre8-temurin-focal
9.0.89-jre8-temurin-jammy
9.0.89-jre8-temurin
9.0.89-jre8
9.0.70-jdk8-temurin-jammy
...
看 Digest 可知,jre-jammy、jre-temurin、jre8 是一样的。
jammy、focal 是 ubuntu 的版本代号,focal 是 20.04,jammy 是 22.04。
temurin 表示用了 Eclipse 基金会维护的 temurin openjdk。其实都差不多。
jdk 包含完整的 java 开发工具包,包含编译器(javac)、jre 等工具,适用于在容器中编译、调试和开发的场景,jdk 镜像一般比较大;jre 只包含运行时环境,体积较小,适用于只运行程序的情况(暂时没有 linux 开发的习惯,jre 比较适合我)。
我们点击 copy 复制想要 pull 的镜像,如
# 很多 tag images, mirror 镜像站没有, 包括下面的命令
# 不一定是镜像站没有, 2024/6/7 这几日镜像站集体崩溃, 只有几个站点能用, 过几天再看
docker pull tomcat:9.0.89-jre8
# 验证过南京大学、阿里云镜像站是有的,推荐。tag 对应 tomcat 10 和 jre 8.
docker pull tomcat:jre8
4.3.1 为什么不用最新版,docker pull tomcat ?
最新版本是 tomcat 10 + jre17↑ 才能跑。旧的项目扔进新版 tomcat 里面根本启动不了,所以不用最新版,这也是 tag 搜索的意义。