文章目录
-
- [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 容器帮我们处理的,使用起来方便,但是它的劣势也很明显,因为这个目录是由数据卷自动帮我们生成的,目录深且复杂,我们到时候找的时候不好找,需要查看数据卷的详细信息才能找到具体的存储位置;
② 目录挂载:需要手动管理,目录容易查找,耦合度高。 宿主机目录和容器目录直接交互,无需中间的数据卷参与,这种方式在创建容器时需要自己指定宿主机的目录,写起来麻烦,但是优点就是自己创建的目录找起来方便,能够快速定位到文件的目录。