前言
上家公司的发展迁移后端服务部署是依托于Docker Swarm部署的线上服务集群。随着业务的不断发展,后来改成了Kubernetes来部署环境,Docker Swarm见证了着我们当时业务从0到1的发展,虽然现在国内使用Docker Swarm已经过时了,还是想总结下如何使用Docker Swarm搭建一个测试集群,可能未来会对你有帮助呢?
Docker Swarm是什么?
Swarm是Docker公司推出的用来管理docker集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/docker/swarm, 它是将一群Docker宿主机变成一个单一的虚拟主机,Swarm使用标准的Docker API接口作为其前端的访问入口,换言之,各种形式的DockerClient(compose,docker-py等)均可以直接与Swarm通信,甚至Docker本身都可以很容易的与Swarm集成,这大大方便了用户将原本基于单节点的系统移植到Swarm上,同时Swarm内置了对Docker网络插件的支持,用户也很容易的部署跨主机的容器集群服务。
Docker Swarm 和 Kubernetes的区别
- Docker Swarm 的优点和缺点都是使用标准的 Docker 接口,因为使用简单,容易集成到现有系统,所以在支持复杂的调度系统时候就会比较困难了,特别是在定制的接口中实现的调度。这也许就是成也在 Docker,败也在 Docker 的原因所在。
- Kubernetes 作为一个容器集群管理系统,用于管理云平台中多个主机上的容器应用,Kubernetes 的目标是让部署容器化的应用变得简单且高效,所以 Kubernetes 提供了应用部署,规划,更新,维护的一整套完整的机制。
Docker Swarm原理
swarm 集群由管理节点(manager)和工作节点(work node)构成。
- swarm mananger:负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。
- work node:即图中的 available node,主要负责运行相应的服务来执行任务(task)。
Docker Swarm搭建演示
我们来演示下docker Swarm搭建测试环境的完成过程,涉及: 构建镜像、创建manager、node等过程。
构建镜像
服务代码
使用python的flask框架编写一个简单的后端服务应用
运行app.py文件代码:
代码语言:javascript复制from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=, socket_connect_timeout=, socket_timeout=)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>"
"<b>Hostname:</b> {hostname}<br/>"
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=)
创建Dockerfile
使用如下dockerfile构建一个python flask项目成镜像。
代码语言:javascript复制# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
运行应用
构建完成镜像后,本地使用如下命令运行调试。
代码语言:javascript复制docker run -p 4000:80 friendlyhello
通过浏览器访问如下地址是正访问,说明启动成功。
代码语言:javascript复制curl http://localhost:4000
推送镜像
如果是企业级使用或者镜像共享的,可以把镜像推送到远程镜像仓库中托管。
注册docker账号
首先到https://hub.docker.com/注册一个账号,保存下用户名密码。
控制台登录docker hub账户
输入刚注册的用户名密码
代码语言:javascript复制docker login
查看镜像
代码语言:javascript复制docker image ls
重命名镜像
选择需要上传的镜像,重命名为指定的格式。
xinxixxxx:为我自己的dockerhub账户名称,替换成你刚注册的名称 friendlyhello:为自己为镜像取的名字 v1:为任意设置的版本号
代码语言:javascript复制docker tag friendlyhello xinxixxxx/friendlyhello:v1
上传镜像
上传镜像到仓库,大概会花费几分钟时间。
代码语言:javascript复制docker push xinxixxxx/friendlyhello:v1
创建docker-compose.yml文件
docker-compose.yml文件是一个YAML文件,用于定义Docker容器在生产中的行为方式。
将下面内容保存为docker-compose.yml, 确保已将第一部分中创建的镜像推送到远程仓库,并将username/repo:tag替换为你自己的镜像信息。
代码语言:javascript复制version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
networks:
webnet:
这个docker-compose.yml文件告诉Docker执行以下操作:
从注册中心中提取我们在步骤1中上传的镜像。
从此镜像运行5个实例作为一个服务,服务名为web,限制每个实例使用最多10%的CPU(所有核心)和50MB的RAM。
如果如果容器出错,立即重启。
将主机上的端口4000映射到Web的端口80。
Web容器通过称为webnet的负载平衡网络共享端口80。(在内部,容器发布在web的80端口)
默认使用Webnet网络(负载平衡网络)。
搭建Docker Swarm集群
前置准备
我们需要4个节点(1个master 3个slave),由于没有真实4台物理机,所以下文中是靠docker-machine、virtualbox以及boot2docker来虚拟出4个独立IP地址的带docker环境的节点,大家注意。
安装虚拟机
在本地安装虚拟机的方式运行。
代码语言:javascript复制https://www.virtualbox.org/
Boot2Docker是一个极简主义的Linux发行版,其唯一目的是运行Docker容器。
代码语言:javascript复制brew install boot2docker
或者
https://github.com/boot2docker/boot2docker/releases/tag/v17.07.0-ce
Docker Swarm集群实验
首先要将之前下载的boot2docker.iso放到/Users/你的用户名/.docker/machine/cache/目录下,然后执行如下命令:
代码语言:javascript复制docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso master
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave1
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave2
docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave3
docker-machine命令创建虚拟机的过程:
创建完4个节点以后,可以使用docker-machine ls命令查看一下各个节点的情况,可以看到自动为其分配了独IP地址。
初始化swarm
代码语言:javascript复制docker swarm init
运行
现在让我们来运行吧,您需要为您的应用程序命名,在这里它被设置为getstartedlab。
代码语言:javascript复制docker stack deploy -c docker-compose.yml getstartedlab
docker service ls
查看所有容器id
代码语言:javascript复制docker container ls -q
扩展容器
代码语言:javascript复制docker stack deploy -c docker-compose.yml getstartedlab
访问集群
集群图形化显示工具
Visualizer非常直观地显示了Swarm集群中,各个Docker主机上的容器负载情况。
部署
代码语言:javascript复制docker run -it -d -p : -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer
集群展示
最终部署完成后的展示效果如下:
结语
虽然Docker Swarm已经沉没在历史的舞台中了,但是它的架构设计和模式还是值得我们学习的,为了后续学习Kubernetes也会有一个帮助指导作用。