参考文档:
- Docker 官方文档:https://docs.docker.com/reference/
镜像命令
查看镜像(docker images)
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest e6a0117ec169 7 months ago 272MB
REPOSITORY
:镜像在仓库中的名称 TAG
:镜像标签 IMAGE ID
:镜像ID CREATED
:镜像创建日期(不是获取该镜像的日期) SIZE
:镜像大小
搜索镜像(docker search)
从网络中找出需要的镜像
[root@localhost ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11997 [OK]
mariadb MariaDB Server is a high performing open sou… 4595 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 899 [OK]
# 可选项,通过搜索来过滤
--filter = STARS = 3000 搜索出的镜像是STARS>3000的
NAME
:镜像名称 DESCRIPTION
:镜像描述 STARS
:用户评价(受欢迎的程度) OFFICIAL
:是否为官方构建 AUTOMATED
:自动构建,表示该镜像是由 Docker Hub 自动构建流程创建的
拉取镜像(docker pull)
拉取镜像就是从中央仓管总下载镜像到本地
如果不声明Tag
镜像标签信息则默认拉取latest
版本,通过https://hub.docker.com搜索镜像,可以查看支持的Tag
信息。
docker pull centos # 相当于 docker pull centos:latest
通过Tag
信息,下载centos_20.04的镜像
docker pull centos:20.04
删除镜像(docker rmi)
# 删除单个镜像
docker rmi 镜像ID
# 删除多个镜像
docker rmi [镜像ID] [镜像ID] [镜像ID]
docker images -q 可以查询到所有镜像的 ID,通过组合命令可以实现删除所有镜像的操作。
docker rmi `docker images -q`
或者
docker rmi $(docker images -aq)
# 删除没用的镜像,按需更改关键字test
docker images|grep none|awk '{print $3}'|xargs docker rmi
docker images|grep test|awk '{print $3}'|xargs docker rmi
# 清除没有用到的数据卷,有重要数据要谨慎
docker volume prune
# 删除 dangling volmue
docker volume rm $(docker volume ls -qf dangling=true)
注意:如果通过了某个镜像创建了容器,则该镜像无法删除。
解决办法:先删除镜像中的容器,在删除该镜像,或者使用-f
强制删除
提交镜像(docker commit)
将已有容器创建为一个新的镜像,包含容器的所有层,包含原来的一些设置,如端口、环境变量等 比较臃肿,主要用来备份容器。
docker commit [可选参数] [容器名|容器ID]:[Tag] [新的镜像名]
参数说明: -a
:提交的镜像作者 -c
:使用Dockerfile指令来创建镜像 -m
:提交时的说明文字 -p
:在commit时,将容器暂停
导出镜像(docker save)
将指定镜像保存成tar归档文件
docker save [可选参数] [tar归档文件] [容器名|容器ID]:[Tag]
# >可指定目录
docker save [可选参数] [容器名|容器ID]:[Tag] > [tar归档文件]
可选参数: -o
:--output 保存到文件,默认为标准输出STDOUT
# 导出镜像,支持同时导出多个镜像,如果没有指定tag,则默认保存所有tag,而非latest
docker save -o images.tar image1:tag [image2:tag ...]
# 导出镜像并压缩
docker save nginx:1.20.1 | gzip > nginx_1.20.1.tar.gz
# 打包所有镜像,两条命令等同
docker save $(docker images --format "{{.Repository}}:{{.Tag}}" |tr '\n' ' ') -o k8s-images.tar
docker save $(docker images | grep -v REPOSITORY | awk 'BEGIN{OFS=":";ORS=" "}{print $1,$2}') -o k8s-images.tar
载入镜像(docker load)
通过save导出和load导入的镜像信息应该是完全一致的才对,如tag和images id都是一致的,否则报错。
# 导入镜像
docker load -i images.tar
# 导入压缩的镜像包
gunzip -c nginx_1.20.1.tar.gz | docker load
# 或者解压后再导入
tar -zxf nginx_1.20.1.tar.gz
docker load -i nginx_1.20.1.tar
# 打包指定前缀的镜像,两条命令等同
docker save $(docker images --format "{{.Repository}}:{{.Tag}}" rancher/* |tr '\n' ' ') -o rancher-images.tar
docker save $(docker images rancher/* | grep -v REPOSITORY | awk 'BEGIN{OFS=":";ORS=" "}{print $1,$2}') -o rancher-images.tar
推送镜像(docker push)
Docker Hub
- 注册
- 登录 通过执行
docker login
命令交互式的输入用户名及密码来完成在命令行界面登录 Docker Hub。
docker login
通过docker logout
退出登录。 3. 新建Tag
# 查看镜像列表
$ docker images
ubuntu:18.04 8.0.11 5dbe5b6313e1 2 years ago 445MB
# 打上Tag,username替换为自己的,这步不能跳过
docker tag 5dbe5b6313e1 username/ubuntu:18.04
- 推送
docker push username/ubuntu:18.04
- 查看
$ docker search username
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
username/ubuntu
注意:推送完成的镜像可能需要几个小时才能被搜索到
ghcr.io
GitHub 镜像仓库服务(ghcr.io)
- Github创建登陆 Token Github Container registry 需要使用 https://github.com/settings/tokens/new 页面创建的 Token 作为密码才可以推送镜像。 打开上面的链接,勾选 write:packages 和 read:packages ,repo 会自动选中,创建 Token。
下面以$PAT
代指这里的Token值。
- 登陆
echo $PAT | docker login ghcr.io --username username --password-stdin
- 新建Tag
# 查看镜像列表
$ docker images
mysql 8.0.11 5dbe5b6313e1 2 years ago 445MB
# 打上Tag
docker tag 5dbe5b6313e1 ghcr.io/username/app:1.0.0
- 推送
docker push ghcr.io/username/app:1.0.0
推送完成镜像之后,在github个人的主页packages
标签页下面,可以看到镜像列表。
构建镜像(Dockerfile)
Dockerfile是用来构建Docker镜像的一种脚本语言,它记录了构建这个镜像的步骤和过程,以及构建出来的镜像所包含的文件系统、指令和配置等信息。
Dockerfile的使用非常简单,只需要在一个文本文件中编写所需的指令,并将其保存为Dockerfile,在最顶层文件夹中构建出Docker镜像。
基本语法:.dockerignore
文件的写法和.gitignore
类似,支持正则和通配符,具体规则如下:
- 每行为一个条目;
- 以
#
开头的行为注释; - 空行被忽略;
- 构建上下文路径为所有文件的根路径;
- 文件匹配规则具体语法如下:
# comment
*/temp* # 匹配根路径下一级目录下所有以 temp 开头的文件或目录
*/*/temp* # 匹配根路径下两级目录下所有以 temp 开头的文件或目录
temp? # 匹配根路径下以 temp 开头,任意一个字符结尾的文件或目录
**/*.go # 匹配所有路径下以 .go 结尾的文件或目录,即递归搜索所有路径
# 匹配根路径下所有以 .md 结尾的文件或目录,但 README.md 除外
*.md
!README.md
下面是几个常用的Dockerfile指令:
FROM
:指定该镜像的基础镜像。 MAINTAINER
:指定该镜像的作者信息。 RUN
:在当前镜像上运行指令。 COPY
:将宿主机上的文件复制到镜像中。 ADD
:将宿主机上的文件或URL添加到镜像中。 CMD
:指定容器启动时运行的指令。 ENTRYPOINT
:指定容器启动时运行的可执行文件。 ENV
:设置环境变量。 ARG
:定义构建时的参数。 WORKDIR
:指定工作目录。 EXPOSE
:暴露容器的端口号。
编写好Dockerfile后,我们可以使用docker build命令来构建这个镜像,例如:
docker build -t myimage:1.0 .
其中,-t指定了该镜像的名称和标签,后面的myimage:1.0
就是镜像的名称和标签,最后的.表示Dockerfile所在的目录。
接着,使用docker run
命令来启动这个镜像创建的容器,例如:
docker run -it myimage:1.0 /bin/bash
其中,-it
表示使用交互式终端,并进入容器的bash shell。myimage:1.0
就是刚刚构建的镜像的名称和标签。
易混淆的dockerfile命令
COPY 和 ADD
ADD
:拷贝文件或目录到容器中,如果是URL或压缩包便会自动下载或自动解压COPY
:拷贝文件或目录到容器中,跟ADD类似,但不具备自动下载或解压的功能
ENTRYPOINT 和 CMD
ENTRYPOINT
:运行容器时执行的shell命令CMD
:运行容器时提供默认值。这些默认值可以是可执行文件,也可以省略可执行文件,省略可执行文件时必须用ENTRYPOINT为指令提供默认参数(Exec 格式);如果有多个则只有最后一个生效
ENV 和 ARG
ENV
:容器环境变量ARG
:只作用于 Dockerfile 内部的环境变量
容器命令
查看容器信息
# 查看正在运行的容器并带出历史运行过的容器
docker ps -a
# 只显示容器ID
docker ps -q
# 查看所有容器(包括运行和停止)
docker ps -f startus=exited
# 查看最后一次运行的容器
docker ps -l
# 列出最近创建的 n 个容器
docker ps -n 3
# 查看容器元信息
docker inspect [容器名称|容器ID]
# 筛选查看IP地址
docker inspect --format='{{.NetworkSettings.IPAddress}}' [容器名|容器ID]
# 查看容器cpu占用
docker stats
# 查看容器内部的进程
docker top [容器ID]
创建容器(docker run)
语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
其中,OPTIONS表示各种启动参数;IMAGE表示要运行的Docker镜像名称或ID;COMMAND表示镜像启动后要运行的命令,通常是一个可执行文件或脚本;ARG...表示命令的参数。
下面是一些常用的docker run命令参数:
-it
: 以交互式的方式启动容器,并分配一个伪终端。 --name <name>
: 为容器指定一个名称。 --rm
: 当容器退出时自动删除容器。 --net <network>
: 指定容器所属的网络,--net参数的常用取值包括:
- bridge: 表示使用默认的docker0网桥,容器可以通过主机的IP地址进行访问,但不能访问其他容器。
- host: 表示容器与主机共享同一个网络命名空间,容器可以通过主机的IP地址直接访问主机网络资源。
- overlay: 表示创建一个跨主机网络。
- none: 表示不使用任何网络,容器只拥有localhost地址。
--restart
: 用于设置Docker容器的自动重启策略,--restart参数的可选值包括: - no: 不自动重启容器。
- on-failure[:max-retries]: 在容器发生错误时自动重启,并可配置最大重试次数。
- always: 总是重启容器,包括容器正常停止和异常停止。
- unless-stopped: 在容器停止时自动重启,但不包括人工停止容器。
-p <host port>:<container port>
: 将主机端口映射到容器内的端口。例如,-p 8080:80表示将主机的8080端口映射到容器内的80端口。-v <host path>:<container path>
: 将主机的文件或目录挂载到容器内的目录。-c <command>
: 用于指定在容器内执行的命令,若命令执行失败容器会立即停止,-c "echo hello world"
:执行命令需要加引号,执行脚本不需要,如-c /bt.sh
。--entrypoint <command>
: 指定容器的启动命令。--privileged=true
: 给容器分配特权模式。
示例:
$ docker run --name test -it debian
$ docker run -it --rm ubuntu bash
$ docker run -it --privileged ubuntu bash
$ docker run -w /path/to/dir/ -it ubuntu pwd
# 挂载本地目录到容器,并指定容器的工作目录
$ docker run -v /doesnot/exist:/foo -w /foo -it ubuntu bash
# 只读挂载
$ docker run --read-only -v /icanwrite busybox touch /icanwrite/here
$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash
$ docker run --expose 80 ubuntu bash
# 指定容器环境变量
$ docker run -e MYVAR1 --env MYVAR2=foo --env-file env.list ubuntu bash
$ docker run --env VAR1=value1 --env VAR2=value2 ubuntu env | grep VAR
$ docker run --env-file env.list ubuntu env | grep VAR
# 指定容器标签
$ docker run -l my-label --label com.example.foo=bar ubuntu bash
$ docker run --label-file labels ubuntu bash
$ docker run -itd --network=my-net busybox
$ docker run --volumes-from 777f7dc92da7 --volumes-from ba8c0c54f0f2:ro -it ubuntu pwd
$ docker run -it --rm --gpus all ubuntu nvidia-smi
$ docker run --restart=always redis
# 指定hosts记录
$ docker run --add-host=docker:192.168.10.10 --rm -it alpine
# 通过host模式运行宝塔镜像,自动映射宝塔面板全端口到外网
$ docker run -tid --name baota --net=host --privileged=true --shm-size=1g --restart always -v ~/wwwroot:/www/wwwroot pch18/baota
进入与退出容器
# 进入容器后开启一个新的终端
docker exec -it [容器名称|容器ID] /bin/bash
# 进入一个容器正在执行的终端
docker attach [容器名称|容器ID]
# 退出当前容器
exit
# 容器不停止退出
Ctrl+P+Q
停止与启动容器
# 启动容器
docker start 容器ID
# 重启容器
docker restart 容器ID
# 停止当前容器
docker stop 容器ID
# 强制停止容器
docker kill 容器ID
# 停止所有容器,两条命令等同
docker stop $(docker ps -aq)
docker ps -aq |xargs docker stop
删除容器(docker rm)
# 删除指定的容器,不能删除正在运行的容器,强制删除rm -f
docker rm [容器名称|容器ID]
# 删除所有容器,两条命令等同
docker rm $(docker ps -q)
docker ps -aq |xargs docker rm
# 删除所有关闭的容器
docker rm $(docker ps -aq -f status=exited)
# 删除异常状态容器
docker ps -a |grep Exited | awk '{print $1}'|xargs docker rm
docker ps -a |grep Created | awk '{print $1}'|xargs docker rm
# 清除没有用到的数据卷,有重要数据要谨慎
docker volume prune
# 删除 dangling volmue
docker volume rm $(docker volume ls -qf dangling=true)
导出容器(docker export)
导出Docker容器的文件系统(类似于安卓里的system分区)到本地,但不包含Docker镜像、容器的元数据(比如启动脚本、环境变量等)等,因此导出后的文件无法直接用于创建新的镜像或者启动容器,一般被用于将容器的文件系统迁移到其他系统中去
# 导出容器,只能导出单个容器
docker export -o container1.tar container1
# 使用 gzip 压缩,大幅减小容器体积
docker save container1 | gzip > container1.tar.gz
导入容器(docker import)
# 导入容器
docker import container1.tar [新容器名]
文件拷贝(docker cp)
将文件拷贝到容器内
docker cp [需要拷贝的文件或目录] [容器名称:容器目录]
将文件从容器内拷贝出来
docker cp [容器名称:容器目录] [需要拷贝的文件或目录]
目录挂载(-v)
目录挂载是属于容器数据卷操作,我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,从而创建一个共享目录 文件共享,但是容器被删除的时候,宿主机的内容并不会被删除,如果多个容器挂载同一个目录,其中一个容器被删除,其他容器的内容也不会受到影响。
创建容器时添加-v
参数,格式为-v [宿主机目录]:[容器目录]
, 例如:
docker run -id -v /mydata/docker_centos/data:/usr/local/data --name centos01 centos:7
# 多个目录挂载
docker run -id -v 宿主机目录1:容器目录1 -v 宿主机目录2:容器目录2 --name 容器名 镜像名
在挂载时有可能会出现权限不足的提示。这是因为 CentOS7 中的安全模块 SELinux 把权限禁掉了,在docker run
时通过-privileged=true
给该容器加权限来解决挂载的目录没有权限的问题
匿名挂载
docker run -id -v /usr/local/data --name centos02 centos:7
匿名挂载只需要写容器目录即可,容器外对应的目录会在/var/lib/docker/volumes
中生成。
查看 volume 数据卷信息
$ docker volume ls
image-20220331113929297
具名挂载
具名挂载就是给数据卷取个名字,容器外对应的目录就会在/var/lib/docker/volume
中生成。
docker run -id -v docker_centos_data:/usr/local/data --name centos03 centos:7
指定目录挂载
最开始的挂载就是指定目录挂载,这种方式的挂载不会在/var/lib/docker/volume
目录生成内容。
docker run -id -v /mydata/docker_centos/data:/usr/local/data --name centos01 centos:7
查看目录挂载关系
通过docker volue inspect [数据卷名称]
可以查看该数据卷对应宿主机目录地址。
[root@localhost ~]# docker volume inspect centos_data
[
{
"CreatedAt": "2022-03-30T20:40:07-07:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/centos_data/_data",
"Name": "centos_data",
"Options": null,
"Scope": "local"
}
]
通过docker inspect [容器ID或名称]
,在返回的JSON节点中找到Mounts
, 可以查看详细数据挂载信息。
只读只写
只读:只能通过修改宿主机内容实现对容器的数据管理
docker run -it -v [宿主机目录]:[容器目录]:ro --name [容器名] [镜像名]:[标签]
只写:默认,宿主机和容器可以双向操作数据
docker run -it -v [宿主机目录]:[容器目录]:rw --name [容器名] [镜像名]:[标签]
继承(volumes-from)
也就是将其他一个或多个容器继承于某一个容器的挂载目录
# 容器 centos7-01 指定目录挂载
docker run -id -v /mydata/data:/usr/local/data --name centos7-01 centos:7
# 容器 centos7-02 和 centos7-03 相当于继承 centos7-01 容器的挂载目录、
docker run -id --volumes-from centos7-01:ro --name centos7-04 centos:7 # 只读
docker run -id --volumes-from centos7-01:rw --name centos7-05 centos:7 # 双向(默认)
其它命令
帮助命令
docker [命令] --help
查看日志
docker -f -t --tail
-f
:显示日志-t
:带上时间戳--tail
:显示多少条日志
显示docker的版本信息
docker version
显示docker的系统信息
镜像和容器的数量等
docker info
彻底删除未使用的容器和镜像
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 36 21 7.412GB 3.798GB (51%)
Containers 69 35 460.8MB 460.4MB (99%)
Local Volumes 8 8 141.8MB 0B (0%)
Build Cache 0 0 0B 0B
$ docker ps -a | grep Exited | wc -l
33
$ docker ps | wc -l
36
$ docker images | wc -l
38
$ docker container prune
$ docker image prune
$ docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 36 17 7.412GB 5.204GB (70%)
Containers 36 35 354.6kB 0B (0%)
Local Volumes 8 5 141.8MB 771.3kB (0%)
Build Cache 0 0 0B 0B