《Docker Deep Dive》阅读笔记(二)
卷和数据持久化
-
非持久化数据,Linux系统下,存放在
/var/lib/docker/<storage-driver>/
,Windows系统下,则是在C:\ProgramData\Docker\windowsfilter\
-
卷挂载到容器中的文件夹示意图:
-
创建:
docker volume create myvol
-d
指定驱动
-
查看:
docker volume ls
-
详情:
docker volume inspect myvol
-
删除:
docker volume rm xxx
-
删除所有未挂载到容器的:
docker volume prune
(慎用) -
可以在Dockerfile文件中通过
VOLUME
指令部署卷 -
卷和容器/服务
docker container run -dit --name voltainer --mount source=bizvol,target=/vol alpine
:这里将卷bizvol
挂载到容器中的/vol
文件夹,如果卷不存在,会自动创建
Docker 网络
- Docker 网络由三部分构成:
- The Container Network Model (CNM) : 设计指导
- libnetwork : CNM的具体实现
- Drivers : 驱动
- CNM模型
由三部分组成:
* Sandboxes : Ethernet interfaces, ports,routing tables, and DNS config.
* Endpoints : 虚拟网络接口,如veth
* Networks : 实现桥接的软件
-
宿主主机、容器与容器之间的网络关系
- 容器A有一个端点,B有两个端点
- A和B可以通讯,因为它们都连接到了网络A
- 一个端点只能连接到一个网络,如果一个容器需要连接到多个网络,就需要多个端点
- 容器A和B的网络通过沙箱隔离,各自独立
-
Libnetwork
- CNM是设计文档,Libnetwork是它的经典实现(使用Go语言)
- 不仅实现了CNM组成的三部分,而且实现了服务发现、ngress-based容器负载均衡、network control plane 和 management plane
-
Drivers
- 相对于Libnetwork实现了network control plane 和 management plane,Driver则是实现了data plane。三个plane的关系示意图:
Docker内置了几种原生Driver,在Linux系统下,包括:bridge, overlay 和 macvlan;在Windows系统下,包括:nat, overlay, transparent 和 l2bridge。还有第三方Driver。
- Driver负责创建和管理它所负责的网络资源
- Libnetwork允许同时又多个Driver
-
单主机桥接网络
- 存在于一个Docker宿主主机
- 是802.1d网桥的实现
- 在Linux下,使用bridge driver创建,而windows下则是nat
- 不同主机之间即使相同的网络名称也不能通讯
- 查看:
docker network ls
- 详情:
docker network inspect xxx
- Linux下的bridge driver是基于Linux bridge,所以可以使用Linux的命令查看详情,比如:
ip link show docker0
- Docker’s 默认的 “bridge” 网络和Linux的 “docker0” bridge关系示意图:
-
创建一个叫localnet的网络(Linux):
docker network create -d bridge localnet
-
apt install bridge-utils
安装查看工具,brctl show
查看Driver(结果跟docker network ls一一对应 ) -
例子
- 运行一个容器,并添加到localnet网络:
docker container run -d --name c1 --network localnet alpine sleep 1d
- 查看结果:
docker network inspect localnet --format '{{json .Containers}}'
,可以看到容器已经添加到网络 brctl show
查看,结果大概是这样的: 可以看到c1的 interface 添加到了br-20c2e8ae4bbb bridge。 示意图:
- 运行一个容器,并添加到localnet网络:
- 如果添加一个新的容器到相同的网络,在这个容器可通过名字
c1
ping同c1容器,因为容器内置了Docker DNS服务,因而可以解析同个网络下其他所有容器的名称 - 注意:默然的bridge network不只是DNS解析,而其他用户自定义的则可以
- 例子:
- 启动另一个容器,添加到同一个网络:
docker container run -it --name c2 --network localnet alpine sh
- 在容器c2中ping容器c1:
ping c1
,结果可以ping通
- 启动另一个容器,添加到同一个网络:
- 容器通过容器端口与宿主主机的端口映射连接外部网络
- 例子
- 运行一个web服务容器,将容器的80端口映射到宿主主机的5000端口:
docker container run -d --name web --network localnet --publish 5000:80 nginx
- 确认端口映射:
docker port web
- 测试:浏览器访问
主机IP:5000
,将可以访问到站点(windows下为localhost:5000或127.0.0.1:5000)
- 运行一个web服务容器,将容器的80端口映射到宿主主机的5000端口:
- 例子
-
多主机overlay网络(Multi-host overlay networks)
-
macvlan driver (在windows上是transparent)
- 通过给容器MAC 和 IP 地址,不需要端口映射和网桥
- 但 host NIC 必需为 promiscuous mode
- 连接到VLAN需要:子网信息、网关、IP段、使用宿主主机的哪个interface 或 sub-interface
- 例子
-
创建
docker network create -d macvlan \ --subnet=10.0.0.0/24 \ --ip-range=10.0.0.0/25 \ # 指定IP段 --gateway=10.0.0.1 \ -o parent=eth0.100 \ # 表示连接到VLAN 100 macvlan100
将会创建名称为macvlan100的网络、the eth0.100 sub-interface,示意图:
-
* 添加到容器:
docker container run -d --name mactainer1 \ --network macvlan100 \ alpine sleep 1d
示意图(多个容器):![《Docker Deep Dive》阅读笔记(二)](https://cdn.learnku.com/uploads/images/201909/20/27146/cuJ581nJHk.PNG!large)
-
容器和排除问题的服务日志
- 守护进程的日志
- windows:位于∼AppData\Local\Docker
- Linux:
journalctl -u docker.service
查看 - 修改daemon.json配置文件,可配置日志的记录级别等,修改后记得重启Docker
- 容器的日志
- 单机容器:
docker container logs <container-name>
- Swarm 服务:
docker service logs <service-name>
- 宿主主机为容器提供日志驱动,可有:
- json-file (default)
- journald (only works on Linux hosts running systemd)
- syslog
- splunk
- gelf
- 可在daemon.json文件中配置驱动:
"log-driver": "syslog
- 单独为容器或服务配置日志驱动:
--log-driver
或者--log-opts
- 单机容器:
- 守护进程的日志
-
服务发现
- 服务发现允许容器之间、Swarm服务之间相互定位(需要在相同的网络)
- Docker内置了DNS服务,每个容器自带DNS解析
- 以下是 容器 “c1” 通过容器名称 ping 容器 “c2”的示意图:
- 容器或Swarm服务启动时添加
--name
,DNS服务就会注册其名称和IP(需在同一个网络) --dns
指定DNS解析服务器地址--dns-search
自定义搜索域名,对于不能解析的名称- 例子
docker container run -it --name c1 \ --dns=8.8.8.8 \ --dns-search=dockercerts.com \ alpine sh
- 容器或Swarm服务启动时添加
-
Ingress 负载均衡
- Swarm支持两种发布模式用于从集群外部访问集群
- Ingress模式(默认):Swarm的任何节点,即使没有service replica也可以访问
- Host模式: 节点需要有service replicas运行才能访问
- 例子,发布为host模式
Ingress模式访问路由示意图:(外部的访问可能命中任意一个节点) 如果有多个副本,将会平衡访问:docker service create -d --name svc1 \ --publish published=5000,target=80,mode=host \ nginx
- Swarm支持两种发布模式用于从集群外部访问集群
-