docker数据卷
docker volume ls #查看有哪些数据卷
docker volume inspect mysql-db #查看具体数据卷的元信息
docker container run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=True -v mysql-db:/var/lib/mysql mysql #会在docker 的卷下面新建一个mysqldb
用于数据持久化,需要注意点是一般启动容器的时候需要加–privileged=true否则可能没有权限操作挂载目录。
- / -v指定了容器路径和主机目录的映射,如果希望容器只读的话/data/mysql/logs:/var/log/mysql:ro 可以加:ro来进行限制
- / -e 是环境变量,这是在构建镜像的时候暴露出来,可以通过这个去配置容器的一些属性和参数,比如这里配置了了mysql的密码。
docker run -d -p 13306:3306 --privileged=true -v /data/mysql/logs:/var/log/mysql -v /data/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=654321 --name mysql mysql:5.7
容器之间的继承也就是说一个容器可以完全复用另一个容器的数据卷,且当前的这个容器不会受被继承者的影响,也就是说被继承者挂掉了,当前容器的运行也不会有任何影响。
一个简单的例子如下:
docker run -itd ---privileged=true --volumes-from 父容器 --name newcontainer mysql
docker网络
docker容器的网络和宿主机不是同一个网段,是和docker0同一个网段。
#安装工具网络工具
yum install bridge-utils
#可以查看网桥
brctl show
#擦可能看端口映射
docker container port redis
#查看内部docker内部IP
docker container inspect redis | grep IPAddress
#查看reids的IP
docker container inspect --format '{{ .NetworkSettings.IPAddress }}' redis
Docker会自动创建三个网络:
- Bridge:此模式会为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,通过 docker0 网桥以及 Iptables nat 表配置与宿主机通信。
- host:容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的IP和端口(和宿主机共用一个 Network Namespace)。
- None:该模式关闭了容器的网络功能。
- Container:创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围。
Docker内置这三个网络,运行容器时,可以用 --network / –net 选项指定容器的网络模式:
- host 模式:使用 –net=host 指定。
- none 模式:使用 –net=none 指定。
- bridge 模式:使用 –net=bridge 指定,默认设置。
- container 模式:使用 –net=container:NAME_or_ID 指定。
- 基础命令
#查看网络模式 更多命令docker network --help
docker network ls
#查看网络模式的详细信息
docker network inspect bridge
可以看到这个网络下面连接了那些容器:
docker inspect redis | tail -n 20 #查看容器网络
#容器内部IP是会发生变化的,随着服务的停止重启创建,会被分配到其它的IP。
- 网络模式
网桥模式工作原理
Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
docker network inspect bridge | grep name #查看bride网络详细信息
具体的容器在启动的时候网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主1)机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
2)每个容器实例内部也有一块网卡,每个接口叫eth0;
3)docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。
如下图一个veth对应这一个eth
我们随便查看一个网桥模式的容器:
从上图可以看到网桥模式每个容器有自己的IP和网关。
主机模式
容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
案例验证:
docker run -d -p 8083:8080 --network host --name tomcattest tomcat:latest
这里会出现警告因为你不是网桥模式是直接用主机的端口,添加端口映射没有意义。
docker run -d --network host --name tomcattest tomcat:latest
可以看到没有自己的IP和网关,都是借用主机的
none模式
禁用网络功能,只有lo标识
docker run -d -p 8083:8080 --network none --name tomcattest tomcat:latest
container模式
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
docker run -d --network container:容器名称 --name demo
注意如果被共用的容器挂了,这这个共享的容器也没有网络了,只有本地回环。
docker自定义网络
自定义网络是经某些服务集中,可以通过服务名相互访问。如果不用服务名需要写死容器IP,但是容器IP可能会变化,这样可能导致某些服务访问不到。
案例实操
#创建自定义网络
docker network create custom_network
在同一个网络下启动容器,这样这个容器就能够通过服务名互通
docker run -d -p 8081:8080 --network custom_network --name tomcat81 tomat:latest
docker run -d -p 8082:8080 --network custom_network --name tomcat82 tomat:latest
#将我们的应用连接到某一个网络
docker network connect custom_networkwebhost #网络名 应用名
docker network inspect custom_network
#取消连接网络
docker network disconnect custom_network webhost
docker network connect custom_network redis #我们让reids 也连接到custom_network 上,可以看到redis除了之前的bridge网络 还有custom_network网络
这样的话redis就可以和多个网络进行通信,就比如我们在启动一个容器然后连接到custom_network网络,然后再内部是可以直接ping通reds的。
通过别名设置负载均衡
- 下面我来部署一个应用
FROM primetoninc/jdk:1.8
#FROM rajkiranp/javapython:latest
# 维护人员
MAINTAINER liyong@dist.com.cn
# 工作目录
WORKDIR webApi
ADD ./target/gis-ubantu-test-2.3.12.RELEASE.jar /webApi/gis-ubantu-test-2.3.12.RELEASE.jar
ENTRYPOINT ["java", "-jar", "gis-ubantu-test-2.3.12.RELEASE.jar"]
docker container run -d --net custom_network --net-alias demoserver demo:1.0
docker container run -d --net custom_network --net-alias demoserver demo:1.0
#发送指令进行请求 --rm表示运行完成后就关闭
docker container run --rm --net custom_network centos curl -s demoserver:8081/port