Docker之网络

1.  端口映射

    -P  宿主机会随便产生一个端口映射容器内部的端口

    -p  自定义宿主机的端口映射容器内部的端口 

        Local_Port:Container_Port

        Local_IP:Local_Port:Container_Port

        Local_IP::Container_Port  与-P相似

        Local_Port:Container_Port/[tcp/udp]

2.  端口暴露

    1.  在dockerfile使用EXPOSE命令

    2.  docker运行时指定--expose

3.  容器互联

    1.  两个容器使用一个自定义的网络

        1.  创建两个容器

            docker run -itd --name=container1 busybox

            docker run -itd --name=container2 busybox 

        2.  创建自定义网络

            docker network create -d bridge --subnet 172.25.0.0/16 demo_net

        3.  将容器连接到自定义网络

            docker network connect demo_net container1

            docker network connect demo_net container2

        4.  启动第三个容器

            docker run --network=demo_net -itd --name=container3 busybox                               

4.  Docker的网络模式

    docker network ls 查看docker网络

    docker network  inspect [bridge|host|none|自定义网桥名称]

    1.  bridge

        默认网络模式,使用docker0作为网桥。默认创建的容器也是加入到这个网络中。

    2.  host

        容器不会获得一个独立的network namespace,而是与宿主机公用一个。

        容器内可以看到宿主机的网卡信息

    3.  none

        获取独立的network namespace,但不为容器进行任何网络配置。

    4.  container

        与指定的容器使用同一个network namespace,网卡配置也都是相同的。

    5.  自定义

        与bridge网络一样。

5.  bridge网络

    当启动docker时,会自动生成一个名为docker0的Linux bridge(网桥)。bridge可以看成是一个软件交换机,负责对挂载在它上面的接口进行包转发。   

    

    每个容器使用bridge模式启动时,Docker都会为容器创建一对虚拟网络接口(veth pair)设备,这对设备一端在容器的Network NameSpace,另一端在docker0。    

6.  host网络

    在启动容器时使用--network host指定为本机网络,则容器将与宿主机共享网络栈,此时容器会使用主机的IP以及其他网络配置。 

    使用host网络时,对容器做端口映射将会无效, 容器会忽略 -p 所指定的端口,而直接在宿主机网络层面开启对应端口。例如,容器中如果开放了80端口,那么此时宿主机也将开放同样端口。

    host网络相比bridge网络具有更高的性能,同时在容器有大量端口要开放的时候 ,也会省事很多。但同时也增加了不安全性,此时可在容器内对主机的网络栈进行操作,所以并不推荐使用。

    docker run -itd --net=host nginx:alpine   

7.  none网络

    none网络会禁用容器的网络栈,使得容器与外部隔离。在启动时通过 --network none 实现。此时,容器除lo外,将不再有其他网卡,完全与外部网络隔离。

8.  container模式

    这个模式表示与另一个运行中的容器共享一个network namespace,共享意味着拥有相同的网络视图

    1.  启动一个容器

        docker run -itd --name nginx nginx:alpine

    2.  再启动一个容器,使用上面容器的网络

        docker run --net=container:nginx -it nginx:alpine

8.  自定义网络

    1.  创建网络桥

        docker network create -d bridge --subnet "172.16.0.0/16" --gateway "172.16.0.1" mybr0

    2.  查看是否有网络

        docker network ls

    3.  查看网络详细信息

        docker network inspect mybr0

    4.  创建容器

        docker run -it -d --name mynginx-v1 --network mybr0 -p 81:80 mynginx:v1

    5.  删除网桥

        docker network rm mybr0

9.  容器内部与外部网络互通访问

    安装docker时,默认会启用Linux的包转发功能,如下:

    $ sudo sysctl net.ipv4.ip_forward

    net.ipv4.ip_forward = 1    

    1.  容器内部访问外部网络

        查看宿主机iptables的nat表上面的POSTROUTING链规则,可看到一条转发规则

        iptables -L -n -v -t nat POSTROUTING

        pkts bytes target prot opt in out source destination

        0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0

        该规则的作用是当docker0收到来自容器网段(172.17.0.0/16)的网络包时,将其交给MASQUERADE处理。MASQUERADE与传统的SNAT相似,会将网络包的源IP替换为网卡IP,这样可以保证容器的网络包能够正常外出。          

    2.  外部网络访问容器内部

        我们开放了80端口,那么会在iptables规则里,加一条DNAT规则

        1198K   69M DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.11:80    

        该规则将访问到主机80端口的网络包,转发到容器地址(172.17.0.2)的80端口,以此实现外部网络对容器的访问。

10.  容器的整体网络架构 

    

11.  修改docker0桥的网段地址

    1.  停止docker服务

    2.  修改/etc/docker/daemon.json文件的内容

{"insecure-registries": ["172.16.20.215:5000"],
"bip": "192.168.110.1/24"
}

    3.  启动docker服务,可以看到docker0的IP地址已经修改。

12.  远程连接docker服务

    1.  停止docker服务

    2.  修改/etc/docker/daemon.json文件的内容

{
  "registry-mirrors": ["https://registry.docker-cn.com"],
  "hosts": ["tcp:0.0.0.0:2375","unix:///var/run/docker.sock"]
}

    3.  启动docker服务

    4.  客户端连接的时候,需要指定docker -H 192.168.1.100:2375 ps    

13.  查看单个容器的IP地址

    docker inspect 容器名称或容器ID | grep IPAddress | grep [1-9] | awk '{print $2}' | sort|uniq | awk -F '"' '{print $2}'

    docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称或容器ID   

14.  查看所有容器的IP地址

    1.  获取所有容器名称及其IP地址

        docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)

    2.  如果是docker-compose启动的容器,使用下面的命令查看

        docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

        docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

    

posted @ 2023-05-23 10:22  奋斗史  阅读(55)  评论(0)    收藏  举报