Docker的常用操作
介绍
- 这里列出本人常用的docker操作
- 部分图片来源网络
- 本教程所有内容均在Ubuntu上操作,正常情况下所有Linux系统基本通用
- 本教程若未说明,全部是在root用户下执行命令,如果是普通用户执行,则需要在命令前面添加sudo进行提权,这里不细究
配置相关
Docker的配置文件是/etc/docker/daemon.json
,如果没有则手动创建即可,创建后重启docker进行生效:systemctl restart docker
该配置文件是josn格式,这里举例常用的个别配置,其他配置去官网或者找其他教程
1 | { |
说明:
字段 | 说明 |
---|---|
experimental | 该参数可以使docker拉取其他架构的镜像,一般用不到 |
registry-mirrors | 配置镜像源,但从2024-06-06开始,国内镜像加速服务逐步停止,只能用魔法了 可以参考这位大佬的帖子Docker Hub 镜像加速器 |
proxies | 配置代理,但是注意只有Docker engine版本在23.0以及之后才支持这个参数 如果需要使用socks5的代理,只需要将代理链接改成socks5即可,详见参考 |
data-root | 配置docker的数据目录,如果不设置,默认为/var/lib/docker |
基本操作
这里用ubuntu的系统镜像举例
- 查看docker生效的信息
docker info
- 搜索镜像
docker search ubuntu
- 拉取/下载/更新镜像
docker pull ubuntu
这里注意:更新镜像同样使用这个命令,并且如果有新镜像被下载后,旧的latest版本镜像的版本号会变为<none>
这种情况下只需要停掉已经拉起的镜像,然后通过id号删除该旧镜像即可,然后再拉起新的镜像使用 - 删除镜像
docker rmi ubuntu
注意:删除镜像前提是当前没有拉起该镜像,也就是没有这个镜像对应的实例才可以删除。当然也可以使用-f
参数强制删除docker rmi -f ubuntu
- 运行镜像/拉起镜像实例
通过latest版本的ubuntu镜像创建名为ubos的镜像实例并运行,而且使用/bin/bash/
进入该镜像命令行docker run -it --name ubos ubuntu:latest /bin/bash
通过latest版本的ubuntu镜像创建名为ubos的镜像实例并运行,而且放在后台运行docker run -d --name ubos ubuntu:latest
其他常用参数:- -v 绑定文件或者文件夹,例如
-v /opt:/mnt
会将系统上/opt目录和镜像实例里的/mnt目录做绑定
该参数为强绑定,如果双方没有对应目录/文件则会强制创建该目录/文件
与其对应的弱绑定为--bind
参数,用法相同,但是没有对应目录会报错 - -p 绑定/映射端口
- -v 绑定文件或者文件夹,例如
- 更新实例参数
如果在创建镜像实例的时候写错了或者忘记设置参数,可以通过update
命令进行更新参数
例如更新--restart
参数docker update --restart=always ubos
PS:这里列举下restart
参数的值- no 默认值,当实例退出后不会重启该实例,例如重启系统后不会自动拉起
- on-failure[:time] 如果实例是异常退出,也就是返回状态为非0,则会重启容器,后面time是可选的重启次数,超过一定次数后则不会再尝试拉起
- always 当实例退出后会再次拉起,当然如果是手动退出,则会在下次docker启动时自动拉起
- unless-stopped 与always类似,但是区别是如果手动退出,下次docker启动时就不会去拉起
- 查看当前运行的镜像实例
docker ps
查询创建的镜像实例的iddocker ps -q
查看创建的所有镜像实例docker ps -a
- 停止镜像实例
docker stop ubos
- 启动镜像实例
docker start ubos
- 进入当前正在运行的镜像实例
docker exec -it ubos /bin/bash
- 删除镜像实例
docker rm ubos
如果没有停止镜像实例,则无法直接删除,可以通过-f
参数进行强制删除docker rm -f ubos
高级操作
代理配置
因为国内网络环境的原因,在docker中需要下载各种组件有时候会异常艰难,如果需要配置docker走代理,可以按如下操作
这里存在三种场景:
- Docker自身代理 用来拉取镜像
- Container内容器代理 容器内特殊网络访问
- docker build代理 创建镜像时期的代理
这里有两种配置方法,配置到service
服务里或者写入docker的配置文件里,二选一即可
配置到
service
服务里- 首先创建一个服务目录
1
sudo mkdir -p /etc/systemd/system/docker.service.d
- 创建一个配置文件
/etc/systemd/system/docker.service.d/http-proxy.conf
并写入内容1
2
3
4[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=https://proxy.example.com:3129"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"修改配置文件后需要刷新配置和重启docker服务生效
1
2sudo systemctl daemon-reload
sudo systemctl restart docker可以通过这个命令进行检查
1
sudo systemctl show --property=Environment docker
- 首先创建一个服务目录
写入docker的配置文件里
配置文件是/etc/docker/daemon.json
1
2
3
4
5
6
7{
"proxies": {
"http-proxy": "http://proxy.example.com:3128",
"https-proxy": "https://proxy.example.com:3129",
"no-proxy": "*.test.example.com,.example.org,127.0.0.0/8"
}
}修改配置文件后需要重启docker服务生效
1
sudo systemctl restart docker
容器内可以按照容器自身的方式配置代理,也可以通过docker来配置代理
需要配置~/.docker/config.json
,以下配置,只在Docker 17.07及以上版本生效
1 | { |
配置完成后对下次拉起的容器生效
创建docker镜像时一些场景也需要特殊网络,可以通过参数进行解决
1 | docker build . \ |
无论是 docker run 还是 docker build,默认是网络隔绝的。如果代理使用的是 localhost:3128 这类,则会无效。这类仅限本地的代理,必须加上--network host
才能正常使用。而一般则需要配置代理的外部IP,而且代理本身要开启 Gateway 模式。
部分查询操作
- 查看镜像实例的日志
docker logs ubos
- 查看镜像的架构信息
docker image inspect ubuntu | grep Arch
下载其他架构的镜像
这里有个前提,就是配置文件中必须配置experimental
参数为true才能下载其他架构的镜像
确认参数没有问题后通过--platform
来指定架构
- 下载x86_64架构的ubuntu镜像
docker pull --platform linux/amd64 ubuntu:latest
- 下载arm64架构的ubuntu镜像
docker pull --platform linux/arm64 ubuntu:latest
镜像的导出和导入
这里用ubuntu的最新版本举例:ubuntu:latest
导出
- 导出镜像打包为tar文件
docker save -o out_ubuntu.tar ubuntu:latest
- 然后得到的tar文件就是导出的镜像,可以通过压缩命令缩小其体积
导入
- 将导出的tar包镜像导入到docker
docker load -i out_ubuntu.tar
制作镜像
通过Dockerfile创建镜像
通过Dockerfile的方式创建镜像在这里不细说,网上教程非常多,这里因为完整性列出来常用命令:
指令 | 含义 |
---|---|
FROM 镜像 | 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
MAINTAINER 名字 | 说明新镜像的维护人信息 |
RUN 命令 | 在所基于的镜像上执行命令,并提交到新的镜像中 |
CMD [“要运行的程序”,“参数1”,“参数2”] | 指令启动容器时要运行的命令或脚本 |
ENTRYPOINT [“要运行的程序”,“参数1”,“参数2”] | 与CMD相似,但是只能有一个并且不会被docker run命令行参数覆盖 |
COPY 源文件/目录 目标文件/目录 | 将本地主机上得文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中 |
ADD 源文件/目录 目标文件/目录 | 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL |
ENV 环境变量 变量值 | 设置一个环境变量的值,会被后面的RUN使用 |
ARG | 定义构建时的变量,可以通过 –build-arg 参数传递 |
EXPOSE 端口号 | 指定新镜像加载到Docker时要开启端口 |
VOLUME [“目录”] | 在容器中创建一个挂载点 |
USER 用户名/UID | 指定运行容器时的用户 |
WORKDIR 路径 | 为后续的RUN、CMD、ENTRYPOINT指定工作目录 |
ONBUILD 命令 | 指定所生成的镜像作为一个基础镜像时所要运行的命令 |
HEALTHCHECK | 健康检查 |
LABEL 标签 | 为镜像添加元数据信息 |
这里说明下什么情况下会创建新层级
结论:只有修改了文件系统的命令才会产生新的镜像层
比如 ADD 命令是添加文件到镜像中,肯定修改了文件系统,所以它会创建新层
而CMD、LABEL等只修改镜像元数据的命令均不会创建新的镜像层
简单理解可以说是导致镜像里操作文件的命令就会创建新层级
创建建议:
- 因为层级关系,每多一层会导致镜像体积增大,所以尽可能的要减少触发层级命令,比如同一类执行的命令尽可能全部写在一条
- 可以通过命令删除不用的内容来减少体积
以创建samba镜像为例
1 | FROM ubuntu |
通过现有的实例创建镜像
该方法一般用途是已经拉起来了实例,然后在实例里做了写特有的修改配置,接着要创建成自己的新镜像方便使用
- 如何拉起镜像并且操作这里不赘述
- 将实例提交成新的镜像
docker commit [参数] 实例id或者实例名称 新镜像名称:版本
这里的选项可以有- -m 说明
- -a 作者
- -p 生成镜像过程中停止实例的运行
例如将ubos提交成新的myub,并且是最后版本docker commit ubos myub:latest
通过iso来创建镜像
这个方法如果你不懂linux,估计会遇到各种问题,加油!
- 与其说是通过iso来创建,不如说是通过当前系统来创建
- 其本质是将当前系统重要目录打包成tar文件,然后通过
import
命令做成镜像 - 操作方法:
- 如果是iso,则需要从iso启动,用iso的好处是没有冗余文件,体积比较小(但是和官方镜像比起来还是大很多)
- 然后创建一个目录,将根分区挂载到这个目录下(这里要注意如果你的usr、var等关键分区是单独的,则也需要挂载过去)
mkdir sysdir
mount /dev/xxx sysdir
这里的xxx就是你的根分区对应的设备 - 然后通过
tar
命令将该目录打包tar -cpf mysys.tar --directory=./sysdir .
- 接着将该tar包导入docker做成镜像
cat mysys.tar | docker import - mysys:latest
通过该方式中间同样有很多灵活性,比如可修改自己任何文件,也可以删除不必要的内容以减少体积
当然也可以直接使用大佬们的脚本进行创建
github contrib
注意事项
- 权限问题:
如果正常进入docker实例进行操作报错没有权限,可以通过--privileged=true
参数进行提权