[Docker核心之容器、数据库文件的导入导出]
使用 Docker 容器
在 Docker 中,真正对外提供服务的还是容器,容器是对外提供服务的实例,容器的本质是进程。
运行一个容器
docker run [参数] [镜像名称|ID] [启动容器执行的命令]
参数:使用什么参数在添加什么参数。
镜像名称|ID:可以使用镜像名称,也可以使用镜像ID
启动命令:不指定则执行默认的启动命令,指定则执行指定的命令。
docker容器启动的前提
至少有一个应用进程运行在前台。
启动流程
1、检查本地是否存在需要被使用的镜像,如果存在则直接使用,如果不存在则去公网下载。
2、根据镜像来创建容器
docker run 参数
-d : 以守护进程方式运行 # 通俗说就是后台运行
-p : (固定)端口映射 # 把容器里面的端口映射到宿主主机,可以通过访问主机端口访问容器端口
-P : (随机)端口映射 # 小p可以设置宿主主机的端口,大P随机一个宿主主机端口映射
-i : 保持标准输入打开
-t : 创建一个伪终端 # 一般都是 -it 一块使用,创建了一个可以输入的伪终端,约等于终端
-v : 将宿主主机上的目录映射到容器中 # 两者类似硬链接关系,在任意一方操作,两者都生效此操作。可以理解为磁盘挂载了宿主本机的目录和容器里面的目录,修改宿主本机的目录内容或者修改容器里面的目录内容都是在修改这个磁盘的文件内容。
--rm : 当容器的生命周期结束时立即删除容器 # 容器生命周期结束会保存容器,docker ps -a 可以查到,这个设置是容器生命周期结束会立即删除,docker ps -a 里面查不到,即立即删除不存在。
--name : 将容器自定义一个容器名称, 将容器的名称加入DNS解析 # 给容器起个名字,不能重复
-e : 设置容器内部的环境变量 # 有的容器需要设置一些环境变量才可以启动。比如 mysql
-h : 设置容器内部的主机名 #
docker create + docker start = docker run
docker create (镜像)
根据镜像创建一个容器,容器的状态是 Created 。如果镜像不存在,和run一样会下载,但是run下载之后会启动镜像,生成一个容器并且运行。create只会下载,创建一个容器,状态 Created ,不会运行。
docker start (容器)
启动容器,这个容器可以是创建的,也可以是一个之前已经运行结束的。
docker run (镜像)
根据镜像创建一个容器,存在则直接运行。如果镜像不存在,下载,然后运行。
以上几个运行镜像(容器)都可以运行几个,空格隔开
docker create|start|run 镜像(容器)1 镜像(容器)2 镜像(容器)3
容器复制
1、将文件复制到容器内
docker cp [宿主主机文件路径] [容器名称|ID]:[容器内路径]
2、将容器内文件复制到宿主主机
docker cp [容器名称|ID]:[容器内路径] [宿主主机文件路径]
停止容器
docker stop 容器ID|容器名
docker stop 容器(ID|名)1 容器(ID|名)2 容器(ID|名)3 # 批量停止容器
docker stop ` docker ps -q ` # 停止所有的容器
关于容器和虚拟机网络小记
127.0.0.1
# 回环网络,谁用指定的就是谁,容器使用,指向的就是容器,虚拟机(宿主)使用,就是指向的虚拟机(宿主)本机
172.16.1.100
# 内部网络,也就是局域网。 docker 开启的几个容器可以理解为同一个局域网内开了几个电脑,而 docke 启动就会在宿主机虚拟一个 Docker 容器网桥(docker0)Docker 启动一个容器时会 根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。几个容器就是连接 docker 这个网关的几个电脑。后面详细介绍。
192.168.177.100
# 对外的ip地址,表示的就是宿主(虚拟机)主机的 IP ,任何人都能访问
docker ps 展示容器列表
docker ps # 默认情况下展示当前系统上所有的正在运行的容器
-a : 展示所有的容器
-q : 仅仅展示容器的ID
解释:
CONTAINER ID:容器ID
IMAGE :镜像ID|镜像名称
COMMAND :容器启动执行的命令
CREATED :创建距离现在的时间
STATUS :状态
PORTS :端口信息
NAMES :容器的名称
删除容器
docker rm [容器的名称|ID]
参数:
-f : 强制删除 # 运行中的也能删除
docker rm -f $(docker ps -a -q) # 删除所有容器
docker rm -f ` docker ps -a -q ` # 删除所有容器
进入容器
1、attach进入容器
docker attach 容器名|容器ID
建立一个宿主主机到容器中pid为1的进程上的一个管道,但是一旦attach断开连接,docker容器随即退出。
如果有一个容器在后台运行,而 attach 方法就是通过某些手段连接 容器 的 pid 为 1 的进程,进入容器来操作。而 attach 操作使用的容器 pid 为 1 的进程在 attach 退出之后,pid 进程 1 也就关闭,docker容器只有一个pid为1的进程,现在因为attach退出而关闭容器内pid为1的进程而导致容器中没有进程存在,容器就会也跟着退出结束。
2、exec进入容器(推荐)
docker exec -it relaxed_bhabha bash(也可以是其他指令)
使用 exec 可以在宿主主机上执行一个容器内部的命令,比如ls啊之类的,也可以执行一个 bash 命令达到进入容器的效果。# ————> 区别在下图可以看,原理就是下面这段。
原理就是新建一个进程连接容器,进入容器之后,来执行一些命令操作容器。这个进程由于是新建的,不会影响到容器内 pid 为 1 的进程,命令执行结束退出容器也只是新建的进程消失,不会影响到容器的正常运行。
3、nsenter进入容器
建立一个宿主主机和容器之间的一个管道,和exec一样,也是容器内新建了一个进程,连接容器内新进程操作容器。
需要配合 docker inspect 来使用(早期没有 exec 命令时,企业当中最长用的方式之一),Docker 是用 golang 语言开发,所以它也支持 go 语言的模版语法。
nsenter --target $( docker inspect -f {{.State.Pid}} elegant_margulis ) --mount --uts --ipc --net --pid
# {{.State.Pid}} elegant_margulis : 获取当前容器(elegant_margulis)的 ID
4、ssh进入容器
???
# 暂时没接触
进入容器的几种方式小结
docker run -it 镜像 bash ,直接启动镜像运行容器(容器启动后默认会有一个 pid 为 1 的进程),就生成了一个伪终端,而我们所有在伪终端上的操作就是在基于 pid 为 1 的 进程 操作这个镜像,如果退出,进程消失,则容器也结束。
attach 就是操作的容器pid为1的进程。
exec 和 nsenter 一样,exec 可以看作是 nsenter 的升级版本,他们进入容器的方式都是先在容器中创建了新的进程,然后连接容器的新进程从而进行容器的内部指令操作。
大概可以这么理解:# 明白进入容器的方式就不要看这段,刘鹏飞觉得理解起来不太合适。
你做了一个蛋糕,而 -it + bash 则表示,你做好之后直接执行一些命令,比如可以做好蛋糕之后直接执行吃了它的命令。而 -d 表示后台运行,也就是说,蛋糕做好之后,可以先放在别的地方,比如放在了冰箱,想用的时候再拿来用。如果我们现在想拿出来蛋糕吃,用 attach 方法,就是直接暴力给冰箱开了个口,把冰箱拆了,拿到了蛋糕,蛋糕只能一次吃完,吃不完也没有冰箱再存放了,这就等于 attach 进入容器内,执行了命令,只能把工作做完,一旦退出,容器就结束了。但是 nsenter 和 exec 方法,就是以柔和的手段正常打开冰箱,拿了蛋糕,切了一块拿来吃,没有吃完还能放回去,不影响冰箱的继续运行,等于说 nsenter 和 exec 方法 进入容器之后,不执行命令了,可以先退出,容器会继续在后台运行,不受到影响。
添加数据库用户
# 创建用户并授权
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
# 刷新权限
FLUSH PRIVILEGES;
m
mysql数据库source命令导出数据库、导入sql文件
mysql导出所有数据库
在cmd终端中输入: # ↓ 这是导出所有 可指定数据库名
mysqldump -uroot -p123456 --all-databases > /home/aa.sql
# 固定写法 用户名 密码 指定导出的数据库 导出至那个文件夹
-----------------------------------------------------------------------------------
在导入大的sql文件时,使用可视化工具导入往往效率极低,此时,我们常常使用在cmd中执行source命令的方式、将整个文件导入
第一步,打开cmd命令窗口,进入数据库
# 可在linux下使用 用法一样 进入mysql即可按如下操作
mysql -u用户名 -p
输入密码
第二步,切换数据库 # 想将文件导入那个库下指定那个即可
mysql> use test; (其中test为要导入的数据库名)
第三步,导入sql文件
mysql> source E:/pro_sql/test.sql (source后边为sql文件存放位置)
# 注意 文件必须为sql结尾
操作完以上步骤,等待命令运行完成即可
————————————————
容器和镜像的导入与导出
容器的导出
docker export -o [打包的文件名] [容器ID或名称]
docker export -o django.tar elegant_margulis
# 一个容器里面安装了自己需要的一些包,不想下次启动再重新安装包,就可以通过容器的导出方式来保存。只要下次使用的时候导入 之前打包好的容器文件 ,就可以继上次操作继续使用 而不需要再安装包。
容器的导入
docker import [文件名] [镜像名及版本号]
docker import django.tar django:v1
镜像的导出
docker save -o [打包的文件名1] 镜像名称及版本号 镜像名称2及版本号
docker save > [打包的文件名1] 镜像名称及版本号 镜像名称2及版本号
docker save -o python.tar python:3.6.8 alvinos/django:v3
镜像的导入
docker load -i [打包的文件名]
docker load < [打包的文件名]
docker load < python.tar
容器和镜像导入导出的区别
1、容器 import 导入可以自定义镜像名称,镜像 load 导入则不行
2、镜像 save 导出可以同时保存多个镜像,容器 export 导出则不能一次保存多个容器
3、镜像 save 导出保存的镜像体积要大于容器 export 导出保存的镜像体积
4、两者之间互不能导入