HM-SpringCloud微服务系列3.2【Docker的基本操作】
1 镜像操作
1.1 镜像名称
- 镜名称一般分两部分组成:[repository]:[tag]。
- 在没有指定tag时,默认是latest,代表最新版本的镜像
这里的mysql就是repository,5.7就是tag,合一起就是镜像名称,代表5.7版本的MySQL镜像
1.2 镜像命令
常见的镜像操作命令如图:
1.3 案例1:拉取、查看镜像
需求:从DockerHub中拉取一个nginx镜像并查看
- 首先去镜像仓库搜索nginx镜像,比如DockerHub
- 根据查看到的镜像名称,拉取自己需要的镜像,通过命令:docker pull nginx
- 通过命令:docker images 查看拉取到的镜像
1.4 案例2:保存、导入镜像
需求:利用docker save将nginx镜像导出磁盘,然后再通过load加载回来
-
利用docker xx --help命令查看docker save和docker load的语法
docker save --help
docker load --help
docker save命令格式docker save -o [保存的目标镜像文件名称] [镜像名称]
docker load命令格式docker load -i [已有的镜像文件名称xxx.tar]
-
使用docker save导出镜像到磁盘
docker save -o nginx.tar nginx:latest
-
使用docker load加载镜像
先删除本地的nginx镜像:docker rmi nginx:latest
然后运行命令,加载本地文件:docker load -i nginx.tar
1.5 小结
1.6 练习
需求:去DockerHub搜索并拉取一个Redis镜像
- 去DockerHub搜索Redis镜像
- 查看Redis镜像的名称和版本
- 利用docker pull命令拉取镜像
docker pull redis
默认拉取最新版
- 利用docker save命令将 redis:latest打包为一个redis.tar包
docker save -o redis.tar redis:latest
- 利用docker rmi 删除本地的redis:latest
docker rmi redis:latest
- 利用docker load 重新加载 redis.tar文件
docker load -i redis.tar
2 容器操作
2.1 容器相关命令
- docker run:创建并运行一个容器,处于运行状态
- docker pause:让一个运行的容器暂停
- docker unpause:让一个容器从暂停状态恢复运行
- docker stop:停止一个运行的容器
- docker start:让一个停止的容器再次运行
- docker rm:彻底删除一个容器
容器保护三个状态:
- 运行:进程正常运行
- 暂停:进程暂停,CPU不再运行,并不释放内存
- 停止:进程终止,回收进程占用的内存、CPU等资源
2.2 案例1:创建并运行一个Nginx容器
创建并运行nginx容器的命令:
docker run --name containerName -p 80:80 -d nginx
命令解读:
- docker run :创建并运行一个容器
- --name : 给容器起一个名字,比如叫做mn
- -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
- -d:后台运行容器
- nginx:镜像名称,例如nginx
这里的
-p
参数,是将容器端口映射到宿主机端口。
默认情况下,容器是隔离环境,我们直接访问宿主机的80端口,肯定访问不到容器中的nginx。
现在,将容器的80与宿主机的80关联起来,当我们访问宿主机的80端口时,就会被映射到容器的80,这样就能访问到nginx了:
centos7可以访问nginx;但远程的本地主机无法访问;可能是centos7虚拟机未开放80端口
https://blog.csdn.net/weixin_38750084/article/details/90387056
https://blog.csdn.net/u011477914/article/details/88862041
先启动防火墙(此前已经关闭了;设置开放端口需要在防火墙中操作)
然后设置端口,最后一定要再关闭防火墙!
测试
ok,可以远程访问了
查看已开放的端口:
firewall-cmd --list-ports
查看防火墙状态:systemctl status firewalld
开启防火墙:systemctl start firewalld
关闭防火墙:systemctl stop firewalld
防火墙永久开放80端口:firewall-cmd --zone=public --add-port=80/tcp --permanent
防火墙重载:firewall-cmd --reload
可以看到日志中:有来自虚拟机本体centos7的访问;也有来自远程主机(实际是本地主机)的访问。
docker logs [容器名称]
命令只能查看当前的日志,若容器中发生活动时(比如有新的访问),需要重新输入docker logs [容器名称]
命令才能查看最新的日志信息。
有没有办法可以设置为动态日志呢(让日志处于监听状态)?
远程访问nginx 3次
查看容器日志:
docker logs [容器名称]
查看容器日志logs命令帮助文档:docker logs --help
动态查看容器日志:docker logs -f [容器名称]
退出容器的动态日志:快捷键ctrl + c
2.3 案例2:进入容器&修改文件
需求:进入Nginx容器,修改HTML文件内容,添加“黑马欢迎您”
提示:进入容器要用到docker exec命令
- 进入我们刚刚创建的nginx容器:
docker exec -it mn bash
- docker exec :进入容器内部,执行一个命令
- -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
- mn :要进入的容器的名称
- bash:进入容器后执行的命令,bash是一个linux终端交互命令
容器内部会模拟一个独立的Linux文件系统,看起来如同一个linux服务器一样。
nginx的环境、配置、运行文件全部都在这个文件系统中,包括我们要修改的html文件。
套娃?!
-
进入nginx的HTML所在目录 /usr/share/nginx/html
查看DockerHub网站中的nginx页面https://hub.docker.com/_/nginx,可以知道nginx的html目录位置在/usr/share/nginx/html
进入该目录:cd /usr/share/nginx/html
查看目录下文件:ls -l
查看index.html文件:cat index.html
-
修改index.html的内容
容器内没有vi命令,无法直接修改,我们用下面的命令来修改:
一条命令:
sed -i -e 's#Welcome to nginx#黑马欢迎您#g' -e 's#<head>#<head><meta charset="utf-8">#g' index.html
或者 两条命令:
sed -i 's#Welcome to nginx#黑马欢迎您#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html
-
访问测试
-
其他
- 退出容器:
exit
- docker停止某容器:
docker stop [容器名称]
- 查看启动状态中的容器:
docker ps
- 查看所有容器(包括退出的):
docker ps -a
- 问题:mn容器停止后,再次启动失败报错
Error response from daemon: driver failed programming external connectivity on endpoint mn (c2931096cd3563acb83a3a3c6b7bc5b64468dae7c3694205343c678711f54e9e): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 80 -j DNAT --to-destination 172.17.0.2:80 ! -i docker0: iptables: No chain/target/match by that name. (exit status 1))
- 解决:https://blog.csdn.net/qq_41545647/article/details/102679560
ok - 删除容器
docker rm [容器名称]
不能删除正在运行中的容器;通过命令docker rm -f [容器名称]
可以强制删除
2.4 小结
2.5 练习
- 创建并运行一个redis容器,并且支持数据持久化
老师:
docker run --name redis -p 6379:6379 -d redis redis-server --appendonly yes
目前:
docker run --name some-redis -d redis redis-server --save 60 1 --loglevel warning
docker run --name myredis -p 6379:6379 -d redis redis-server --appendonly yes
- 进入redis容器,并执行redis-cli客户端命令,存入num=666
docker exec -it myredis bash
+ redis-cli
或者直接一步到位docker exec -it myreis redis-cli
3 数据卷(容器数据管理)
3.1 什么是数据卷
3.1.1 容器与数据耦合的问题
- 在之前的nginx案例中,修改nginx的html页面时,需要进入nginx内部。并且因为没有编辑器,修改文件也很麻烦。
- 这就是因为容器与数据(容器内文件)耦合带来的后果。
- 要解决这个问题,必须将数据与容器解耦,这就要用到数据卷了。
3.1.2 who is volume
- 数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
- 一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。
- 这样,我们操作宿主机的/var/lib/docker/volumes/html目录,就等于操作容器内的/usr/share/nginx/html目录了
3.2 数据卷操作命令
- 数据卷操作的基本语法如下:
docker volume [COMMAND]
- docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
- create 创建一个volume
- inspect 显示一个或多个volume的信息
- ls 列出所有的volume
- prune 删除未使用的volume
- rm 删除一个或多个指定的volume
3.3 创建和查看数据卷
需求:创建一个数据卷,并查看数据卷在宿主机的目录位置
- 创建数据卷
docker volume create [数据卷名称]
- 查看所有数据
docker volume ls
- 查看数据卷详细信息卷
可以看到,我们创建的html这个数据卷关联的宿主机目录为docker volume inspect [数据卷名称]
/var/lib/docker/volumes/html/_data
目录。
- 删除数据卷
方式1:docker volume prune
方式2:docker volume rm [数据卷名称]
3.4 挂载数据卷
我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下:
docker run \
--name mn \
-v html:/root/html \
-p 8080:80
nginx \
3.5 案例1:给Nginx挂载数据卷
需求:创建一个nginx容器,修改容器内的html目录内的index.html内容
分析:上个案例中,我们进入nginx容器内部,已经知道nginx的html目录所在位置/usr/share/nginx/html ,我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。
提示:运行容器时使用 -v 参数挂载数据卷
-
创建容器并挂载数据卷到容器内的HTML目录
docker run --name mynginx -v html:/usr/share/nginx/html -p 80:80 -d nginx
-
进入html数据卷所在位置,并修改HTML内容,访问测试
# 查看html数据卷的位置 docker volume inspect html # 进入该目录 cd /var/lib/docker/volumes/html/_data # 修改文件 vi index.html
-
删除容器&数据卷
-
在没有事先创建数据卷的情况下,直接挂载nginx到指定数据卷(同时自动生成该数据卷)
3.6 案例2:给MySQL挂载本地目录
3.6.1 案例内容
- 需求:创建并运行一个MySQL容器,将宿主机目录直接挂载到容器
- 容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下:
- 带数据卷模式:宿主机目录 --> 数据卷 ---> 容器内目录
- 直接挂载模式:宿主机目录 ---> 容器内目录
- 目录挂载与数据卷挂载的语法是类似的:
- -v [宿主机目录]:[容器内目录]
- -v [宿主机文件]:[容器内文件]
- 数据卷挂载方式对比:
- 实现思路:
- 在将课前资料中的mysql.tar文件上传到虚拟机,通过load命令加载为镜像
- 创建目录/tmp/mysql/data
- 创建目录/tmp/mysql/conf,将课前资料提供的hmy.cnf文件上传到/tmp/mysql/conf
- 去DockerHub查阅资料,创建并运行MySQL容器,要求:
- 挂载/tmp/mysql/data到mysql容器内数据存储目录
- 挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
- 设置MySQL密码
3.6.2 实际操作
- 本地宿主机文件通过filezilla工具传输至centos7虚拟机
- 导入镜像
docker load -i mysql.tar
docker images
- 创建目录
- 创建并运行MySQL容器
翻译页面
docker run \ --name mysqldemo \ -e MYSQL_ROOT_PASSWORD=1234 \ -p 3306:3306 \ -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \ -v /tmp/mysql/data:/var/lib/mysql \ -d \ mysql:5.7.25
- 本地宿主机远程通过Navicat工具连接虚拟机中的mysql
3.7 小结