简介
从上一篇Docker快速入门(上),我们学习和了解了docker的安装和常用的命令,也尝试了如何通过一个dockerfile文件,可以快速创建一个docker镜像文件.也了解了docker镜像的结构.
在本小节中,我们将学习到docker如何管理自己的数据和如何让外部网络访问到docker容器以及如何快速构建多个docker镜像关联.
docker的数据管理
数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性
1. **数据卷**可以在容器之间共享和重用
2. 对**数据卷**的修改会立马生效
3. 对**数据卷**的更新,不会影响镜像
4. **数据卷**默认会一直存在,即使容器被删除
创建数据卷
命令 : docker volume create 自定义数据卷名称
示例 : docker volume create my-vol
查看数据卷
命令 : docker volume ls
删除数据卷
命令 : docker volume rm 数据卷名称
示例 : docker volume rm my-vol
将数据卷挂在到容器上
第一种(官方的)
命令 : docker run -itd -P --name 自定义容器名称 --mount source=数据卷名称(如:my-vol),target=/容器内部的文件夹中(如:/webapp) 镜像名:标签
示例 : docker run -d -P --name web --mount source=my-vol,target=/webapp training/webapp python app.py
第二种命令方式(常用)
命令 : docker run -itd --name 自定义容器名称 -v=数据卷名称(如:my-vol):/容器内部的文件夹中(如:/webapp) 镜像名:标签
示例 : docker run -d -P --name web -v my-vol:/wepapp python app.py
查看数据卷的具体信息
命令 : docker inspect 自定义的容器名称(如:web)
示例 : docker inspect web
docker容器数据管理
在生产环境中,关于数据卷一般采用的宿主机的文件路径,作为数据卷.用来挂载到容器上.这样做的好处是,便于更新和修改应用程序
示例 : -v 宿主机文件(/data/redis5):/容器(/var)
dockerfile共享数据卷指令
docker的网络管理
docker开放端口
对于docker里面的容器来说(也就是系统),
从系统来看是会独立的网络,同时也会有独立的ip,而如果说外部想要访问的话就需要暴露端口;
可以通过dockerfile中EXPOSE参数或者 docker run -p 的方式,如下示意图
docker开放端口命令
命令 : docker run -it -p 宿主机端口(如:81):容器端口(如:80) --name 容器名 镜像名:标签
示例 : docker run -itd -p 6379:6379 --name redis5 redis5:latest
dockerfile开放网络端口指令
指令 : EXPOSE 端口号(如:6379)
示例 : EXPOSE 6379
二者的区别
expose指令只是开放端口
用来指明容器内进程对外开放的端口,多个端口之间使用空替隔力。
运行容器通过参数-P(大写)即可将EXPOSE里所指定的端口映射到主机上另外的随机端口,容器或主机就可以通过映射后的端口与此容器通信。
同时,我们也可以通过-p (小写)参数将dockerfile中EXPOSE中没有列出的端口设置成公开的。
docker的网络模式
docker安装后,默认会创建下面三种网络类型
bridge(桥接网络)
默认情况下启动的Docker容器,都是使用 bridge,Docker安装时创建的桥接网络,每次Docker容器重启时,会按照顺序获取对应的IP地址,这个就导致重启下,Docker的IP地址就变.如下图
从上面的网络模型可以看出,容器从原理上是可以与宿主机乃至外界的其他机器通信的。
同一宿主机上,容器之间都是连接掉docker0这个网桥上的,它可以作为虚拟交换机使容器可以相互通信。
然而,由于宿主机的IP地址与容器的IP地址均不在同一个网段,不足以使宿主机以外的网络主动发现容器的存在。
为了使外 界可以方位容器中的进程,docker采用了端口绑定的方式,也就是通过iptables的NAT,将宿主机上的端口端口流量转发到容器内的端口上
在宿主机上,可以通过iptables -t nat -L -n,查到一条DNAT规则:
bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,对宿主机端口的管理会是一个比较大的问题。
同时,由于容 器与外界通信是基于三层上iptables NAT,性能和效率上的损耗是可以预见的
none
无指定网络 使用 --network=none ,docker 容器就不会分配局域网的IP
host
主机网络 使用 --network=host,此时,Docker 容器的网络会附属在主机上,两者是互通的。
例如,在容器中运行一个Web服务,监听8080端口,则主 机的8080端口就会自动映射到容器中
缺点:
1)最明显的就是容器不再拥有隔离、独立的网络栈。容器会与宿主机竞争网络栈的使用,并且容器的崩溃就可能导致宿主机崩溃,在生产环境中,这种问题可能是不被允许的。
2)容器内部将不再拥有所有的端口资源,因为一些端口已经被宿主机服务、bridge模式的容器端口绑定等其他服务占用掉了
指定自定义网络(常用)
因为默认的网络不能制定固定的地址,所以我们将创建自定义网络,并指定网段:192.168.1.0/24 并命名为mynetwork
注意:这个网络段不要和宿主机的网络端冲突,不然会容易对宿主机产生影响
命令: docker network create --subnet=网络地址端(如:192.168.1.0/24) 自定义网络名称(如: mynetwork)
示例 : docker network create --subnet=192.160.1.0/24 mynetwork
docker-compose的使用
这个工具是做什么呢?可以帮助我们快速的构建和对容器的启动以及停止等操作
介绍
Compose是 Docker 的服务编排工具,诞生主要是来帮助开发或运维人员很好地管理docker容器;减少繁琐的单个容器创建、删除等操作,比较适合组合使用多个容器进行开发的场景。
对于需要多个容器的操作,传统的方式是一个个的创建及运行,而composer则只需要通过一次性把这些命令写在docker-composer.yml文件中,以后每次启动这一整个环境的时候,只需要你只要敲一个 docker-composer up命令就ok了。
相关命令
docker-compose up -d # 启动命令
docker-compose stop
docker-compose down
具体请参考这篇文章(https://www.cnblogs.com/minseo/p/11548177.html)
安装
#下载安装
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#修改权限
chmod +x /usr/local/bin/docker-compose
#安装完成后可以查看版本
docker-compose --version
使用
docker-compose的默认模版文件为: docker-compose.yml。
和Dockerfile一样,它也是有自己的语法命令的。
其中定义的每个服务都必须通过image指令指定镜像或build指令(需要Dockerfile)来自动构建。
其它大部分指令都跟docker run中的类似。
需要注意的是docker-composer运用的时候一定要注意版本的问题,如下图显示
示例
每个docker-compose.yml必须定义image或者build中的一个,其它的是可选的。 image 指定镜像tag或者ID
# 编排php,redis,nginx容器
version: "3.6" # 确定docker-composer文件的版本
services: # 代表就是一组服务 - 简单来说一组容器
nginx: # 这个表示服务的名称,课自定义; 注意不是容器名称
build: # 根据dockerfile构建镜像及构建为容器
context: ./nginx
image: nginx # 指定容器的镜像文件
container_name: nginx_compose # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "82:80"
networks: ## 引入外部预先定义的网段
lrnp:
ipv4_address: 172.100.100.110 #设置ip地址
privileged: true # 执行特殊权限的命令
volumes: # 配置数据挂载
- /www/wwwroot/2007_SRM/00-1/lrnp/nginx/conf:/conf
working_dir: /conf #工作目录
php: # 这个表示服务的名称,课自定义; 注意不是容器名称
build: # 根据dockerfile构建镜像及构建为容器
context: ./php
image: php7 # 指定容器的镜像文件
container_name: php_compose # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "9002:9000"
networks: ## 引入外部预先定义的网段
lrnp:
ipv4_address: 172.100.100.120 #设置ip地址
volumes: # 配置数据挂载
- /www/wwwroot/2007_SRM/00-1/lrnp/php/www:/www
redis: # 这个表示服务的名称,课自定义; 注意不是容器名称
image: redis5asm # 指定容器的镜像文件
networks: ## 引入外部预先定义的网段
lrnp:
ipv4_address: 172.100.100.130 #设置ip地址
container_name: redis_compose # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "6380:6379"
volumes: # 配置数据挂载
- /www/wwwroot/2007_SRM/00-1/lrnp/redis:/redis
# command: top
# 设置网络模块
networks:
# 使用之前定义的网络
lrnp:
external:
name: lrnp
# 自定义网络
# nginx_net:
# driver: bridge
# ipam: #定义网段
# config:
# - subnet: "172.15.22.0/24"
小结
在本小节中,我们学习了docker如何管理它自己的数据.即通过创建数据卷或者跟宿主机文件夹进行挂在关联.
也知道了如何让外部网络访问到docker,即通过开放端口.
也明白了如何让各个容器进行互联互通,是通过自定义网络段来进行内部互通.
最后,为了能更快速的管理多个docker镜像/容器,我们也学习docker-compose,用来管理
参考资料
<<docker从入门到实践>>