当前位置: 首页 > 科技观察

在Docker中运行MySQL:多主机网络下DockerSwarm模式下的容器管理

时间:2023-03-14 22:19:00 科技观察

本文将以多主机网络环境为基础,探讨如何使用内置的编排工具DockerSwarm模式管理容器在每个主机上。Docker引擎–Swarm模式在多台主机上运行MySQL容器会带来一定程度的复杂性,具体取决于您选择的集群技术。在尝试使用容器加多主机网络运行MySQL之前,我们首先需要了解镜像的工作原理、资源分配(包括磁盘、内存和CPU)、网络(覆盖网络驱动,包括flannel和weaveby默认)等)和容错机制(容器如何重新定位、故障转移、负载平衡等)。所有这些都会影响数据库的整体操作、正常运行时间和性能。我们建议您使用编排工具来保证Docker引擎集群更好的可管理性和可扩展性。最新的DockerEngine(1.12版本,2016年7月14日发布)包含一个Swarm模式,专门用于原生管理一个名为Swarm的DockerEngine集群。需要注意的是,DockerEngineSwarm模式和DockerSwarm是两个不同的项目。虽然它们的工作原理相似,但它们的安装步骤不同。下面来看看在继续之前需要完成的准备工作:首先要打开以下端口:2377(TCP)-集群管理7946(TCP和UDP)-节点通信4789(TCP和UDP)-overlay网络流量节点类型有2种类型:管理器节点-管理器节点负责执行必要的编排和集群管理功能,以维护Swarm的必要状态。管理节点会选择一个单一的主管理方来执行编排任务。工作节点-工作节点负责接收和执行来自管理器节点的任务。默认情况下,管理节点本身也作为工作节点存在,但您可以将其配置为仅执行管理任务。在本文中,我们将在基于3个Docker主机(docker1、docker2和docker3)的负载均衡Galera集群上部署应用程序容器,并将它们连接到覆盖网络。我们将使用DockerEngineSwarm模式作为编排工具。集群构建首先让我们将Docker节点合并到Swarm集群中。Swarm模式需要使用奇数个管理节点(当然不止一个)来维持容错。因此,我们这里需要将三个节点都设为管理节点。需要注意的是,默认情况下,管理节点同时充当工作节点。首先在docker1上初始化群模式。\--tokenSWMTKN-1-16kit6dksvrqilgptjg5pvu0tvo5qfs8uczjq458lf9mul41hc-dzvgu0h3qngfgihz4fv0855bo\192.168.55.111:2377Toaddamanagertothisswarm,运行'dockerswarmjoin-tokenmanager'并按照说明操作。我们还需要将另外两个节点添加为管理节点。使用join命令将这两台节点注册为管理节点:[docker1]$dockerswarmjoin-tokenmanagerToaddamanagertothisswarm,runthefollowingcommand:dockerswarmjoin\--tokenSWMTKN-1-16kit6dksvrqilgptjg5pvu0tvo5qfs8uczjq458lf9mul41hc-7fd1an5iucy4poa4g1bnav0pt\192.168.55.111:2377在docker2与docker3上,运行以下命令以进行节点注册:$dockerswarmjoin--tokenSWMTKN-1-16kit6dksvrqilgptjg5pvu0tvo5qfs8uczjq458lf9mul41hc-7fd1an5iucy4poa4g1bnav0pt192.168.55.111:2377验证是否全部节点都已经正确添加:[docker1]$dockernodelsIDHOSTNAMESTATUSAVAILABILITYMANAGERSTATUS5w9kycb046p9aj6yk8l365eshdocker3.localReadyActiveReachable6r22rd71wi59ejaeh7gmq3rge*docker1.localReadyActiveLeaderawlh9cduvbdo58znra7uyuq1ndocker2.localReadyActiveReachable到这里,我们的docker1.localasthemastermanagementnode.Theonlywaytoallowcontainersrunningondifferenthoststoconnecttoeachotheristouseanoverlaynetwork.Youcanthinkofitasacontainernetworkbuiltontopofanothernetwork(inthiscase,thephysicalhostnetwork).TheDockerSwarmmodeprovidesadefaultoverlaynetwork,whichisresponsibleforimplementingaVxLAN-basedsolutionwithlibnetworkandlibkv.Ofcourse,youcanalsochooseotheroverlaynetworkdriversolutionssuchasFlannel,CalicoorWeave,butyouneedtoperformadditionalinstallationsteps.在DockerEngineSwarm模式下,可以简单地创建一个基于管理节点的overlay网络,不需要额外的key-value存储机制,如etcd、consul、Zookeeper。这套Swarm只是为集群中的每个节点提供了一个overlay网络。当你创建一个需要使用overlay网络的服务时,管理节点会自动将overlay网络扩展到运行该服务任务的节点。让我们为每个容器创建一个覆盖网络。这里,我们需要在每台Docker主机上部署PerconaXtraDB集群和应用容器来实现容错。这些容器必须在同一个覆盖网络上运行,以便它们可以相互通信。Herewenamethenetwork"mynet".大家只能在管理节点上完成这一创建工作:[docker1]$dockernetworkcreate--driveroverlaymynet下面来看我们的现有网络:[docker1]$dockernetworklsNETWORKIDNAMEDRIVERSCOPE213ec94de6c9bridgebridgelocalbac2a639e835docker_gwbridgebridgelocal5b3ba00f72c7hosthostlocal03wvlqw41e9gingressoverlayswarm9iy6k0gqs35bmynetoverlayswarm12835e9e75b9nonenulllocal现在Swarm当中拥有2套“mynet”网络是我们在部署容器时创建的网络。“入口”覆盖网络是默认提供的。Swarm管理节点使用入口负载平衡来在集群外发布服务。使用服务和任务部署接下来我们将通过服务和任务来部署Galera集群容器。创建服务时,需要指定使用哪个容器镜像,在容器中执行哪些命令。有两种类型的服务:Replicationservice——分发一系列复制任务到每个节点,根据你需要的配置状态,比如“--replicas3”。全局服务——适用于集群中所有可用节点上的服务任务,如“--modeglobal”。如果你的Swarm集群中有7个Docker节点,那么所有节点上都会有对应的容器。DockerSwarm模式在管理持久数据存储方面的能力有限。当一个节点出现故障时,管理节点会绕过所有相关的容器,创建新的容器继续保持原来的运行状态。由于容器下线后会被丢弃,我们会丢失其中所有的数据卷。幸运的是,Galera集群允许每个MySQL容器在以自动方式加入时接受带有状态/数据的配置。部署键值存储我们在这里使用的docker镜像是Percona-Lab。此映像要求每个MySQL容器访问键值存储(仅限etcd)以在集群初始化和引导期间发现IP地址。每个容器都会在etcd中搜索其他IP地址,以使用正确的wsrep_cluster_address完成MySQL启动。否则,第一组容器将使用gcomm://作为引导程序地址。首先部署我们的etcd服务。你可以点击这里获取我们使用的etcd镜像。它要求我们根据需要部署的etcd节点数量使用发现URL。这种情况下,我们需要单独设置一个etcd容器,具体命令为:[docker1]$curl-w"\n"'https://discovery.etcd.io/new?size=1'https:///discovery.etcd.io/a293d6cc552a66e68f4b5e52ef163d68之后,在为etcd创建服务时使用生成的URL作为“-discovery”值:[docker1]$dockerservicecreate\--nameetcd\--replicas1\--networkmynet\-p2379:2379\-p2380:2380\-p4001:4001\-p7001:7001\elcolio/etcd:latest\-nameetcd\-discovery=https://discovery.etcd.io/a293d6cc552a66e68f4b5e52ef163d68这里DockerSwarm模式会编排一个容器Docker主机上的部署作业。检索etcd服务虚拟IP地址。我们在下一步部署集群的时候需要用到这个IP地址:[docker1]$dockerserviceinspectetcd-f"{{.Endpoint.VirtualIPs}}"[{03wvlqw41e9go8li34z2u1t4p10.255.0.5/16}{9iy6k0gqs35bn541pr31mly5910.0.0.2/24}]到这里,我们的架构如下图所示:部署数据库集群使用如下命令为etcd指定虚拟IP地址部署Galera(PerconaXtraDB集群)容器:[docker1]$dockerservicecreate\--namemysql-galera\--replicas3\-p3306\--networkmynet\--envMYSQL_ROOT_PASSWORD=我的密码\--envDISCOVERY_SERVICE=10.0.0.2:2379\--envXTRABACKUP_PASSWORD=我的密码\--envCLUSTER_NAME=galera\perconalab/percona-整个部署过程需要xtradb-cluster:5.6需要一段时间,包括下载镜像到对应的工作/管理节点。大家可以使用以下命令验证其部署状态:[docker1]$dockerservicepsmysql-galeraIDNAMEIMAGENODEDESIREDSTATECURRENTSTATEERROR8wbyzwr2x5buxrhslvrlp2uy7mysql-galera.1perconalab/percona-xtradb-cluster:5.6docker1.localRunningRunning3minutesago0xhddwx5jzgw8fxrpj2lhcqeqmysql-galera.2perconalab/percona-xtradb-cluster:5.6docker3.localRunningRunning2minutesagof2ma6enkb8xi26f9mo06oj2fhmysql-galera.3perconalab/percona-xtradb-cluster:5.6docker2.localRunningRunning2minutesagoYoucanseethatthemysql-galeraserviceiscurrentlyrunning.下面列出全部现有服务:[docker1]$dockerservicelsIDNAMEREPLICASIMAGECOMMAND1m9ygovv9zuimysql-galera3/3perconalab/percona-xtradb-cluster:5.6au1w5qkez9d4etcd1/1elcolio/etcd:latest-nameetcd-discovery=https://discovery.etcd.io/a293d6cc552a66e68f4b5e52ef163d68Swarm模式包含AninternalDNScomponentresponsibleforautomaticallyassigningaDNSentrytoeachserviceintheSwarm.因此,可以使用服务名解析到对应的虚拟IP地址:[docker2]$dockerexec-it$(dockerps|grepetcd|awk{'print$1'})pingmysql-galeraPINGmysql-galera(10.0.0.4):56databytes64bytesfrom10.0.0.4:seq=0ttl=64time=0.078ms64bytesfrom10.0.0.4:seq=1ttl=64time=0.179ms或者直接使用“dockerserviceinspect”命令获取虚拟IP地址:[docker1]#dockerserviceinspectmysql-galera-f"{{.Endpoint.VirtualIPs}}"[{03wvlqw41e9go8li34z2u1t4p10.255.0.7/16}{9iy6k0gqs35bn541pr31mly5910.0.0.4/24}]这里,我们的架构如下图所示:部署应用最后,你可以创建应用程序服务并将MySQL服务名称(mysql-galera)作为数据库主机值:[docker1]$dockerservicecreate\--namewordpress\--replicas2\-p80:80\--networkmynet\--envWORDPRESS_DB_HOST=mysql-galera\--envWORDPRESS_DB_USER=root\--envWORDPRESS_DB_PASSWORD=mypassword\wordpress部署后,我们就可以检索虚拟IP通过“dockerserviceinspect”命令的wordpress服务地址:[docker1]#dockerserviceinspectwordpress-f"{{.Endpoint.VirtualIPs}}"[{p3wvtyw12e9ro8jz34t9u1t4w10.255.0.11/16}{kpv8e0fqs95by541pr31jly4810.0.0.8/24}】现在看看现在的架构Intent:我们的分布式应用和数据库设置已经通过Docker容器部署完成接入服务和负载均衡。这里,集群中所有Docker节点都已经开启了以下端口(基于每个“dockerservicecreate”命令-pflagon),不管每个节点当前是否正在运行服务任务:etcd-2380、2379、7001,4001MySQL-3306HTTP-80如果我们用一个简单的循环直接访问PublishedPort,我们可以看到每个容器都实现了MySQL服务负载均衡:[docker1]$whiletrue;domysql-uroot-pmypassword-h127.0.0。1-P3306-NBe'select@@wsrep_node_address';sleep1;done10.255.0.1010.255.0.810.255.0。910.255.0.1010.255.0.810.255.0.910.255.0.1010.255.0.810.255.0.910.255.0.10^C现在Swarmmanager负责负载均衡的内部管理,我们无法配置负载均衡算法。之后,我们可以使用外部负载均衡器将外部流量路由到每个Docker节点。如果任何Docker节点发生故障,服务将重新定位到其他可用节点。