Docker学习

Docker架构

概念介绍

  • 镜像(Image):Docker镜像,就相当于是一个root文件系统。
  • 容器(Container):镜像和容器的关系,就像是面向程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

Docker学习_第1张图片

概念 说明
Docker 镜像(Images) Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。
Docker 容器(Container) 容器是独立运行的一个或一组应用,是镜像运行时的实体。
Docker 客户端(Client) Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。
Docker 主机(Host) 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker Registry Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker Machine Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

Docker安装

  • Docker安装教程参考:https://blog.csdn.net/qq_43556844/article/details/120604383
  • Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境。
  • Docker 实质上是在已经运行的 Linux 下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的 Linux 主机。
  • 因此,Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。
  • 在 Windows 上部署 Docker 的方法都是先安装一个虚拟机,并在安装 Linux 系统的的虚拟机中运行 Docker。

常用命令

  • 首先我们需要移除所有的环境。方便之后操作。
  • 移除所有容器:docker rm -f $(docker ps -aq)
  • 移除所有的镜像:docker rmi -f $(docker images -aq)
  • 把容器指定位置的东西复制出来
  • docker cp 5eff66eec7e1:/etc/nginx/nginx.conf /data/conf/nginx.conf
  • 把外面的内容复制到容器里面
  • docker cp /data/conf/nginx.conf 5eff66eec7e1:/etc/nginx/nginx.conf

Docker仓库管理

  • 仓库(Repository)是集中存放镜像的地方。
  • 以下介绍一下 Docker Hub。当然不止 docker hub,只是远程的服务商不一样,操作都是一样的。
  • Docker Hub:目前 Docker 官方维护了一个公共仓库 Docker Hub。
  • 大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
  • 注册:在 Docker Hub官网 免费注册一个 Docker 账号。
  • 登录和退出
- 使用命令进行登录
- 登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像
docker login [options] [server]
options
	--	password,-p 密码
	--	password-stdin 从stdin获取密码
	--	username,-u 用户名
server 不指定的话,默认是Docker Hub

- 退出
docker logout
  • 镜像发布
    • 查看登录命令:docker login --help
    • 进行登录:docker login -u 用户名 回车输出密码
    • 可以给镜像给名字:docker tag 镜像id 镜像名:标签
    • 上传:docker push 作者名/需要上传的镜像名:版本号
    • 退出:docker logout
  • 也可以发布到阿里云上:
  • 登录阿里云服务器-》找到容器镜像服务-》创建命名空间-》创建镜像仓库-》浏览阿里云命令操作-》上传镜像到阿里云
  • 首先退出DockerHub的账号【docker logout】,然后复制自己创建的阿里云镜像仓库中的命令,输入密码登录
  • 登录成功之后使用【docker push 镜像名:版本号】上传即可

Docker客户端

  • 通过docker来查看所有客户端指令

Docker学习_第2张图片

  • 可以使用docker command –help更加深入的了解指定的Docker命令使用方法
  • 如:查看stats指令的具体使用方法。
  • Docker stats –help
    Docker学习_第3张图片

Docker镜像的使用

在运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub公共镜像源下载。

Docker学习_第4张图片
Docker学习_第5张图片

  • 使用docker image --help 查看关于镜像的相关命令

  • 使用docker images来列出本地主机上的镜像
    在这里插入图片描述

    • 各个选项说明:
    • REPOSITORY:表示镜像的仓库源
    • TAG:镜像的标签
    • IMAGE ID:镜像ID
    • CREATED:镜像创建时间
    • SIZE:镜像大小
    • 同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 20.04、latest 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
    • 例如:我们如果要使用版本为20.04的ubuntu系统镜像来运行容器时
  • 运行镜像,即启动容器

    • docker run -t -i ubuntu:20.04 /bin/bash
      • 参数说明:
      • -i: 交互式操作。
      • -t: 终端。
      • ubuntu:20.04: 这是指用 ubuntu 20.04 版本镜像为基础来启动容器。
      • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash
      • 注*:若不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。
  • 查找镜像

    • 我们可以从 Docker Hub 网站来搜索镜像
    • 也可以使用 docker search 命令来搜索镜像。
    • 通过 docker search httpd 命令来寻找合适的httpd镜像。
    • 说明
    • NAME: 镜像仓库源的名称
    • DESCRIPTION: 镜像的描述
    • OFFICIAL: 是否 docker 官方发布
    • stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
    • AUTOMATED: 自动构建。
      Docker学习_第6张图片
  • 获取一个新的镜像

    • 使用 docker pull 命令来下载
    • 通过使用上图中的查询命令来查询 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像Docker学习_第7张图片
  • 推送镜像

    • 用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。
    • 以下命令中的 username 请替换为你的 Docker 账号用户名。
    • docker push ubuntu:18.04 username/ubuntu:18.04
    • docker image ls
  • 删除镜像

    • 镜像删除使用 docker rmi 命令,比如我们删除httpd镜像
    • docker rmi httpd
  • 自定义自己的镜像

    • 当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时。
    • 我们可以通过以下两种方式对镜像进行更改。
    • 从已经创建的容器中更新镜像,并且提交这个镜像,以ubuntu为例子进行以下操作
    • 更新镜像之前,我们首先需要使用镜像来创建一个容器。
      • docker run -t -i ubuntu:20.04 /bin/bash
      • 在运行的容器内使用 apt update 命令进行更新。
      • 在完成操作之后,输入 exit 命令来退出这个容器。
      • 若此时更改完成后,例如可以获取容器的ID为e218edb10161的容器
      • 是按我们的需求更改的容器。这是我们可以通过命令docker commit来提交容器副本。
      • docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
        • 各个参数说明:
        • -m: 提交的描述信息
        • -a: 指定镜像作者
        • e218edb10161:容器 ID
        • runoob/ubuntu:v2: 指定要创建的目标镜像名
        • 我们可以使用 docker images 命令来查看我们的新镜像 runoob/ubuntu:v2
        • 使用我们的新镜像 runoob/ubuntu 来启动一个容器
        • docker run -t -i runoob/ubuntu:v2 /bin/bash
  • 使用 Dockerfile 指令来创建一个新的镜像

    • 我们使用命令 docker build , 从零开始来创建一个新的镜像。
    • 为此,我们需要创建一个 Dockerfile(后面将会介绍) 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
    • 编写Dockerfile文件如下
    FROM    centos:6.7
    MAINTAINER      Fisher "[email protected]"
    RUN     /bin/echo 'root:123456' |chpasswd
    RUN     useradd runoob
    RUN     /bin/echo 'runoob:123456' |chpasswd
    RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
    EXPOSE  22
    EXPOSE  80
    CMD     /usr/sbin/sshd -D
    
    • 每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
    • 第一条FROM,指定使用哪个镜像源
    • RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
    • 然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
    • docker build -t runoob/centos:6.7 .
      • 参数说明:
    • -t :指定要创建的目标镜像名
    • . :Dockerfile文件所在目录,也可以指定Dockerfile的绝对路径
  • 设置镜像标签

  • 使用docker tag设置镜像标签

  • docker tag 860c279d2fec runoob/centos:dev

    • 说明
    • docker tag 镜像ID,这里是 860c279d2fec ,用户名称/镜像源名(repository name):新的标签名(tag)。

容器的使用

  • 首先获取镜像

  • 若我们本地没有ubuntu镜像,我们可以使用docker pull命令来载入ubuntu镜像:

    • docker pull ubuntu 默认使用最新的ubuntu镜像
      在这里插入图片描述
  • 启动容器

    • 以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:
    • docker run -it ubuntu /bin/bash
      • 参数说明:
      • 通过 docker 的两个参数 -i -t,从而让Docker具有交互性
      • -i: 交互式操作。允许你对容器内的标准输入 (STDIN) 进行交互。
      • -t: 终端。在新容器内指定一个伪终端或终端。
      • ubuntu: ubuntu 镜像。指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
      • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。 在启动的容器里执行的命令
  • 要退出终端,直接输入 exit命令或者使用ctrl+D来退出容器。

  • 启动已停止运行的容器

    • 首先查看所有的容器命令如下
    • docker ps -a
    • 使用 docker start 启动一个已停止的容器
    • docker start 容器ID
  • 后台运行

    • 我们可以过 -d 指定容器进入后台运行模式。
    • 注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec(下面会介绍到)。
  • 停止一个容器

    • 停止容器的命令如下
    • docker stop <容器 ID>
    • 停止的容器可以通过 docker restart 重启
    • docker restart <容器 ID>
  • 进入容器

    • 在使用 -d 参数时,容器启动后会进入后台。
    • 此时想要进入容器,可以通过以下指令进入:
    • docker attach 容器ID
      • 注意: 使用该指令如果从这个容器退出,会导致容器的停止。
    • docker exec 容器ID
      • 推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
      • 具体使用:docker exec -it 容器ID 对应的命令
      • 更多参数说明请使用 docker exec --help 命令查看。
  • 导出和导入容器

    • 镜像保存/载入

    • docker load/docker save

      • 将一个镜像导出为文件,再使用docker load命令将文件导入为一个镜像,会保存该镜像的的所有历史记录。
      • 比docker export命令导出的文件大,很好理解,因为会保存镜像的所有历史记录。
    • 容器导入/导出

      • docker import/docker export
        • 将一个容器导出为文件,再使用docker import命令将容器导入成为一个新的镜像
        • 但是相比docker save命令,容器文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。
    • 导出容器

      • 如果要导出本地某个容器,可以使用 docker export 命令
        -docker export -o <保存路径> <容器标识>
        参数:
        -o 通过-o来指定到处的tar文件名,也可以使用重定向来实现。
        容器标识:这里可以填容器的name ,也可以填容器id的前三位,也可以使用 <镜像名称:标签>
        这样将导出容器快照到本地文件。
        具体使用(保存到当前目录下):
        docker export -o ./ubuntu.tar ubuntu:20.04
        另一种到处方法:docker export 容器id/name >文件名.tar
    • 导入容器快照

      • docker import <文件路径> <容器名>
      • 可以使用 docker import 从容器快照文件中再导入为镜像
      • 以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
      • cat docker/ubuntu.tar | docker import - test/ubuntu:v1
      • 此外,也可以通过指定 URL 或者某个目录来导入,例如:
      • docker import http://example.com/exampleimage.tgz example/imagerepo
  • 删除容器

    • 使用 docker rm 命令删除容器
    • docker rm -f 容器ID
    • 注意*:在删除容器的时候必须是停止状态,否则会报错。
    • 下面的命令可以清理掉所有处于终止状态的容器。
    • docker container prune
  • 具体例子

    • 运行一个Web应用

    • 接下来让我们尝试使用 docker 构建一个 web 应用程序。

    • 我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。

    • docker pull training/webapp # 载入镜像
      Docker学习_第8张图片

    • docker run -d -P training/webapp python app.py #运行镜像

      • 参数说明:
      • -d:让容器在后台运行。
      • -P:将容器内部使用的网络端口随机映射到我们使用的主机上。
        在这里插入图片描述
    • 运行后访问:
      在这里插入图片描述

    • 我们也可以通过 -p 参数来设置不一样的端口:

      • docker run -d -p 5000:5000 training/webapp python app.py
    • 以上是将容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
      在这里插入图片描述

    • 使用docker port 容器ID

    • 可以查看容器端口的映射情况和容器内部的内容

      • docker logs [ID或者名字]
        • -f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。
          在这里插入图片描述
    • 从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。

    • 查看WEB应用程序容器的进程
      docker top [ID或者名字]

    • 检查 WEB 应用程序,可以查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

    • docker inspect [ID或者名字]

    • 查询最后一次创建的容器

    • docker ps -l
      在这里插入图片描述

  • 通过docker container lsdocker ps(该操作首先需要确定有容器在运行)来查看那些容器在运行

    • 输出的详细介绍
    • CONTAINER ID: 容器 ID。
    • IMAGE: 使用的镜像。
    • COMMAND: 启动容器时运行的命令。
    • CREATED: 容器的创建时间。
    • STATUS: 容器状态。
      • 状态有7种:
      • created(已创建)
      • restarting(重启中)
      • running 或 Up(运行中)
      • removing(迁移中)
      • paused(暂停)
      • exited(停止)
      • dead(死亡)
    • PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
    • NAMES: 自动分配的容器名称。
      在这里插入图片描述
  • 通过docker logs命令(后面跟的是容器ID或者容器名),可以查看容器内的标准输出。
    Docker学习_第9张图片

  • Docker容器连接

    • 容器中可以运行一些网络应用,要让外部也可以访问这些应用,
    • 可以通过 -P 或 -p 参数来指定端口映射。
    • 我们创建了一个 python 应用的容器
    • docker run -d -P training/webapp python app.py
    • 另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。
  • 我们使用 -P 绑定端口号,使用 docker ps 可以看到容器端口 5000 绑定主机端口 32768。
    我们也可以使用 -p 标识来指定容器端口绑定到主机端口。

    • 两种方式的区别是:
      • -P :是容器内部端口随机映射到主机的高端口。
      • -p : 是容器内部端口绑定到指定的主机端口。
    • docker run -d -p 5000:5000 training/webapp python app.py
    • 另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。
    • docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
    • 这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。
    • 上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp。
    • docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
    • docker port 命令可以让我们快捷地查看端口的绑定情况。
  • Docker容器互联

    • 端口映射并不是唯一把 docker 连接到另一个容器的方法。
    • docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
    • docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。
    • 容器命名
      • 当我们创建一个容器的时候,docker 会自动对它进行命名。
      • 另外,我们也可以使用 --name 标识来命名容器
      • 例如:docker run -d -P --name runoob training/webapp python app.py
      • 我们可以使用 docker ps 命令来查看容器名称。docker ps -l
    • 创建网络
      • docker network create -d bridge test-net
        • 参数说明:
        • -d:参数指定 Docker 网络类型,有 bridge、overlay。
      • 其中 overlay 网络类型用于 Swarm mode,在这里可以忽略
        在这里插入图片描述
    • 通过docker network ls参看网络信息 在这里插入图片描述
    • 连接容器
      • 运行一个容器并连接到新建的 test-net 网络:
      • docker run -itd --name test1 --network test-net ubuntu /bin/bash
      • 打开新的终端,再运行一个容器并加入到 test-net 网络:
      • docker run -itd --name test2 --network test-net ubuntu /bin/bash
      • 下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。
      • 如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping
      • (即学即用:可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)。
      • apt update
      • apt install iputils-ping
      • 之后在test1容器中使用docker exec -it test1 /bin/bash 进入容器后,执行ping test2命令
      • 也可以在test2容器中使用docker exec -it test2 /bin/bash 进入容器后,执行ping test1命令
      • 若多个容器之间需要互相连接,推荐使用 Docker Compose,后面介绍。
    • 配置 DNS
      • 我们可以在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS
      {
        "dns" : [
          "114.114.114.114",
          "8.8.8.8"
        ]
      }
      
    • 设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8
    • 配置完,需要重启 docker 才能生效
    • 查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息
      • docker run -it --rm ubuntu cat etc/resolv.conf
    • 手动指定容器的配置
    • 如果只想在指定的容器设置 DNS,则可以使用以下命令
      • docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
    • 参数说明:
      • -rm:容器退出时自动清理容器内部的文件系统。
      • -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
      • –dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
      • –dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。
    • 如果在容器启动时没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。

Docker容器卷

  • 概念
    • docker的原理是将所使用的应用和环境打包成一个镜像,最终以容器的方法运行。
    • 而当容器产生了数据,而如果我们不通过docker commit生成新的镜像,来使得数据作为容器的一部分保存下来的话,因为数据是存储在容器中,那么当容器删除的时候,数据也就丢失了。所以我们需要将数据持久化,故需要在docker容器中使用卷。
    • Docker的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。
    • 数据卷在Docker容器的形式就是一个目录,支持多个容器间共享,修改并不会影响镜像,使用Docker数据卷,类似在系统中使用mount挂载一个文件系统。
    • 可以在Docker容器间进行共享和重用数据
    • 可以使数据持久化,完全独立与容器的生命周期,故Docker不会在容器删除时删除其挂载的数据卷
    • 数据卷的生命周期会一直持续到没有容器使用为止
    • 卷的更改可以直接生效
    • 数据卷的更改不会包含在镜像的更新中
    • 实际使用
      • 如果MySQL数据中,容器删除了,数据库内的数据就会丢失,故我们需要将MySQL的数据存储在本地。
  • 数据卷使用
    • 直接使用命令来挂载
    • docker run -it -v 主机目录:容器目录
    • 几种:
      • -v 容器内路径 #匿名挂载
      • -v 卷名:容器内路径 #具体挂载
      • -v /宿主机路径:容器内路径 #指定路径
      • 可以使用-v 容器内路径,ro(readonly) rw(readwrite)改变容器对数据卷读写权限
      • docker run -d -P --name ubunut01 -v /home/demo:/home:ro ubuntu
      • docker run -d -P --name ubunut02 -v /home/demo:/home:rw ubuntu
    • 详细使用
      • docker run -it -v /home/demo:/home ubuntu /bin/bash
      • 解释:该操作执行后,会将Linux下的demo目录和容器内的home目录连接,两者内容会同步。之后我们就可以直接在Linux目录下进行数据操作,容器内会同步。
      • 在容器启动,通过在Linux主机的终端中使用docket inspect 容器id来查看卷的挂载信息(找到Mounts字段,其Source就是主机目录,Destination就是容器目录),若没有该字段,说明挂载失败,需要重新挂载
    • 查看卷的帮助文档
      • docker volume --help来查看关于卷的帮助文档
      • 说明:
        • create :创建卷
        • inspect :查看卷
        • ls :列出所有卷
        • prune:移除卷
        • rm:移除卷
          Docker学习_第10张图片
  • 通过使用–volumes-from来指定父容器实现容器间数据的同步。
    • 具体使用
    • docker run -it --name docker02 --volumes-from docker01 demo/ubunut:0.1
    • 这样的话新创建的docker02容器里就有了docker01的数据。

Docker网络总结

  • 查看容器内部网络的ip地址命令:ip addr 【或者 ifconfig】

  • Docker关于网络的处理。

  • 一个网络模型图

  • Docker学习_第11张图片

  • Docker使用的是Linux的桥接模式,宿主机中是一个Docker容器的网桥docker0,所有东西都是经过这个docker0的,只要你启动一个容器,不指定一个网络它就会往docker0这里给你分配一个IP,最多能分配65535个。

  • Docker中的所有的网络接口都是虚拟的。虚拟的转发效率高!(内网传递文件!)

  • 如果是容器之间需要通信,那么就通过Veth-pair给转发连接过去,如下图所示。核心就是利用了Linux的虚拟化网络技术,在容器内和Docker0分别创建了一个虚拟网卡,通过Veth-pair进行一个连接。

  • 为什么是65535个的原因:

  • 因为docker0分配的ip后面有16,我们拿255.255.0.1/16为例,因为原有的为00000000.00000000.00000000.00000000,转化为十进制【255.255.255.255】而16表示的是截止到前面的第二个255,也就是【255.255.0.0】,而每位的范围是0~255个数,那么能存储的个数就为后面的位数相乘,也就是255*255=65535个。假如是255.255.0.1/24,那么就代表255.255.255.0,也就是只有最后的0-255个,也就是可分配255个。而我们的docker0课分配的个数就是65535个

  • 容器互联 --link 【了解即可】

    • 当我们编写微服务的时候,database url=ip,项目不重启,而数据库ip换掉了,因此我们希望用名字来进行容器的访问。
    • 我们通过名字是无法ping通的。如ping tomcat01
    • 当然我们可以使用–link可以解决网络连通问题
    • 使用docker run -d -P --name tomcat03 --link tomcat02 tomcat运行tomcat03并且连通tomcat02是可以的,并且通过docker exec -it tomcat03 ping tomcat02可以ping通。
    • 但是反向就不能ping通了docker exec -it tomcat02 ping tomcat03就会ping失败
    • 原理:这项技术实际就是在hosts配置文件添加了一个域名解析,故不能反向,因为上述只在tomcat 03加入了tomcat02的域名解析。
    • 现在不推荐使用–link,现在的容器互联使用的是自定义网路来实现的。
  • 通过docker network --help查看网络的相关命令

  • 网络模式

    • bridge:桥接docker(默认,自己创建也使用bridge模式);
    • none:不配置网络;
    • host:和宿主机共享网络;
    • container:容器网络连通!(用的少,局限很大);
  • 直接使用–net bridge,而这个就是我们的docker0

    • docker run -d -P --name tomcat01 tomcat
  • 以上命令就相当于

    • docker run -d -P --name tomcat01 --net bridge tomcat
  • docker0特点:默认,域名不能访问。 --ling可以打通,不建议使用

  • 创建自定义网络

  • docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mytestnet

  • 参数说明:

  • –driver bridge # 桥接模式

  • –subnet 192.168.0.0/16 # 配制一个子网,65535个字段 192.168.0.2——192.168.255.255

  • –gateway 192.168.0.1 # 配制默认的路由网关

  • mytestnet #表示自定义的网络名
    在这里插入图片描述

  • 查看一下:docker network ls
    Docker学习_第12张图片

  • 查看一下mynet的详情:docker network inspect mynet
    Docker学习_第13张图片

  • 使用我们自定义的网络启动两个tomcat,然后查看一下信息。

  • 启动tomcat-mytestnet-01

    • docker run -d -P --name tomcat-mytestnet-01 --net mytestnet tomcat
  • 启动tomcat-net-02

  • docker run -d -P --name tomcat-mytestnet-02 --net mytestnet tomcat

  • 查看一下

    • docker network inspect mytestnet
      Docker学习_第14张图片
  • tomcat01 ping一下02的IP地址

  • docker exec -it tomcat-mytestnet-01 ping 192.168.0.3

  • tomcat02 ping一下01的IP地址

  • docker exec -it tomcat-mytestnet-02 ping 192.168.0.2

  • tomcat01 ping一下02的name

  • docker exec -it tomcat-mytestnet-01 ping tomcat-mytestnet-02

  • tomcat02 ping一下01的IP地址

  • docker exec -it tomcat-mytestnet-02 ping tomcat-mytestnet-01

  • 发现可以ping通

  • 网络联通connect

  • 查看帮助命令:docker network connect --help

  • 查看两个网段是否可以ping通
    Docker学习_第15张图片

  • 启动tomcat01,使用的是docker0路由

  • docker run -d -P --name tomcat01 tomcat

  • 启动tomcat02,使用的是docker0路由

  • docker run -d -P --name tomcat02 tomcat

  • 查看一下启动的容器

  • docker ps

  • 测试tomcat01是否能ping通tomcat-net-01
    docker exec -it tomcat01 ping tomcat-mytestnet-01
    结果是不可以ping通
    我们通过connect将两个不同网段的容器来ping通

  • docker network connect mytestnet tomcat01

  • 然后再去ping

  • docker exec -it tomcat01 ping tomcat-mytestnet-01

  • 这下就能ping通了,这里连通之后就是将tomcat01放到了mynet下【注意:tomcat-02依旧是打不通的】,就相当于下图所示。
    Docker学习_第16张图片

  • 使用connect就是将tomcat01放到了mynet下,如果我们以后想要跨网络操作别人的容器,就需要使用docker network connect连通。

  • 可以在Linux中ping通tomcat01容器,而且容器与容器之间是可以互相ping通的。

  • 启动一个tomcat

    • docker run -d -P --name tomcat01 tomcat
    • 使用以下命令进入容器并查看容器内部ip addr,可以得到一个eth0@if262 ip地址,这个是docker分配的。
    • docker exec -it tomcat01 ip addr
    • docker容器内查看
      Docker学习_第17张图片
  • 宿主机查看
    在这里插入图片描述

  • 经过测试,发现当我们启动一个容器的时候,会多一对网卡,上图中的8和容器的7是对应的。
    启动容器带来的网卡是一对对的,这就是evth-pair,是一对虚拟设备接口,它们是成对出现的,一端连着协议,一端彼此连接。正是因为有这个特性,evth-pair才能充当一个桥梁,连接着各种虚拟网络设备。OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术。同时发现Linux是可以ping通容器内部的。

  • 原理:我们每启动一个docker容器,docker就会给容器分配一个ip地址,我们只要安装了docker就会有一个docker0的网卡,使用的是桥接模式bridge,使用的技术就是evth-pair技术。

Docker学习_第18张图片

  • docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mytestnet
    Docker学习_第19张图片
  • docker run -d -P --name tomcat-testnet-01 --net mytestnet tomcat
  • docker run -d -P --name tomcat-testnet-02 --net mytestnet tomcat
    在这里插入图片描述
    Docker学习_第20张图片

在这里插入图片描述

Docker学习_第21张图片
Docker学习_第22张图片

Dockerfile

  • Dockerfile 是一个用来构建镜像的文本文件,相当于命令脚本,文本内容包含了一条条构建镜像所需的指令和说明。
  • 每个保留关键字(指令)都必须是大写字母;执行顺序是从上往下依次执行;
  • 可以使用 Dockerfile 定制镜像
  • 使用Dockerfile 文件来定制一个镜像,具体 Dockerfile 文件内指令详解
    • 定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)
    • 在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:
  • 初体验
# 创建一个dockerfile文件,名字可以随意,建议Dockerfile
# 编写dockerfile脚本 
# 文件中的内容,指令需要大写
FROM ubuntu                       # 基础镜像
VOLUME  ["volume01","volume02"]    # 挂载卷的目录,这里没有指定
CMD echo "-------hello-------"     # 生成完之后发一段消息
CMD /bin/bash                      # 生成完之后执行的命令
# 这里的每个命令就是镜像的一层

-	编写完成后使用以下命令来构建镜像
	docker build -f /home/dockerfile -t demo/ubuntu:1.0 .
	-f(from)   通过什么文件来构建,后面接构建文件的地址
	-t   生成文件的版本

Docker学习_第23张图片

  • 启动自己构建的容器
  • 使用docker image ls查看镜像
    在这里插入图片描述
  • 使用以下命令启动自己的容器
  • docker run -it --name docker01 demo/ubuntu:1.0
  • 启动后可以看到volume01和volume02两个目录,这两个就是容器内同步的卷目录。
    Docker学习_第24张图片
  • 同步操作的验证:
  • 首先在容器的卷目录中写一个文件。
    在这里插入图片描述
  • 在容器中使用以下命令查看卷挂载的路径(在linux终端执行)
  • #查看容器id
  • docker ps
  • #根据容器id查看容器信息
  • docker inspect 容器id
    Docker学习_第25张图片
  • 进入该路径查看可以看到文件已经进行了同步。
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
  • FROM 和 RUN 指令的作用
    - FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
    - RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
    - shell 格式
    - RUN <命令行命令>
    - <命令行命令> 等同于,在终端操作的 shell 命令。
    - exec 格式:
    - RUN [“可执行文件”, “参数1”, “参数2”]
    - 例如:
    - RUN [“./test.php”, “dev”, “offline”] 等价于 RUN ./test.php dev offline
    • 注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
      FROM centos
      RUN yum install wget
      RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
      RUN tar -xvf redis.tar.gz
      # 以上执行会创建 3 层镜像。可简化为以下格式:
      # 以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
      FROM centos
      RUN yum install wget \
          && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
      && tar -xvf redis.tar.gz
      
  • 开始构建镜像
    • 在 Dockerfile 文件的存放目录下,执行构建动作。
    • 以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
    • 注:最后的 . 代表本次执行的上下文路径
    • docker build -t nginx:v3 .
    • 上下文路径
      • 上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
      • 解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
      • 如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
      • 注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
  • Dockerfile指令详解
指令 解释
FROM 基础镜像,在此基础上开始构建
MAINTAINER 指定维护者信息 姓名+邮箱
RUN 构建镜像需要运行的命令
ADD 步骤,添加内容
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 保留端口配置
CMD 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 当构建一个被继承,DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
COPY 基类似ADD,将我们文件拷贝到镜像中
ENV 构建的时候设置环境变量

Docker学习_第26张图片

  • COPY
    - 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
    - 格式:
    - COPY [--chown=:] <源路径1>... <目标路径>
    - COPY [--chown=:] ["<源路径1>",... "<目标路径>"]
    - [–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
    - <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
    - COPY hom* /mydir/
    - COPY hom?.txt /mydir/
    - <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
    • ADD
      • ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似
      • 不同之处如下:
        • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
        • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
    • CMD
      • 类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
      • CMD 在docker run 时运行。
      • RUN 是在 docker build。
      • 作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
      • 注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
      • 格式:
        • CMD
        • CMD [“<可执行文件或命令>”,“”,“”,…]
        • CMD [“”,“”,…] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
          推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
  • ENTRYPOINT
    • 类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
    • 但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。
    • 优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
    • 注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
    • 格式:
    • ENTRYPOINT [“”,“”,“”,…]
    • 可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
    • 示例:
    • 假设已通过 Dockerfile 构建了 nginx:test 镜像:
      FROM nginx
      ENTRYPOINT ["nginx", "-c"] # 定参
      CMD ["/etc/nginx/nginx.conf"] # 变参 
      # 不传参运行
      docker run  nginx:test
      # 容器内会默认运行以下命令,启动主进程。
      nginx -c /etc/nginx/nginx.conf
      # 传参运行
      docker run  nginx:test -c /etc/nginx/new.conf
      # 容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
      nginx -c /etc/nginx/new.conf
      
  • ENV
    • 设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
    • 格式:
      • ENV
      • ENV = =…
      • 以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:
      ENV NODE_VERSION 7.2.0
      RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
        && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
      
  • ARG
    • 构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
    • 构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
    • 格式:
    • ARG <参数名>[=<默认值>]
  • VOLUME
    • 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
    • 作用:
    • 避免重要的数据,因容器重启而丢失,这是非常致命的。
    • 避免容器不断变大。
    • 格式:
      • VOLUME [“<路径1>”, “<路径2>”…]
      • VOLUME <路径>
    • 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
  • EXPOSE
    • 仅仅只是声明端口。
    • 作用:
      • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
      • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
      • 格式:
        • EXPOSE <端口1> [<端口2>…]
  • WORKDIR
    • 指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
    • docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
    • 格式:
      • WORKDIR <工作目录路径>
  • USER
    • 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
    • 格式:
    • USER <用户名>[:<用户组>]
  • HEALTHCHECK
    • 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
    • 格式:
      • HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
      • HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
      • HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
  • ONBUILD
    • 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
    • 格式:
      • ONBUILD <其它指令>
  • LABEL
    • LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
    • LABEL = = = …
    • 比如我们可以添加镜像的作者:
    • LABEL org.opencontainers.image.authors=“runoob”
  • 实战
  • 构建自己的centos镜像,官方的centos基础镜像没有vim 、ifconfig命令,故在官方的基础上增加这几个命令。
  • 编写dockerfile文件
# 书写内容
FROM centos                # 首先会从本地查找该镜像,若没有会在网上下载
MAINTAINER 名字<邮箱>   # 写作者,邮件

ENV MYPATH /usr/local        # 设置环境变量
WORKDIR $MYPATH           # 配置登录进行的路径,引用上面配置的

RUN yum -y install vim            # 安装vim
RUN yum -y install net-tools    # 安装网络工具

EXPOSE 80                              # 暴露80端口

# 打印信息
CMD echo $MYPATH
CMD echo "--------END---------"
CMD /bin/bash
  • 通过命令构建镜像
  • docker build -f dockerfile 文件路径 -t 镜像名:[tag]
  • 具体:docker build -f dockerfile -t mycentor:0.1 .
  • Docker学习_第27张图片
  • 查看镜像docker images
  • 在这里插入图片描述- 运行自己镜像 docker run -it mycentor:0.1
  • 在这里插入图片描述
  • 可以使用docker history 镜像id 来查看变更历史,也可以使用其查看官方的变更历史
  • 在这里插入图片描述
    参考网址:
    https://blog.csdn.net/weixin_43246215/article/details/108934216
    https://www.bilibili.com/video/BV1og4y1q7M4
    https://www.bilibili.com/video/BV1kv411q7Qc

你可能感兴趣的:(云原生,docker,容器,Linux)