Docker之网络篇

在Docker中需要在容器间相互访问是非常困难的,默认Docker不会开放任何端口,因此需要将容器与宿主机进行端口映射,使容器可外部访问。而容器间互相访问,除了可以基于端口映射进行访问外,还可以通过容器链接(Link)的方式,也可以通过Docker 网络(Networking)实现。对docker不熟悉的同学,可参阅我之前的docker笔记。

基于端口映射

容器与宿主机间建立端口映射关系时,可以在运行容器时使用-P-p参数指定端口映射。两者区别如下:

-P绑定宿主机随机端口

-P参数会随机分配一个49000~49900之间的端口到容器内部开放的网络(通过EXPORT指定的)端口

#通过itbilu/express-app镜像创建并运行了一个名为express-app的容器
docker run -d --name experss-app -P itbilu/express-app
#查看所分配的端口号,会发现宿主机的32771端口被绑定到了容器的3000端口
docker ps

-p指定端口、IP地址绑定

如果不想使用随机端口,则可以使用-p参数来指定要绑定的端口号。-p参数除了可以指定端口号外,还可以指定宿主机的IP,这一点在使用过程中非常有用。

#宿主机的3001端口映射到了容器的3000端口
docker run -d --name experss-app -p 3001:3000 itbilu/express-app
#将宿主机IP(127.0.0.1)及3001端口,绑定到容器3000端口
docker run -d --name experss-app -p 127.0.0.1:3001:3000 itbilu/express-app
#会绑定宿主机的指定IP(127.0.0.1)及随机端口到容器3000端口
docker run -d --name experss-app -p 127.0.0.1::3000 itbilu/express-app
#在创建/运行容器时,-p参数可以被多次使用,以绑定多个容器端口
docker run -d --name experss-app -p 3001:3000 -p 5000:80 itbilu/express-app
#默认会绑定TCP端口。还可以使用udp标记来绑定udp端口
docker run -d --name experss-app -p 3001:3000/udp itbilu/express-app
#查看所绑定的端口及IP地址
docker port experss-app

容器的连接(link)系统是除了端口映射外,另一种跟容器中应用交互的方式。该系统会在源容器和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。Docker的链接是一个可以将具体的容器连接到一起来进行通信的抽像层。

Docker的连接系统会依据容器的名称来进行连接,因此,首先需要定义容器的名称。在不指定容器命令的情况,系统会随机分配一个名称。但相对来说,自定义容器名称更容易记。

--link参数让容器间安全的进行互联,会在两个互联的容器之间创建了一个安全的隧道,从而避免了暴露端口到外部网络上,增加了容器的安全性。

--link name:alias

name表示要连接的容器的名称

alias表示连接后的别名

#自定义容器名称使用--name
docker run -d --name db training/postgres
#查看相关信息
docker ps
#也可以通过inspect查看容器的名称
docker inspect -f "{{ .Name }}" db2093b13127
#创建一个名为web的容器,并将它连接到db容器
docker run -d -P --name web --link db:db training/webapp python app.py

Networking

在Docker 1.9及之后,增加了Docker Networkingdocker network命令。容器之间的连接通过网络来创建,这被称为Docker Networking

通过端口映射的方式开放容器的内部网络,这种方式并不够灵活、强大,且会暴露端口到外部网络。

link和Dcoker Networking是更好的处理方式,Docker 1.9之前的版本推荐使用容器链接(Link)的方式,在Docker 1.9及之后则更推荐使用Dcoker Networking。

相对link来说,Networking具有以下优点:

  • Dcoker Networking可以将容器连接到不同宿主机上的容器
  • 通过Dcoker Networking连接的容器,可以在不更新连接的情况下对容器进行停止、启动或重启。而链接则需要通过更新配置,重启对应的容器来更新容器之间的网络
  • 使用Dcoker Networking可以不用关心容器是否已运行,也不用关心容器的运行顺序,而可以在网络内部获取容器名的解析和发现
#Docker安装后,有三个网络会被自动创建,查看
docker network ls
#NETWORK ID          NAME                DRIVER              SCOPE
#32dfd86b7900        bridge              bridge              local
#18814c612f64        host                host                local
#7914b1c3168c        none                null                local

在Docker历史上,这三个网络是Docker执行的一部分。在运行容器时,可以使用--network指定要运行容器的网络,

创建网络

Docker Engine 会在引擎安装时自动创建一个名为bridge(桥接)网络,这个网络会与docker0(Docker内部网络)相对应。除此之外,用户还可以自行创建bridgeoverlay类型的网络。

  • bridge网络适用于单台宿主机运行的单Docker引擎环境
  • overlay网络允许我们跨多台宿主机进行通讯

Docker Networking允许用户创建自己的网络,容器间可以通过这个网络互相通讯。Docker Networking允许容器跨越不同的宿主机通讯,且网络配置方式更灵活。

#创建一个网络,在不添加额外参数的情况下,创建的是一个本地桥接网络
docker network create my_network
#查看这个新建的网络详情
docker network inspect my_network
#[
#    {
#        "Name": "my_network",
#        "Id": "32ddd24fd698665888ffa542215ae79a140b31ab3a10c96422ce2aee67b904a9",
#        "Created": "2017-04-04T04:05:13.230681143Z",
#        "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,
#        "Containers": {},
#        "Options": {},
#        "Labels": {}
#    }
#]
#也可以看到网络列表
docker network ls

创建容器并连接到网络

创建网络后,可以在创建容器时通过--network参数指定容器要使用的网络

docker run -d --name db --network=my_network training/postgres
#查看的网络情况
network inspect my_network
#[
#    {
#        "Name": "my_network",
#        "Id": "32ddd24fd698665888ffa542215ae79a140b31ab3a10c96422ce2aee67b904a9",
#        "Created": "2017-04-04T04:05:13.230681143Z",
#        "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,
#        "Containers": {
#            "dccb4267650d8659e65aa3876ec6a427224111a91b4b253bb105af2295ad7a4a": {
#                "Name": "db",
#                "EndpointID": "6b1610e37eafbd044beb33f91f1d5d8e337da1b7376690f05b6fdeb0916edb9f",
#                "MacAddress": "02:42:ac:12:00:02",
#                "IPv4Address": "172.18.0.2/16",
#                "IPv6Address": ""
#            }
#        },
#        "Options": {},
#        "Labels": {}
#    }
#]
#在另一个交互式容器中测试是否可以连接到db容器
ping db

将已有容器连接到Docker网络

当需要将已在运行的容器添加到已有的网络时,可以使用docker network connect命令,一个容器可以连接入多个网络,从而构建出非常复杂的网络模型。

#删除刚创建的web容器
docker run -d --name web training/webapp python app.py
#将这个容器连接到已创建的名为my_network的网络
docker network connect my_network web
#查看的网络情况(Containers节点)
docker network inspect

#将容器与网络断开连接
docker network disconnect my_network web
#将网络删除
docker network rm my_network

还可以使用docker network disconnect命令将容器与网络断开连接,网络不在需要后,可以使用docker network rm命令将网络删除。

注:删除网络时,需要已断开所容器的连接,否则会删除失败。

你可能感兴趣的:(#,docker,k8s)