目录
学习通道:狂神说Java】Docker最新超详细版教程通俗易懂
docker官网:Docker Documentation | Docker Documentation
docker hun:Docker Hub
Docker 网络
理解Docker0网络
清空所有环境
root@ajj666-virtual-machine:~# docker rmi -f $(docker images -aq) root@ajj666-virtual-machine:~# docker images
查看镜像发现已经全部删除
ifconfig查看本地网络设置
三个网络
# 问题:docker是如何处理容器网络访问的?
# 测试
首先我们进入容器内安装net-tools工具,然后查看容器网络网卡情况
root@ajj666-virtual-machine:~# docker exec -it tomcat01 /bin/bash root@6c7386b5878e:/usr/local/tomcat# apt update && apt install -y iproute2 root@6c7386b5878e:/usr/local/tomcat# apt install net-tools
# 查看容器的内部网络地址,ifconfig,发现容器启动的时候会得到一个eth0@if5地址,这个是由docker分配的!
root@6c7386b5878e:/usr/local/tomcat# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
# 思考:linux能不能ping通容器内部?root@ajj666-virtual-machine:~# ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.033 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.039 ms
# 由结果可以看出,linux是能ping通docker容器内部的!
# 原理
1、我们每次启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡桥接模式,使用的技术是evth-pair技术!
然后我们在宿主机中再测试ip addr
2、再启动一个容器测试,发现又多了一对网卡!
# 我们发现这个容器带来的网卡,都是一对一对的
# evth-pair 就是一对虚拟设备接口,他们是成对出现的,一段连着协议,一段彼此相连
# 正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备
# openstac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
3、我们来测试一下tomcat01和tomcat02之间是否可以ping通
# 先给tomcat01或者tomcat02安装好ping工具(容器里真是啥命令都没有啊!)
root@ajj666-virtual-machine:~# docker exec -it tomcat02 /bin/bash root@6c7386b5878e:/usr/local/tomcat# apt update && apt-get install inetutils-ping root@6c7386b5878e:/usr/local/tomcat# ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.069 ms 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.074 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.089 ms
# 结论:容器和容器之间也是可以相互ping通的!
绘制一个网络模型:
结论:tomcat01和tomcat02是共用的一个路由器,docker0
所有的容器不指定网络的情况下,都是docker01路由的,docker会给我们的容器分配一个默认可用的IP:255.255.0.1/16
小结
Docker使用的是linux的桥接,宿主机中是一个Docker容器的网桥,docker0.
Docker中的所有网络接口都是虚拟的,虚拟的转发效率特别高!(内网传递文件)
只要容器删除,对应网桥对就没了!
--link
思考:我们编写了一个微服务,database ulr=ip,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以用名字来进行访问容器?
root@ajj666-virtual-machine:~# docker exec -it tomcat02 ping tomcat1 ping: unknown host
# 我们直接ping容器名字发现并未找到主机,那么这要如何解决呢?
# 通过--link即可解决网络连通问题
root@ajj666-virtual-machine:~# docker run -d -P --name tomcat03 --link tomcat02 tomcat oot@6c7386b5878e:/usr/local/tomcat# apt update && apt-get install inetutils-ping root@a245a38ae3a0:/usr/local/tomcat# ping tomcat02 PING tomcat02 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.062 ms 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.062 ms 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.062 ms
# 但是反向ping能可以嘛?答案是不可以,因为没有配置
root@e451ed355c48:/usr/local/tomcat# ping tomcat03 ping: unknown host
# 查看hosts配置,在这里可以看到tomcat02已经被配置在其中
root@ajj666-virtual-machine:~# docker exec -it tomcat03 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 tomcat02 e451ed355c48 172.17.0.4 a245a38ae3a0
本质探究:--link就是我们在hosts配置中增加了一个 172.17.0.3 tomcat02 e451ed355c48
但是我们现在使用Docker已经不建议使用--link了!
我们需要自己自定义网络,不去使用docker01!
docker01的问题:它不支持容器名连接访问!
自定义网络
容器互联
查看所有的docker网络
root@ajj-virtual-machine:/# docker network ls NETWORK ID NAME DRIVER SCOPE 412706dca263 bridge bridge local 3f78a339be64 host host local 5bae26517f79 none null local
网络模式
bridge:桥接模式docker
none:不配置网络
host:和宿主机共享网络
container:容器网络互联(用的少,局限大)
测试
# 我们之前直接启动的命令--net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat
# docker0特点:默认,域名不能访问,--link可以打通连接!
# 我们可以自定义一个网络!
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
root@ajj-virtual-machine:/# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 366d689db3a2dd25d2b978c3d5d5b646ee19c68dde2970d197d46492f5dd8a08 root@ajj-virtual-machine:/# docker network ls NETWORK ID NAME DRIVER SCOPE 412706dca263 bridge bridge local 3f78a339be64 host host local 366d689db3a2 mynet bridge local 5bae26517f79 none null local
我们自己的网络就创建好了
接下来我们再用mynet新建两个容器
root@ajj-virtual-machine:/# docker run -d -P --name tomcat_net01 --net mynet tomcat 4d7a7029b72578219f172061736ffc0d920301c4c21dc1422b99b72afeb14aa4 root@ajj-virtual-machine:/# docker run -d -P --name tomcat_net02 --net mynet tomcat 6f8761fe5829bca652dd29b49bca5f3c82d63037a3459b57f2bc563070a67e29
# 创建完成之后再次查看mynet
root@ajj-virtual-machine:/# docker network inspect mynet
# 发现新建的两个容器的IP地址是基于mynet设置的!
# 之后再测试一下两个容器之间能否ping通
root@ajj-virtual-machine:/# docker exec -it tomcat_net01 ping tomcat_net02 PING tomcat_net02 (192.168.0.3): 56 data bytes 64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.194 ms 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.076 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.060 ms
# 可以看到我们不适用link也能之间ping通容器名了!
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis-不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
# 核心指令--connect
# 用法:docker network connect + 网络(mynet)+容器名
# 测试用tomcat01打通tomcat_net01
# 执行命令:
docker network connect mynet tomcat01
# 查看mynet:
docker network inspect mynet
# 可以看到tomcat01已经连接到了mynet当中!也就是将tomcat01放到了mynet网络下!
# 一个容器两个IP,就像公网IP和内网IP!
# 阿里云服务:公网IP 私网IP
# 测试tomcat_net01能否ping通tomcat01
root@ajj-virtual-machine:/# docker exec -it tomcat_net01 ping tomcat01 PING tomcat01 (192.168.0.4): 56 data bytes 64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=0.223 ms 64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=0.055 ms
# 测试tomcat_net01能否ping通tomcat02
root@ajj-virtual-machine:/# docker exec -it tomcat_net01 ping tomcat02 ping: unknown host
# 发现tomcat_net01能够ping通tomcat01但是不能ping通tomcat02,因为tomcat02并没有连接到mynet!
实战:部署Redis集群
# 创建网卡
docker network create redis --subnet 172.138.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
# 启动六个容器
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 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 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 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 docker run -p 6375:6379 -p 16375:16379 --name redis-5 -v /mydata/redis/node5/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 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
# 创建完成之后查看一下容器
docker ps -a
docker network inspect redis
# 创建集群
root@ajj666-virtual-machine:~# docker exec -it redis-1 /bin/sh /data # redis-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 >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 172.38.0.15:6379 to 172.38.0.11:6379 Adding replica 172.38.0.16:6379 to 172.38.0.12:6379 Adding replica 172.38.0.14:6379 to 172.38.0.13:6379 M: 6ecfc09e8826387564c27784971a6c607ad1d707 172.38.0.11:6379 slots:[0-5460] (5461 slots) master M: b32360ea662e9b276de003a95672017a5875953b 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master M: d60337e8f997452a513ab9c1ee4907d5ad112710 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master S: f1c53df0898854a789ddecbe54323c1f6e3211e4 172.38.0.14:6379 replicates d60337e8f997452a513ab9c1ee4907d5ad112710 S: 1d65b7898b4907cfafa5cecf90333d9d457896a4 172.38.0.15:6379 replicates 6ecfc09e8826387564c27784971a6c607ad1d707 S: 8d7823e36a3fa653231dc9c8db54fa1a8ea2e19c 172.38.0.16:6379 replicates b32360ea662e9b276de003a95672017a5875953b Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node 172.38.0.11:6379) M: 6ecfc09e8826387564c27784971a6c607ad1d707 172.38.0.11:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: 8d7823e36a3fa653231dc9c8db54fa1a8ea2e19c 172.38.0.16:6379 slots: (0 slots) slave replicates b32360ea662e9b276de003a95672017a5875953b M: b32360ea662e9b276de003a95672017a5875953b 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 1d65b7898b4907cfafa5cecf90333d9d457896a4 172.38.0.15:6379 slots: (0 slots) slave replicates 6ecfc09e8826387564c27784971a6c607ad1d707 M: d60337e8f997452a513ab9c1ee4907d5ad112710 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: f1c53df0898854a789ddecbe54323c1f6e3211e4 172.38.0.14:6379 slots: (0 slots) slave replicates d60337e8f997452a513ab9c1ee4907d5ad112710 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
docker Redis集群搭建完成!
# 测试Redis集群
root@ajj666-virtual-machine:~# docker exec -it redis-1 /bin/sh /data # redis-cli -c 127.0.0.1:6379> set a b 172.38.0.14:6379> get a Could not connect to Redis at 172.38.0.14:6379: Host is unreachable (34.31s) not connected> /data # redis-cli -c 127.0.0.1:6379> get a -> Redirected to slot [15495] located at 172.38.0.13:6379 "b"
所以当我们使用docker之后,所有的技术使用起来就会变得相当快速简单!