1.前言

在前两篇文章中,大家了解了swarm集群的管理、数据的持久化等技术点。大家可能会问,我会了这些有啥用?公司的业务大多数是跑在nginx、tomcat、php等这些集群应用中,技术是死的,思路是活的。在本文中我们来通过相关案例一起去探索这些应用集群的服务是如何发布的。

2.环境

本文的环境还是沿用上次的swarm集群环境,不过这一次多增加一台nginx服务器,用4台服务器来演示。如果你没有这么多服务器,可以把其中一台agent节点替换成nginx服务器也一样。并且在swarm集群中创建3个nginx副本来演示,你也可以创建tomcat或php副本都一样。

服务器 角色 运行服务 系统版本
172.18.18.32 Manager docker 17.12.0-ce、swarm创建nginx副本 centos7.4 x64
172.18.18.33 agent01 docker 17.12.0-ce 、swarm创建nginx副本 centos7.4 x64
172.18.18.34 agent02 docker 17.12.0-ce 、swarm创建nginx副本 centos7.4 x64
172.18.18.90 nginx 源码安装nginx centos7.4 x64

3.案例演示nginx集群副本

在上文中描述了,我们会在swarm集群中创建3个nginx副本来进行演示。(副本你也可以理解成容器的意思,在docker中称作容器、swarm和k8s中称为副本),笔者画了一张简易的架构图,我们先通过下图的信息来了解一下本文的案例演示:

 本次案例是通过访问nginx服务器 172.18.18.90负载到swarm集群中的3个nginx副本中(172.18.18.32/33/34)。当我们创建swarm集群时,在swarm所有的集群节点中会自动创建ingress网络,swarm模式内置DNS组件,自动为每个服务分配DNS记录,然后服务的DNS名称在集群内的服务直接分发请求。Ingress网络会自动分配一个虚拟IP(VIP),在DNS解析时返回VIP,到达VIP的流量将自动发送(IPVS)该服务的任务,也就是下发到副本中(容器中)。

 上图中,Ingress网络分配的虚拟IP网段为(10.255.0.0/16),VIP为(10.255.0.1/2/3),其余3个副本分配的IP为(10.255.0.16/17/18)。由此可以得出访问顺序是这样的:

客户端请求 >>> nginx服务器 >>> swarm集群宿节点 >>> VIP >>> IPVS >>> nginx副本

3.1 部署nginx服务器

nginx部署安装不是本文的重点,笔者就用源码包简易安装来达到本文的实验目的。 1、下载并解压nginx: 你可以用docker的镜像运行nginx、也可以用源码包编译安装nginx。在本文中nginx用源码包的方式安装

[root@nginx /]# cd /usr/src/
[root@nginx src /]# tar -zxvf nginx-1.12.1.tar.gz

2、编译安装nginx:

[root@nginx src]# yum -y install gcc gcc-c++ make openssl-devel pcre-devel
[root@nginx src]# cd nginx-1.12.1/
[root@nginx nginx-1.12.1]# ./configure --prefix=/usr/local/nginx   --with-http_stub_status_module --with-http_realip_module --with-pcre  --with-http_ssl_module
[root@nginx nginx-1.12.1]# make -j 2
[root@nginx nginx-1.12.1]# make install

3、配置nginx.conf,省略部分内容:

[root@nginx conf]# vim nginx.conf
  http {
	...
	...
	upstream swarm_nginx {
        server 172.18.18.32;
        server 172.18.18.33;
        server 172.18.18.34;
    }

    server {
        listen 80;
        server_name localhost;
        location / {
            proxy_pass http://swarm_nginx;
        }
    }
...
...

4、启动nginx服务:

[root@nginx conf]# /usr/local/nginx/sbin/nginx 

3.2 swarm集群中创建nginx副本

1、在Manager节点上创建nginx副本

[root@Manager ~]#docker service create --replicas 3 --name web_nginx -p 80:80 nginx 

2、查看副本状态

[root@Manager ~]# docker service ps web_nginx 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE         ERROR               PORTS
g0zkll6wasu7        web_nginx.1         nginx:latest        agent01             Running             Running 5 hours ago                       
o7dkinqaofla        web_nginx.2         nginx:latest        agnet02             Running             Running 5 hours ago                       
ko8t7stwm7qs        web_nginx.3         nginx:latest        Manager             Running  

3个nginx副本分别分配到了3台swarm集群中。

3、查看ingress网络 通过docker network ls可以看出,ingress属于overlay网络驱动,此驱动采用IETE标准的VXLAN方式,并且是VXLAN中被普遍认为最适合大规模的云计算虚拟化环境的SDN controller模式。

在Manager节点上查看ingress详细信息:

[root@Manager ~]# docker network inspect ingress 
...
#下面可以看到ingress的网络,网关信息:
"Config": [
                {
                    "Subnet": "10.255.0.0/16",
                    "Gateway": "10.255.0.1"
                }
            ]

...
#下面这段可以看到Manager节点上nginx副本的IP和MAC等信息:
 "Containers": {
            "fac0f4270885e34f19c42932041c0259858ac181439ac576ad9022bec1ef3047": {
                "Name": "web_nginx.3.ko8t7stwm7qsi7l9346g6hvyn",
                "EndpointID": "5b22bd2419bfc245ce2a354e64aeb5166ceb31981edb463fb0d8a7c843835c7a",
                "MacAddress": "02:42:0a:ff:00:12",
                "IPv4Address": "10.255.0.16/16",

#下面这段内容可以看到哪些swarm节点在ingress网络中:
 "Peers": [
            {
                "Name": "24f08eb37fc4",
                "IP": "172.18.18.32"
            },
            {
                "Name": "cd12c6d569bf",
                "IP": "172.18.18.33"
            },
            {
                "Name": "41609535c963",
                "IP": "172.18.18.34"
            }
        ]
...

当然,你还可以通过“docker inspect 容器ID”命令查看副本分配的IP相关信息:

[root@Manager ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
fac0f4270885        nginx:latest        "nginx -g 'daemon of…"   5 hours ago         Up 5 hours          80/tcp              web_nginx.3.ko8t7stwm7qsi7l9346g6hvyn
[root@Manager ~]# docker inspect fac0f4270885

其它两个swarm集群节点不做演示查看了,大家可以看行在另外两台agent节点上查看IP相关信息。

3.3 访问测试

接下来,我们通过浏览器访问nginx服务器 http://172.18.18.90 进行验证测试,多刷新几次试试:

然后,在Manager节点上跟踪一下副本的日志:

[root@Manager ~]# docker service logs web_nginx  -f

通过日志跟踪,可以发现访问nginx服务器被分别负载到了swarm集群中的3个副本上了,这就说明了swarm副本的集群状态都是可用的。

4.案例演示tomcat集群副本

可能有些朋友看了有点晕,nginx负载到nginx副本,啥玩意啊。为了让大家能够更好的理解,我把swarm集群中的nginx副本换成tomcat副本进行演示:

1、在swarm中创建3个tomcat副本

[root@Manager ~]# docker service create --replicas 3 --name web_tomcat -p 8080:8080 tomcat
v12jxeo8cq0tialjezd0lvn7q
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

注意:我这里用的tomcat镜像为docker hub官方的,这个镜像比较大,所以这个步骤很长,建议大家先在每台swarm节点上提前docker pull tomcat。如果有私有镜像仓库就用私有仓库的镜像来测试。

2、查看tomcat副本状态:

[root@Manager ~]# docker service  ps web_tomcat 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
3i30jp0uee5d        web_tomcat.1        tomcat:latest       agent01             Running             Running about a minute ago                       
k6kz95io17al        web_tomcat.2        tomcat:latest       agnet02             Running             Running about a minute ago                       
rohntxnifnh3        web_tomcat.3        tomcat:latest       Manager             Running             Running 2 minutes ago   

也都很均匀的分配到了每个swarm集群节点上了。

3、配置nginx服务器:

[root@nginx conf]# vim nginx.conf
    upstream swarm_tomcat {
        server 172.18.18.32:8080;
        server 172.18.18.33:8080;
        server 172.18.18.34:8080;
    }

    server {
        listen 8080;
        server_name localhost;
        location / {
            proxy_pass http://swarm_tomcat;
        }
    }

重启下nginx:

[root@nginx conf]# ../sbin/nginx -s reload

4、验证访问 我们用浏览器访问nginx的8080端口测试一下:http://172.18.18.90:8080 ,也同样多刷新几次。

然后,在Manager节点跟踪tomcat副本的日志:

[root@Manager ~]# docker service  logs  web_tomcat  -f

你会发现跟踪tomcat的副本日志只是tomcat启动的日志,并没有访问的日志,需要进入副本里面查看tomcat的localhost_access_log日志。

5.案例演示自定义overlay网络

下面通过自己创建自定网络test_net、创建nginx副本test_nginx并加入test_net、创建busybox副本test_busy并加入test_net,然后通过ping测试两个副本是否相通。

1、创建自定义overlay网络test_net

[root@Manager ~]# docker network  create --driver overlay test_net
7zapi1r90xghatyetzg048eo6
[root@Manager ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
...
7zapi1r90xgh        test_net            overlay             swarm
...

2、创建nginx副本test_nginx

[root@Manager ~]# docker service create --name  test_nginx --replicas 1 --network test_net  nginx 
0kn7kx6er0r2ijuffe6w4bwux
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 

3、创建busybox副本test_busy

[root@Manager ~]# docker service  create --name test_busy --replicas 1 --network test_net busybox top
fiyi3jhnc9qhnthwo12doj5is
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 

4、进入test_busy副本ping busy_nginx测试:

[root@Manager ~]# docker exec -it 
test_busy.1.coypjdeytu4latnmrww8yswyr  web_nginx.3.lzbgset0cwlmwxzb71prr9q7q
[root@Manager ~]# docker exec -it test_busy.1.coypjdeytu4latnmrww8yswyr sh
/ # ping test_nginx
PING test_nginx (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.030 ms
64 bytes from 10.0.0.5: seq=1 ttl=64 time=0.033 ms
64 bytes from 10.0.0.5: seq=2 ttl=64 time=0.047 ms
64 bytes from 10.0.0.5: seq=3 ttl=64 time=0.046 ms
^C
--- test_nginx ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.030/0.039/0.047 ms

进入test_busy副本可以发现可以ping通test_nginx副本。

6、其它相关命令 #查看副本虚IP

[root@Manager ~]# docker service inspect  -f '{{json .Endpoint.VirtualIPs}}' test_nginx 
[{"NetworkID":"7zapi1r90xghatyetzg048eo6","Addr":"10.0.0.5/24"}]

[root@Manager ~]# docker service inspect  -f '{{json .Endpoint.VirtualIPs}}' test_busy 
[{"NetworkID":"7zapi1r90xghatyetzg048eo6","Addr":"10.0.0.7/24"}]

#还可以进入副本nslookup解析测试

[root@Manager ~]# docker exec -it test_busy.1.coypjdeytu4latnmrww8yswyr sh
/ # nslookup  test_nginx
Server:    127.0.0.11
Address 1: 127.0.0.11
Name:      test_nginx
Address 1: 10.0.0.5

/ # nslookup  test_busy
Server:    127.0.0.11
Address 1: 127.0.0.11
Name:      test_busy
Address 1: 10.0.0.7

6.案例演示端点模式dnsrr负载均衡

其实,当我们创建副本的时候,有1个参数是省略的 --endpoint-mode vip,也就是负载均衡的模式(dnsrr 和 vip),默认是vip模式的方式,下面我们用dnsrr模式来演示一下。

1、用busy镜像创建3个副本test_dnsrr,也把它加入test_net网络

[root@Manager ~]# docker service create --name test_dnsrr --replicas 3 --network test_net --endpoint-mode dnsrr busybox top
v574isy80agvurussrbl8htyx
overall progress: 3 out of 3 tasks 
1/3: running   
2/3: running   
3/3: running   
verify: Service converged 

2、查看一下test_dnsrr副本

[root@Manager ~]# docker service ps  test_dnsrr 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
uem1xiwnla5t        test_dnsrr.1        busybox:latest      Manager             Running             Running 29 seconds ago                       
wtje7pgstmeg        test_dnsrr.2        busybox:latest      agnet02             Running             Running 3 minutes ago                        
3xzanggatp4d        test_dnsrr.3        busybox:latest      agent01             Running             Running 2 minutes ago   

每个swarm节点都分配到了副本在运行。

3、进入test_dnsrr副本测试

[root@Manager ~]# docker exec -it test_dnsrr.1.uem1xiwnla5tbnh0kfcxr89xh sh
/ # nslookup  test_dnsrr
Server:    127.0.0.11
Address 1: 127.0.0.11

Name:      test_dnsrr
Address 1: 10.0.0.14 test_dnsrr.3.3xzanggatp4d8e8hayz99ngyc.test_net
Address 2: 10.0.0.16 46c86efbd56b.test_net
Address 3: 10.0.0.15 0cd47777c912

进入副本,通过nslookup发现dnsrr模式生效 ,同时能解析到3个副本的IP地址。如果你用默认的VIP模式,只能解析当前的副本IP,大家可以在创建3个副本不配置dnsrr模式,然后进入其中一个副本用nslookup测试一下看看。

本章内容到此结束,喜欢我的文章,请点击最上方右角处的《关注》!!!