docker小册学习笔记之二——使用容器

第6课 镜像与容器

Docker镜像

定义:docker镜像是基于unionFS文件系统的一组镜像层依次挂载而得,而每个镜像层包含的其实是对上一层镜像层的修改,这些修改是发生在容器运行过程中的。可以反过来理解,镜像是对容器运行环境进行持久化存储的结果。

docker images   //查看镜像

第7课 从仓库中获取镜像

docker pull ubuntu //获取镜像

docker search ubuntu  //查找镜像

docker inspect redis:3.2  //获得镜像的详细信息

docker rmi redis:3.2 redis:4.0 //删除镜像,支持同时删除多个

第8课 运行和管理容器

容器的状态
  1. Created:容器已经被创建,容器所需的相关资源已经准备就绪,但容器中的程序还未处于运行状态。
  2. Running:容器正在运行,也就是容器中的应用正在运行。
  3. Paused:容器已经暂停,表示容器中的所有程序都处于暂停(不是停止)状态。
  4. Delete:容器已经删除,相关占用的资源存储在Docker中的管理信息也都已释放和删除。
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  //将当期那输入输出流连接到指定容器   限制较多,用的较少

第9课 为容器配置网络

容器网络
  1. 沙盒(Sandbox):提供了容器的虚拟网络栈,也就是之前所提到的端口套接子、IP路由表、防火墙等内容。其实现隔离了容器网络与宿主机网络,形成了完全独立的容器网络环境。
  2. 网络可以理解为docker内部的虚拟子网,网络内的参与者相互可见并能够进行通讯。Docker的这种虚拟网络也是宿主机网络存在隔离关系的,其目的主要是形成容器间的安全通讯环境。
  3. 端点是位于容器或网络隔离墙上的洞,其主要目的是形成一个可以控制的突破封闭的网络环境的出入口。当容器的端点与网络的端点形成配对后,就如同在这两者之间搭起了桥梁,便能够进行数据传输了。
docker的网络实现

目前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,是一种端口转发,需要设定双方的对应端口。
容器互联讲究的更多是容器内部的互相访问,端口映射更讲究的是通过宿主机外部访问到容器。

第10节 管理和存储数据

数据管理的实现方式

dcoker容器中的文件系统虽有很多优势,但也有很多弊端,其中最显著的是

  1. 沙盒文件系统是跟随容器生命周期所创建和移除的,数据无法直接被持久化存储。
  2. 由于容器隔离,我们很难从容器外部获得操作容器内部文件中的数据。

挂载方式:

  1. Bind Mount:能够直接将宿主操作系统中的目录和文件挂载到容器内的文件系统中,通过指定容器外的路径和容器内的路径,就可以形成挂载映射关系,在容器内外对文件的读写,都是相互可见的。
  2. Voulume:也是从宿主操作系统中挂载目录到容器内,只不过这个挂载目录由Docker进行管理,我们只需要指定容器内的目录,不需要关心具体挂载到了宿主操作系统的哪里。
  3. Tmpfs Mount:支持挂载系统内存中一部分到容器的文件系统里,不过由于内存和容器的特征,它的存储并不是持久的,其中的内容随着容器的停止而消失。

挂载文件到容器

使用-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 <name>:<container-path>来进行命名。
                // 由于-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=<nfs-server>:<nfs-path> ' webapp:latest

//--mount 通过逗号分割这种CVS格式来定义多个参数,其中type是挂载类型,可以是: bind,volume,tmpfs。  

另外 --mount选项能够帮助我们实现集群挂载的定义,如本例,我们挂载的来源是一个NFS目录。

实际开发中,-v基本满足我们的需求,所以不常用相对复杂的–mount定义挂载。

留言互动

问题: 结合我们所提到的三种挂载方式各自适用的场景,分别尝试使用它们进行数据挂载

答:

  1. 挂载文件方式,docker从本地读取文件场景:把宿主机的文件挂载到docker,可以方便指定软件的配置相关文件,比如 nginx.conf,mysqli.ini,tomcat的server.xml等。
  2. 挂载卷的方式,docker写入本地的场景:文件服务器,ftp服务器,要把服务产生的数据写入到宿主机,几个容器之间还可共享。
  3. 挂载tmpfs:挂载内存文件到docker适合高速读写的问加,适合不需要持久化类似session性质问加,重点理解tmp临时性,和内存高性能读写两个点。

PS: 这是学习docker小册的笔记,附上小册地址:https://juejin.im/book/5b7ba116e51d4556f30b476c

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值