欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Docker:网络 有大用

了解 Docker 的网络是怎么回事,创建自定义的网络,在容器上使用这些网络。

封面摄影:Jimmy Mcintyre

来自 https://ninghao.net/course/3814


网络

1)网络

Docker 提供了几种网络的类型,它们决定了容器之间,还有外界跟容器之间怎么样相互通信 .. 查看这些网络可以执行一下 

docker network ls ..

这里会列出当前主机上面的 docker 网络 .. none 就是无网络,使用这种网络的容器会被完全隔离 .. host 是主机网络,使用这种网络的容器跟主机使用同样的网络 .. 这种容器对外界是完全开放的 .. 也就是能访问到主机就能访问到使用 host 这种网络的容器 ..

bridge 是桥接网络,除非在创建容器的时候手工指定使用的网络,不然默认容器就会属于这个叫 bridge 的网络 ... 属于这个网络的容器相互之间可以进行通信 ..

不过外界想要访问到这个网络上的容器,需要通过这个桥接网络 .. 它有点像是容器与主机之间的一座桥 .. 这样对容器有个隔离的作用 ..

我们可以通过发布端口的方法,让外界跟容器之间使用某个指定的端口进行通信 ...

来自 https://ninghao.net/video/3816#info


2)理解 bridge 网络

我们可以先把之前创建的容器都删除掉 .. 然后我们再去检查一下网络 .. 可以使用 docker network inspect .. 加上网络的名字 .. 比如 bridge ..

docker network inspect bridge  

这里会列出 bridge 这个网络的相关信息 .. 在 Containers 这里,会包含使用这种网络的容器 .. 现在还没有 .. 下面我们再去创建一个容器 .. 让它在后台运行 .. 名字是 web1 .. 在创建容器的时候,可以使用一个 --net 选项,为容器指定要使用的网络 .. 如果不用的话,这个容器会默认使用 bridge 这个网络 ..

用一下 nginx 这个镜像 .. 如果主机没有这个镜像 docker 会自动给我们去下载它 ..

docker run -d --name web1 nginx

再去查看一下 bridge 这个网络 ..

docker network inspect bridge

 在 Containers 这里,现在有了一个使用这个网络的容器 .. 就是刚才我们创建的这个 web1 .. 这里还有这个容器在这个网络上的 ip 地址 ...

下面我们再去创建一个容器 .. 名字是 web2 ... 

docker run -d --name web2 nginx

再查看一下 bridge 网络 .. 

docker network inspect bridge

现在已经有两个容器使用这个网络了 ...

在这个网络下的容器之间可以相互通信 .. 我们可以去验证一下 ... 复制一下 web2 这个容器的 ip 地址 ..

然后我们可以登录到 web1 .. 

docker exec -it web1 bash

 .. 去 ping 一下 web2 的 ip 地址 ..

ping 172.17.0.3

 这里能 ping 得通 .. 说明 web1 与 web2 之间可以相互通信 ..

来自 https://ninghao.net/video/3817#info


3)理解 none 网络


下面我们去创建一个容器,然后让它使用 none 这个网络 ... 让它在后台运行 .. 名字是 web_none .. 再用一个 --net 指定一下这个容器使用的网络 .. 这里设置成 none .. 让它使用 nginx 这个镜像 ..

docker run -d --name web_none --net none nginx ..

完成以后,我们先检查一下默认的 bridge 这个网络 ..

docker network inspect bridge

 在它的 Containers 里面,没有刚才我们创建的 web_none 这个容器 .. 因为在创建这个容器的时候我们让它属于 none 这个网络 ...

再去检查一下这个 none 网络 .. 

docker network inspect none

这里可以找到 web_none 这个容器 .. 不过你会发现,这个容器并没有一个可以使用的 ip 地址 .. 也就是说,这个容器跟外界是完全隔离的状态 ... 谁也没有办法跟他沟通 ...

我们可以登录到这个容器再看一下\

 docker exec -it web_none bash

 .. 执行一下 

ip addr ...

你会看到,这个容器只有一个 lo 网络 .. 就是本机环路网络 .. 也就是这个容器里的服务只能跟在本机上的服务沟通 ...

来自 https://ninghao.net/video/3818#info


4)理解 host 网络

我们再去看一下 host 这个网络 ... 先去创建一个容器让它属于这个网络 .. 让这个容器在后台运行 .. 名字是 web_host .. 用一个 --net 指定一下它的网络 .. 这里就是 host .. 使用的镜像是 nginx ...

docker run -d --name web_host --net host nginx

检查一下 host 这个网络 ... 

docker network inspect host

在这里你可以找到 web_host 这个容器 .. 你会发现它仍然没有 ip 地址 .. 因为使用 host 网络的容器的 ip 地址跟主机是一样的 .. 我们可以登录到这个容器再去查看一下 ..

docker exec -it web_host bash

执行一下 ip addr .. 它的 ip 是 .. 退出来 .. 再 ssh 到默认的 docker 主机看一下 ..

 docker-machine ssh default 

.. 执行一下

 ifconfig

 .. 你会看到容器跟主机的 ip 地址是一样的 ..

复制一下这个地址 .. 打开浏览器 .. 访问一下它 .. 会显示一个 nginx 的欢迎界面 ... 这个页面的内容就是 web_host 这个容器提供的服务 ..

这个容器对于外界来说是完全开放的 ...

来自  https://ninghao.net/video/3819#info


端口

5)端口

如果你想让外界可以访问到在默认的 bridge 网络上的容器提供的服务,你要告诉 docker 一声,要使用哪些端口 .. 在镜像的仓库介绍页面上,会告诉你这个镜像使用的端口 ...

或者我们也可以使用 docker inspect 去查看一下 .. 后面加上镜像的名字 ..

 比如查看一下 nginx 这个镜像

docker inspect nginx

 .. 在这个 ExposedPorts 里面,会告诉你这个镜像使用的端口 .. 这个镜像使用了两个端口.. 一个是 443 ,一个是 80 .. 443 应该是使用 https 的时候使用的端口 .. 80 是 http 默认的端口 ..

在创建容器的时候,我们可以指定一下主机跟容器之间的端口的映射关系 .. 创建一个在后台运行的容器 .. 名字是 web3 .. 再加上一个 --publish 选项 (感觉是port的意思).. 它的简写形式就是一个 p ...

然后先是主机上的端口号 ... 比如 80 .. 冒号的右边是容器的端口号 .. 这里也是 80 .. 这个意思就是,如果有人访问主机上的 80 这个端口的时候,这个访问会被定向到这个容器的 80 端口上 .. 这个容器用的镜像是 nginx ...

docker run -d --name web3 -p 80:80 nginx

这里提示了一个错误,意思就是 80 这个端口被占用了 .. 这是因为之前我们创建了一个在 host 网络上的容器,它也使用了 80 这个端口 ..

我们可以先把这个容器删除掉 .. 

docker rm -f web_host 

.. 强制删除 web_host 这个容器 ..

再删除一下刚才创建的 web3 这个容器 .. 

docker rm -f web3

 ..

然后重新执行一下这个创建容器的命令 ...

docker run -d --name web3 -p 80:80 nginx

再去查看一下主机的 ip 地址 .. 

docker-machine inspect default

 .. default 是我正在用的 docker 主机的名字 ..

IPAddress 后面的东西就是这台主机的 ip 地址 .. 复制一下 ... 在浏览器上访问一下这个地址 ... 因为 http 默认的端口号就是 80 ,所以不需要指定这个端口号 ..

这里显示的内容,就是 web3 这个容器的 nginx 提供的服务 ..

来自  https://ninghao.net/video/3821#info


6)端口绑定

查看容器跟主机绑定的端口,可以使用 docker inspect .. 后面加上容器的名字

 docker inspect web3

 .. 在 Ports 这里,你可以找到 .. 443 这个端口,没有跟主机绑定对应的端口 .. 80 端口跟主机绑定了 .. 在主机上也是 80 这个端口 ..

或者我们也可以使用 docker port 这个命令 .. 把容器的名字放到它后面 .. 

 docker port web3

这里会告诉我们,容器的 80 端口 .. 跟主机上的 80 端口绑定到一块儿了 ..

下面我们删除掉这个 web3 容器 .. 

docker rm -f web3

 .. 重新再创建一个 ... 在 --publish 选项的后面,都写一个 80 端口 .. 意思就是我们要公布容器的 80 这个端口 .. 然后让它指向在主机上的一个随机的端口 ...

docker run -d --name web3 --publish 80 nginx

查看一下 web3 的端口 .. 

docker port web3

 .. 这里显示在主机上跟容器上的 80 端口对应的是 xxx 这个端口号 ..

回到浏览器 .. 直接访问主机的 80 端口 .. 现在已经不能显示那个 nginx 的欢迎界面了 .. 这里我们要手工的指定一下端口号 ..

这次又会显示这个欢迎界面了 ..

下面我们再去试一下 .. 删除掉 web3 这个容器 .. 重新再创建一个容器 .. 这次用一个 --publish-all 这个选项 .. 

docker run -d --name web3 --publish-all 80 nginx

使用它我们可以不用手工指定端口或者端口的映射关系 .. 它会自动公布在镜像里面设置的要公布的所有的端口 ...

 --publish-all 也有一个简写形式 .. 就是一个大写的 P ...

再查看一下 web3 的端口 .. 

docker port web3

这里会出现两条信息 .. 容器上的 80 对应主机上的 xx .. 容器上的 443,对应的主机上的 xxx 这个端口 ...

来自  https://ninghao.net/video/3822#info


自定义网络

7)自定义网络

我们可以基于某个类型的网络去创建一些自定义的网络,这样属于这个网络的容器会被单独隔离出来,它们之间可以相互通信,其它的不在这些自定义网络上的容器不能直接访问到它们 ..

一个容器可以属于多个网络 ... 在用户自定义网络上的容器,它们之间可以使用各自的容器的名字访问到对方,因为会用到 Docker 内嵌的 DNS 功能 ...

创建一个新的网络用的是 docker network create ... 用一个 --driver 选项,指定一下网络的类型 .. 比如 bridge .. 或者 overlay ..

这里我们创建一个 bridge ,也就是桥接类型的自定义网络 ... 后面再加上网络的名字 .. 比如叫它 web ...

docker network create --driver bridge web

完成以后再检查一下这个网络 .. 

docker network inspect web

 ... 它的子网是 172.18.0.0 .. 也就是属于这个网络的容器,它们的 ip 地址应该是用 172.18 开头的 ..

目前还没有容器使用这个自定义的网络 ...

来自   https://ninghao.net/video/3824#info


8)把容器放到自定义网络里

在创建容器的时候我们可以把容器放到指定的网络里面 .. 先创建一个在后台运行的容器 .. 名字是 web5 .. 用一个 --net 让这个容器属于刚才我们创建的 web 这个网络 .. 用的镜像是 nginx ..

docker run -d --name web5 --net web nginx 

检查一下 web 这个网络 .. 

docker network inspect web

现在它里面已经有了一个容器,就是刚才我们创建的 web5 ... 下面我们可以手工的再把一个已有的容器放到指定的网络里面 ..

docker ps -a #查看所有的容器?

我这里有一个 web3 .. 现在它属于默认的 bridge 网络 .. 下面我们把它放到自己定义的 web 这个网络里面来 .. 执行一下 docker network connect .. 它可以把容器放到指定的网络里面 .. 使用 docker network disconnect 可以把容器从指定的网络里面移除掉 ..

connect 的后面,先是要连接到的网络的名字 .. 这里就是 web .. 然后是要放到这个网络里面的容器的名字 .. 我这里就是 web3 这个容器 ... 执行一下 ..

 docker network connect web web3

再去检查一下 web 这个网络 

 docker network inspect web

.. 现在它里面有两个容器 .. web3 还有 web5 .. 它们的 ip 地址都是 172.18 开头的 ... 它们之间可以相互沟通 .. 而且我们可以直接使用容器的名字 .. 因为 docker 里有个 dns 服务 ..

先登录到 web3 .. 

 docker exec -it web3 bash

然后再 ping 一下 web5 .. 

ping web5

你会看到,我们可以直接使用容器的名字跟它进行沟通 ...

注意 web3 这个容器现在同时属于 bridge 还有 web 这两个网络.. 也就是,它即可以跟 bridge 上的容器通信 .. 又可以跟 web 网络上的容器通信 ..

我们也可以把它从某个网络里面去掉 .. 执行一下 docker network disconnect .. 要去掉的是容器的 bridge 这个网络 .. 容器的名字是 web3 ..

docker network disconnect bridge web3 

再去检查一下 bridge 这个网络 ..

docker network inspect bridge 

 现在,这里已经看不到 web3 这个容器了 ...

来自 https://ninghao.net/video/3825#info


普通分类: