Docker学习

认识docker

什么是docker

docker是一个用Go语言实现的开源项目,可以让我们方便的创建和使用容器,docker将程序以及程序所有的依赖都打包到docker container,这样你的程序可以在任何环境都会有一致的表现,这里程序运行的依赖也就是容器就好比集装箱,容器所处的操作系统环境就好比货船或港口,程序的表现只和集装箱有关系(容器),和集装箱放在哪个货船或者哪个港口(操作系统)没有关系。

如何使用docker

docker中有这样几个概念:

  • dockerfile
  • image
  • container

实际上可以简单的把image理解为可执行程序,container就是运行起来的进程。

那么写程序需要源代码,那么“写”image就需要dockerfile,dockerfile就是image的源代码,docker就是“编译器”。

因此我们只需要在dockerfile中指定需要哪些程序、依赖什么样的配置,之后把dockerfile交给“编译器”docker进行“编译”,也就是docker build命令,生成的可执行程序就是image,之后就可以运行这个image了,这就是docker run命令,image运行起来后就是docker container。

docker如何工作

docker client负责处理用户输入的各种命令,比如docker build、docker run,真正工作的其实是server,也就是docker demon,值得注意的是,docker client和docker demon可以运行在同一台机器上。

接下来我们用几个命令来讲解一下docker的工作流程:

①docker build
当我们写完dockerfile交给docker“编译”时使用这个命令,那么client在接收到请求后转发给docker daemon,接着docker daemon根据dockerfile创建出“可执行程序”image。
在这里插入图片描述
②docker run
有了“可执行程序”image后就可以运行程序了,接下来使用命令docker run,docker daemon接收到该命令后找到具体的image,然后加载到内存开始执行,image执行起来就是所谓的container。
在这里插入图片描述
③docker pull
docker中image的概念就类似于“可执行程序”,可以从Docker Hub下载别人写好的image,这样就不用自己编写dockerfile了。

docker registry 可以用来存放各种image,公共的可以供任何人下载image的仓库就是docker Hub。

使用docker pull可以下载image,用户通过docker client发送命令,docker daemon接收到命令后向docker registry发送image下载请求,下载后存放在本地,这样我们就可以使用image了。
在这里插入图片描述

docker与vm区别

Docker 是一种轻量级的虚拟化技术,目的和虚拟机一样,都是为了创造“隔离环境”。但是它不像 VM 采用操作系统级的资源隔离,容器采用的是进程级的系统隔离。

  • VM:使用 Hypervisor 提供虚拟机的运行平台,管理每个 VM 中操作系统的运行。每个 VM都要有自己的操作系统、应用程序和必要的依赖文件等。
  • Docker 容器:使用Docker引擎进行调度和隔离,提高了资源利用率,在相同硬件能力下可以运行更多的容器实例;每个容器拥有自己的隔离化用户空间。

基本概念

docker 有三大基本概念,分别是镜像(Image)、容器(Container)和仓库(Repository)。镜像是 Docker 容器运行的前提,仓库是存放镜像的场所。

docker 镜像(Docker Image)

docker 镜像(Image),就相当于是一个 root 文件系统。

docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像使用分层存储,镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

docker 容器(Docker Container)

通过镜像运行的实例称之为容器,两者的关系就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

Docker 利用容器来运行应用,每个容器都是相互隔离的、保证安全的平台。我们可以把容器看做是一个轻量级的Linux 运行环境。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
在这里插入图片描述
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume),或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

docker仓库(Docker Repository )

Docker Repository 用于镜像的集中存储、分发的地方。有了它,镜像在构建完成后,在其他机器上就可以非常方便的下载使用这个镜像了。

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签,表示最新的一个版本。

以 Ubuntu 镜像为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。

仓库名经常以以两段式路径形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。

公有仓库
公有仓库是允许用户免费上传、下载的公开镜像服务。比如官方的 Docker Hub ,也是默认的 Docker Repository,里面拥有着大量的高质量镜像。但是国内访问它可能比较慢,国内的云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为镜像加速器。国内常见有阿里云加速器、网易加速器、DaoCloud 加速器等。

本教程提供了阿里云加速器的配置方法,链接如下:

Docker 配置阿里云镜像加速器

私有仓库
除了公有仓库外,用户还可以在本地搭建私有仓库。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。

Docker安装

https://www.quanxiaoha.com/docker/docker-search-image.html

在这里插入图片描述

Docker使用

docker Hello world
在这里插入图片描述
Docker 允许你在容器内运行应用程序,使用 docker run 命令来在容器内运行一个应用程序。
例,输出Hello world。

root@ubuntu:~# docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world

各个参数解析:

  • docker: Docker 的二进制执行文件。
  • run:与前面的 docker 组合来运行一个容器。
  • ubuntu:15.10指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库
    Docker Hub 下载公共镜像。
  • /bin/echo “Hello world”: 在启动的容器里执行的命令

以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果。

运行交互式的容器
我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现"对话"的能力:

docker run -i -t ubuntu:15.10 /bin/bash
root@16452c56c56f:/# 

各个参数解析:

-t: 在新容器内指定一个伪终端或终端。

-i: 允许你对容器内的标准输入 (STDIN) 进行交互。

注意第二行root@16452c56c56f:/# ,此时我们已进入一个 ubuntu15.10 系统的容器

我们尝试在容器中运行命令 cat /proc/version和ls分别查看当前系统的版本信息和当前目录下的文件列表

root@16452c56c56f:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

我们可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。

root@16452c56c56f:/# exit

启动容器(后台模式)

使用以下命令创建一个以进程方式运行的容器

runoob@runoob:~$ docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
fd0e4ac8775a3079f64abd0133ea5fa97e5dacff3e9ec07de1456be36ea9de43

在输出中,我们没有看到期望的 “hello world”,而是一串长字符

fd0e4ac8775a3079f64abd0133ea5fa97e5dacff3e9ec07de1456be36ea9de43

这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。

首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:

root@ubuntu:~# docker ps

在这里插入图片描述
输出详情介绍:

  • CONTAINER ID:容器 ID。
  • IMAGE:使用的镜像。
  • COMMAND:启动容器时运行的命令。
  • CREATED:容器的创建时间。
  • STATUS:容器状态。

状态有7种:

  • created(已创建)
  • restarting(重启中)
  • running 或 Up(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)

PORTS:容器的端口信息和使用的连接类型(tcp\udp)。

NAMES:自动分配的容器名称。

在宿主主机内使用 docker logs 命令,查看容器内的标准输出:
root@ubuntu:~# docker stop fd0e4ac8775a

在这里插入图片描述
我们使用 docker stop 命令来停止容器
在这里插入图片描述

Docker镜像使用

一,列出镜像列表
我们可以使用 docker images 来列出本地主机上的镜像。
在这里插入图片描述
各个选项说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:

root@ubuntu:~# docker run -t -i ubuntu:15.10 /bin/bash 
root@d77ccb2e5cca:/#

二,获取一个新的镜像
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。

root@ubuntu:~# docker pull ubuntu:13.10

三,查找镜像
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/

我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。

root@ubuntu:~# docker search httpd

四,拖取镜像
我们决定使用 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像:docker pull httpd
在这里插入图片描述

五,删除镜像
镜像删除使用 docker rmi 命令,比如我们删除 httpd 镜像:docker rmi httpd
在这里插入图片描述

比如删除image id为56f4649dfd93的镜像:docker rmi 56f4649dfd93
在这里插入图片描述
从创建镜像到删除的完整过程:
在这里插入图片描述
(docker的删除有两种,一个是rm 删除容器,一个是rmi删除镜像)

六,创建子镜像
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

①从已经创建的容器中更新镜像,并且提交这个镜像

更新镜像之前,我们需要使用镜像来创建一个容器。

root@ubuntu:~#docker run -t -i ubuntu:15.10 /bin/bash
root@69ef002b1b0d:/# exit

在运行的容器内使用 apt-get update 命令进行更新。

在完成操作之后,输入 exit 命令来退出这个容器。

此时 ID 为69ef002b1b0d的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。

root@ubuntu:~# docker commit -m="has update" -a="runoob" 69ef002b1b0d runoob/ubuntu:v2
sha256:56f4649dfd9326838ff82cf518b5f55683e737f69eb82826b92a6a2f4d87a134

在这里插入图片描述

各个参数说明:

  • -m: 提交的描述信息
  • -a: 指定镜像作者
  • e218edb10161:容器 ID
  • runoob/ubuntu:v2: 指定要创建的目标镜像名

在这里插入图片描述

使用我们的新镜像 runoob/ubuntu 来启动一个容器:(新镜像是原来的子镜像,此时无法删除父镜像)

root@ubuntu:~# docker run -t -i runoob/ubuntu:v2 /bin/bash  

在这里插入图片描述

②使用 Dockerfile 指令来创建一个新的镜像

Docker容器使用

1,查看所有容器docker ps -a
在这里插入图片描述
2,启动容器,以下命令使用 ubuntu 镜像启动一个新容器,参数为以命令行模式进入该容器:

root@ubuntu:~# docker run -it ubuntu:15.10 /bin/bash
root@69ef002b1b0d:/# exit
exit

此时添加了一个新容器。
在这里插入图片描述
在这里插入图片描述
参数说明:

  • -i: 交互式操作。
  • -t: 终端。
  • ubuntu: ubuntu 镜像。
  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

要退出终端,直接输入 exit:

root@0104ce9e8a4a:/# exit
exit

4,使用 docker start启动一个已停止的容器: docker start <容器 ID>

root@ubuntu:~# docker start 0104ce9e8a4a
0104ce9e8a4a

停止的容器可以通过 docker restart 重启:docker restart <容器 ID>

root@ubuntu:~# docker restart 0104ce9e8a4a
0104ce9e8a4a

5,进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:docker attach <容器ID>

下面演示了使用 docker attach 命令。
在这里插入图片描述
输入exit后会导致容器停止:

Error response from daemon: container 0104ce9e8a4aebd7cc1973588e88784920b282c7b0cf73e7ed76c05317693eff is not running

docker exec:推荐大家使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。
在这里插入图片描述
6,导入导出容器
①导出容器

如果要导出本地某个容器,可以使用 docker export 命令。

docker export 1e560fca3906 > ubuntu.tar

导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。

这样将导出容器快照到本地文件。

②导入容器快照

可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:

cat docker/ubuntu.tar | docker import - test/ubuntu:v1

7,后台运行
在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。

docker run -itd --name ubuntu-test ubuntu:15.10  /bin/bash

7,使用docker rm -f <容器ID> 来删除容器。

root@ubuntu:~# docker rm -f 2e6403c43331
2e6403c43331
root@ubuntu:~# docker rm -f fd0e4ac8775a 
fd0e4ac8775a

在这里插入图片描述

Docker容器连接

连接mysql

一,Docker安装mysql
1,查看可用版本
在这里插入图片描述
在这里插入图片描述
2,拉取mysql镜像
这里我们拉取官方的最新版本的镜像:

root@ubuntu:~# docker pull mysql:latest

3,查看本地镜像:docker images

4,运行容器
安装完成后,我们可以使用以下命令来运行 mysql 容器:

root@ubuntu:~# docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

参数说明:

  • -p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过宿主机ip:3306 访问到 MySQL 的服务。
  • –name mysql-test mysql (前者为names,后者为images)
  • MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。
    5,进入mysql
root@ubuntu:~# docker start mysql-test
mysql-test
root@ubuntu:~# docker exec -it mysql-test /bin/bash
bash-4.4# mysql -uroot -p123456
mysql> show databases;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

docker安装nginx

下载并运行Nginx镜像

root@ubuntu:~# docker run -d -p 80:80 --name nginx nginx:1.19.4

参数说明:

  • -p 80:80: 将容器的 80 端口映射到宿主机的 80 端口上
  • -d: 以后台方式运行镜像;
  • –name: 指定容器的名称为 nginx; 命令执行完成后
  • docker ps命令确认一下容器是否启动成功。
    在这里插入图片描述
    复制 Nginx 配置文件至宿主机
    因为容器重启会丢失内部数据,因此要将需要持久化的文件挂载到宿主机中,以防数据丢失。

挂载之前,复制容器中需要持久化的相关配置文件到宿主机的指定路径下:

 #复制名称为 nginx 容器中 /etc/nginx/nginx.conf 文件夹到宿主机的 /nginx 路径下,宿主机的持久化目录根据你的需要自定义路径
root@ubuntu:~# docker cp nginx:/etc/nginx/nginx.conf /nginx
# 复制名称为 nginx 容器中 /etc/nginx/conf.d 文件到宿主机的 /nginx 路径下
root@ubuntu:~# docker cp nginx:/etc/nginx/conf.d /nginx

在这里插入图片描述

Docker 网络

容器与主机、容器与容器之间是互相隔离的。同时,我们可以通过配置 docker 网络,为容器创建完全独立的网络命名空间,或者使容器共享主机或者其他容器的网络命名空间,以应对不同场景的需要。

这里有4种常用的单宿主机网络模式:
1.bridge 模式
2.host 模式
3.container 模式
4.none 模式

bridge模式

Docker 服务启动时,会自动在宿主机上创建一个 docker0 虚拟网桥 (Linux Bridge, 可以理解为一个软件虚拟出来的交换机)。它会在挂载到它的网口之间进行转发。同时 Docker 随机分配一个可用的私有 IP 地址给 docker0 接口。如果容器使用默认网络参数启动,那么它的网口也会自动分配一个与 docker0 同网段的 IP 地址。

我们使用命令 ip address show dev docker0 获取 docker0 网络信息,它的地址是 172.17.0.1, 子网掩码为 255.255.0.0,如下图所示:
在这里插入图片描述
我们来做个测试,看看默认新建的容器是否能互相连通。
使用 busybox 镜像分别运行 b0,b1 两个容器:

docker run -d -t --name b0 busybox
docker run -d -t --name b1 busybox

容器新建并运行成功后,查看两个容器的 IP 地址:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' b0
docker inspect --format '{{ .NetworkSettings.IPAddress }}' b1

在这里插入图片描述
两个容器互相 ping 一下,证明它们的网络能连通:

docker exec -it b0 ping 172.17.0.3
docker exec -it b1 ping 172.17.0.2

在这里插入图片描述
在这里插入图片描述
此时网络拓扑结构如下所示:
在这里插入图片描述
端口映射访问容器
将宿主机的本地端口,与指定容器的服务端口进行映射绑定,之后访问宿主机端口时,会将请求自动转发到容器的端口上,实现外部对容器内网络服务的访问。

创建名为 n0 的 nginx 容器,映射宿主机 8000 端口到它的 80 端口

docker run -d -t -p 8000:80 --name n0 nginx

Tips:指定的宿主机端口必须是未被占用的端口,否则操作会失败,且生成一个无法正常启动的容器 n0, 需要手动删除。

使用 docker port n0 查看 n0 的端口映射信息,显示如下:
在这里插入图片描述打开浏览器,地址栏输入 http://localhost:8000 或 http:// 宿主机 IP:8000, 都能访问到 n0 的 nginx 服务。

①如果需要绑定多个容器端口,可以连续使用 -p 参数多次指定

docker run -d -t -p 8001:80 -p 8433:443 --name n1 nginx

②如果不想主动指定宿主机端口,可以使用 -P 参数,宿主机随机使用一个可用端口与容器端口进行映射

docker run -d -t -p --name n2 nginx

③如果只想使用宿主机上特定的网口与容器进行映射

docker run -d -t -p 192.168.32.149:8002:80 --name n3 nginx

Tips:此处192.168.32.149 指代宿主机映射网口的 IP 地址,需要根据网口的实际 IP 更改。
在这里插入图片描述
我们执行 docker ps 可能出现如下几个的 nginx 容器:
在这里插入图片描述
再执行 iptables -t nat -nL 查看下防火墙:
在这里插入图片描述
比对上面两个的输出,不难发现,这种端口转发方式的本质是通过配置 iptables 规则转发实现的,效率较低,如果容器的服务端口数量过多,需要配置较多的映射,占用大量宿主机端口,也不便于管理。

不再使用的容器记得删除掉,释放资源和空间

docker rm -f n0 n1 n2 n3

host模式

host 模式下启动的容器,网络不再与宿主机隔离,访问容器服务可以直接使用访问宿主机对应的网络端口,且不需要端口转发。网络拓扑图如下:
在这里插入图片描述
以 host 模式启动 nginx 的容器 h0:

docker run -d -t --network host --name h0 nginx

启动成功后,在浏览器输入任意的本机地址,都可以打开 nginx 的默认页面,访问宿主机80端口就是访问容器的80端口,它们是一致的。

以 host 模式启动 nginx 的容器 h1:

docker run -d -t --network host --name h1 nginx

container模式

与 host 模式类似,container 模式可以使一个容器共享另一个已存在容器的网络,此时这两个容器共同使用同一网卡、主机名、IP 地址,容器间通讯可直接通过本地回环 lo 接口通讯。新运行一个 busybox 的容器 b1,设定它共享已存在的容器 b0 的网络:

docker run -d -t --network container:b0 --name b1 busybox

Tips:端口转发设定以已存在的容器为准,出于安全和权限控制的角度,container 模式下运行的容器设定端口转发不生效。
查看 b0,b1 的网络配置,验证两者的网络配置是否相同:

docker exec b0 ifconfig
docker exec b1 ifconfig

在这里插入图片描述
在这里插入图片描述
此时的网络拓扑图如下:
在这里插入图片描述
不再使用的容器记得删除掉,释放资源和空间

docker rm -f b0 b1

nginx 镜像自带的网络命令非常少,查看网络不方便,而 busybox 的网络命令比较齐全,使用 container 模式,可以快速解决这个问题。我们新运行一个名为 n0 的 nginx 容器,再将它的网络共享给 busybox 容器 n0-net:

docker run -d -t --name n0 nginx
docker run -d -t --network container:n0 --name n0-net busybox

使用 n0-net 容器,执行 docker exec n0-net ip a 进行网络状态查看自身网络信息,也就是 nginx 的网络信息:
在这里插入图片描述

执行如下命令,通过 localhost 访问 n0 的 web 服务,说明通过 container 模式下,共享的网络中的容器能够使用 lo 访问其他容器的服务。

docker exec  n0-net telnet localhost 80 #不显示
docker exec -it n0-net telnet localhost 80 #显示信息

不再使用的容器记得删除掉,释放资源和空间:docker rm -f n0 n0-net

Docker数据管理-挂载目录或文件

挂载宿主机目录

我们可以将宿主机的目录,挂载到容器内,容器与宿主机的目录可以实时共享。在宿主机上执行如下命令:

# 新建一个目录
mkdir -p ~/mydir/tmp
# 在目录中新建一个文件,填充内容 hello docker
echo "hello docker" >  ~/mydir/tmp/text.txt 

然后新建一个容器 busybox,将 /mydir/tmp 目录挂载到容器的 /tmp/ 目录:

docker run -d -it --name busybox -v ~/mydir/tmp/:/tmp/ busybox

Tips:挂载宿主操作系统目录的参数是 -v <宿主机目录路径>:<容器目录路径>。

确认查看容器对应的文件内容:

docker exec -it busybox cat /tmp/test.txt

在这里插入图片描述

挂载宿主机文件

我们也可以将宿主机的文件挂载到容器内,实现文件的共享。新建一个容器 busybox1,将 /mydir/tmp/test.txt 文件挂载到容器的 /tmp/test.txt:

docker run -d -it --name busybox1 -v ~/mydir/tmp/test.txt:/tmp/test.txt busybox

确认容器对应的文件内容:

docker exec -it busybox1 cat /tmp/test.txt

在这里插入图片描述
Tips:使用 docker rm -f busybox busybox1 移除不再使用的容器

Docker 数据管理 - 数据卷

我们知道,Docker 提供了两类数据管理的方式:

挂载宿主机目录或文件;
使用数据卷;

使用数据卷的好处就在于:我们不必自己维护一个外部路径挂载和存储的关系,借助Docker管理数据,并且通过语义化数据卷命名,更加方便直观地使用它来数据共享。

概念与特性

什么是数据卷
简单来说,数据卷是一个可供一个或多个容器使用的特殊目录,用于持久化数据以及共享容器间的数据,它以正常的文件或目录的形式存在于宿主机上。 另外,其生命周期独立于容器的生命周期,即当你删除容器时,数据卷并不会被删除

数据卷特性
①数据卷可以在容器之间共享和重用;
②对数据卷的修改会立刻生效;
③更新数据卷不会影响镜像;
④数据卷默认一直存在,即使容器被删除;

挂载数据卷
在使用数据卷进行挂载时,我们只需指定容器中被挂载的目录即可,如:

docker run -d -it --name busybox -v mydata:/tmp busybox

常用数据卷
1,volume : Docker 管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录下,也是最常用的方式。
在这里插入图片描述

看上图,所有的 Docker 容器数据都保存在
/var/lib/docker/volumes 目录下。若容器运行时未指定数据卷, Docker 创建容器时会使用默认的匿名卷(名称为一堆很长的 ID)。

2,bind mount
bind mount : 意为可以存储在宿主机中的任意位置。需要注意的是,bind mount 在不同的宿主机系统时不可移植的,比如 Windows 和 Linux 的目录结构是不一样的,bind mount 所指向的 host 目录也不一样。这也是为什么 bind mount 不能出现在 Dockerfile 中的原因所在,因为这Dockerfile 就不可移植了。

volume使用

创建一个数据卷

root@ubuntu:~# docker volume create vol-test
#查看数据卷名为vol-test的信息
root@ubuntu:~# docker volume ls

在这里插入图片描述
查看数据卷信息

root@ubuntu:~# docker volume inspect vol-test

在这里插入图片描述

共用数据卷

通过挂载相同的数据卷,让多个容器能够操作数据卷中的数据,实现容器间的目录共享。

数据卷的命名在 Docker 中是唯一的,让多个容器挂载同一个数据卷, 只需要指定同一个数据卷名称即可。

docker run -d -it --name busybox -v mydata:/tmp busybox
docker run -d -it --name busybox1 -v mydata:/tmp busybox

挂载数据卷时,如果数据卷不存在,Docker 会自动创建,如果同名数据卷已经存在,则直接引用。

这里我们再补充一些常用的数据卷操作:

# 删除数据卷
docker volume rm mydata
# 手动创建数据卷
docker volume create mydata
# 删除那些没有被容器引用的数据卷
docker volume prune
  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值