定义:docker镜像是基于unionFS文件系统的一组镜像层依次挂载而得,而每个镜像层包含的其实是对上一层镜像层的修改,这些修改是发生在容器运行过程中的。可以反过来理解,镜像是对容器运行环境进行持久化存储的结果。
docker images //查看镜像
docker pull ubuntu //获取镜像
docker search ubuntu //查找镜像
docker inspect redis:3.2 //获得镜像的详细信息
docker rmi redis:3.2 redis:4.0 //删除镜像,支持同时删除多个
docker create nginx:1.12 //创建容器
docker create --name nginx:1.12 //创建容器,配置容器名
docker start nginx //启动容器
docker run --name nginx -d nginx:1.12 //docker run相当于docker create和docker start合成一步。 -d 或 --detach 进入后台
docker ps // 列出所有容器(运行中)
docker ps -a //所有容器,或 --all
//所列出列中的 status,表示容器所处的状态,
//常见状态三种:Created:此时容器已创建,但还没被启动过; Up[Time] 这时容器处于正在运行状态,而这里的Time表示容器从开始运行到查看时的时间; Exited([Code])[Time] 容器已经结束运行,这里的code表示容器结束运行时,主程序返回的退出码,而TIme则表示容器结束到查看时的时间。
docker stop nginx // 停止正在运行的容器
docker rm nginx // 删除容器 -f 或 --force可以强制删除正在运行的容器
docker exec nginx more /etc/hostname //docker exec命令让容器来运行我们所给出的命令
docker exec -it nginx bash //进入容器bash -i:保持输入流 -t:启用一个伪终端 -it 一般连着用
docker attach nginx //将当期那输入输出流连接到指定容器 限制较多,用的较少
目前docker官方为我们提供了五种docker驱动,分别是:Bridge Driver,Host Driver,Overlay Driver,None Driver。
docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
docker run -f --name webapp --link mysql webapp:latest
jdbc:
String url = "jdbc:mysql://mysql:3306/webapp";
docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7
//通过别名连接
docker run -d --name webapp --link mysql:database webapp:latest
java:
String url = "jdbc:mysql//database:3306/webapp";
docker inspect mysql //查看容器,network中查看容器相关的网络信息
docker CLI里与网络相关的命令都以docker network开头,其中创建网络的命令是 docker network create
docker network create -d bridge individual //创建网络
docker network ls // 查看docker中已经存在的网络
docker network list // 同上
//创建容器时,通过--network来指定容器所加入的网络,被指定后,容器不会默认加入到bridge网络中
docker run -a --name mysql -e MYSQL_RANDOM_ROOT=yes --network individual mysql:5.7
//此时,通过--link让处于另外一个网络的容器连接到这个容器上,报错
docker run -d --name webapp --link mysql --network bridge webapp:latest
// 改变一下,让运行web应用的容器加入到individual这个网络,就成功建立容器间网路连接啦
docker run -d --name webapp --link mysql --network individual webapp:latest
格式:-p ::,ip是宿主操作系统的监听ip,可以用来控制监听的网卡,默认是0.0.0.0,也就是监听所用网卡。 host-port和container-port分别表示映射到宿主机的端口和容器的端口,这两者可以不一样。将容器的80端口映射到宿主机操作系统的8080端口,传入 -p 8080:80即可
docker run -d --name nginx -p 80:80 -p 443:443 nginx:1.12
通过docker网络进行的容器互联,与通过宿主机端口映射的容器互联有怎样的区别,又各有怎样的优劣?
回答:
docker网络进行的容器互联是横向的,各个容器是平等的。与宿主机进行端口映射的容器互联是纵向的。容器互联甚至不需要知道ip,只要知道需要连接容器的名称和应用端口,把容器名映射为ip。宿主机端口映射在网桥网络中只需要把宿主的端口和容器端口进行映射即可,也不用管ip,是一种端口转发,需要设定双方的对应端口。
容器互联讲究的更多是容器内部的互相访问,端口映射更讲究的是通过宿主机外部访问到容器。
dcoker容器中的文件系统虽有很多优势,但也有很多弊端,其中最显著的是
挂载方式:
使用-v或者–volune来挂载, -v : ,需要注意,为了避免混淆,docker这里强制定义目录时必须使用绝对路径,不能使用相对路径。
docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx:1.12
//挂载目录的容器启动后,宿主机操作系统中的文件已经出现在容器中
docker exec nginx ls /usr/share/nginx/html
//docker inspect查看容器详情
docker inspect nginx
{
## ......
"Mounts": [
{
"Type": "bind",
"Source": "/webapp/html",
"Destination": "/usr/share/nginx/html",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
## ......
}
//在“Mounts”中可以看到有关容器挂载的信息,其中“RW”表示读写性,如果希望容器只读
docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html:ro nginx:1.12
挂载临时文件目录需要通过–tmpfs来完成,由于内存的具体位置无需我们来指定,这个选项里只需传递挂载到容器内的目录即可。
docker run -d --name webapp --tmpfs /webapp/cache webapp:latest
docker inspect webapp
{
## ......
"Tmpfs": {
"/webapp/cache": ""
},
## ......
}
除了与其他虚拟机工具近似的宿主操作系统目录挂载的功能意外,docker还创造了数据卷(Volume)这个概念。 数据卷的本质依然是宿主机操作系统上的一个目录,只不过这个目录存放在Dokcer内部,接受docker的管理。
使用数据卷挂载时,不需要知道数据具体存储在了宿主操作系统的何处,只需要给定容器中哪个目录会被挂载即可。
依旧使用 -v 或者 --volume 来实现
docker run -d --name webapp -v /webapp/storage webapp:latest
docker inspect webapp
{
## ......
"Mounts": [
{
"Type": "volume",
//数据卷命名,也可以通过 -v :来进行命名。
// 由于-v即可以用来bind Mount的定义,又参与volume,所以其参数方式需要特别留意。所以 -v定义挂载时,需要使用绝对路径,目的就是避免与数数据卷挂载中命名这种形式的冲突
"Name": "2bbd2719b81fbe030e6f446243386d763ef25879ec82bb60c9be7ef7f3a25336",
// source 是docker为我们分配用于挂载的宿主机目录,位于docker的资源区域(默认是/var/lib/docker),我们无需关心这个目录,对它的管理已经在docker中实现
"Source": "/var/lib/docker/volumes/2bbd2719b81fbe030e6f446243386d763ef25879ec82bb60c9be7ef7f3a25336/_data",
"Destination": "/webapp/storage",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
## ......
}
数据卷的另一大作用是实现容器内的目录共享,也就是通过挂载相同的数据卷,让容器之间能够同时看到并操作数据卷中的内容。虽也能通过绑定挂载来实现,但是数据卷操作更加舒适简单。
// 数据卷名在docker中是惟一的,所以让多个容器挂载同一个数据卷即可
docker run -d --name webapp -v html:/webapp/html webapp:latest
docker run -d --name nginx -v html:/usr/share/nginx/html:ro nginx:1.12
//专门用于操作数据卷的命令
docker volume create appdata // 创建名称为appdata的数据卷
docker volume ls //列出当前已创建的数据卷
docker volume rm appdata // 删除名为 appdata的数据卷
//删除容器的命令中 加 -v 可以删除掉容器关联的数据卷
docker rm -v webapp
docker volume prune //删除没有被容器引用的数据卷
所谓数据卷容器,就是一个没有具体指定的应用,甚至不需要运行的容器,我们使用它的目的,是为了定义一个或多个数据卷并持有它们的引用。
创建数据卷容器方式很简单,由于不需要容器本身运行,因而找个简单的系统镜像都可以完成创建。
使用数据卷容器时,不建议再定义数据卷的名称,我们可以通过对数据卷容器的引用来完成数据卷的引用。
docker create --name appdata -v /webapp/storage ubuntu
之前提到,Docker的Network是容器间的网络桥梁,如果类比,数据卷容器就可以算是容器间的文件系统桥梁。我们可以向加入网络一样引用数据卷容器, 只需要在创建新容器时使用专门的 --volumes-from选项即可。
docker run -d --name webapp --volumes-from appdata webapp:latest
引用数据卷容器时,不需要再定义数据卷挂载到容器中的位置,docker会以数据卷容器中的挂载定义将数据卷挂载到引用的容器中。
利用数据卷容器,我们还可以能够更方便的对数据卷中的数据进行迁移。
对数据的备份、迁移、恢复的过程我们可以理解为对数据进行打包、移动到其他位置,在需要的地发进行解压的过程。
docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar cvf /backup/backup.tar /webapp/storage
//命令解析 /backup 是我们用来存放打包文件的目录
// --rm 我们可以让容器停止后自动删除,临时容器中很有帮助
// tar cvf /backup/backup.tar /webapp/storage 在容器所定义的镜像之后的命令。 在镜像定义之后接上命令,可以直接替换掉所定义的主程序启动命令,而去执行本条命令。
备份之后,我们可以在/backup下找到数据卷的备份文件,也就是backup.tar了。
如果恢复数据卷中的数据,我们也借助临时容器完成
docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar xvf /back/backup.tar -C /webapp/storage --strip
//恢复过程与备份类似,只不过把打包的命令转换为解包的命令
-v选项来挂载存在容易混淆的问题,主要原因是挂载的方式和配置随着docker的不断发展日渐丰富,而-v选项的传参方式限制了它的使用场景。
Docker中为我们提供了一个相对支持丰富的挂载方式,也就是通过–mount这个选项配置挂载
docker run -d --name webapp webapp:latest --mount 'type=volume,src=appdata,dst=/webapp/storage,volume-driver=local,volume-opt=type=nfs,volume-opt=device=: ' webapp:latest
//--mount 通过逗号分割这种CVS格式来定义多个参数,其中type是挂载类型,可以是: bind,volume,tmpfs。
另外 --mount选项能够帮助我们实现集群挂载的定义,如本例,我们挂载的来源是一个NFS目录。
实际开发中,-v基本满足我们的需求,所以不常用相对复杂的–mount定义挂载。
问题: 结合我们所提到的三种挂载方式各自适用的场景,分别尝试使用它们进行数据挂载
答:
PS: 这是学习docker小册的笔记,附上小册地址:https://juejin.im/book/5b7ba116e51d4556f30b476c