Docker三剑客实践之部署集群

三剑客简介

docker-machine

docker技术是基于Linux内核的cgroup技术实现的,那么问题来了,在非Linux平台上是否就不能使用docker技术了呢?答案是可以的,不过显然需要借助虚拟机去模拟出Linux环境来。

docker-machine就是docker公司官方提出的,用于在各种平台上快速创建具有docker服务的虚拟机的技术,甚至可以通过指定driver来定制虚拟机的实现原理(一般是virtualbox)。

docker-compose

docker镜像在创建之后,往往需要自己手动pull来获取镜像,然后执行run命令来运行。当服务需要用到多种容器,容器之间又产生了各种依赖和连接的时候,部署一个服务的手动操作是令人感到十分厌烦的。

dcoker-compose技术,就是通过一个.yml配置文件,将所有的容器的部署方法、文件映射、容器连接等等一系列的配置写在一个配置文件里,最后只需要执行docker-compose up命令就会像执行脚本一样的去一个个安装容器并自动部署他们,极大的便利了复杂服务的部署。

docker-swarm

swarm是基于docker平台实现的集群技术,他可以通过几条简单的指令快速的创建一个docker集群,接着在集群的共享网络上部署应用,最终实现分布式的服务。

相比起zookeeper等集群管理框架来说,swarm显得十分轻量,作为一个工具,它把节点的加入、管理、发现等复杂的操作都浓缩为几句简单的命令,并且具有自动发现节点和调度的算法,还支持自定制。虽然swarm技术现在还不是非常成熟,但其威力已经可见一般。

浅谈docker服务架构和远程API

在正式使用docker技术部署集群应用时,我们应该先来了解一下docker工作的一些底层原理,和docker远程调用的API,这样才能大体了解集群究竟是如何运作的。

daemon

之前的docker入门文章中讲过,docker的基础服务,比如容器的创建、查看、停止、镜像的管理,其实都是由docker的守护进程(daemon)来实现的。

每次执行的docker指令其实都是通过向daemon发送请求来实现的。

daemon的运作(通信模式)主要有两种,一种是通过unix套接字(默认,但只能在本地访问到,比较安全),一种是通过监听tcp协议地址和端口来实现(这个可以实现在远程调用到docker服务)。

远程API

除了通过远程tcp协议访问远程主机上的docker服务外,docker还提供了一套基于HTTP的API,可以使用curl来实现操作远程主机上的docker服务,这为开发基于WEB的docker服务提供了便利。

远程docker使用示例

最终实现集群的时候实际是使用docker的远程调用来将不同的docker主机连接成一个整体的(通过tcp协议)。

我们不妨先来手动模拟尝试一下docker服务的远程调用吧。

首先需要在提供服务的主机上将docker的运行方式改为tcp,具体方法为修改/etc/default/docker中的DOCKER_OPTS为如下内容

-H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock
-H 后的参数是自己定义的要绑定的tcp地址和端口,成功绑定后重启docker服务就可以在该端口访问到docker的daemon服务。

不幸的是:

在OSX平台上,并没有找到docker的daemon配置文件
在OSX平台上,使用docker -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock -d这样的命令来尝试以tcp的方式启动docker daemon也是失败的,并没有任何作用
目前推测除了Linux平台上,其他平台上的配置方法都不太一样,但是在网络上暂时没有找到解决方案,所以后面的操作我只能通过在本地创建多个docker-machine的方式来模拟实现远程调用。
假设我们在192.168.1.123这台主机上开启了docker服务,监听了2375端口,那么我们就可以在同一网段的其他主机上(比如192.168.1.233)通过docker -H tcp://192.168.1.123:2345 <command>的方式调用到该主机上的docker服务。

比如

docker -H tcp://192.168.1.123:2345 ps
docker -H tcp://192.168.1.123:2345 images
docker -H tcp://192.168.1.123:2345 run ...
最终swarm构建集群的时候,就是通过这样的远程服务调用来调度各个节点的。

集群和分布式运算

在正式开始实践集群之前,我们有必要了解究竟什么是集群,什么是分布式计算。

首先,这两者有一个共同点,就是他们都是使用了多个服务节点的,通俗的说,就是要用到多台服务器协同工作(不一定是实体,也可能是虚拟机)。

而两者的区别在于:

集群是多台机器执行同一个业务,每次根据调度算法寻找最合适的节点来执行该业务
分布式计算是将一个业务拆分成多个独立的部分,由多台机器共同协作完成
集群的优点在于,当业务的需要的资源比较大时,可以避免由一个服务器去独自承担压力,而且即便有一个节点宕机了,业务仍然可以继续正常运行。这有点类似于负载均衡。

分布式的优点则是在计算上,可以协同多台机器发挥计算的威力,进行需要超高性能的运算。

构建集群

说现在我们正式开始构建集群。

使用docker-machine创建节点

由于实体机器的缺乏以及在osx上无法正常开启tcp的docker服务,我们基于docker-machine来创建多个虚拟机,作为集群中的节点。

执行下面的命令就可以创建一个新的docker-machine虚拟机manager1

docker-machine create --driver virtualbox manager1
在创建了虚拟机后,可以使用docker-machine env manager1来查看虚拟机manager1的相关信息,包括IP地址等

现在我们继续执行命令创建worker1和worker2两个节点,使用docker-machine ls命令可以查看到所有正在工作的虚拟机:

docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
manager1 - virtualbox Running tcp://192.168.99.100:2376 v17.06.1-ce
worker1 - virtualbox Running tcp://192.168.99.101:2376 v17.06.1-ce
worker2 - virtualbox Running tcp://192.168.99.102:2376 v17.06.1-ce

创建docker machine后,可以通过docker-machine ssh manager1 <command>的方式来访问虚拟机,执行指令。

创建swarm集群

初始化一个swarm集群的命令为:

docker swarm init --listen-addr <MANAGER-IP>:<PORT> --advertise-addr <IP>
--listen-addr参数是管理者节点的docker服务所在的IP:PORT,也就是说,可以通过这个组合访问到该节点的docker服务。

--advertise-addr是广播地址,也就是其他节点加入该swarm集群时,需要访问的IP

现在我们在manager1节点里创建swarm网络,执行

docker-machine ssh manager1 docker swarm init --listen-addr 192.168.99.100:2377 --advertise-addr 192.168.99.100
返回响应:

Swarm initialized: current node (23lkbq7uovqsg550qfzup59t6) is now a manager.

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

docker swarm join \
--token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
这样便创建了一个swarm集群,并且manager1节点目前是以管理者的身份加入在节点中的。

现在我们把worker1和worker2两个节点加入到swarm集群中去,分别在两个节点的虚拟机中执行docker swarm join --token ..即可:

docker-machine ssh worker1 docker swarm join --token \
SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
192.168.99.100:2377
This node joined a swarm as a worker.
docker-machine ssh worker2 docker swarm join --token \
SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
192.168.99.100:2377
This node joined a swarm as a worker.
在任何一个节点上执行docker node ls都可以查看到当前整个集群中的所有节点:

docker-machine ssh manager1 docker node ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
manager1 - virtualbox Running tcp://192.168.99.100:2376 v1.12.3
worker1 - virtualbox Running tcp://192.168.99.101:2376 v1.12.3
worker2 - virtualbox Running tcp://192.168.99.102:2376 v1.12.3
创建跨主机网络

集群建立完毕之后我们要做的就是在集群上部署我们的服务。但是首先应该让所有的节点处在一个共享的网络中,这样当我们把服务部署在这个共享网络中,就相当于部署在整个集群中了。

使用docker network ls可以查看到当前主机所参与的所有网络:

docker-machine ssh manager1 docker network ls
NETWORK ID NAME DRIVER SCOPE
764ff31881e5 bridge bridge local
fbd9a977aa03 host host local
6p6xlousvsy2 ingress overlay swarm
e81af24d643d none null local

其中SCOPE为swarm,DRIVER为overlay的即为集群节点中的共享网络。集群建立后会有一个默认的ingress共享网络,现在我们来再创建一个:

docker-machine ssh manager1 docker network create --driver overlay swarm_test
在跨主机网络上部署服务

在集群上部署应用,就是在共享网络上部署服务(service)。

但首先要保证每个节点上都已经有所需的镜像和环境了,这点便可以通过将同一份docker-compose配置文件共享到每个主机上,使用docker-compose在每个节点上下载镜像和搭建环境的工作。

由于judge_server的服务架构很简单,就一个镜像,所以我在这里直接在每台主机上把它pull下来就好了:

docker-machine ssh manager1 docker pull registry.cn-qingdao.aliyuncs.com/marklux/judge_server:1.0
docker-machine ssh worker1 docker pull registry.cn-qingdao.aliyuncs.com/marklux/judge_server:1.0
docker-machine ssh worker2 docker pull registry.cn-qingdao.aliyuncs.com/marklux/judge_server:1.0
接下来便是重头戏,我们使用manager1节点,在共享网络上启动我们的服务

docker service create --replicas 3 --name judge_swarm -p 8090:8090 --network=swarm_test registry.cn-qingdao.aliyuncs.com/marklux/judge_server:1.0
这个命令看起来是不是很像docker run?没错,swarm最终的目的就是把操作集群变得像操作单一的docker服务端一样简单!

--replicas 用于指定服务需要的节点数量,也就是集群的规模,这个值是弹性的,你可以在后续动态的更改它。

当服务中某个节点挂掉时,swarm将会搜寻集群中剩余的可用节点,顶替上去。也就是说,swarm会动态的调度,总是保持服务是由3个节点运行着的。

-p 用于暴露端口到宿主机,这样我们就能访问到了。

--network用于指定部署service的网络是哪一个

现在在manager1节点中使用docker service ls来查看集群中的服务:

docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kofcno637cmq judge_swarm replicated 3/3 registry.cn-qingdao.aliyuncs.com/marklux/judge_server:1.0 *:8090->8090/tcp

现在我们尝试在本地访问192.168.99.100:8090/ping,就可以得到响应了,事实上,现在无论将ip换为worker1或者worker2的,响应的结果都是一样,因为此时所有节点已经处在一个共同的集群网络下了
经过大量的访问测试,可以看到hostname是在变化着的,这说明每次请求,都由swarm动态的调度,选择了不同的节点来进行处理。
#go# #docker# #三剑客#

评论1

  • bash_operator.py     email_operator.py        hive_to_mysql.py            latest_only_operator.py   oracle_operator.py         python_operator.py              slack_operator.py
    bash_operator.pyc email_operator.pyc hive_to_mysql.pyc latest_only_operator.pyc oracle_operator.pyc python_operator.pyc slack_operator.pyc
    check_operator.py generic_transfer.py hive_to_samba_operator.py mssql_operator.py pig_operator.py redshift_to_s3_operator.py sqlite_operator.py
    check_operator.pyc generic_transfer.pyc hive_to_samba_operator.pyc mssql_operator.pyc pig_operator.pyc redshift_to_s3_operator.pyc sqlite_operator.pyc
    dagrun_operator.py hive_operator.py http_operator.py mssql_to_hive.py postgres_operator.py s3_file_transform_operator.py subdag_operator.py
    dagrun_operator.pyc hive_operator.pyc http_operator.pyc mssql_to_hive.pyc postgres_operator.pyc s3_file_transform_operator.pyc subdag_operator.pyc
    docker_operator.py hive_stats_operator.py __init__.py mysql_operator.py presto_check_operator.py s3_to_hive_operator.py
    docker_operator.pyc hive_stats_operator.pyc __init__.pyc mysql_operator.pyc presto_check_operator.pyc s3_to_hive_operator.pyc
    dummy_operator.py hive_to_druid.py jdbc_operator.py mysql_to_hive.py presto_to_mysql.py sensors.py
    dummy_operator.pyc hive_to_druid.pyc jdbc_operator.pyc mysql_to_hive.pyc presto_to_mysql.pyc sensors.py

    2017-11-23 10:27:23 回复
评论请先登录

最近热帖

  1. 基于 Harbor 搭建 Docker 私有镜像仓库 317577
  2. PPS代理节点池 192483
  3. PPS代理节点池② 110080
  4. PPS代理节点池③ 73387
  5. 订阅池记录 64720
  6. V2ray免费账号 11515
  7. WEB代理地址 2840
  8. 全栈开发笔记 2611
  9. 百度的无刷新搜索之PJAX 1942
  10. GITHUB项目 1830

近期热议

  1. GITHUB项目 55
  2. PPS代理节点池 50
  3. WEB代理地址 43
  4. 全栈开发笔记 42
  5. ROBOT机器人之路 31
  6. PPS代理节点池③ 26
  7. PPS代理节点池② 20
  8. C++回归之路 19
  9. OCR识别探索 16
  10. 错误笔记本 14