MySQL on Docker: Introduction to Docker Swarm Mode and Multi-Host Networking

1月 28th, 2017

主要介绍多主机网络的基本概念和Docker的Swarm模式,一个用于管理多台物理机上容器的内置编排工具;

— Docker引擎-Swarm模式;
把MySQL容器运行到多个宿主机上会根据选择的集群技术不同而变的复杂;

在我们尝试把MySQL运行在容器+多主机网络的环境中,必须要理解image是怎么工作的;有多少的资源(磁盘,内存,CPU)需要分配,网络(overlay网络的选择:默认,flannel,weave等)和容错性(容器是怎么重新分布,故障转移和负载均衡的);所有的这些都会影响整体的数据库操作,启动时间和性能;非常推荐在Docker引擎集群的上面使用一个编排工具来获得更好的管理性和扩展性;最新的Docker引擎(v1.12,2016.06.14发布的)包含了原生管理Docker引擎集群的工具,叫Swarm模式;Docker引擎的Swarm模式和Docker Swarm是两个不同的项目,尽管两者的工作原理很像,但是使用不同的安装步骤;

一些必要的知识:
1.必须要打开的端口:
1)2377(TCP):用于集群管理;
2)7946(TCP and UDP):用于节点间通信;
3)4789(TCP and UDP):overlay网络传输;
2.两种类型的节点:
1)Manager:管理节点执行编排和集群管理函数从而维护swarm的期望状态(desired state),管理节点选举出来一个leader来构建编排任务;
2)Worker:工作节点接收并执行管理节点分派的任务,默认情况下管理节点也是工作节点,但是可以配置管理节点只做管理节点;

这篇文章,准备部署应用容器到三台Docker宿主机(docker1, docker2, docker3)上,并使用Galera集群的负载均衡,通过多主机环境间的overlay网络进行网络连接;将使用Docker引擎的Swarm模式作为编排工具;

— 启动Swarm模式;
首先需要配置Docker节点到Swarm模式;Swarm模式需要奇数个(推荐三个,节点数越多效率越低)管理节点来维护错误时的法定人数;使用三台物理机器作为管理节点,默认的管理节点也是工作节点;

0.测试环境;
docker1.htsec.com 192.168.10.201
docker2.htsec.com 192.168.10.202
docker3.htsec.com 192.168.10.203

1.首先在docker1上初始化Swarm模式,会使得节点变成为Manager和Leader;
[root@docker1 ~]# docker swarm init –advertise-addr 192.168.10.201
Swarm initialized: current node (385guihkvrmuuuftm34ubr9v2) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join \
–token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-4370suyaolwu0ts8ujv3r7xy2 \
192.168.10.201:2377

To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions.

2.准备把另外两台物理机也作为Manager,生成注册成为管理节点的命令;
[root@docker1 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

docker swarm join \
–token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-2mnogcl6y71n85msftv40vbnb \
192.168.10.201:2377

3.在节点docker2和节点docker3分别执行命令注册为管理节点;
[root@docker2 ~]# docker swarm join \
> –token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-2mnogcl6y71n85msftv40vbnb \
> 192.168.10.201:2377
This node joined a swarm as a manager.

[root@docker3 ~]# docker swarm join \
> –token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-2mnogcl6y71n85msftv40vbnb \
> 192.168.10.201:2377
This node joined a swarm as a manager.

4.验证所有的节点;
[root@docker1 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
385guihkvrmuuuftm34ubr9v2 * docker1.htsec.com Ready Active Leader
63o59qn38i70iej61h7edm1s1 docker3.htsec.com Ready Active Reachable
ahorta43as7m7yupv3bsnc7pg docker2.htsec.com Ready Active Reachable

此时docker1.htsec.com是Leader节点;

— overlay网络;
使运行在不同宿主机上的容器可以互相通信的唯一方法是使用overlay网络;可以认为,容器的网络是构建在其它的网络之上的(在这个环境中,是构建在宿主机网络上的);Docker Swarm模式的默认overlay网络实现了一个基于VxLAN的解决方案,底层依赖于libnetwork和libkv库,所以overlay网络需要一个key-value存储服务,用于在不同的docker引擎间交换信息;可以选择使用其他外部的overlay网络驱动(比如Flannel,Calico或者Weave),但是需要额外的安装步骤;

使用Docker引擎的Swarm模式,可以在管理节点创建一个overlay网络,不需要外部的key-value存储(比如etcd,consul或者Zookeeper);

Swarm会使overlay网络在需要运行服务的节点上都有效;当你创建一个使用overlay网络的服务,管理节点会自动扩展overlay网络到运行服务任务的节点;

首先创建一个overlay网络,来把Percona XtraDB Cluster和应用容器运行在不同的Docker服务器上,从而达到容灾的效果;这些容器必须运行在同一个overlay网络上,以至于它们可以互相通信;

1.首先创建一个叫”mynet”的overlay网络,这个网络只能在管理节点创建;
[root@docker1 ~]# docker network create –driver overlay mynet
32tayer754amlqnwti9a0c4ht

2.查看当前环境的网络状况;
[root@docker1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
9e1f395cbd90 bridge bridge local
3c63a1302938 docker_gwbridge bridge local
3996de1d0f28 host host local
3uvc0j5s4t1y ingress overlay swarm
32tayer754am mynet overlay swarm
3e1b264a2086 none null local

在swarm范围内有两个overlay网络,”mynet”网络是刚刚创建并用于部署MySQL集群的网络,”ingress”网络是默认的overlay网络;Swarm的Manager使用”ingress”来实现服务间的负载均衡;

— 使用服务和任务进行部署;
计划使用服务和任务来部署Galera Cluster容器;当创建一个服务,需要指定使用哪一个容器镜像和在运行的容器里面运行哪些命令;

有两种类型的服务:
1)Replicated services:基于设置的期望状态(desired state),会在集群的节点上分布指定数量的任务来达到扩展的目的,例如:”–replicas 3″;
2)Global services:集群中每一个可用的节点上都运行一个服务的任务,例如:”–mode global”;如果在swarm中有7个docker节点,则每一个节点都会运行一个容器;

Docker Swarm模式在管理持久性数据存储方面有一定的局限,当一个节点失败,Manager会除掉这个容器并且创建一个新的来替换旧的,从而达到期望状态;因为一个容器失败后会被丢弃,相应的也会失去数据卷;幸运的是,对于Galera集群来说,当新的MySQL容器可以自动的达到相应状态;

— 部署Key-Value存储;
使用的Docker镜像来自Percona,当集群初始化和引导时,这个镜像需要MySQL容器访问一个key-value存储(仅支持etcd),从而来发现相应的IP地址;这些容器会从etcd中查看其它的IP地址,如果保存的有IP地址,则会使用一个适合的wsrep_cluster_address参数来启动MySQL,否则,第一个容器会使用”gcomm://”来作为引导地址;

1.首先在docker1上运行一个etcd服务(也可以使用服务发现的方式);
[root@docker1 ~]# export HostIP=”192.168.10.201″
[root@docker1 ~]# docker run -d -p 2379:2379 -p 2380:2380 -p 4001:4001 –name etcd elcolio/etcd \
> -name etcd1 \
> -advertise-client-urls http://${HostIP}:2379,http://${HostIP}:4001 \
> -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001 \
> -initial-advertise-peer-urls http://${HostIP}:2380 \
> -listen-peer-urls http://0.0.0.0:2380 \
> -initial-cluster-token etcd-cluster \
> -initial-cluster etcd1=http://${HostIP}:2380 \
> -initial-cluster-state new
fc994bb85036b57bef06e55e1856ef1c6f12198b7700744a9be61c22ea62f170
[root@docker1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc994bb85036 elcolio/etcd “/bin/run.sh -name et” 6 seconds ago Up 4 seconds 0.0.0.0:2379-2380->2379-2380/tcp, 0.0.0.0:4001->4001/tcp, 7001/tcp etcd

2.此时可以通过http://192.168.10.201:2379访问etcd服务(如果是使用服务启动的etcd,可以通过命令:docker service inspect etcd -f “{{ .Endpoint.VirtualIPs }}”查看);
[root@docker1 ~]# curl http://192.168.10.201:2379/v2/members
{“members”:[{“id”:”e4379b6d6b63f88c”,”name”:”etcd1″,”peerURLs”:[“http://192.168.10.201:2380″],”clientURLs”:[“http://192.168.10.201:2379″,”http://192.168.10.201:4001”]}]}

— 部署数据库集群;
1.在部署Galera(Percona XtraDB Cluster)容器的命令中指定etcd的服务地址;
[root@docker1 ~]# docker service create –name mysql-galera –replicas 3 \
> -p 3306:3306 –network mynet \
> –env MYSQL_ROOT_PASSWORD=mypassword \
> –env DISCOVERY_SERVICE=192.168.10.201:2379 \
> –env XTRABACKUP_PASSWORD=mypassword \
> –env CLUSTER_NAME=galera \
> percona/percona-xtradb-cluster
b8uica0izpvytrtw097csjfrz

2.查看服务的状态,会发现在三个节点上分别运行了percona-xtradb-cluster容器;
[root@docker1 ~]# docker service ps mysql-galera
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
eknbellxg7y3zpujxzmv05dd5 mysql-galera.1 percona/percona-xtradb-cluster docker1.htsec.com Running Running 30 seconds ago
67bs9tu87zt81mjn5salk4rtn mysql-galera.2 percona/percona-xtradb-cluster docker3.htsec.com Running Running 30 seconds ago
6njkyk7pj4r02rdef3ihikrcj mysql-galera.3 percona/percona-xtradb-cluster docker2.htsec.com Running Running 30 seconds ago

3.查看mysql-galera服务的状态,正在正常运行;
[root@docker1 ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
b8uica0izpvy mysql-galera 3/3 percona/percona-xtradb-cluster

4.Swarm模式内部的DNS组件可以自动的给服务的每个任务分配IP,所以可以通过服务名查看到对应的虚拟IP地址;
[root@docker1 ~]# docker service inspect mysql-galera -f “{{ .Endpoint.VirtualIPs }}”
[{3uvc0j5s4t1yuzi9yfxmt4s22 10.255.0.6/16} {32tayer754amlqnwti9a0c4ht 10.0.0.2/24}]

Running Percona XtraDB Cluster in a multi-host Docker network


http://severalnines.com/blog/mysql-docker-introduction-docker-swarm-mode-and-multi-host-networking
https://hub.docker.com/r/percona/percona-xtradb-cluster/

2016-11-21T14:38:09.786753Z 0 [ERROR] WSREP: failed to open gcomm backend connection: 131: No address to connect (FATAL)
at gcomm/src/gmcast.cpp:connect_precheck():286
2016-11-21T14:38:09.786761Z 0 [ERROR] WSREP: gcs/src/gcs_core.cpp:gcs_core_open():208: Failed to open backend connection: -131 (State not recoverable)
2016-11-21T14:38:09.786921Z 0 [ERROR] WSREP: gcs/src/gcs.cpp:gcs_open():1407: Failed to open channel ‘galera’ at ‘gcomm://10.255.0.9,10.255.0.7,10.255.0.9’: -131 (State not recoverable)
2016-11-21T14:38:09.786930Z 0 [ERROR] WSREP: gcs connect failed: State not recoverable
2016-11-21T14:38:09.786933Z 0 [ERROR] WSREP: wsrep::connect(gcomm://10.255.0.9,10.255.0.7,10.255.0.9) failed: 7

— 相关技术;
1.VXLAN(Virtual eXtensible LAN,可扩展虚拟局域网):是基于IP网络之上,采用的是MAC in UDP技术,本来OSI七层模型里就是一层叠一层的,这种和GRE/IPSEC等tunnel技术是不是很像,这种封装技术对中间网络没有特殊要求,只要你能识别IP报文即可进行传送;

2.为何需要Vxlan:
1)虚拟机规模受到网络规格的限制,大L2网络里,报文通过查询MAC地址转发,MAC表容量限制了虚拟机的数量;
2)网络隔离的限制,普通的VLAN和VPN配置无法满足动态网络调整的需求,同时配置复杂;
3)虚拟器搬迁受到限制,虚拟机启动后假如在业务不中断基础上将该虚拟机迁移到另外一台物理机上去,需要保持虚拟机的IP地址和MAC地址等参数保持不变,这就要求业务网络是一个二层的网络;

标签:
目前还没有任何评论.