Docker 的基本操作

发布于:2024-06-05 ⋅ 阅读:(45) ⋅ 点赞:(0)

大家好 , 今天我要和大家分享一个现代软件开发中不可或缺的工具 - Docker . 在这个快速发展的技术时代 , 我们经常面临着应用部署的复杂性、环境差异以及不同操作系统之间的兼容性问题 . 这些问题不仅消耗大量时间 , 还可能导致项目延期和成本增加 . Docker 的出现解决了我们在应用部署过程中遇到的障碍和挑战 . 通过将应用程序及其依赖环境封装在一个轻量级的、可移植的容器中 , Docker 不仅简化了开发和部署流程 , 还确保了不同环境间的无缝衔接和一致性 .

docker01.png

本文参考资源 : https://www.bilibili.com/video/BV1HP4118797/?spm_id_from=333.337.search-card.all.click

专栏地址 : https://blog.csdn.net/m0_53117341/category_12682419.html

文章目录

一 . 镜像操作

镜像的名称一般都由两部分组成 : [repository]:[tag]
比如 mysql:5.7 , mysql 就是 Repository , 5.7 就是 Tag (版本) , 因此 mysql:5.7 和 mysql:5.6 其实是两个版本的镜像 .
如果没有指定 tag , 默认就是 latest (最新版本的镜像)

1.1 镜像操作命令

我们常见的镜像操作命令如下 :
image.png
其中的命令如下

# 后续详细介绍
# 构建镜像
docker build

# 从服务器中拉取镜像
docker pull

# 推送本地镜像到服务
docker push

# 查看本地镜像
docker images

# 删除镜像 
docker rmi

# 将镜像保存为压缩包 (可以 U 盘传给同事)
docker save

# 解压缩压缩包
docker load

如果记不住这些命令 , 我们还可以查阅帮助手册

docker --help

image.png
我们还可以查看某个具体的命令的用法

docker images --help

image.png

1.2 案例 1 : 从 DockerHub 中拉取 nginx 镜像并查看

1.2.1 拉取镜像

首先 , 我们就需要先访问 DockerHub 的网站 : https://hub.docker.com/
然后搜索 nginx
image.png
然后就展示出了一系列结果
image.png
然后点击这个镜像
image.png
我们将官方提供的命令复制下来 , 然后进行粘贴

docker pull nginx

下载可能会比较缓慢 , 稍等片刻
image.png

1.2.2 查看镜像

我们使用这条命令查看本地存在的镜像

# 本地存在的镜像
docker images

image.png
我们可以观察一些字段

  • TAG : 他是 latest , 代表最新版本 .
  • IMAGE ID : 该镜像对应的 ID
  • CREATED : 创建时间 (这个镜像是 12 天前官方创建 / 更新的)
  • SIZE : 该镜像的大小

1.3 案例 2 : 利用 docker save 将 nginx 镜像导出磁盘 , 然后再通过 load 加载回来

1.3.1 导出镜像

我们可以通过 docker --help 命令来查看一下帮助文档

# 查看 save 命令的用法
docker save --help

image.png
那 Usage 就是 save 命令的用法了

# [OPTIONS]: 选项,-o 选项表示输出到哪里
# IMAGE: 要输出的镜像
docker save [OPTIONS] IMAGE [IMAGE...]

我们可以试验一下
image.png

docker save -o nginx.tar nginx:latest

image.png

1.3.2 导入镜像

我们先把本地的 nginx 镜像删除掉

# 删除 nginx 镜像
docker rmi nginx:latest

image.png
然后再将我们刚才导出的镜像重新导入进来
我们先来看一下 docker load 的用法

# 查看导入镜像的语法
docker load --help

image.png
-i 参数表示要读取哪个镜像 , 所以我们就选择 -i 参数

# 导入镜像
docker load -i nginx.tar

image.png

1.4 案例 3 : 从 DockerHub 上搜索并拉取一个 Redis 镜像

第一步 : 去 DockerHub 搜索 Redis 镜像
访问 DockerHub 的官方网站 : https://hub.docker.com/
然后搜索 Redis
image.png
然后我们选择官方推荐的 Redis 镜像
image.png
第二步 : 查看 Redis 镜像的名称和版本
第三步 : 利用 docker pull 命令拉取镜像
我们直接复制 DockerHub 提供给我们的命令即可
image.png

docker pull redis

image.png
我们可以查看本地都有哪些镜像

docker images

image.png
第四步 : 利用 docker save 命令将 redis:latest 打包成一个 redis.tar 包

docker save -o redis.tar redis:latest

image.png
第五步 : 利用 docker rmi 删除本地的 redis:latest

docker rmi redis:latest

image.png
第六步 : 利用 docker load 重新加载 redis.tar 文件

docker load -i redis.tar

image.png

二 . 容器操作

2.1 容器相关命令

image.png
那我们分别列举出上面的命令

# 创建并运行容器
docker run

# 运行 -> 暂停
docker pause

# 暂停 -> 运行
docker unpause

# 运行 -> 停止
docker stop

# 停止 -> 运行
docker start

# 查看所有运行的容器以及状态
docker ps

# 查看所有容器以及状态
docker ps -a

# 查看容器的运行日志
docker logs

# 进入容器中执行一些命令
docker exec

# 删除容器
docker rm

2.2 创建并运行一个 Nginx 容器

我们首先来到 nginx 的详情页面
https://hub.docker.com/_/nginx
然后往下翻 , 找到 How to use this image , 在这个位置就会展示出具体的容器创建方法
image.png
那下面给出了许多命令 , 我们可以选择一条简单的 , 比如这个 :
image.png
那我们可以来分析一下这段命令的含义

$ docker run --name some-nginx -d -p 8080:80 some-content-nginx
  • docker run : 创建并运行一个容器
  • –name : 给容器起一个名 , 叫做 some-niginx
  • -d : 让容器后台运行
  • -p : 将宿主机端口与容器端口进行映射 , 冒号左侧是宿主机端口 , 右侧是容器端口

我们这里将宿主机的 8080 端口与容器的 80 端口进行绑定

  • some-content-nginx : 要操作的镜像的名称

那我们也可以试验一下

# docker run : 创建并运行一个容器
# --name : 给容器起一个名, 叫做 mynginx
# -p 80:80 : 将宿主机的 80 端口与容器的 80 端口进行绑定
# -d : 让容器后台运行
# nginx : 要操作的镜像名称
docker run --name mynginx -p 80:80 -d nginx

image.png
那执行完这条命令 , 就会返回给我们一个独一无二的容器 ID
我们可以查看该容器是否运行成功

# 查看所有运行的容器以及状态
docker ps

image.png
那接下来我们就可以访问 80 端口来验证一下 nginx 容器是否创建成功
image.png
那访问了 nginx , 肯定就会有日志产生 , 我们也可以看一下

# 查看容器生成的日志
docker logs mynginx

image.png
那我们每次想要查看新的日志 , 就需要重新输入一次命令 , 我们能不能动态的渲染日志呢 ?
我们可以通过 docker 手册来看一下

# 查看 logs 命令的用法
docker logs --help

我们观察一下 , 发现 -f 参数可以实现日志的持续输出
image.png
那我们就执行一下这条命令

# 持续动态输出日志
docker logs -f mynginx

-f 动态刷新.gif

2.3 案例 1 : 进入 Nginx 容器 , 修改 HTML 文件内容 , 添加 “Hello World”

2.3.1 进入容器

那我们之前也介绍过进入容器的命令

# 可以进入容器中执行一些命令
docker exec

这个命令可以进入到 Nginx 容器中 , 去执行一些命令
那我们详细分析解读一下这个命令

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

image.png
那我们就可以在当前状态下执行一些命令 , 比如 : pwd
image.png

2.3.2 进入 nginx 的 HTML 所在目录 /usr/share/nginx/html

那接下来我们想修改 Nginx 提供的 HTML 文件的位置 , 那这个文件在哪找呢 ?
我们还是需要回到 Docker Hub 的界面来找一下
image.png
那接下来我们跳转到这个目录即可

cd /usr/share/nginx/html

image.png
那我们通过 vim 直接修改这个代码即可

vim index.html

但是他提示找不到此命令
image.png
这是因为我们之前也介绍过 , Docker 镜像封装的时候 , 只会封装一些需要的函数库 , 那这就代表 vim 并未被 nginx 收录进来 .
那我们该怎样修改这个文件呢

2.3.3 修改 index.html

我们需要通过这个命令来进行修改

sed -i -e 's#Welcome to nginx#Hello World#g' -e 's#<head>#<head><meta charset="utf-8">#g' index.html

image.png
那怎样验证呢 , 我们可以重新刷新一下页面来查看效果
image.png

2.3.4 停掉容器

我们先退出进入容器的状态 , 使用 exit 退出即可
image.png
那停止容器的命令如下 :

# 停掉容器
docker stop mynginx

image.png

2.3.5 启动容器

# 启动容器
docker start mynginx

image.png

2.3.6 删除容器

# 删除容器
docker rm mynginx

但是我们发现 , 报错了
image.png
他的意思是说 mynginx 这个容器还在运行 , 不能够删除 .
那我们能否强制删除呢 ? 我们还可以通过帮助手册来看一下

# 查看 rm 用法
docker rm --help

image.png
那我们加一个 -f 参数即可

# 强制删除容器
docker rm -f mynginx

image.png

2.4 案例 2 : 创建并运行一个redis容器 , 并且支持数据持久化

2.4.1 到 DockerHub 中搜索 Redis 镜像

image.png

2.4.2 查看 Redis 镜像中的描述信息

image.png

2.4.3 利用 docker run 命令运行一个 Redis 容器

docker run --name some-redis -d redis redis-server --save 60 1 --loglevel warning

但是我们还需要将这个命令进行一些改造 , 因为他还没进行宿主机和容器端口的绑定
那我们改造之后的命令如下 :

# docker run : 创建并运行容器
# --name myredis : 给当前容器设置名称
# -p 6379:6379 : 将宿主机的 6379 端口与容器的 6379 端口进行绑定
# -d : 让容器后台运行
# redis : 表示要操作的镜像名 
# redis-server : 表示 Redis 服务
# --appendonly yes : 开启 AOF 持久化
docker run --name myredis -p 6379:6379 -d redis redis-server --appendonly yes

image.png

2.4.4 进入 Redis 容器

# docker exec : 进入 Docker 容器
# -it : 提供标准输入输出终端
# myredis : 要进入的容器的名称
# bash : 进入到 Linux 的命令行
docker exec -it myredis bash 

image.png

2.4.5 执行 Redis 客户端

那我们此时已经进入到了 Linux 的终端 , 我们此时就可以再进入到 Redis 客户端

redis-cli

image.png
那我们就可以写入数据了

set k1 v1

image.png

2.4.6 直接进入到 Redis 客户端

我们刚才进入容器 , 是访问的 bash 命令行 , 那我们能否直接访问 Redis 客户端呢 ?

docker exec -it myredis redis-cli

image.png

三 . 数据卷

我们之前已经学习了镜像和容器的操作 , 我们发现了一个问题 : 所有的数据都是和容器耦合在一起的 , 因此带来了许多问题

  1. 不便于修改 : 如果我们想要修改数据 , 就必须先进入到容器内部中 , 并且容器内部一般没有什么高级的工具可以进行修改 , 非常麻烦 .
  2. 数据不可复用 : 在容器内的修改 , 对外是不可见的 . 这就导致所有数据的修改 , 对新创建的容器是不可复用的 .
  3. 升级维护困难 : 数据全部存储在容器的内部 , 那如果我们想要更新容器的话 , 就需要删除掉旧的容器 , 这也会导致数据被删除掉 .

那为了解决这些问题 , Docker 推出了一个叫做 “数据卷” 的东西 .

3.1 什么是数据卷 ?

数据卷是一个虚拟的目录 , 它指向宿主机文件系统中某个具体的目录 .
那容器创建出来 , 就会去使用对应的数据卷 , 数据卷就相当于宿主机和容器之间的桥梁 .
数据卷的作用是将容器与数据分离 , 进行了解耦合 . 这样就方便操作容器内的数据 , 保证了数据的安全 .
数据卷的作用.png

数据卷的作用.png

那这样的话 , 就解决了我们上面提出的问题

  1. 不便于修改 : 容器中的文件与宿主机中的文件通过数据卷一一对应 , 修改了宿主机的文件就相当于修改了容器中的文件
  2. 数据不可复用 : 我们可以让新的容器也来挂载修改过的数据卷 , 这样也解决了数据共享的问题
  3. 升级维护困难 : 如果我们升级版本的话 , 容器中的数据会被删除掉 , 但是数据卷以及宿主机中的数据不会被删除掉 , 之后新版本的容器只需要挂载之前的数据卷即可

3.2 操作数据卷

语法 :

docker volume [command]

那 command 提供了许多选项

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

3.3 案例 1 : 创建一个数据卷 , 并且查看数据卷在宿主机的目录位置

首先 , 我们可以来查看帮助文档

docker volume --help 

image.png
帮助手册提示给了我们许多的参数 , 那我们接下来就逐一演示上面的各种 COMMAND 参数

3.3.1 创建数据卷

我们通过 create 来创建一个数据卷

# 创建一个名为 test 的数据卷
docker volume create test

image.png

3.3.2 查看当前所有的数据卷

那我们可以通过 ls 来查看当前所有的数据卷

# 查看当前所有的数据卷
docker volume ls

image.png

第一行的数据卷是 Docker 默认创建的数据卷 , 我们无需关注

3.3.3 查看数据卷的具体信息

# 查看 test 数据卷的具体信息
docker volume inspect test

image.png
那 Mountpoint 就是该数据卷的挂载点 , 也就是绑定的宿主机对应的目录

3.3.4 删除数据卷

删除数据卷有两种方式 :

  1. 删除未使用的数据卷
  2. 删除指定的数据卷

那我们先演示第一种 : 删除未使用的数据卷

# 删除未使用的数据卷
docker volume prune

image.png
那我们输入 y 就会将未使用的数据卷进行删除

接下来演示一下删除指定的数据卷

# 删除指定的数据卷
docker volume rm test

image.png

3.4 挂载数据卷

我们在创建容器的时候 , 可以通过 -v 参数来挂载一个数据卷到某个容器目录 , 这样的话就会实现宿主机的文件与容器的文件的绑定 .
我们可以举个例子

docker run \  # 创建并运行容器
--name mynginx \  # 给容器命名为 mynginx
-v test:/root/test \  # : 前半部分是数据卷, 后半部分是容器内的目录
-p 8080:80 # 将宿主机的 8080 端口与容器的 80 端口进行绑定
nginx \ # 要操作的镜像名称

其他的部分我们都见过了 , 我们格外关注一下这个部分 : -v test:/root/test
这段代码的意思就是将 test 数据卷挂载到容器内的 /root/test 目录下
那知道了语法 , 我们就可以实现一个案例

3.5 案例 2 : 创建一个 Nginx 容器 , 修改容器内的 HTML 目录中的 index.html 内容

我们在之前的案例中 , 已经知道了 nginx 的 HTML 目录所在位置 : /usr/share/nginx/html , 那我们就需要将这个目录挂载到 test 这个数据卷上

3.5.1 创建容器并挂载数据卷到容器的 HTML 目录

我们先来看一下本地都有哪些容器

# 查看本地所有容器
docker ps -a

image.png
接下来 , 我们就可以创建 nginx 容器

# docker run : 创建并运行容器
# --name mynginx : 为该容器起名
# -p 80:80 : 将宿主机的 80 端口和容器的 80 端口进行绑定
# -v : 前半部分是数据卷的名称, 后半部分是要挂载的目录
# -d : 让容器后台运行
# nginx : 要操作的容器
docker run --name mynginx -p 80:80 -v test:/usr/share/nginx/html -d nginx

image.png
接下来我们就可以查看一下 test 数据卷挂载到宿主机的位置

# 查看 test 数据卷的相关信息
docker inspect test

image.png
那实际上这两个位置就是对应的了 , 他们之间通过数据卷进行关联

容器内部 : /usr/share/nginx/html
容器外部 : /var/lib/docker/volumes/test/_data

3.5.2 进入 html 数据卷所在位置 , 并修改 html 文件内容

我们刚才已经找到了 test 数据卷所挂载到宿主机的位置 , 那我们就可以进入到这个目录来看一下

cd /var/lib/docker/volumes/test/_data

然后查看一下这个目录的文件
image.png
我们此时可以发现 , 我们目前还并未进入到容器中 , 目前处在容器外部 , 就能看到 nginx 对应的 index.html 文件
那这就说明 , 数据卷的挂载已经实现 , 此时我们可以直接修改 index.html , 对宿主机的修改 , 也会影响到容器内部的 index.html
image.png
那我们可以访问一下此页面了
image.png


那我们上述完成的工作 , 都是建立在数据卷都已经提前创建好的情况 .
如果数据卷不存在 , 能否成功呢 ?
我们先把 mynginx 容器和 test 数据卷删除掉

# 删除 mynginx 容器
docker rm -f mynginx

# 清除 test 数据卷
docker volume rm test

image.png
此时 test 数据卷已经被删除了 , 那此时我们不提前创建好数据卷 , 选择直接来去挂载数据卷 .

docker run --name mynginx -p 80:80 -v test:/usr/share/nginx/html -d nginx

image.png
那我们可以回到页面看一下
image.png
这就说明如果我们在做数据卷挂载的时候 , 数据卷不存在的话 , 会自动帮助我们创建数据卷并且进行挂载 .

3.6 案例 3 : 创建并运行一个 MySQL 容器 , 将宿主机目录直接挂载到容器

我们刚才已经完成了将数据卷挂载到容器目录 , 事实上 , 宿主机目录也可以直接跟容器进行挂载 .
那目录挂载与数据卷挂载的语法是类似的

  • -v [宿主机目录]:[容器内目录]
  • -v [宿主机文件]:[容器内文件]

那目录挂载还允许将宿主机文件跟容器内文件进行挂载 , 这样的话宿主机文件的内容就会覆盖掉容器内文件的内容 .

3.6.1 将 mysql.tar 文件上传到服务器 , 通过 load 命令加载为镜像

我们将 mysql.tar 文件导入到 tmp 目录中
mysql.tar

cd /tmp/

image.png
上传成功之后 , 我们就需要将这个镜像进行解压缩了

docker load -i mysql.tar

image.png
那我们就可以查看一下 Docker 中都有哪些镜像了

docker images

image.png

3.6.2 创建目录 /tmp/mysql/data

mkdir -p mysql/data

image.png

3.6.3 去 DockerHub 查阅资料 , 创建并运行 MySQL 容器

我们来到 DockerHub , 搜索 MySQL
因为我们需要进行挂载 , 所以我们寻找带有 -v 的命令即可
image.png
那我们再稍加改造一下

# --restart=always 表示 Docker 重启的时候, MySQL 也进行重启
# -p 3306:3306 表示将宿主机的 3306 端口与容器中的 3306 端口进行绑定
# --name mysql 表示将该镜像命名为 mysql
# -v /tmp/mysql/data:/var/lib/mysql 表示将宿主机的 MySQL 数据目录与宿主机的目录(DockerHub 查询到的)进行绑定
# -e 表示环境变量的意思
# MYSQL_ROOT_PASSWORD=root 表示设置 MySQL 的密码
# -d 表示让容器后台运行
# mysql:5.7.25 表示要操作的镜像
docker run --restart=always -p 3306:3306 --name mysql -v /tmp/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.25

image.png