一、镜像命令
1.列出本机上的镜像
docker images
参数:
- -a 列出本地所有(默认隐藏了中间状态的镜像)
- -q 只显示镜像ID
- --digests 显示镜像的摘要信息
- --no-trunc 显示完整的镜像信息
2.搜索镜像
docker search <image_name>
参数:
- -s 列出收藏数不小于指定值的镜像(-s 30 收藏数大于30的)
- --no-trunc 显示完整的镜像描述
- --automated 只列出automated build类型的镜像
3.下载镜像
docker pull <image_name>[:tag]
如果不指定tag,则下载latest版本
4.删除镜像
docker rmi <image_name>[:tag]/<image_id>
- 强制删除单个
docker rmi -f <image_id>
或docker rmi --force <image_id>
- 删除多个
docker rmi <image_id> <image_id>
- 删除全部
docker rmi $(docker images -qa)
- 删除所有未使用的镜像
docker image prune -f -a
- 删除空悬镜像(
<none>
)(dangling images) ,高版本docker image prune
低版本docker rmi $(docker images -f "dangling=true" -q)
- 删除指定标签的镜像
docker rmi $(docker images | grep "1.0" | awk '{print $3}')
5.导出镜像
docker save -o demo.tar demo:1.0
6.导入镜像
`docker load -i demo.tar
7.打标签
docker tag old_image:old_tag new_image:new_tag
二、容器命令
有镜像才能创建容器,这是根本前提
1.新建容器
docker create <image_name>[:tag]/<image_id>
例如:
docker create --name busybox_1 busybox:1.35.0
参数:
- -t 为容器重新分配一个伪输入终端
2.新建并启动容器
docker run <image_name>[:tag]/<image_id>
例如:
docker run -it --name mycentos0 centos
docker run -it -p 8888:8080 tomcat
docker run -itd --name busybox_1 busybox:1.33.1
-e TZ=Asia/Shanghai
设置中国时区
参数:
--name <container_name>
为容器指定一个名称- -d 后台运行容器,并返回容器ID,也启动守护式容器
- -i 以交互模式运行容器,通常与-t同时使用
- -t 为容器重新分配一个伪输入终端,通常与-i 同时使用
- -P 随机端口映射
- -p 指定端口映射,有四种格式
ip:host_port:container_port,ip::container_port,host_port:container_port,container_port
- -v或--volume 添加数据卷
- -e 设置环境变量
- –net或--network 连接到指定网络
- --ip 指定 ip
- -h或--hostname 指定容器的hostname(修改/etc/hostname)
--link <container-name/container-id>:alias
添加链接到另一个容器(添加到/etc/hosts) 例:--link=nginx_80:nginx_host
- --add-host (添加到/etc/hosts) 例:
--add-host www.abc.com:127.0.0.1
- --privileged 使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限
-u或--user <user>或--user <user>:<group>
执行命令的用户名或者ID- --cpus 最大使用CPU核数
- -m或--memory 最大内存
- --memory-swap 交换内存,-1 表示无限制
- --restart=always 在容器退出时总是重启容器
- --restart=no 默认策略,在容器退出时不重启容器
- --restart=on-failure 在容器非正常退出时(退出状态非0),才会重启容器
- --restart=unless-stopped 在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
- -w 指定工作目录
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
docker run -it -v /myDataVolume:/dataVolumneContailner 镜像名
对于已经启动的容器,设置开启自启动
docker update --restart=always <container_name>/<container_id>
注:查看容器内存情况,free -h
,容器和宿主机显示的一样,因为 free -h
本质上是读取 /proc/meminfo
文件内容,可使用 docker stats --no-stream
查看
主机层没有开启 swap ,容器运行时无论怎么设置 --memory-swap,都不会使用到 swap,容器最大能使用的内存等于设置的内存限制;
docker run的退出状态码如下:
- 0,表示正常退出
- 非0,表示异常退出(退出状态码采用chroot标准)
- 125,Docker守护进程本身的错误
- 126,容器启动后,要执行的默认命令无法调用
- 127,容器启动后,要执行的默认命令不存在
- 其他命令状态码,容器启动后正常执行命令,退出命令时该命令的返回状态码作为容器的退出状态码
容器关闭 swap 分区:
- 启动容器时,增加启动参数--memory-swappiness=0,即可禁止容器使用swap;
- 同时,配置 --memory的值 与 --memory-swap的值 相等,也可以阻止容器使用swap:
- 宿主机执行
sudo swapoff -a
,临时关闭宿主机的 swap 分区,也临时关闭容器的 swap;
3.列出当前容器
docker ps
列出当前正在运行的容器
参数:
- -a 或 --all 列出当前所有正在运行的容器+历史上运行过的
- -l 或 --latest 显示最近创建的容器
- -n 显示最近n个创建的容器
- -q 或 --quiet 静默模式,只显示容器编号
- --no-trunc 不截断输出
- -f 或 --filter 过滤
docker ps -a --filter name=ubuntu
4.退出容器
exit
容器停止退出
ctrl+P+Q
容器不停止退出
5.启动容器
docker start <container_id>
docker restart <container_id>
6.停止容器
docker stop <container_name>/<container_id>
停止容器
docker kill <container_name>/<container_id>
强制停止容器
7.删除容器
docker rm <container_name>/<container_id>
删除所有容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
docker container prune -f
删除所有停止的容器
8.容器重命名
docker rename <old_container_name> <new_container_name>
9.查看容器日志
docker logs <container_name>/<container_id>
参数:
- -t, --timestamps 显示时间戳
- -f, --follow 跟随最新的日志打印
- --tail n 显示最后n条
- --since string 显示自某个 timestamp 之后的日志,或相对时间,如42m(即42分钟)
- --until string 显示自某个 timestamp 之前的日志,或相对时间,如42m(即42分钟)
docker logs --since 30m mysql_1
docker logs --since '2024-08-08T16:12:00.000Z' --until '2024-08-08T16:13:00.000Z' mysql_1
docker logs --since '2024-08-09T00:12:00.000' --until '2024-08-09T00:13:00.000' mysql_1
2024-08-08T01:00:00.000Z
与 2024-08-08T09:00:00.000
区别,Z 表示这个时间是按照协调世界时 (UTC) 计算的
zxm@zxm-pc:~$ docker logs --since '2024-08-08T16:12:00.000Z' --until '2024-08-08T16:13:00.000Z' mysql_1
2024-08-08 16:12:45+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
2024-08-08 16:12:46+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-08-08 16:12:46+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
zxm@zxm-pc:~$ docker logs --since '2024-08-09T00:12:00.000' --until '2024-08-09T00:13:00.000' mysql_1
2024-08-08 16:12:45+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
2024-08-08 16:12:46+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-08-08 16:12:46+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
例如:docker nginx 的 access.log 会软连接到 /dev/stdout
,才实现了在 docker logs
看日志,也就是写入 /dev/stdout
的信息,会出现在 docker 日志中
10.查看容器内运行的进程
docker top <container_name>/<container_id>
11.查看容器内部细节
docker inspect <container_name>/<container_id>
12.主机执行容器内命令
docker exec -it <container_name>/<container_id> command
例:docker exec -it <container_name>/<container_id> ls
13.进入正在运行的容器
docker exec -it <container_name>/<container_id> /bin/bash
docker attack <container_name>/<container_id>
docker exec -it -u root <container_name>/<container_id> /bin/bash
-u root
以 root 进入容器
attach 直接进入容器启动命令的终端,不会启动新的进程
exec 是在容器打开新的终端,并且可以启动新的进程
14.提交
提交容器副本使之成为一个新的镜像
docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]
15.拷贝
docker cp 容器ID:容器内路径 目的主机路径
16.统计
docker stats <container_name>
实时统计容器内存情况
docker stats --no-stream <container_name>
统计容器内存情况
zxm@zxm-pc:~$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f0af77a27b96 node3 0.03% 134MiB / 31.21GiB 0.42% 57.7kB / 164B 324kB / 24.6kB 41
a92739d831f8 node2 0.02% 135.3MiB / 31.21GiB 0.42% 58.4kB / 164B 328kB / 24.6kB 42
aed1ad426890 node1 0.02% 243.6MiB / 31.21GiB 0.76% 61.8kB / 164B 159MB / 24.6kB 42
17.导出
例如:
docker export busybox_1 -o busybox_1.tar
18.保存镜像
将运行中的容器保存为镜像
docker commit <container_name> <image_name>:<tag>
三、系统命令
1.查看 docker 所占的硬盘大小
docker system df
查看 docker 所占的硬盘大小
-docker system df -v
查看 docker 每部分占用硬盘大小
zxm@zxm-pc:~$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 27 18 13.44GB 2.482GB (18%)
Containers 23 0 13.74GB 13.74GB (100%)
Local Volumes 188 19 13.2GB 11.53GB (87%)
Build Cache 21 0 70.41MB 70.41MB
TYPE 列出了 Docker 使用磁盘的 4 种类型:
- Images 所有镜像占用的空间,包括拉取下来的镜像,和本地构建的
- Containers 运行的容器占用的空间,表示每个容器的读写层的空间
- Local Volumes 容器挂载本地数据卷的空间
- Build Cache 镜像构建过程中产生的缓存空间(只有在使用 BuildKit 时才有,Docker 18.09 以后可用)
最后的 RECLAIMABLE 这一列表示可回收的大小
2.清理空间
docker builder prune
一键清理 Build Cache 缓存命令
docker builder prune --filter 'until=240h'
清理时长更久的缓存,保留最近10天的缓存
docker system prune
自动清理空间
该指令默认会清除所有如下资源:
- 已停止的容器(container)
- 未被任何容器所使用的卷(volume)
- 未被任何容器所关联的网络(network)
- 所有悬空镜像(image)
docker system prsune -a
清理得更加彻底,可以将没有容器使用 Docker 镜像都删掉
四、网络命令
网络类型有:
- host模式 –net=host 容器和宿主机共享Network namespace。
- container模式 –net=container-name/container-id 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。
- none模式 –net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
- bridge模式 –net=bridge (默认为该模式)
1.创建网络并指定网段
docker network create -d networktype network_name
-d 参数指定 Docker 网络类型,有 bridge overlay
例如:docker network create -d bridge my-net
;
建立网络,并指定网段 docker network create --driver bridge --subnet 172.18.0.0/24 --gateway 172.18.0.1 my-net
2.查看网络
docker network ls
3.删除网络
docker network rm <network_id>/<network_name>
4.查看网络的详细信息
docker network inspect <network_id>/<network_name>
五、数据卷
数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS。数据卷 可以在容器之间共享和重用;数据卷 默认会一直存在,即使容器被删除。
注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。
1.创建数据卷
docker volume create <volume_name>
例如:
docker volume create busybox_vol_1
2.查看数据卷
docker volume ls
查看所有的数据卷docker volume inspect <volume_name>
查看指定的数据卷
3.启动一个挂载数据卷的容器
docker run -itd --name busybox_1 -v busybox_vol_1:/test/1 busybox:1.36.0
docker run -itd --name busybox_1 --mount source=busybox_vol_1,target=/test/1 busybox:1.36.0
docker run -itd --name busybox_1 --mount type=volume,source=busybox_vol_1,target=/test/1 busybox:1.36.0
容器目录不可以为相对路径
映射容器目录/test/1
(如果目录不存在则自动创建)
docker inspect busybox_1
查看容器的数据卷信息
"Mounts": [
{
"Type": "volume",
"Name": "busybox_vol_1",
"Source": "/var/lib/docker/volumes/busybox_vol_1/_data",
"Destination": "/test/1",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
]
4.映射主机目录
docker run -itd --name busybox_2 -v /data/test/2:/test/2 busybox:1.36.0
容器目录不可以为相对路径
-v
参数,会在宿主机创建目录 /data/test/2
(如果目录不存在则自动创建),映射容器目录/test/2
(如果目录不存在则自动创建),主机目录的内容会覆盖容器目录的内容
docker run -itd --name busybox_2 --mount type=bind,source=/data/test/2,target=/test/2 busybox:1.36.0
--mount
参数,需要宿主机目录存在,否则会报错
"Mounts": [
{
"Type": "bind",
"Source": "/data/test/2",
"Destination": "/test/2",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
docker run -itd --name busybox_3 -v test3:/test/3 busybox:1.36.0
若主机目录,是相对目录,则会在 docker 数据目录 /var/lib/docker/volumes
,创建目录
"Mounts": [
{
"Type": "volume",
"Name": "test3",
"Source": "/var/lib/docker/volumes/test3/_data",
"Destination": "/test/3",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
]
docker run -itd --name busybox_4 -v /test/4 busybox:1.36.0
若 -v 指定一个目录,则会在 docker 数据目录 /var/lib/docker/volumes
下,随机生成的一个目录名
"Mounts": [
{
"Type": "volume",
"Name": "7120d0b42f7825f41ef90adeba1e912f383eaab36f0ed6ef1496a95336e0629f",
"Source": "/var/lib/docker/volumes/7120d0b42f7825f41ef90adeba1e912f383eaab36f0ed6ef1496a95336e0629f/_data",
"Destination": "/test/4",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
如果你使用 Bind mounts
挂载宿主机目录到一个容器中的非空目录,那么此容器中的非空目录中的文件会被隐藏,容器访问这个目录时能够访问到的文件均来自于宿主机目录。这也是 Bind mounts
模式和 Volumes
模式最大的不同
5.删除数据卷
docker volume rm <volume_name>
删除数据卷docker volume prune
删除无主数据卷
数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v
这个命令。
六、数据目录
docker info
可以查询到数据目录的位置,默认 docker 数据目录在 /var/lib/docker
/var/lib/docker/containers
: 包含 Docker 容器的元数据和持久化数据,如容器的配置信息、日志、状态等。/var/lib/docker/volumes
: 存储 Docker 卷的数据,这些卷可以用来在容器之间共享数据或持久化数据。/var/lib/docker/images
: 存储 Docker 镜像的数据,这些镜像可以用来创建容器。/var/lib/docker/networks
: 存储 Docker 网络的数据,这些网络可以用来连接容器。/var/lib/docker/swarm
: 存储 Docker Swarm 的数据,这些数据包括集群的配置信息、状态信息等。/var/lib/docker/tmp
目录用于存储 Docker 的临时文件/var/lib/docker/overlay2
目录用于存储 Docker 的文件系统层
zxm@zxm-pc:~$ sudo ls -lh /var/lib/docker
总用量 80K
drwx--x--x 4 root root 4.0K 10月 18 2022 buildkit
drwx--x--- 24 root root 4.0K 4月 27 10:11 containers
drwx------ 3 root root 4.0K 10月 18 2022 image
drwxr-x--- 3 root root 4.0K 10月 18 2022 network
drwx--x--- 256 root root 36K 4月 28 08:56 overlay2
drwx------ 4 root root 4.0K 10月 18 2022 plugins
drwx------ 2 root root 4.0K 4月 28 08:56 runtimes
drwx------ 2 root root 4.0K 10月 18 2022 swarm
drwx------ 2 root root 4.0K 4月 28 08:56 tmp
drwx------ 2 root root 4.0K 10月 18 2022 trust
drwx-----x 56 root root 4.0K 4月 28 08:56 volumes
七、ubuntu 20.04 安装 docker
1.卸载旧版本
apt-get remove docker docker-engine docker.io containerd runc
2.设置 Docker 仓库
1)安装依赖包
apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
2)添加GPG密钥
添加 Docker 的官方 GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
如果你在阿里云上部署,可能使用阿里云的镜像源,添加阿里云的证书会更好一些。添加阿里云证书:
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
3)添加软件源
使用阿里云的软件仓库:
add-apt-repository
"deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu
$(lsb_release -cs)
stable"
也可以使用官方的软件仓库:
add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/ubuntu
$(lsb_release -cs)
stable"
3.安装 DOCKER ENGINE-COMMUNITY
apt update
apt install docker-ce
systemctl restart docker
免 sudo 运行:
usermod -aG docker $USER
八、docker 与 虚拟机
docker 容器文件系统与 host OS 是隔离的。容器镜像中的应用软件无法看到主机文件系统,除非将主机文件系统挂载为容器的卷。
base image 并不带有 linux 内核,因为容器会使用主机的内核。
之所以成为 base image,而不是 base OS,是因为 base image 中并不包括完整的 OS。而这一点,是容器与虚拟机之前的本质区别之一。那就是,容器并没有虚拟化,而是共享主机上的linux 内核。