#MySQL容器默认使用了匿名数据卷
[root@ubuntu1804 ~]#docker run -d --name mysql -p 3306:3306 -e  MYSQL_ROOT_PASSWORD=123456 mysql:5.7.30

#备份数据库
[root@ubuntu1804 ~]#docker run -it --rm --volumes-from mysql -v $(pwd):/backup  centos tar xvf /backup/mysql.tar -C /var/lib/mysql

网络管理

容器一旦创建,就会生成一个网卡,一半在宿主机,桥接在docker0网卡上,一半在容器上;
同一个宿主机上的容器之间是可以互相通讯的,--icc=true;
要想不让容器之间相互通讯,在容器的service里修改:
vim /lib/systemd/system/docker.service
将下列内容增加--icc=false
ExecStart=/usr/bin/dockerd --icc=false -H fd:// --containerd=/run/containerd/containerd.sock
重新加载启动
[root@ubuntu2004 nginx]#systemctl daemon-reload
[root@ubuntu2004 nginx]#systemctl restart docker
此时容器之间ping不通了

如果内部IP与dockers地址冲突,可以将dockers地址修改,如果加速过,此文件是有内容的
vim /etc/docker/daemon.json  
{
  “bip": "192.168.100.1/24"
}
[root@ubuntu2004 nginx]#systemctl restart docker
容器的IP也会变成此网段

或者修改service文件
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --icc=false -H fd:// --containerd=/run/containerd/containerd.sock --bip=192.168.100.1/24

或者自己创建网桥:不是持久化的,重启就会失效
brctl addr docker1
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --icc=false -H fd:// --containerd=/run/containerd/containerd.sock -b docker1

通过容器名互联

使用--link,容器会自动做host解析,解析,这样就可以通过容器名称进行访问了
[root@ubuntu2004 ~]#docker run -d --name web01 -p 81:80 nginx:v1.22.0-2022-10-18 
48b42a48a8fae96bd5caafb96fcf0090e3974d59e5f95e2b9693936ba81d0b26
[root@ubuntu2004 ~]#docker run --link web01 -d --name web02 -p 82:80 nginx:v1.22.0-2022-10-18

网络连接模式

docker五种网络模式:
none  :无网络
bridge :桥接模式
host  :和宿主机共用度端口,可以直接跟外部通讯,性能好
container :几个容器共享一个网络
自定义网络模式 network-name
默认带了三种网络模式:
[root@ubuntu2004 ~]#docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5a1ff77c87d7   bridge    bridge    local
c82e11ca1965   host      host      local
19fa6ecebf86   none      null      local

默认模式是:桥接模式bridge

格式:docker run --network <mode>
bridge模式:
可以和外部网络之间进行通信,通过SNAT访问外网,使用DNAT可以让容器被外部主机访问,所以此模式也称为NAT模式 
此模式宿主机会主动启动ip_forward功能 

bridge网络模式特点 
网络资源隔离: 不同宿主机的容器无法直接通信,各自使用独立网络 
无需手动配置: 容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改 
可访问外网: 利用宿主机的物理网卡,SNAT连接外网 
外部主机无法直接访问容器: 可以通过配置DNAT接受外网的访问 
低性能较低: 因为可通过NAT,网络转换带来更的损耗 
端口管理繁琐: 每个容器必须手动指定唯一的端口,容器产生端口冲容
container模式:
第一台wordpress容器:
docker run -d 80:80 --name wordpress -v /data/wordpress:/var/www/html --restart=always wordpress:php7.4-apache

MySQL容器共享wordpress网络:
docker run --network container:wordpress  -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=123456 --name mysql -d  -v /data/mysql:/var/lib/mysql --restart=always mysql:8.0.29-oracle

此时访问web网页,数据库主机填127.0.0.1

通过容器模式实现LNP架构

#准备nginx连接php-fpm的配置文件
[root@ubuntu2004 ~]#mkdir /data/nginx/conf.d/ -p
[root@ubuntu2004 ~]#vim /data/nginx/conf.d/php.conf

server {
     listen 80;
     server_name www.li.org;
     root /usr/share/nginx/html;
     index index.php;
     location ~ \.php$ {
         root           /usr/share/nginx/html;
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index index.php;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include       fastcgi_params;  
    }
}

#启动nginx容器:
[root@ubuntu2004 ~]#docker run -d -v /data/nginx/conf.d/:/apps/nginx/conf/conf.d/ -v /data/nginx/html/:/usr/share/nginx/html/ --name nginx01 -p 80:80 nginx:1.22.0 
f28820f8114832b82944bf654bddd9765820c6c6a54e7dbad98dc83b741d9b7f

#启动PHP-fpm,自动去官网拉取
[root@ubuntu2004 ~]#docker run -d --network container:nginx01 --name php-fpm -v /data/nginx/html/:/usr/share/nginx/html/ php:8.1-fpm

#准备php的测试页文件
[root@ubuntu2004 nginx]#vim /data/nginx/html/index.php
<?php
phpinfo();
?>

自定义网络模式

创建网络:默认是bridge模式,mode不支持host和none

[root@ubuntu2004 nginx]#docker network create -d bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 test-net
4323eb01594f2d7b266a2d3d0ef014686b91e996d8eba903fc6e05773bd4f5c2
[root@ubuntu2004 nginx]#docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
5a1ff77c87d7   bridge     bridge    local
c82e11ca1965   host       host      local
19fa6ecebf86   none       null      local
4323eb01594f   test-net   bridge    local
此时会增加一个br开头的网卡,是桥接网卡
[root@ubuntu2004 nginx]#brctl show
bridge name	bridge id		STP enabled	interfaces
br-4323eb01594f		8000.024241337909	no		

创建两个容器,并查看IP是否在一个网段
[root@ubuntu2004 nginx]#docker run -d --name nginx01 --network test-net -p 80:80 nginx:v1.22.0-2022-10-18 
6f42bc01a1fbb4f22754a13ad99be657f13c2950afd2499539642d244cbab130
[root@ubuntu2004 nginx]#docker run -d --name nginx02 --network test-net -p 81:80 nginx:v1.22.0-2022-10-18 
7ab879a1e9fec9831cec5c196cb4be1953d53792db4500471e810a3d8151964d
[root@ubuntu2004 nginx]#docker exec -it nginx01 ip a
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
50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.20.0.2/16 brd 172.20.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@ubuntu2004 nginx]#docker exec -it nginx02 ip a
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
52: eth0@if53: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:14:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.20.0.3/16 brd 172.20.255.255 scope global eth0
       valid_lft forever preferred_lft forever

同一个宿主机之间不同网络通讯

方法一:
将iptables规则到出到一个文件,进行修改
[root@ubuntu2004 nginx]#iptables-save > /root/iptables.rule
[root@ubuntu2004 nginx]#vim /root/iptables.rule

-A DOCKER-ISOLATION-STAGE-2 -o br-4323eb01594f -j ACCEPT
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j ACCEPT

将iptables规则导入
[root@ubuntu2004 nginx]#iptables-save < /root/iptables.rule

#docker重启会重新生成规则

方法二:
打通网络connect,将一个容器接到一个网络里
[root@ubuntu2004 nginx]#docker run -d --name nginx02 --network test-net -p 81:80 nginx:v1.22.0-2022-10-18
[root@ubuntu2004 nginx]#docker run -d --name nginx01 -p 82:80 nginx:v1.22.0-2022-10-18
nginx01 在网络docker0里
nginx02 在网络test-net里

把nginx01加到test-net里,nginx01就可以访问test-net网络里的容器
[root@ubuntu2004 nginx]#docker network connect test-net nginx01
把nginx02加到bridge里,nginx02就可以访问bridge网络里的容器
[root@ubuntu2004 nginx]#docker network connect bridge nginx02

原理是:在本容器增加了一个对方网络网段的IP

实现跨宿主机的容器之间网络互联

方法一:不可靠

宿主机1:
[root@ubuntu2004 ~]#docker run -d --name nginx01 -p 80:80 nginx:v1.22.0-2022-10-18
[root@ubuntu2004 ~]#docker run -d --name nginx02 -p 81:80 nginx:v1.22.0-2022-10-18
桥接eth0到docker0上
[root@ubuntu2004 ~]#brctl addif docker0 eth0

宿主机2:
[root@ubuntu2004 ~]#docker run -d --name nginx01 -p 80:80 nginx:v1.22.0-2022-10-18
[root@ubuntu2004 ~]#docker run -d --name nginx02 -p 81:80 nginx:v1.22.0-2022-10-18
桥接eth0到docker0上
[root@ubuntu2004 ~]#brctl addif docker0 eth0

方法二:

修改一个机器上的网段,使两个机器上容器不在一个网段
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --icc=false -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.27.0.1/16
[root@ubuntu2004 ~]#systemctl daemon-reload 
[root@ubuntu2004 ~]#systemctl restart docker.service 
[root@ubuntu2004 ~]#docker run -d --name nginx01 -p 80:80 nginx:v1.22.0-2022-10-18
a02ac269ba8651ab32ec3bf5f5c6df39704033490ea44085c8d13e3022386482
[root@ubuntu2004 ~]#docker run -d --name nginx02 -p 81:80 nginx:v1.22.0-2022-10-18
37fdf480651db19c82abfbbb918dc25fa935e017ce48e6e0a07ca90b9fbac8ae

添加网关:
[root@ubuntu2004 ~]#route add -net 172.27.0.0/16 gw 10.0.0.101
[root@ubuntu2004 ~]#route add -net 172.17.0.0/16 gw 10.0.0.102

修改iptables策略
[root@ubuntu2004 ~]#iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT