Bootstrap

Docker容器技术(四)——docker网络

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

;