暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Docker overlay network

勤劳的存锋 2019-02-07
254

单独一个容器,存在的意义不大,无法横向扩展。因此需要一个编排系统来控制容器的生命周期,包括创建,部署,扩展,自动扩展,升级等等,目前这个默认是由kubenetes来完成的,但docker也提供了自己的编排系统叫做swarm。

Docker overlay network的提出,是为了实现swarm集群的对外提供服务,通常就是load balance负载均衡服务。服务的概念在docker的swarm集群和kubenetes中基本是一样的。

服务概念的提出是因为容器的生命周期是不确定,经常会存在重新生成,迁移等情况。一旦发生这些情况,容器的IP地址也发生了变化,而服务的地址是不变的。因而不管容器怎么变化,用户访问的IP地址永远不变。Overlay网络创建一个跨越多个docker主机的分布式网络,用户对于overlay网络IP的访问由docker透明转发给每个主机的每个容器。

Docker swarm启动后(docker swarm init)默认会产生一个overlay类型的网络ingress

frank@ubuntu:~$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE

yqj5siq7377c        ingress             overlay             swarm

在Swarm集群里面创建的service默认情况下自动连接到这个ingress网络。

如果有其他host需要加入这个swarm集群,则可以在启动docker后用命令

docker swarm join --token SWMTKN-1-2olksxxervw9fj4bokqcucb0ii9hh4ybkofnst3pvpcj07z7vh-9210hcxemu75pyygtcnq7xd4x   192.168.199.142:2377

这里的关键是token。


加入后可以通过命令docker node ls来查看swarm集群中的节点数量。

frank@ubuntu:~$ docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

bcukwug9ikt0u5on8f9lhqnrk *  ubuntu    Ready   Active        Leader


后面会看到这些命令跟kubenetes非常类似。逻辑本来就是一样的,swarm和kubenetes都是容器的编排系统,只不过swarm是docker原生的,kubenetes是来自google的,现在kubenetes明显胜出。


overlay network的架构如下图所示


也可以自己用下列命令创建一个overlay网络

$ docker network create -d overlay --attachable cisco 


frank@ubuntu:~$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE

8e3dd79a135a        bridge              bridge              local

ugkc3cyhn8pk        cisco               overlay             swarm

然后创建一个service挂到这个overlay 网络(这个只是把容器挂到了这个overlay网络,对外提供服务的地址还是挂载在ingress overlay网络)

$ docker service create --name my-nginx --publish target=80,published=80 \
  --replicas=2 --network cisco nginx

frank@ubuntu:~$ docker service ls

ID            NAME      MODE        REPLICAS  IMAGE

po195ps9ld69  my-nginx  replicated  2/2       nginx:latest

检查overlay network(docker inspect cisco),可以看到挂接了两个container

        "Containers": {

            "53e38da31894b8423ddc9135b5de1419fd5a185aa4cbdd1d6d56e573cb1c0a04": {

                "Name": "mydocker.1.md0zesv11i2revbwzuniczp6h",

                "EndpointID": "3f395e169aeb9b4fb184bf38a242676fb69952a2a5d00c071a5b49a8edcf9bd4",

                "MacAddress": "02:42:0a:00:00:04",

                "IPv4Address": "10.0.0.4/24",

                "IPv6Address": ""

            },

            "64ed89a47dbfb16221a06e7229d1615e913036c09db07032e10c55b2f4206d67": {

                "Name": "mydocker.2.ilj4qfdn248odo4eqe79qc7ft",

                "EndpointID": "b0bedd2dce5437ebd03621cdfa8cf7b47b534ffac71fb6b3aeeb960af4e01de7",

                "MacAddress": "02:42:0a:00:00:03",

                "IPv4Address": "10.0.0.3/24",

                "IPv6Address": ""

            }

        },


检查默认的ingress网络,可以发现这个网络上除了attach了两个容器外,还挂了一个虚地址。

        "Containers": {

            "53e38da31894b8423ddc9135b5de1419fd5a185aa4cbdd1d6d56e573cb1c0a04": {

                "Name": "mydocker.1.md0zesv11i2revbwzuniczp6h",

                "EndpointID": "43cdf011149e57b8e1aebcdc8af9eedfa28c7e5cce2b8e78afbb42cb88ec18e7",

                "MacAddress": "02:42:0a:ff:00:06",

                "IPv4Address": "10.255.0.6/16",

                "IPv6Address": ""

            },

            "64ed89a47dbfb16221a06e7229d1615e913036c09db07032e10c55b2f4206d67": {

                "Name": "mydocker.2.ilj4qfdn248odo4eqe79qc7ft",

                "EndpointID": "927e8527519da0d3c0615b86f696eeea3c68b4e06bbabca7e0a6c6693925d4de",

                "MacAddress": "02:42:0a:ff:00:05",

                "IPv4Address": "10.255.0.5/16",

                "IPv6Address": ""

            },

            "ingress-sbox": {

                "Name": "ingress-endpoint",

                "EndpointID": "42524c9f035815a5b767e963bd420316bfd0d291f35d31f2864b1fed149eb37a",

                "MacAddress": "02:42:0a:ff:00:03",

                "IPv4Address": "10.255.0.3/16",

                "IPv6Address": ""

            }

        },

检查swarm service my-nginx(docker inspect my-nginx)

     "Endpoint": {

            "Spec": {

                "Mode": "vip",

                "Ports": [

                    {

                        "Protocol": "tcp",

                        "TargetPort": 80,

                        "PublishedPort": 80,

                        "PublishMode": "ingress"

                    }

                ]

            },

            "Ports": [

                {

                    "Protocol": "tcp",

                    "TargetPort": 80,

                    "PublishedPort": 80,

                    "PublishMode": "ingress"

                }

            ],

            "VirtualIPs": [

                {

                    "NetworkID": "t0q7o3qnje8wnc9fpamka88xz",

                    "Addr": "10.255.0.4/16"

                },

                {

                    "NetworkID": "plbxreq6bks9zkg8hb4o2rrb8",

                    "Addr": "10.0.0.2/24"

                }

            ]

        },


service 已经发布在主机的或者说是这个swarm集群的地址上,可以从外部访问。主机地址和service IP之间的转换是通过iptables

C:\Windows\system32>curl 192.168.199.142

<!DOCTYPE html>

<html>

<head>

<title>Welcome to nginx!</title>

<style>

    body {

        width: 35em;

        margin: 0 auto;

        font-family: Tahoma, Verdana, Arial, sans-serif;

    }

</style>

</head>

<body>

<h1>Welcome to nginx!</h1>

<p>If you see this page, the nginx web server is successfully installed and

working. Further configuration is required.</p>


<p>For online documentation and support please refer to

<a href="http://nginx.org/">nginx.org</a>.<br/>

Commercial support is available at

<a href="http://nginx.com/">nginx.com</a>.</p>


<p><em>Thank you for using nginx.</em></p>

</body>

</html>


理论上多访问几次就会在容器之间进行负载均衡。

kill任何一个容器,swarm service会自动再创建一个容器,但新容器的地址和旧的不一定一样。但对外提供服务的地址不变,但新的容器可能采用新的地址

文章转载自勤劳的存锋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论