Docker 操作之数据卷挂载【云原生】

文章目录

    • [1. 镜像](#1. 镜像)
      • [1.1 基本命令](#1.1 基本命令)
      • [1.2 案例练习](#1.2 案例练习)
    • [2. 容器](#2. 容器)
      • [2.1 基本命令](#2.1 基本命令)
      • [2.2 Nginx 案例](#2.2 Nginx 案例)
      • [2.3 Redis 案例](#2.3 Redis 案例)
    • [3. 数据卷](#3. 数据卷)
      • [3.1 基本命令](#3.1 基本命令)
      • [3.2 Nginx 案例](#3.2 Nginx 案例)
      • [3.3 MySQL 案例](#3.3 MySQL 案例)

1. 镜像

镜像命令一般分两部分组成:repository:tag。比如 mysql:5.7,表示名称加版本。

在没有指定 tag 时,默认是 latest,代表最新版本的镜像。

命令太多记住不,通过 docker --help 就能够查看到 docker 中的所有命令了。

1.1 基本命令

① 获取镜像

获取镜像有两种方式:

① 一种是通过 docker build 命令,把本地的 Dockerfile 文件构建成一个镜像;

② 另一种是通过 docker pull 命令,从 Docker Registry 镜像服务器上拉取镜像(一般都是这种方式)。

powershell 复制代码
docker pull

② 查看镜像

powershell 复制代码
docker images

③ 删除镜像

powershell 复制代码
docker rmi

④ 分享镜像

两种方式:

① 可以通过 docker push 命令,将你的镜像推送到镜像服务器去;

② 用 docker save 命令,将你的镜像打包为一个压缩包,其他人就可以拿着 U 盘来拷贝你的镜像了,最后通过 docker load 命令加载压缩包为镜像

powershell 复制代码
docker save -o nginx.tar nginx:latest
powershell 复制代码
docker load -i nginx.tar

1.2 案例练习

需求:从 DockerHub 中拉取一个 nginx 镜像并查看,再利用 save 将 nginx 镜像导出磁盘,然后再通过 load 把镜像加载回来.

① 首先去镜像仓库 hub.docker.com 搜索 nginx 镜像

② 通过 docker pull nginx 命令就可以拉取最新版本的 nginx 镜像了

记得先启动 docker!

③ 查看一下我们拉取的镜像

④ 将 nginx 镜像导出到 nginx.tar 文件中去

⑤ 将 nginx.tar 文件加载成镜像

在导入镜像之前,我们先把原来的镜像删掉!

2. 容器

2.1 基本命令

① 创建容器

powershell 复制代码
docker run

② 切换容器状态

powershell 复制代码
#运行 → 暂停
docker pause
#暂停 → 运行
docker unpause
powershell 复制代码
#运行 → 停止
docker stop
#停止 → 运行
docker start

③ 查看容器

powershell 复制代码
#查看容器运行状态
docker ps
#查看容器运行日志
docker logs

docker ps 默认只能查看运行中的容器,要想查看全部容器加上 -a 参数!

④ 进入容器内部

powershell 复制代码
docker exec

⑤ 删除指定的容器

powershell 复制代码
docker rm

rmi 删的是镜像,rm 删的是容器,它不仅回收内存、干掉进程,还会把硬件上与该容器相关的所有文件系统也彻底删掉!

2.2 Nginx 案例

需求:创建并运行一个 Nginx 容器,并在主机浏览器访问。进入 Nginx 容器,修改 HTML 文件的内容。

① 运行 Nginx 容器

powershell 复制代码
docker run --name containerName -p 80:80 -d nginx

命令解读:
docker run:创建并运行一个容器
--name:给容器起一个名字
-p:将宿主端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口,宿主端口可以自己设置,容器端口一般是由应用本身决定的
-d:后台运行容器docker
nginx:镜像名称,该容器是基于 nginx 创建的

因为容器是对外隔离的,所以对于外部的用户请求,容器内部是无法感知的。这时候就需要将宿主端口和容器端口做一个映射,用户的请求首先发到宿主机,之后由宿主机再转发给容器去处理。所以,端口映射是容器与外部进行沟通的入口。

执行命令后,返回容器的唯一 id!

② 通过 ifconfig 命令找到虚拟机的 IP 地址

③ 在主机浏览器访问 192.168.149.100:80,成功

④ 回到虚拟机终端,查看一下日志,可以看到我们发起了三次 GET 请求

docker logs -f mn,可以持续输出 mn 容器的日志,Ctrl+C 停止输出!

⑤ 进入容器

powershell 复制代码
docker exec -it mn bash

命令解读:
docker exec:进入容器内部,执行一个命令
-it:给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
mn:要进入的容器名称
bash:进入容器后执行的命令,bash 是一个 Linux 终端交互命令

⑦ 从 DockerHub 官网上找到Nginx 的静态资源目录,回到终端切换到此目录,可以发现我们要修改的 index.html 文件就在这里

⑧ 编辑 index.html 文件,注意容器内部是不支持 vim 编辑的,我们可以用其他的方式来修改

powershell 复制代码
sed -i 's#Welcome to nginx#栈老师不回家哈哈哈#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html

不推荐在容器内修改文件,首先是不方便,其次在容器内修改的文件是没有日志记录的!

⑨ 案例成功,exit 退出容器,stop 停掉容器

⑩ 最后删除容器

运行中的容器不能删除,加上 -f 参数可强行删除!

2.3 Redis 案例

需求:拉取 Redis 镜像,创建并运行一个 Redis 容器,要求支持数据持久化。

① 拉取 Redis 镜像

② 到 DockerHub 搜索 Redis 镜像,查看镜像文档帮助信息,选择支持数据持久化的命令

③ 创建容器,这里我们要加一个端口映射

powershell 复制代码
docker run --name mr -p 6379:6379 -d redis redis-server --appendonly yes

④ 打开防火墙,放行指定端口,最后再关闭防火墙

powershell 复制代码
firewall-cmd --zone=public --add-port=6379/tcp --permanent

⑤ 打开 Redis 客户端看一下,这里的地址是我虚拟机的 IP 地址

⑥ 进入 Redis 容器,添加数据,再回到 Redis 客户端可以看到我们的数据依据添加进来了

其实也可以直接进入 redis-cli:

powershell 复制代码
docker exec -it mr redis-cli

⑦ 我在本机客户端所做的修改,通过 Linux 终端也是可以看到的

3. 数据卷

容器与数据耦合的问题:

① 不便于修改。当我们需要修改 Nginx 的 html 内容时,需要进入容器内部修改,很不方便;

② 数据不可复用。在容器内的修改对外是不可见的。所有修改对新创建的容器是不可以复用的;

③ 升级维护困难。数据在容器内,如果要升级容器必然得删除旧容器,所有的数据也都跟着删除了。

而数据卷可以解除容器与数据的耦合,方便操作容器内的数据,保证数据安全。

数据卷是一个虚拟目录,指向宿主机文件系统中的某个真实的目录。

也可以认为,Nginx 容器中的 html 文件与宿主机文件系统中的 html 文件,通过一个虚拟的数据卷建立起了联系,一个发生改变另一个也跟着发生改变,这就是双向绑定。

有了数据卷之前的问题得以解决:

① 修改方便。我们可以直接在宿主机文件系统中修改文件内容,修改后的结果也会立刻传达给容器文件;

② 数据共享。当有一个新的容器也想采用旧容器的配置数据时,我们完全可以把新容器和旧容器挂在同一个数据卷下,指向宿主文件系统目录,这样数据就得到了共享;

③ 升级容易。容器删除了,但是数据卷是不会删除的,我们升级了新的容器,然后把它挂在之前的数据卷上,这样就可以继续使用旧的数据了。

3.1 基本命令

① 创建、查看、删除数据卷

powershell 复制代码
docker volume

docker volume 命令是数据卷操作,根据命令后跟随的 command 来决定下一步的操作:

create:创建一个数据卷
inspect:显示一个或多个数据卷信息
ls:列出所有的数据卷
prune:删除未使用的数据卷
rm:删除一个或多个指定的数据卷

Mountpoint 就是数据卷的挂载点,它是一个真实的目录!

② 挂载数据卷

我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器目录。

一个数据卷对应一个硬盘目录,容器自行将自己的目录上挂载到数据卷上即可使用。

powershell 复制代码
docker run --name mn -p 80:80 -v html:/root/html -d nginx

命令解读:
docker run:创建并运行容器
--name mn:给容器 起个名字叫 mn
-v html:/root/html:把 html 数据卷挂载到容器内的 /root/html 这个目录中
-p 80:80:把宿主机的 80 端口映射到容器的 80 端口
nginx:依据 nginx 镜像创建容器

3.2 Nginx 案例

需求:上个案例中,我们进入 Nginx 容器内部,依据指定 Nginx 的 html 目录的所在位置 /usr/share/nginx/html,我们需要把这个目录挂载到 html 这个数据卷上,方便操作其中的内容。

① 创建 html 数据卷

② 创建 Nginx 容器,并将 html 所在目录挂载到数据卷上

powershell 复制代码
docker run --name mn -p 80:80 -v html:/root/html -d nginx

当数据卷不存在的时候,Docker 会帮我们自动创建!

③ 切换到 html 数据卷的挂载点目录,可以看到我们 Nginx 中 /usr/share/nginx/html 目录下的文件已经被挂载到硬盘目录中了

powershell 复制代码
cd /var/lib/docker/volumes/html/_data

④ 接下来复制目录去可视化界面,用高级的客户端工具打开该目录

⑤ 右键打开 index.html 就可以编辑了

⑦ 看一下我们的编辑内容已经保存成功,再去浏览器访问一下容器,成功

在本地用高级编辑器所做的修改将会通知给容器,最终访问到 index.html 页面,我们再也不用忍受容器内低端的 vim 编辑模式了!

3.3 MySQL 案例

需求:创建并运行一个 MySQL 容器,将宿主机目录直接挂载到容器。

① 挂载 /tem/mysql/data 到 mysql 容器内的数据存储目录;

② 挂载 /tem/mysql/config/hmy.cnf 到 mysql 容器的配置文件;

③ 设置 MySQL 密码。

以前我们是先将容器目录挂载到数据卷,再由数据卷指向具体的宿主机目录。其实,我们完全可以将宿主机目录直接挂载到容器上。

powershell 复制代码
#目录挂载与数据卷挂载的语法是类似的:
-v 宿主机目录:容器内目录
-v 宿主机文件:容器内文件

① FinalShell 控制台切换到 tmp 目录,然后将本地的 mysql.tar 拖拽到 Linux 的该目录下

② 将该文件上传为一个镜像,并查看版本号

powershell 复制代码
docker load -i mysql.tar

③ 创建宿主机目录

powershell 复制代码
#-p创建多级目录
mkdir -p mysql/data
mkdir -p mysql/config

④ 将 hmy.cnf 拖拽到 config 目录

⑤ 查阅 DockerHub,找到 mysql 镜像的使用方法,-e 就可以直接设置 mysql 密码,其实这里还缺两个配置项,端口映射和数据卷挂载

⑥ 创建容器,设置 mysql 密码,并将宿主机目录挂载到容器目录,容器目录从官方文档查看

powershell 复制代码
docker run --name mysql -e MYSQL_ROOT_PASSWORD=123 -p 3306:3306 -v /tem/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf -v /tmp/mysql/data:/var/lib/mysql -d mysql:5.7.25

⑦ 创建数据库,并连接本地 mysql 客户端测试一下

数据卷挂载和目录挂载的区别:

① 数据卷挂载:自动化,隐藏目录细节,耦合度低。 挂载点目录由数据卷自动帮我们生成,我们只需要将容器挂在数据卷上就 OK 了,整个挂载过程完全是交给 Docker 容器帮我们处理的,使用起来方便,但是它的劣势也很明显,因为这个目录是由数据卷自动帮我们生成的,目录深且复杂,我们到时候找的时候不好找,需要查看数据卷的详细信息才能找到具体的存储位置;

② 目录挂载:需要手动管理,目录容易查找,耦合度高。 宿主机目录和容器目录直接交互,无需中间的数据卷参与,这种方式在创建容器时需要自己指定宿主机的目录,写起来麻烦,但是优点就是自己创建的目录找起来方便,能够快速定位到文件的目录。

相关推荐
Dusk_橙子4 小时前
在K8S中,nodePort的externalTrafficPolicy字段有什么作用?
云原生·容器·kubernetes
dessler8 小时前
Dokcer-Dockerfile案例(二)
linux·运维·docker
FF在路上9 小时前
Docker应用-项目部署及DockerCompose
运维·docker·容器
Elastic 中国社区官方博客11 小时前
从 ELK Stack 到简单 — Elastic Cloud Serverless 上的 Elastic 可观察性
大数据·数据库·elk·elasticsearch·搜索引擎·云原生·serverless
小陈far12 小时前
Docker中的MYSQL导入本地SQL语句
sql·mysql·docker
angelasp13 小时前
Docker部署neo4j
docker·容器·neo4j
YOLO_WY14 小时前
Docker 开启远程端口访问2375
docker
运维小文14 小时前
K8S中,pod的创建流程
云原生·容器·kubernetes
大飞哥~BigFei14 小时前
Docker安装体验kuboard-k8s多集群管理工具
docker·容器·kubernetes·kuboard
m0_7482382715 小时前
开源轻量级文件分享服务Go File本地Docker部署与远程访问
docker·golang·开源