Docker从入门到出门

Docker简介

  • 镜像(Image):Docker 镜像是一个轻量级、独立的、可执行的软件包,它包含了运行一个应用所需的所有内容,包括代码、运行时、库、环境变量和配置文件,好比是一个模板,可以用来创建容器。
  • 容器(Container):Docker 容器是镜像的运行实例,它可以在隔离的环境中运行,类似于虚拟机,但更轻量级和高效。
  • 仓库(Repository):Docker 仓库是存储和分发 Docker 镜像的地方,类似于代码仓库,但专门用于 Docker 镜像。

1762918733068.png

Docker安装

  • Docker Desktop:适用于 Windows 和 macOS,提供了图形界面和命令行工具,方便用户管理和操作 Docker 容器。
  • Docker Engine:适用于 Linux,提供了命令行工具,需要手动安装和配置。

Docker基本命令

  • docker version:查看 Docker 版本信息。

  • docker info:查看 Docker 系统信息,包括镜像和容器的数量。

  • docker –help:查看 Docker 命令的帮助信息。

  • docker images:列出本地所有镜像。

    1. REPOSITORY:镜像的仓库名称。
    2. TAG:镜像的标签,通常用来表示版本。
    3. IMAGE ID:镜像的唯一标识符。
    4. CREATED:镜像创建的时间。
    5. SIZE:镜像的大小。
    • -a:只显示镜像的仓库名称。
    • -q:只显示镜像的 IMAGE ID。
  • docker search:从 Docker 仓库搜索镜像。

    • –filter=stars=100:只显示星标数大于等于 100 的镜像。
  • docker build:从 Dockerfile 构建镜像。

  • docker pull:从 Docker 仓库拉取镜像。

    • –tag:指定镜像的标签,default为latest。
  • docker rmi:删除一个镜像。

    • -f:强制删除镜像,即使有容器正在使用该镜像,后接Image名称或ID。
    • -f:$(docker images -aq):删除所有镜像。
  • docker run:创建并运行一个新容器 –name 指定容器名称。

    • [parameters]:容器参数,包括 -d(后台运行)、-p(端口映射)、-v(挂载卷),-i(交互模式)、-t(分配一个伪终端)等。
    • -p:将容器的端口映射到主机的端口,格式为 [host_port]:[container_port]。
    • [image]:要运行的镜像名称或 ID。
    • [command]:容器启动后要执行的命令。
  • exit:停止并退出容器。

  • Ctrl + P + Q:退出容器,但容器仍在后台运行。

  • docker ps:列出当前正在运行的容器。

    • -a:显示所有容器,包括已经停止的(历史)容器。
    • -q:只显示容器的 CONTAINER ID。
    • -n:显示最近创建的 n 个容器。
  • docker rm:删除一个容器。

    • -f:强制删除容器,即使容器正在运行。
    • -f:$(docker ps -aq):删除所有容器。
    • -l:删除容器的链接。
    • -v:删除容器的卷。
  • docker start:启动一个容器。

  • docker restart:重启一个容器。

  • docker stop:停止一个容器。

  • docker kill:强制停止一个容器。

Docker常用其他命令

  • 后台启动容器:docker run -d [image]

    • docker ps 发现容器停止
    • 常见错误:docker 容器后台运行,必须有一个前台进程,否则会自动停止
  • 查看容器日志:docker logs [container]

    • -t:显示时间戳
    • -f:实时查看日志
    • –tail:显示日志的最后几行
    • -t –tail 100:显示最后100行日志
  • 查看容器内运行的进程:docker top [container]

  • 查看容器内部细节:docker inspect [container]

  • 进入容器内部:docker exec -it [container] /bin/bash

  • 查看当前正在运行的容器终端:docker attach [container]

  • 从容器内拷贝到主机上:docker cp [container]:[path] [host_path]

  • 可视化工具:Portainer、Rancher

    • portainer:docker run -d -p 8088:9000--restart=always -v /var/run/docker.sock:/var/run/docker.sock –privileged=true portainer/portainer

Commit镜像

  • commit镜像本身相当于在镜像的基础上加了一层,可以用来保存对镜像的修改,例如添加新的文件或修改配置文件等。

  • docker commit:将容器的文件系统保存为一个新的镜像。

    • -a:指定作者信息。
    • -m:指定提交信息。
    • [container]:要提交的容器名称或 ID。
    • [image]:要创建的新镜像名称。
    • [tag]:要创建的新镜像标签。
  • docker commit -a “author” -m “commit message” [container] [image]:[tag]

Docker从出门到入土

1762922703996.png

容器数据卷

  • 容器数据卷:容器数据卷是 Docker 容器中用于持久化数据的一种机制,可以将容器内的数据保存到宿主机上,从而实现数据的持久化和共享。

  • docker run -p [host_port]:[container_port] [image]

    • host_port:主机端口。
    • container_port:容器端口。
    • image:镜像名称或 ID。

类比如上的docker命令对于数据容器,可以理解为将主机上的数据挂载到容器中,使得容器可以访问和修改主机上的数据。

  • docker run -v [host_path]:[container_path] [image]

    • host_path:主机上的路径。
    • container_path:容器内的路径。
    • image:镜像名称或 ID。
  • docker ps 查看当前正在运行的容器

  • docker inspect 查看当前容器内部

    • Mounts:查看挂载信息
      • Source:主机上的路径
      • Destination:容器内的路径
      • Mode:挂载模式
      • RW:是否可读写
      • Name:挂载名称
      • Driver:挂载驱动
      • Type:挂载类型

具名和匿名挂载

  • 匿名挂载:在挂载时,只指定了容器内的路径,没有指定主机上的路径,Docker 会自动在主机上创建一个临时目录来存储数据。

    • docker run -d -p -v /data [image]
    • 会在主机上创建一个临时目录来存储数据,可以通过 docker inspect [container] 查看挂载信息。
    • docker volume ls 查看所有卷
    • Driver:local 本地存储驱动,Volume Name:卷名称,Scope:卷的作用域,Driver:卷驱动,Mountpoint:卷挂载点,Status:卷状态
  • 具名挂载:在挂载时,同时指定了主机上的路径和容器内的路径,Docker 会将主机上的路径和容器内的路径进行绑定。

    • docker run -d -p -v mydata:/data [image]
      • mydata:卷名称,如果不存在会自动创建
      • /data:容器内的路径
      • :前如果以/开头,表示绝对路径,否则表示名称
      • 通过 docker volume inspect [卷名称] 查看卷信息
      • Mountpoint:卷挂载点(主机)
  • -v [host_path]:[container_path]:ro:只读挂载,容器内只能读取数据,不能修改数据。

  • -v [host_path]:[container_path]:rw:读写挂载,容器内可以读取和修改数据。

Dockerfile基础

  • Dockerfile:类似docker commit,将镜像保存为模板,通过模板创建镜像,类似于脚本命令。

    • vim dockerfile

    • FROM [base_image]:指定基础镜像,例如ubuntu、centos、alpine等。

    • VOLUME [host_path]:[container_path]:挂载卷,将主机上的路径和容器内的路径进行绑定。

    • VOLUME [“host_path1”, “host_path2”, …]:挂载多个卷。

    • Dockerfile 中的 VOLUME 指令只是在镜像中声明 “该路径未来运行容器时需要挂载卷”,但在 docker build 过程中,这个指令不会实际创建卷,也不会挂载任何主机路径。构建阶段中,VOLUME 声明的路径会被标记为 “卷目录”,但构建容器内的该路径数据会被忽略(不会写入最终镜像),因为卷的数据是运行时动态挂载的。

    • 假如我现在创建镜像的时候写了这个VOLUME [“volume01”, “volume02”],那么我在用这个镜像创建容器docker01的时候,会自带两个volume目录作为挂载目录,那么我下次往docker01的volume01中写入文件的时候这个文件实际是存在哪里?

    • Dockerfile 中通过 VOLUME [“volume01”, “volume02”] 声明卷后,用该镜像创建容器 docker01 时,Docker 会自动为这两个路径创建匿名卷,并将容器内的 volume01 和 volume02 目录分别挂载到这两个匿名卷上。向 docker01 的 volume01 中写入文件时,文件的实际存储位置是主机上 Docker 管理的匿名卷目录中,具体路径取决于主机操作系统。

  • 构建镜像:docker build -f [dockerfile_path] -t [image_name]:[tag] [context_path] .

数据卷容器

  • 数据卷容器:多个容器之间共享数据,类似于挂载卷,但是数据卷容器可以共享数据,而挂载卷只能挂载到容器中。
    • docker run -it –name [container_name] -v [host_path]:[container_path] [image]
    • docker run -it –name [container_name] –volumes-from [data_container] [image]
      • data_container:数据卷容器的名称或 ID。
      • image:镜像名称或 ID。

Dockerfile使用

  • 构建步骤:

    1. 编写dockerfile文件
    2. docker build构建成为镜像
    3. docker run 运行镜像
    4. docker push 发布镜像(Docker Hub、阿里云镜像仓库)
  • 基础知识:

    • 每个保留关键字(指令)都必须是大写字母
    • 执行从上到下顺序执行
    • #表示注释
    • 每一个指令都会创建提交一个新的镜像层,并提交
  • Dockerfile常用指令:

    • FROM:基础镜像,一切从这里开始构建,先检查本地的[image],再检查镜像仓库
    • MAINTAINER:镜像维护者的姓名和邮箱地址
    • RUN:镜像构建时需要运行的命令
    • ADD:将宿主机目录下的文件拷贝进镜像,并且会自动处理URL和解压tar压缩包
      • 无需指定容器内的路径,会自动拷贝到容器内
      • 在基础镜像上添加新的一层,并且将文件拷贝到镜像中
    • WORKDIR:指定在创建容器后,终端默认登陆进来的工作目录 eg:/bin/bash
    • VOLUME:容器数据卷,用于数据保存和持久化工作,挂载到主机目录
    • EXPOSE:暴露端口配置,告诉容器要打开哪些端口,类似于docker run -p
    • CMD:指定一个容器启动时要运行的命令,CMD 指令指定的命令可以被 docker run 命令行参数中指定的命令覆盖
    • ENTRYPOINT:指定一个容器启动时要运行的命令,ENTRYPOINT 指令指定的命令不会被 docker run 命令行参数中指定的命令覆盖
    • ONBUILD:当构建一个被继承的 Dockerfile 时运行命令,父镜像在被子镜像继承后父镜像的 onbuild 被触发
    • COPY:类似ADD,将文件拷贝到镜像中,但是不会解压
    • ENV:设置环境变量,可以在构建过程中使用,也可以在运行容器时使用
  • Docker Hub最基础的镜像scratch,相当于一个空白的镜像,没有任何基础镜像,从零开始构建

  • docker history [image] 查看镜像历史,查看如何创建的镜像,步骤和过程

  • CMD和ENTRYPOINT的区别:

    • CMD:指定一个容器启动时要运行的命令,CMD 指令指定的命令可以被 docker run 命令行参数中指定的命令覆盖。
      • CMD [“ls”, “-a”] - Dockerfile中
      • docker run -it [image] -l - Docker命令行参数中,会报错因为-l覆盖了原本的ls -a。
    • ENTRYPOINT:指定一个容器启动时要运行的命令,ENTRYPOINT 指令指定的命令不会被 docker run 命令行参数中指定的命令覆盖。
      • ENTRYPOINT [“ls”, “-a”] - Dockerfile中
      • docker run -it [image] -l - Docker命令行参数中,-l不会覆盖原本的ls -a,而是会作为参数传递给ls -a 变成ls -a -l。

Docker Hub

  • Docker Hub:Docker Hub 是一个云端的 Docker 镜像仓库,用于存储和分发 Docker 镜像。用户可以在 Docker Hub 上创建自己的镜像仓库,并将镜像推送到仓库中,以便其他人可以下载和使用。

  • docker login 登录 Docker Hub

    • docker login -u [username] -p [password]
  • docker push [image] 推送镜像到 Docker Hub

    • docker push [username]/[image]:[tag]
    • 提交不成功的情况可以新增一个dockerfile,并且修改[tag]
    • docker tag [image] [new_image]:[tag]

aliyun镜像服务

  • 阿里云镜像服务:阿里云镜像服务是阿里云提供的一个云服务,用于存储和分发 Docker 镜像。用户可以在阿里云镜像服务上创建自己的镜像仓库,并将镜像推送到仓库中,以便其他人可以下载和使用。
  1. 登录阿里云账号,进入容器镜像服务控制台。
  2. 创建命名空间,命名空间是镜像仓库的隔离单位,可以创建多个命名空间来隔离不同的镜像仓库。
  3. 创建镜像仓库,镜像仓库是存储 Docker 镜像的地方,可以创建多个镜像仓库来存储不同的镜像。
    • 根据命名空间和镜像仓库的名称,生成镜像的完整名称
  • docker login –username=[username] [registry_address] 登录阿里云镜像仓库
  • docker tag [image] [registry_address]/[namespace]/[repository]:[tag] 标记镜像
  • docker push [registry_address]/[namespace]/[repository]:[tag] 推送镜像到阿里云镜像仓库

Docker 网络

  • ip addr 查看网络信息

    • lo:本地回环地址,用于本地通信
    • eth0:网卡地址,用于连接网络
    • docker0:Docker 的虚拟网桥,用于连接 Docker 容器
  • Docker 容器网络模式:

    • 问题:docker是如何处理容器之间的网络通信的?
  • docker run -d -P –name [container_name] [image]:随机端口映射,将容器内的端口映射到宿主机的随机端口。

  • docker exec -it [container_name] /bin/bash:进入容器内部

    • /bin/bash:进入容器内部的 bash 终端
    • ip addr:查看容器内的网络信息
  • 容器启动的时候会分配一个ip地址,这个ip地址只能在容器内部使用,容器之间可以通过这个ip地址进行通信。

    • eth0ifxxx:容器内的网卡地址,用于容器内部通信
    • 从Linux主机ping容器内部的ip地址是可行的,因为容器内的ip地址是Linux主机上的一个虚拟网卡地址。
  • 每个容器启动的时候都会分配一个eth0@ifxxx的网卡地址,这个网卡地址只能在容器内部使用,容器之间可以通过这个网卡地址进行通信。

    • 桥接模式,使用的是evth-pair技术,evth-pair技术可以创建一对虚拟网卡,一对网卡地址,可以实现网络通信。
    • evth-pair是一对虚拟的设备接口,一端连接协议栈,一端彼此相连,数据从一端进入,从另一端出来,就像一个管道。
    • 通过evth-pair技术,容器内的ip之间可以通信,容器内的ip和宿主机的ip之间也可以通信。
      • docker exec -it [container_name] ping [anather_container_ip]:容器内部ping另一容器内部的ip地址