docker0:docker服务启动创建的虚拟网桥→bridge(类似于虚拟交换机)
veth pair:虚拟以太网对,相当于一根网线,一端在容器上,另一端在网桥上
容器内接口对应宿主机网桥上接口
容器里执行ip a查看 62: eth0@if63 (interface 63)
宿主机网桥 63: veth94c0956@if62
查看虚拟网桥: [root@linxuan ~]$ yum -y install bridge-utils [root@linxuan ~]$ brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242f3165a9c no veth94c0956
网桥叫docker0,它有一个网口也叫docker0,docker0有自己的IP172.17.0.1,是所有容器的网关
容器网络有三个方向:
容器→外部网络 SNAT
外部网络→容器 DNAT(docker run -p 3306:3306)docker自动实现
容器←→容器
容器访问外部默认可以访问(docker自动实现),首先开启了包转发net.ipv4.ip_forward = 1,其次配置了防火墙SNAT规则
[root@linxuan ~]$ iptables -tnat -nvL POSTROUTING Chain POSTROUTING (policy ACCEPT 160 packets, 11948 bytes) pkts bytes target prot opt in out source destination 161 9990 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
容器之间通信,默认使用IP地址可以互相通信,但IP地址不是固定的无法互相通信,docker提供两种方案解决:
--link 传统方式
目前 Docker 官网已不建议使用;是通过在本地解析文件 /etc/hosts 添加主机记录来实现DNS域名解析的。
启动msyql容器 docker run -d --name db_wordpress --restart always \ -e MYSQL_ROOT_PASSWORD=wordpress \ -e MYSQL_DATABASE=db_wordpress \ -e MYSQL_USER=wordpress_rw \ -e MYSQL_PASSWORD=123456 \ -p 3306:3306 mysql:5.7 ###--name db_wordpress起个名字,--restart always随着docker服务启动而启动,-e MYSQL_ROOT_PASSWORD=给超级用户设置密码 ###-e MYSQL_DATABASE=创建一个库,-e MYSQL_USER=创建一个用户,-e MYSQL_PASSWORD=给新创建的用户设置密码,-p端口映射 docker run -d --name wordpress --restart always --link db_wordpress \ -e WORDPRESS_DB_HOST=db_wordpress:3306 \ -e WORDPRESS_DB_USER=wordpress_rw \ -e WORDPRESS_DB_PASSWORD=123456 \ -e WORDPRESS_DB_NAME=db_wordpress \ -p 80:80 wordpress:php7.4 ###--link db_wordpress连接数据库;-e WORDPRESS_DB_HOST=db_wordpress:3306指定数据库库名和端口;-e WORDPRESS_DB_USER=设置用户 ###-e WORDPRESS_DB_PASSWORD=设置用户的密码;-e WORDPRESS_DB_NAME=设置数据库名
先启动MySQL容器,再启动wordpress,使用--link将两个容器建立连接,它会在目标容器和发起连接容器之间创建一个网络桥接,使得发起连接容器通过目标容器的别名来访问目标容器
--network 建议使用
user-defined network 用户按项目创建网桥,自定义网络
用自定义网络创建的容器默认就可以使用容器的别名通信
#创建一个网络 [root@linxuan ~]$ docker network create net0 b3c9260b6e01dfb7cf8e178b45d5dc3c2198edfadf701c809e5bf860228149ee
查看docker网络:docker network ls
查看新建网络的网段和网关:[root@linxuan ~]$ docker network inspect net0![]()
##可以在创建网络的时候定义网段和网关
docker network create --subnet 172.100.0.0/16 --gateway 172.100.0.1 net1
使用--network启动容器
[root@linxuan ~]$ docker network create wp-net docker run -d --name db_wordpress --restart always \ --network wp-net \ -e MYSQL_ROOT_PASSWORD=wordpress \ -e MYSQL_DATABASE=db_wordpress \ -p 3306:3306 mysql:5.7 ###--network wp-net使用自定义网络; docker run -d --name wordpress --restart always --network wp-net \ -e WORDPRESS_DB_HOST=db_wordpress:3306 \ -e WORDPRESS_DB_USER=root \ -e WORDPRESS_DB_PASSWORD=wordpress \ -e WORDPRESS_DB_NAME=db_wordpress \ -p 80:80 wordpress:php7.4 ###--network wp-net自定义网桥
使用其他容器加入此网络,可以ping通以上两个容器,默认一个docker网络内可以通信
docker网络模式
-brdige(默认)
docker run --network=brdige
-host
docker run --network=host
这种模式下,容器和宿主机之间不做隔离,容器是没有IP地址的,原本容器监听的端口之间变成主机监听,直接访问主机的IP+端口就能访问到容器的内容
-none
docker run --network=none
这种模式下,容器没有自己的IP地址,完全没有网络,一般用于跑一些离线任务
Namespace
docker借助Linux内核Namespace技术实现隔离的,Namespace机制提供一种资源隔离方案
查看当前系统下的namespace:lsns
查看某个进程的namespace: ls la /proc/1/ns
Docker 默认没有启用 user namespace
在宿主机上容器的pid是一个随机的pid,在容器里就是pid为1
在网络host模式下,docekr对容器的network和user都不做隔离
网络模式none与brdige一样,只有user不做隔离
网络Namespace
使用ip netns命令操作network namespace
# 创建一个名为 nstest 的 network namespace [root@linxuan ~]$ ip netns add nstest # 列出系统已存在的 network namespace [root@linxuan ~]$ ip netns ls nstest [root@docker ~]# ls -al /var/run/netns/ total 0 drwxr-xr-x 2 root root 60 Dec 8 08:35 . drwxr-xr-x 31 root root 1140 Dec 8 08:35 .. -r--r--r-- 1 root root 0 Dec 8 08:35 nstest # 在 network namespace 中执行命令 [root@docker ~]# ip netns exec nstest ip addr 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 删除 network namespace: nstest [root@docker ~]# ip netns delete nstest