Docker网络管理

一、基础配置
1、端口映射
从外部访问容器应用
docker run -d -P nginx  #映射随机端口
docker run -d -p 80:80 nginx  #映射指定端口
docker run -d -p 80:80 -p 5000:5000 nginx  #映射多个指定端口
docker run -d -p 127.0.0.1:80:50 #映射指定地址的指定端口,默认会绑定本地所有接口上的所有地址
docker run -d -p 127.0.0.1::80 nginx #映射到指定地址的任意端口
docker port 610889eaab4b 80 #查看映射端口配置,610889eaab4b为容器ID,80为容器端口。
2、容器互联实现容器间通信
自定义容器名
docker run -d -p 80:80 --name web nginx
查看容器名称
docker inspect -f "{{.Name}}" 8f3c7f469b18
容器互联
docker run -d --name db mysql
docker run -d -p 80:80 --name web2 --link web1:web1 nginx
--link参数的格式为--link name:alias,其中name是要链接的容器名称,alias是这个连接的别名。
3、查看映射IP
docker inspect --format '{{ .NetworkSettings.IPAddress }}'  web1
docker inspect web1|awk -F\" '/"IPAddress/{print $--NF}'
docker exec -ti web1 awk 'END{print $1}' /etc/hosts
 
二、网络设置
1、创建网络
Docker 安装好,有三个网络会被自动创建。可以通过docker network ls命令查看:
# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
aaa59fabf719        bridge              bridge              local
1b89626fd45a        host                host                local
fe1dc2ce9a7c        none                null                local
用户可以自行创建bridge或overlay类型的网络。bridge网络适用于单台宿主机运行的单Docker引擎环境,而overlay网络允许我们跨多台宿主机进行通讯。
docker network create my_network 
使用docker network inspect my_network可以进行查看,创建的是一个本地桥接网络
# docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "421dae49712391e4f45c1397ee62281022eea83077f51696a2391a1ab36df53c",
        "Created": "2017-07-04T23:37:02.611184435+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

2、创建容器并连接到网络

docker run -ti --name system1 --network=my_network centos /bin/bash
docker run -ti --name system2 --network=my_network centos /bin/bash

docker network inspect my_network #可以查看新建容器的IP
"Containers": {
            "612e416f671fd90d9a0b644dcfd2870b4b8c15e0651e6636dd062d6c33125c75": {
                "Name": "system2",
                "EndpointID": "1b8e7ffe5cbbdd246239ea8aedf0fc04ed8c16ab838551eae5e9d7e3af98b536",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "bca3b58af0a265399822f1d476744e627e2f629be5cc3e6c1084271600171457": {
                "Name": "system1",
                "EndpointID": "b25b67251cc93d5cbf3821dc2e33954ae8142aa8ab380ed59f8ce83ceacc6c11",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
在system2中测试连通性:
# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.463 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.068 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.093 ms
#直接ping容器的名称也可以
# ping system1  
PING system1 (172.18.0.2) 56(84) bytes of data.
64 bytes from system1.my_network (172.18.0.2): icmp_seq=1 ttl=64 time=0.719 ms
64 bytes from system1.my_network (172.18.0.2): icmp_seq=2 ttl=64 time=0.095 ms
64 bytes from system1.my_network (172.18.0.2): icmp_seq=3 ttl=64 time=0.077 ms
3、断开网络与网络删除
断开
docker network disconnect my_network system1
删除
docker network rm my_network
4、网络模式
Docker的网络模式分为四种:Bridge、Host、Container、None
Bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
Host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
None模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

 

三、docker高级网络设置
1、配置 DNS在docker run时使用以下参数:

参数说明
-h HOSTNAME or --hostname=HOSTNAME 设定容器的主机名,它会被写到容器内的 /etc/hostname 和/etc/hosts。但它在容器外部看不到,既不会在 docker ps 中显示,也不会在其他的容器的/etc/hosts 看到。
--link=CONTAINER_NAME:ALIAS 选项会在创建容器的时候,添加一个其他容器的主机名到 /etc/hosts 文件中,让新容器的进程可以使用主机名 ALIAS 就可以连接它。
--dns=IP_ADDRESS 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
--dns-search=DOMAIN 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索host,还会搜索 host.example.com。 注意:如果没有上述最后 2 个选项,Docker 会默认用主机上的 /etc/resolv.conf 来配置容器。

2、容器访问控制
容器访问外部网络
容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。

sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

容器之间访问
容器之间相互访问,需要两方面的支持。
容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 docker0 网桥上。
本地系统的防火墙软件 -- iptables 是否允许通过。
访问所有端口
当启动 Docker 服务时候,默认会添加一条转发策略到 iptables 的 FORWARD 链上。策略为通过(ACCEPT)还是禁止(DROP)取决于配置 --icc=true(缺省值)还是 --icc=false。当然,如果手动指定 --iptables=false 则不会添加 iptables 规则。
可见,默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在docker服务修改/usr/lib/systemd/system/docker.service启动时添加--icc=false。
访问指定端口在通过 -icc=false 关闭网络访问后,可以通过 --link=CONTAINER_NAME:ALIAS 选项来访问容器的开放端口。
例如,在启动 Docker 服务时,可以同时使用 --icc=false --iptables=true 参数来关闭允许相互的网络访问,并让 Docker 可以修改系统中的 iptables 规则。
此时,系统中的 iptables 规则可能是类似:

iptables -nL 
... 
Chain     FORWARD   (policy ACCEPT) 
target     prot   opt   source     destination 
DROP      all     --   0.0.0.0/0   0.0.0.0/0...

之后,启动容器(docker run)时使用 --link=CONTAINER_NAME:ALIAS 选项。Docker 会在 iptable中为 两个容器分别添加一条 ACCEPT 规则,允许相互访问开放的端口(取决于 Dockerfile 中的 EXPOSE 行)。当添加了 --link=CONTAINER_NAME:ALIAS 选项后,添加了 iptables 规则。

iptables -nL
 ... 
Chain   FORWARD   (policy ACCEPT)
target   prot   opt   source     destination
ACCEPT   tcp    --   172.17.0.2   172.17.0.3     tcp spt:80 
ACCEPT   tcp    --   172.17.0.3   172.17.0.2     tcp dpt:80 
DROP    all    --   0.0.0.0/0    0.0.0.0/0
注意:--link=CONTAINER_NAME:ALIAS 中的 CONTAINER_NAME 目前必须是 Docker 分配的名字,或使用 --name 参数指定的名字。主机名则不会被识别。
 

posted on 2017-07-27 15:31  K‘e0llm  阅读(277)  评论(0编辑  收藏  举报

导航