- 理解Dock0
- 可以使用exec 命名后带参数执行ip addr 命令, 这样无需进入容器再去执行ip addr 命令
- 发现容器启动时会得到一个eth0@if9 的ip 地址, 这是docker 分配的
- 以下是docker 返回的信息
- —link
- 发现直接使用容器名, 不能ping 通
- 自定义网络
- 使用docker network create 命令创建自定义的网络
- —driver: 使用的模式, bridge, 使用的是桥接(docker0)
- —subnet: 子网掩码, 后面跟划分网络内主机的掩码
- —gateway: 网关地址
- mynet: 网络名, 可以换成其他名字
- 创建完毕后产生的信息
- 查看网络列表
- 发现已经有自定义网络
- 实战: 部署redis 集群
- 创建网络
- 通过脚本创建6 个redis 配置
- 可以将这段代码拷贝到for 循环中, 这样就可以一次性启动redis 容器
- docker run -p 637${port}:6379 -p 1637${port}:16379 —name redis-${port} \
- -v /mydata/redis/node-${port}/data:/data \
- -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
- -d —net redis —ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
- 启动第一个redis 容器
- 启动第二个redis 容器
- 启动第三个redis 容器
- 启动第四个redis 容器
- 启动第五个redis 容器
- 启动第六个redis 容器
- 实战: springboot 微服务打包Docker 镜像
- 返回以下信息
理解Dock0

- 从上图中可以看出, 该Linux 本机有3 个网络地址
- 问题: docker 是如何处理容器网络访问?
如下图, tomcat 容器是如何连接MySQL 容器?
测试
启动tomcat 容器
docker run -d -P --name tomcat01 tomcat
查看容器内部的IP 地址 ```shell
可以使用exec 命名后带参数执行ip addr 命令, 这样无需进入容器再去执行ip addr 命令
发现容器启动时会得到一个eth0@if9 的ip 地址, 这是docker 分配的
docker exec -it tomcat01 ip addr
以下是docker 返回的信息
1: lo:
- 问题1: 容器内没有ip addr 命令, 如何安装?- 执行以下命令:```shellapt update&& apt install -y iproute2
- 问题2: linux 宿主机能否ping 通容器内部?
- 发现可以ping 通docker 容器内部

原理
- 每启动一个docker 容器, docker 就会给容器分配一个ip, 只要安装了docker, 就会有一个网卡 docker0, 使用的是桥接模式, 是由evth-pair 技术实现的
再次测试ip addr
- 再启动一个容器测试, 发现有多了一对网卡

- 给容器分配的网卡地址都是成对出现的, veth-pair 就是一对虚拟设备接口, 它们都是成对出现的, 一端连接协议, 一端彼此相连, 正是因为这个特性, veth-pair 充当一个桥梁, 用来连接各种虚拟网络设备
- OpenStac, Docker 容器之间的连接, OVS 的连接, 都是使用veth-pair 技术
- 测试容器之间是否能ping 通, 如下所示:
网络模型图

- 结论:
- tomcat01 和tomcat02 公用一个路由器, docker0
- 所有的容器不指定网络的情况下, 都是由docker0 路由的, docker 会给容器分期一个默认的可用IP
- Docker 使用的是Linux 桥接, 宿主机中是一个Docker 容器的网桥docker0, 最多分配65535 个

- Docker 中所有的网络接口都是虚拟的, 虚拟的转发效率高
- 只要容器删除, 对应的网络地址就会被删除

—link
抛出问题
- 微服务项目中, 配置了数据库IP 地址, 如果使用docker 部署, 每次分配给MySQL 的ip 地址就会变, 希望使用服务名来访问容器
测试
- 使用tomcat02 容器ping tomcat01 容器 ```shell docker exec -it tomcat02 ping tomcat01
发现直接使用容器名, 不能ping 通
ping: tomcat01: Name or service not known
- 使用--link 命令进行容器之间的连接, 发现可以使用容器名来ping 通- 但是反向不能ping 通, 因为没有配置<a name="lV8JD"></a>## 原理探究- 在tomcat03 的hosts 中配置了tomcat02 的地址- 本质:- 在hosts 配置中增加了容器名和IP 的配置<a name="mEGif"></a>## network 命令```shell#使用network ls 命令来查看网络列表docker network lsNETWORK ID NAME DRIVER SCOPEd09975f74ad0 bridge bridge locald30adabb09ce host host local2f73acc8df73 none null local
#使用inspect 命令来查看网络具体信息docker network inspect d09975f74ad0#以下是docker0 的具体信息[{"Name": "bridge","Id": "d09975f74ad0fb541aac83f498fb57faed55157b61ae4dcb9e53f97b74fd5464","Created": "2022-02-02T02:30:04.985189843-05:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.17.0.0/16","Gateway": "172.17.0.1"}]},"Internal": false,"Attachable": false,"Containers": {"3fbf9cd2ca26d07a9d77df5be6afa554ead335c8cbe30f22ec962c664feae53d": {"Name": "tomcat03","EndpointID": "300ca07f517257e39f24ff158479e7971782e3dc07a2a59c7618876d7386a60a","MacAddress": "02:42:ac:11:00:04","IPv4Address": "172.17.0.4/16","IPv6Address": ""},"8bf803d31d17bf70e8b5a045692a802cee45d542afa4571c8afe0b6305980477": {"Name": "tomcat02","EndpointID": "968d07131fd81c2f4118a997b2db91dcb40581d4b95e194723d9aaa7ebae46d0","MacAddress": "02:42:ac:11:00:03","IPv4Address": "172.17.0.3/16","IPv6Address": ""},"b94a83be3fc9c179fc4f3dd418add445758ab7f712ace032b8ef25ec51101072": {"Name": "tomcat01","EndpointID": "43b95090964a868c8162e901c3fcb7db1d46183a81e9887aa848525eb8ce1852","MacAddress": "02:42:ac:11:00:02","IPv4Address": "172.17.0.2/16","IPv6Address": ""}},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}}]
自定义网络
抛出问题
- docker0 不支持容器名连接访问
查看所有的docker 网络

网络模式
- bridge (桥接模式, 自己创建使用这个模式)
- 有0.2 和0.3 两个网络地址, 它们不能直接访问, 需要通过0.1 转发访问
- none (不配置网络)
- host:
- 和宿主机共享网络
- container
- 容器网络连通 (局限性很大)
测试
- 启动容器
#使用--net bridge 参数, 使用的桥接方式是通过docker0 转发docker run -d -P --name tomcat01 --net bridge tomcatip:0.1
- docker0 特点: 默认, 域名不能访问, —link 可以打通连接
- 创建自定义网络
```shell
使用docker network create 命令创建自定义的网络
—driver: 使用的模式, bridge, 使用的是桥接(docker0)
—subnet: 子网掩码, 后面跟划分网络内主机的掩码
—gateway: 网关地址
mynet: 网络名, 可以换成其他名字
docker network create —driver bridge —subnet 192.168.0.0/16 —gateway 192.168.0.1 mynet创建完毕后产生的信息
ee7ec2ca1d394e79916fcf5ed4f358e869cad2a4ce450722af2c728f3dc22431
查看网络列表
docker network ls
发现已经有自定义网络
NETWORK ID NAME DRIVER SCOPE d09975f74ad0 bridge bridge local d30adabb09ce host host local ee7ec2ca1d39 mynet bridge local 2f73acc8df73 none null local
3. 查看自定义网络信息4. 启动容器, 将容器添加到自定义的网络中(通过--net 网络名添加到网络中), 之后再查看自定义的网络信息5. 测试ping 命令, 发现可以通过容器名ping 通<a name="WWNLF"></a>## 好处- 自定义网络中, docker 会维护每个容器之间的关系, 这样容器之间就可以通过容器名来访问彼此- 不同的集群使用不同的网络, 保证集群安全和健康<a name="I4RwA"></a># 网络连通<a name="csiYI"></a>## 抛出问题- 让Docker0 的tomcat-01 ping mynet 的tomcat-net-01, 发现ping 不通- 需要将docker0 的tomcat-01 连到mynet, 这样就可以实现以上目标<a name="tqVvd"></a>## network 之connect 命令- 使用说明```shelldocker network connect --helpUsage: docker network connect [OPTIONS] NETWORK CONTAINERConnect a container to a networkOptions:--alias stringSlice Add network-scoped alias for the container--help Print usage--ip string IP Address--ip6 string IPv6 Address--link list Add link to another container (default [])--link-local-ip stringSlice Add a link-local address for the container
将tomcat-01 添加到mynet 中
docker network connect mynet tomcat01
查看mynet 网络信息, 可以看到tomcat01 被添加到了mynet 网络中
- 这样就实现了一个容器两个IP 地址

- 再次ping tomcat-net-01, 发现可以ping 通

- 结论:
- 假设要跨网络操作别人, 就需要使用docker network connect 连通网络
实战: 部署redis 集群
- 创建redis 网络, 6 个redis 容器, 挂载每个节点的目录, 并启动容器
```shell
创建网络
docker network create redis —subnet 172.38.0.0/16
通过脚本创建6 个redis 配置
for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >/mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done
可以将这段代码拷贝到for 循环中, 这样就可以一次性启动redis 容器
docker run -p 637${port}:6379 -p 1637${port}:16379 —name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d —net redis —ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
启动第一个redis 容器
docker run -p 6371:6379 -p 16371:16379 —name redis-1 \ -v /mydata/redis/node-1/data:/data \ -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \ -d —net redis —ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
启动第二个redis 容器
docker run -p 6372:6379 -p 16372:16379 —name redis-2 \ -v /mydata/redis/node-2/data:/data \ -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \ -d —net redis —ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
启动第三个redis 容器
docker run -p 6373:6379 -p 16373:16379 —name redis-3 \ -v /mydata/redis/node-3/data:/data \ -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \ -d —net redis —ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
启动第四个redis 容器
docker run -p 6374:6379 -p 16374:16379 —name redis-4 \ -v /mydata/redis/node-4/data:/data \ -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \ -d —net redis —ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
启动第五个redis 容器
docker run -p 6375:6379 -p 16375:16379 —name redis-5 \ -v /mydata/redis/node-5/data:/data \ -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \ -d —net redis —ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
启动第六个redis 容器
docker run -p 6376:6379 -p 16376:16379 —name redis-6 \ -v /mydata/redis/node-6/data:/data \ -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \ -d —net redis —ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
- 进入其中一个redis 容器, 创建集群```shellredis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
- 创建成功后, 会产生以下信息

- 测试redis 集群

实战: springboot 微服务打包Docker 镜像
- 创建springboot 项目
- 打包应用
- 编写dockerfile ```dockerfile FROM java:8
COPY *.jar /app.jar
CMD [“—server.port=8080”]
EXPOSE 8080
ENTRYPOINT [“java”, “-jar”, “/app.jar”]
- 构建镜像- 将jar 包和dockerfile 上传到服务器- 执行生成镜像命令```shelldocker build -t demo .
发布运行
- 执行以下命令
docker run -d -P --name demo01 demo
- 执行以下命令
测试
- 执行以下命令 ```shell curl localhost:32781/hello
返回以下信息
Hello, FLM ```
