docker 🐋
1. docker镜像管理
- 镜像搜索
# 命令
$ docker search 镜像的名字
# 字段关键字
NAME - 镜像名字
DESCRIPTION - 镜像描述
STARS - 下载量
OFFICIAL - 是不是官方制作
AUTOMATED - 是不是自动化编译出来的,自动化:通过dockerfile制作的
- 获取镜像
$ docker pull 镜像名
- 查看镜像
# 命令
$ docker images
$ docker image ls
# 查看所有的镜像
# 细节
docker xxx ubuntu 等同于 docker xxx ubuntu:latest
写一个镜像名 == 镜像名:latest(最新的镜像)
- 镜像重命名
# 查看tag的帮助文档
$ docker tag --help
Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
# 重命名
$ docker tag ubuntu myubuntu:v1.0
- 删除镜像
# 根据id删除(注意不能删除有别名的,因为有别名的id是相同的,删除时有歧义)
$ docker rmi id
# 根据名字删除
$ docker rmi 镜像名
# 注意要加上版本号,如果不写版本号默认latest
-
镜像的导出
- 第一种 -> 基于镜像,导出镜像
Usage: docker save [OPTIONS] IMAGE [IMAGE...] $ docker save -o nginx.img mynginx # -o 后面是要生成的文件的名字 # 最后是要导出的镜像的名字
- 第二种 -> 基于容器,导出镜像,可以修改镜像
# 创建和启动容器 $ docker run -itd --name contains 镜像名(ubuntu) bash(shell命令) # 导出 $ docker export 容器名 > 导出的镜像名(随便起名) # 导入 $ cat 要导入的镜像文件名 | docker import - 导入的新镜像的名字
-
镜像的导入
# 第一种
# 命令:docker load -i 用save导出的镜像文件名
$ docker load -i nginx.img
# 第二种
# 命令:docker load < 用save导出的镜像文件
$ docker load < nginx.img
- 上面导入导出两种的区别
- 导出
- 通过export导出的时候,会将镜像中历史记录删除,但是save不会删除
- 因为文件大小发生变化,所以镜像的哈希值会发生变化
- 导入
- 通过import导入镜像的时候,给导入的镜像重命名,load不可用
- 导出
- 查看镜像的历史信息
# 制作镜像的时候的操作步骤
$ docker history 镜像名/镜像ID
- 查看镜像的详细信息
# 镜像的属性信息,以json格式输出的
# 格式说明网址:https://yq.aliyun/articles/230067
$ docker inspect 镜像名/镜像ID
$ docker inspect -f {{.}} 镜像名/镜像ID
# eg: docker inspect -f {{.ContainerConfig.Hostname}} ubuntu
# .代表当前对象
2.docker容器管理
docker将镜像文件启动,得到一个容器,一个容器可以被看作一个操作系统
2.1 容器的查看/创建/启动
- 容器查看
# 命令, 只能看到正在运行的容器的状态
$ docker ps
# 关键字
CONTAINER ID:容器启动之后的ID
IMAGE:这个容器是通过哪个镜像启动起来的,对应的镜像的名字
COMMAND:镜像启动之后,默认执行的启动命令
CREATED:容器创建的时间
STATUS:容器当前状态
- 运行
- 停止
- 暂停
PORTS:容器和宿主机对应的映射端口
NAMES:容器启动之后的名字,启动镜像的时候没有指定名字,会自动指定,是随机的
# 参数:
-a, --all:查看所有容器的状态
- 运行
- 停止
- 暂停
-q, --quiet:只显示容器ID
- 容器创建
# 容器被创建,但是还不能使用,需要启动
Usage: docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
- OPTIONS:
-i, --interactive: 创建的容器是否关联标准输入(终端操作)
-t, --tty: 是不是给这个容器分配终端
--rm: 容器被停止(关闭)之后,是否自动删除容器
--name: 创建容器的时候给容器起名,没指定就随机生成
- IMAGE: 容器是基于哪个镜像启动,指定的是镜像的名字
- [COMMAND] [ARG...]
容器启动之后,指定一个默认执行的shell命令,根据实际情况指定,如果不知道写什么,写bash
ls -a
pwd
-
容器启动
- 启动创建的容器
$ docker start 参数 容器名 - 参数: a:关联标准输出和标准错误 i:关联标准输入 # 应用场景 1. 容器创建之后,启动 2. 容器被关闭(停止),也就是重新启动
-
创建容器并启动
# 创建并运行容器 run == create + start
$ docker run [OPTION] IMAGE [COMMAND] [ARG...]
- OPTION:
-i, --interactive: 关联标准输入(终端操作)
-t, --tty: 给这个容器分配终端
--rm: 容器被停止(关闭)之后,是否自动删除容器
--name: 创建容器的时候给容器起名,没指定就随机生成
-d, --detach: 容器启动之后是不是一个守护进程,也就不会进入镜像终端,容器在后台运行
- IMAGE: 容器名字/容器ID
- [COMMAND] [ARG...]
容器启动之后运行搞得第一个shell命令
2.2 容器的暂停/重启
-
暂停
$ docker pause 容器名/容器ID
-
取消暂停
$ docker unpause 容器名/容器ID
-
容器重启
$ docker restart 容器名/容器ID
2.3 容器的关闭/终止/删除
-
关闭
# 延时关闭,默认10s $ docker stop 容器名/容器ID 参数: -t, --time:指定延时时间关闭容器
-
终止
# 马上关闭,不会延迟 $ docker kill 容器名/容器ID
-
删除
- 删除未运行的容器 -> 状态非 up
$ docker rm 容器名/容器ID
- 删除运行状态的容器 ->
$ docker rm -f 容器名/容器ID
- 批量删除容器
$ docker rm -f $(docker ps -a) $ docker rm -f `docker ps -a`
2.3 容器的进入/退出
-
进入容器
-
创建并进入
$ docker run -it --name 容器名 镜像名 shell命令(bash) # 不推荐使用,因为进入后再退出了它的终端,有可能这个镜像也会退出 # 这种情况要根据镜像来决定,有的镜像不会产生这种现象
-
手动进入
$ docker exec 参数 容器名 bash 参数: -i:关联标准时如遇 -t:分配一个操作终端
-
-
退出容器
如果通过exec进入到容器内部 输入:exit命令 快捷键:contrl+d
3. docker数据管理
3.0 数据拷贝
# 容器和宿主机之间的数据拷贝
$ docker cp 宿主机目录/文件 容器名/容器ID:容器路径
$ docker cp 容器 宿主机
3.1 数据卷和使用
-
数据卷:宿主机的存储目录,要将目录中的数据和docker容器进行数据共享。可以理解为一个共享目录。
-
数据卷在docker中的应用
# 挂在的时机: # 1. 容器被创建的时候 $ docker create # 2. 容器被创建并运行的时候 $ docker run # 需要添加参数 -v, --volume $ docker run -itd --name alinubuntu -v 宿主机的路径:容器的路径 ubuntu bash # 将宿主机的路径映射到容器的路径中,二者都互相共享 - 宿主机的路径:必须使用绝对路径(相对路径不会挂载成功),如果写了一个不存在的路径,会自动创建 - 容器的路径:如果不存在会被自动创建
-
权限问题
通过-v进行数据卷挂载,默认是读写的挂载方式
- 权限是限制容器的,rw
- 可以修改权限,改为只读:ro
$ docker run -itd --name alinubuntu -v 宿主机的路径:容器的路径:ro ubuntu bash
-
挂载目录
$ docker run -itd --name tmp1 -v /home/itcast/backup:/itcast:ro ubuntu bash
-
挂载文件 -> 不推荐:因为版本问题兼容性问题可能会出现共享失败的问题。
$ docker run -itd --name tmp2 -v /home/itcast/backup/abc:/itcast2/abc.sh ubuntu bash
-
3.3 数据卷容器的使用
-
数据卷容器
就是一个普通的容器,在这个容器中提供了一个挂载目录(共享目录)
- 数据卷容器只要被创建出来就可以使用
docker create
docker run
-
创建数据卷容器
$ docker create -itd --name 容器名 -v 容器的挂载目录 镜像名 shell命令 $ docker run -itd --name 容器名 -v 容器的挂载目录 镜像名 shell命令 # 当挂载目录不存在的时候就会自动创建
-
数据卷容器的挂载和使用
# 挂载数据卷容器的参数 --volumes-from 数据容器的名字/数据容器的ID # 1. 创建数据卷容器 $ docker run -itd --name containsVolume -v /itcast_bk ubuntu bash # 2. 启动测试容器1,挂载到数据卷容器 $ docker run -itd --name test1 --volumes-from containsVolume ubuntu bash # 3. 启动测试容器2,挂载到数据卷容器 $ docker run -itd --name test2 --volumes-from containsVolume ubuntu bash # 4. 测试数据是否共享 # 4.1 进入到test1容器中 $ docker exec -it test1 bash # 4.2 进入到test2容器中 $ docker exec -it test2 bash # 备份数据 # 1. 创建一个临时新容器,挂载到数据卷容器上,和宿主机目录形成映射关系 $ docker run -itd --name backup --volumes-from containsVolume -v /home/itcast/backup:/xxx ubuntu bash # 2. 进入到backup容器中 $ docker exec -it backup bash # 3. 将itcast_bk中的内容拷贝到xxx目录中即可 # 4. 删除backup容器即可 # 合并上述4个步骤进行备份 $ docker run -itd --rm --name backup --volumes-from containsVolume -v /home/itcast/backup:/xxx ubuntu tar zcpf /xxx/backup.tar.gz /itcast_bk # tar zcpf中的p:代表去掉当前文件的权限
3.4 备份数据还原到数据卷容器
# 还原数据
# 1. 创建一个临时新容器,挂载到数据卷容器上,和宿主机目录形成映射关系
$ docker run -itd --name backup --volumes-from containsVolume -v /home/itcast/backup:/xxx ubuntu bash
# 2. 进入到backup容器中
$ docker exec -it backup bash
# 3. 将xxx目录中的内容拷贝到itcast_bk目录中即可
# 4. 删除backup容器即可
# 合并上述4个步骤进行备份
$ docker run -itd --rm --name backup --volumes-from containsVolume -v /home/itcast/backup:/xxx ubuntu tar zxpf /xxx/backup.tar.gz -C /
4. docker网络管理
4.1 docker端口映射
端口映射也就是说访问宿主机的这个端口相当于访问了容器的一个端口
-
随机端口映射
# 创建启动容器的时候指定端口映射 # 在宿主机随便找一个没有哦占用的空闲端口,和容器的80端口进行映射 docker run -itd -P --name mynginx nginx
-
指定端口映射/指定多端口映射 -> 推荐
# 使用的参数 $ docker run -itd -p xxx --name mynginx nginx -p: 宿主机的IP:宿主机的端口:容器的端口 宿主机的端口:容器的端口 # 指定多个端口映射 $ docker run -itd -p 80:80 -p 81:81 --name mynginx nginx
4.2 网络管理
-
网络管理相关命令
# 如果多个docker容器想进行通信,那么这些容器必须要在同一个网络中 $ docker network --help Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network `将指定的容器加入到指定的网络中 create Create a network `创建一个网络 disconnect Disconnect a container from a network `将一个容器从一个网络中删除 inspect Display detailed information on one or more networks `查看网络详细信息 ls List networks `查看当前网络 prune Remove all unused networks `删除所有没有被使用过的网络,慎用! rm Remove one or more networks `删除一个或多个指定的网络
4.3 bridge 网络模式
-
创建bridge网络
$ docker network create -d 网络驱动的名字 要创建的网络的名字 # 网络驱动的名字默认是bridge
-
自定义网段与网关
--subnet:指定子网络的网段 --gateway:指定网关 $ docker network create -d 网络驱动的名字 --subnet 180.18.10.0/24 --gateway 180.18.10.1 要创建的网络的名字 $ docker network create -d bridge --subnet 180.18.10.0/24 --gateway 180.18.10.1 bridge_test
-
在自定义网络中启动容器
$ docker run -it --name test1 ubuntu bash --network: 指定要加入的网络 $ docker run -it --name test1 --network bridge_test ubuntu bash
-
容器断开网络
$ docker network disconnect [OPTION] NETWORK CONTAINER - OPTIONS: -f:强制执行
-
容器连接网络
$ docker network connect [OPTION] NETWORK CONTAINER # 一个容器可以同时加入到两个网络中
4.4 host网络
# 将一个容器加入到一个网络中
$ docker run -itd --name test3 --network host ubuntu bash
5. Dockerfile
5.1 Dockerfile介绍
# 构建一个基于ubuntu的docker定制镜像
# 基础镜像
From ubuntu
# 镜像作者
MAINTAINER panda kstwoak47@163.com
# 执行命令
RUN mkdir hello
RUN mkdir world
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install nginx -y
# 对外端口
EXPOSE 80
-
宿主机创建一个空目录,将上面的dockerfile文件创建出来
-
在dockerfile对应的目录中执行一个命令,构建新的镜像
$ docker build -t xxx_test:v1.0 ./
优化Dockerfile
From ubuntu
# 镜像作者
MAINTAINER panda kstwoak47@163.com
# 执行命令
RUN mkdir hello && mkdir world
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
&& sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update && apt-get install nginx -y
# 对外端口
EXPOSE 80
- 将同类的命令合并,生成的镜像会变小一点
- 原因:写的命令越多,生成的log越多,镜像也就越大
5.2 Dockerfile基础指令
-
FROM
FROM 镜像名 FROM 镜像名:tag # FROM必须要出现在Dockerfile的第一行(除去注释),可以连续写多个FROM创建多个镜像 # 如果本地仓库没有指定的镜像,那么会先pull到本地,如果远程仓库也没有则报错
-
MAINTAINER
dockerfile维护者信息 MAINTAINER 维护人员信息
-
RUN
# 构建镜像时执行的shell命令,如果命令有确认操作,必须要加上 -y # 如果命令太长需要换行,行末尾需要加 \ RUN shell命令 RUN mkdir /home/go/test -p # 用方括号括起来,引号引起来,逗号间隔 RUN ["mkdir", "/home/go/test", "-p"]
-
EXPOSE
# 设置对外开放的端口 # 在使用的时候,让宿主机和容器开放端口形成一个映射关系,就可以访问了 EXPOSE 80 $ docker run -itd -p 8888:80
5.3 Dockerfile运行指令
-
CMD
# 新镜像已经被制作完毕, 启动新镜像-> 得到一个容器 # 容器启动后默认执行的命令 # 一个dockerfile文件只能指定一个CMD指令 # 如果指定多个, 只有最后一个有效 # 该CMD会被 docker run指定的shell命令覆盖 CMD shell命令 CMD ["shell命令", "命令参数1", "命令参数2"]
-
ENTRYPOINT
# docker容器启动之后执行的命令, 该命令不会被docker run指定的shell指令覆盖 # ENTRYPOINT只能指定一个, 指定多个, 只有最后一有效 # ENTRYPOINT 和 CMD可以同时指定 # 如果想被docker run覆盖, 启动docker容器时可使用docker run --entrypoint ENTRYPOINT shell命令 ENTRYPOINT ["shell命令", "命令参数1", "命令参数2"]
-
CMD ENTRYPOINT 综合使用
docker run -itd ubuntu # 任何docker run设置的命令参数或者CMD指令的命令,都将作为ENTRYPOINT 指令的命令参数,追加到ENTRYPOINT指令之后 ENTRYPOINT mkdir /home/go/a/b/c/d/e/f CMD -p mkdir /home/go/a/b/c/d/e/f -p ls
5.4 Dockerfile文件编辑指令
-
ADD
# 将宿主机文件拷贝到容器目录中 # 如果宿主机文件是可识别的压缩包, 会进行解压缩 -> tar ADD 宿主机文件 容器目录/文件 # 实例 ADD ["宿主机文件", "容器目录"] - 宿主机文件一般放到Dockerfile对应的目录中 - 容器目录, 有可能存在, 有可能不存在 - 存在: 直接拷贝到容器目录 - 不存在: 先在容器中创建一个, 再拷贝 ADD ["a.txt", "/home/go/a.txt"] - 第二个参数如果指定的是一个文件名 - 这个文件存在: 直接覆盖 - 不存在: 直接拷贝
-
COPY
# COPY 指令和ADD 指令功能和使用方式类似。只是COPY 指令不会做自动解压工作。 # 单纯复制文件场景,Docker 推荐使用COPY COPY ["a.tar.gz", "/home/"]
-
VOLUME
# 数据卷容器创建, 挂载点为/backup docker create -it --name contains -v /backup ubuntu bash # 其他容器挂载到数据卷容器上 docker run -itd --volumes-from contains ubuntu bash # VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点 # 通过VOLUME 指定挂载点目录是自动生成的。 VOLUME ["/data"]
5.5 Dockerfile环境指令
-
ENV
环境变量:
- 系统级别
- 用户级别
环境变量名大写
Linux: env
# 设置环境变量,可以在RUN 之前使用,然后RUN 命令时调用,容器启动时这些环境变量都会被指定 ENV <key> <value> (一次设置一个环境变量) ENV <key>=<value> ... (一次设置一个或多个环境变量) ENV HELLO 12345 ENV HELLO=12345 ENV HELLO=12345 WORLD=12345 NIHAO=12345 ENV MYPATH=/a/b/c/d/e/f/g/h/....../z mkdir /home/go $MYPATH
-
WORKDIR
# 切换目录,为后续的RUN、CMD、ENTRYPOINT 指令配置工作目录。相当于cd # 可以多次切换(相当于cd 命令), # 也可以使用多个WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。 WORKDIR /path/to/workdir RUN a.sh WORKDIR /path WORKDIR /bin/abc WORKDIR to # 相对路径 /bin/abc/to WORKDIR workdir # /bin/abc/to/workdir RUN pwd /bin/abc/to/workdir # 可执行程序 a.out # 现在在家目录下 ./a.out # 工作目录进行了切换 WORKDIR /home/go/test/work ./a.out
-
USER
# 指定运行容器时的用户名和UID,后续的RUN 指令也会使用这里指定的用户。 # 如果不输入任何信息,表示默认使用root 用户 USER daemon # /etc/passwd 文件的第一列就是用户名
-
ARG
# ARG 指定了一个变量在docker build 的时候使用,可以使用--build-arg <varname>=<value>来指定参数的值。 ARG <name>[=<default value>] #dockerfile写好之后 docker build -t 镜像名:镜像tag dockerfile的存储目录
5.6 Dockerfile触发器指令
-
ONBUILD
# 当一个镜像A被作为其他镜像B的基础镜像时,这个触发器才会被执行, # 新镜像B在构建的时候,会插入触发器中的指令。 ONBUILD [command] # 原始镜像 -> 纯净版 -> 修改 ONBUILD ["echo", "hello,linux"] # 基于原始镜像制作新镜像 -> 镜像A -> 启动镜像A -> 不会输出hello, linux # 基于镜像A制作了镜像B -> 启动镜像B -> 会输出 hello, linux
5.7 Dockerfile构建缓存
构建新镜像的时候不使用缓存机制
docker build -t 新镜像名:版本号 --no-cache