使用docker快速部署一个consul集群
作为一个开发者,有时候需要一个集群环境,之前的做法要么就是使用多个虚拟机,要么就是采用不同的端口来模拟,但是虚拟机比较占内存,而且启动慢,采用不同的端口来模拟,管理起来比较麻烦一些,程序隔离性差一些。
docker的出现让我们可以在一台虚拟机上模拟构建出来一个几乎完全隔离的集群,本文提供一种快速构建consul集群的方法。
首先我们需要consul的镜像,这个可以从dockerhub上获取:
上面第一个就是consul官方的镜像
# 搜索镜像
sudo docker search consul
# 拉取镜像
sudo docker pull consul
获取到镜像之后,可以使用docker run运行,consul镜像运行的相关参数可以参考官方的文档
consul镜像官方说明:https://registry.hub.docker.com/_/consul
consul的官方文档:https://www.consul.io/docs
直接使用docker run来启动一个consul节点的集群,如:
# 不启用acl时,可直接执行下面的命令,创建一个只有一个节点的consul集群
sudo docker run -id -expose=[8300,8301,8302,8500,8600] --restart always -p 18300:8300 -p 18301:8301 -p 18302:8302 -p 18500:8500 -p 18600:8600 --name server1 -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' consul agent -server -bootstrap-expect=1 -node=server1 -bind=0.0.0.0 -client=0.0.0.0 -ui -datacenter dc1
# 启用acl是,只需要修改上面-e参数,如下面的命令,其中token_value可自行设置
sudo docker run -id -expose=[8300,8301,8302,8500,8600] --restart always -p 18300:8300 -p 18301:8301 -p 18302:8302 -p 18500:8500 -p 18600:8600 --name server1 -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true,"acl": {"enabled": true,"default_policy": "deny","down_policy": "extend-cache","tokens": {"master": "token_value"}}}' consul agent -server -bootstrap-expect=1 -node=server1 -bind=0.0.0.0 -client=0.0.0.0 -ui -datacenter dc1 各参数说明:
-expose:暴露出出来的端口,即consul启动所需的端口:8300,8301,8302,8500,8600
--restart:always表示容器挂了就自动重启
-p:建立宿主机与容器的端口映射
--name:容器名称
-e:环境变量,这里用于对consul进行配置
consul:这是consul镜像名,不是consul命令
agent:容器中执行的命令,各参数含义:
-server:表示节点是server类型
-bootstrap-expect:表示集群中有几个server节点后开始选举leader,既然是单节点集群,那自然就是1了
-node:节点名称
-bind:集群内部通信地址,默认是0.0.0.0
-client:客户端地址,默认是127.0.0.1
-ui:启用consul的web页面管理
-datacenter:数据中心
更多配置参考:https://www.consul.io/docs/agent/options
命令执行后,可以在浏览器上访问宿主机上的18500端口(映射到容器的8500),就可以访问到consul的web管理页面了,如果启动了acl,那么需要点击右上角的登录进行授权,授权值即上面自己设置的token_value,之后页面大概是这样子的:
如果是启动一个多节点的consul集群,docker run管理起来就会非常繁琐,所以分享两种简单的管理方式:
使用shell命令来管理
自己可以写一个shell文件来时间集群的管理,比如:


#!/bin/bash servers=3 #server节点数
prefix_server="server" #server节点名称前缀
clients=3 #client节点数
prefix_client="client" #client节点名称前缀
datacenter="dc1" #数据中心
port_rpc=18100 #rpc端口(起始)(不包含)
port_lan=18200 #lan端口(起始)(不包含)
port_wan=18300 #wan端口(起始)(不包含)
port_http=18400 #http端口(起始)(不包含)
port_dns=18500 #dns端口(起始)(不包含)
network_name="net-consul" #docker网络名称
token= #认证token,可以使用guid,之后连接需要携带token # 检查网络是否存在
network_create(){
if [ -z "$network_name" ];then
echo network not exists
exit 1
fi if [ $(sudo docker network ls | grep -c "$network_name") -gt 0 ];then
echo network [$network_name] exists
return
fi echo create network [$network_name]
sudo docker network create --driver bridge $network_name > /dev/null
} # 停止并删除docker容器
node_down(){
for i in $(seq 1 $2); do
node_name="$1$i"
sudo docker stop $node_name > /dev/null && sudo docker rm $node_name > /dev/null
echo node [$node_name] removed
done
} # 停止运行docker容器
node_stop(){
for i in $(seq 1 $2); do
node_name="$1$i"
sudo docker stop $node_name > /dev/null
echo node [$node_name] stoped
done
} # 生成一组可用的端口
generate_ports(){
port_rpc=`expr 1 + $port_rpc`
port_lan=`expr 1 + $port_lan`
port_wan=`expr 1 + $port_wan`
port_http=`expr 1 + $port_http`
port_dns=`expr 1 + $port_dns` p_rpc="$port_rpc:8300"
p_lan="$port_lan:8301"
p_wan="$port_wan:8302"
p_http="$port_http:8500"
p_dns="$port_dns:8600" bind_ports="-p $p_rpc -p $p_lan -p $p_wan -p $p_http -p $p_dns"
} # 创建并运行集群
consul_run(){
network_create if [ $servers -eq 0 ];then
echo no servers
exit 0
fi common_agent="-bind=0.0.0.0 -client=0.0.0.0"
common_docker="--network $network_name -expose=[8300,8301,8302,8500,8600] --restart always" #设置通用的环境变量
if [ -z "$token" ];then
e_server='CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' # 不使用token
else
e_server='CONSUL_LOCAL_CONFIG=
{
"skip_leave_on_interrupt": true,
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"tokens": {
"master": "'$token'"
}
}
}'
echo server token:$token
fi
e_client='CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}' # 创建并启动server节点
for i in $(seq 1 $servers); do
node_name="$prefix_server$i" #节点名称 generate_ports if [ $(sudo docker ps -a | grep -c "$node_name") -gt 0 ];then
echo node [$node_name] exists
continue
fi node_join=
if [ $i -ne 1 ];then
node_join="-join ${prefix_server}1"
fi sudo docker run -d $common_docker -e "$e_server" $bind_ports --name $node_name consul \
agent -server -bootstrap-expect=$servers -node=$node_name $common_agent -ui -datacenter $datacenter $node_join > /dev/null echo "server node:[$node_name] is running => $p_rpc $p_lan $p_wan $p_http $p_dns"
done if [ $clients -gt 0 ];then
sleep 3
fi # 创建并启动client节点
for i in $(seq 0 `expr $clients - 1`); do
node_name="$prefix_client`expr $i + 1`" if [ $(sudo docker ps -a | grep -c "$node_name") -gt 0 ];then
echo node [$node_name] exists
continue
fi generate_ports
server_node="$prefix_server`expr $i % $servers + 1`" sudo docker run -d $common_docker -e "$e_client" $bind_ports --name $node_name consul \
agent -node=$node_name $common_agent -retry-join=$server_node > /dev/null echo "client node:[$node_name] is running => $p_rpc $p_lan $p_wan $p_http $p_dns"
done
} consul_down(){
node_down $prefix_client $clients
node_down $prefix_server $servers
} consul_start(){
if [ $servers -le 0 ];then
echo invalid servers
exit 2
fi for i in $(seq 1 $servers); do
node_name="$prefix_server$i"
sudo docker start $node_name > /dev/null
echo node [$node_name] started
done if [ $clients -gt 0 ];then
sleep 3
fi for i in $(seq 1 $clients); do
node_name="$prefix_client$i"
server_node_name="$prefix_server`expr $i % $servers + 1`"
sudo docker start $node_name > /dev/null
echo node [$node_name] started
done
} consul_stop(){
node_stop $prefix_client $clients
node_stop $prefix_server $servers
} consul_up(){
consul_run
sleep 3
consul_status
} consul_restart(){
consul_stop
sleep 3
consul_start
} consul_logs(){
sudo docker logs $1
} consul_status(){
para_token=
if [ -n "$token" ];then
para_token="-token $token"
fi
# 检测并等待leader选举
consul_exec consul operator raft list-peers $para_token > /dev/null
consul_exec consul members $para_token
} consul_exec(){
sudo docker exec -i ${prefix_server}1 $@
} if [ ! -z "$1" ];then
_args=$@
_index=`expr index "$_args" " "`
_args=`echo ${_args:$_index}`
consul_$1 $_args
exit 0
fi echo "
Usage: $0 COMMAND 可用命令:
start 启动集群
stop 停止集群服务
up 创建并启动集群
run 创建并启动集群
down 停止并删除集群
status 查看集群容器节点信息
logs 输出指定节点的日志
exec 在集群中的首个节点执行指定的命令
restart 重新启动集群"
consul.sh
赋值上面的代码到一个sh文件,比如叫consul.sh,其中,文件开头是几个配置,可以修改:
servers=3 #server节点数
prefix_server="server" #server节点名称前缀
clients=3 #client节点数
prefix_client="client" #client节点名称前缀
datacenter="dc1" #数据中心
port_rpc=18100 #rpc端口(起始)(不包含)
port_lan=18200 #lan端口(起始)(不包含)
port_wan=18300 #wan端口(起始)(不包含)
port_http=18400 #http端口(起始)(不包含)
port_dns=18500 #dns端口(起始)(不包含)
network_name="net-consul" #docker网络名称
token= #认证token,可以使用guid,之后连接需要携带token
然后进行下面的操作:
# 赋予可执行的权限,脚本需要使用/bin/bash来执行,如果使用sh执行可能会报错,sh默认使用/bin/dash执行
sudo chmod +x consul.sh
# 启动
./consul.sh up
# 查看状态
./consul.sh status
# 停止并删除
./consul.sh down
如,启动后:
然后可以在浏览器上访问数组机上对应server节点的8500端口的端口,比如这里的18401,18402,18403,就是打开consul的web管理页面了,如果需要token,就是文件中配置的token参数
使用docker-compose来管理
使用shell命令来管理可以很灵活的拓展,以及实现自己的需求,但是需要自行编码比较繁琐,如果需要拓展自己的一些功能,可以使用docker-compose来管理,如下面的内容复制到一个docker-compose.yml文件中:


# yaml 配置
version: '2'
services:
server1:
image: consul
restart: always
container_name: server1
ports:
- 18101:8300
- 18201:8301
- 18301:8302
- 18401:8500
- 18501:8600
expose:
- 8300
- 8301
- 8302
- 8500
- 8600
command: agent -server -bootstrap-expect=3 -node=server1 -bind=0.0.0.0 -client=0.0.0.0 -ui -datacenter dc1
environment:
# 不启用acl
#CONSUL_LOCAL_CONFIG: '{"skip_leave_on_interrupt": true}'
# 启用acl,下面的token_value是token值,可自行设置
CONSUL_LOCAL_CONFIG: '{"skip_leave_on_interrupt": true,"acl": {"enabled": true,"default_policy": "deny","down_policy": "extend-cache","tokens": {"master": "token_value"}}}'
server2:
image: consul
restart: always
container_name: server2
ports:
- 18102:8300
- 18202:8301
- 18302:8302
- 18402:8500
- 18502:8600
expose:
- 8300
- 8301
- 8302
- 8500
- 8600
depends_on:
- server1
command: agent -server -bootstrap-expect=3 -node=server2 -bind=0.0.0.0 -client=0.0.0.0 -ui -datacenter dc1 -join server1
environment:
# 不启用acl
#CONSUL_LOCAL_CONFIG: '{"skip_leave_on_interrupt": true}'
# 启用acl,下面的token_value是token值,可自行设置
CONSUL_LOCAL_CONFIG: '{"skip_leave_on_interrupt": true,"acl": {"enabled": true,"default_policy": "deny","down_policy": "extend-cache","tokens": {"master": "token_value"}}}'
server3:
image: consul
restart: always
container_name: server3
ports:
- 18103:8300
- 18203:8301
- 18303:8302
- 18403:8500
- 18503:8600
expose:
- 8300
- 8301
- 8302
- 8500
- 8600
depends_on:
- server1
command: agent -server -bootstrap-expect=3 -node=server3 -bind=0.0.0.0 -client=0.0.0.0 -ui -datacenter dc1 -join server1
environment:
# 不启用acl
#CONSUL_LOCAL_CONFIG: '{"skip_leave_on_interrupt": true}'
# 启用acl,下面的token_value是token值,可自行设置
CONSUL_LOCAL_CONFIG: '{"skip_leave_on_interrupt": true,"acl": {"enabled": true,"default_policy": "deny","down_policy": "extend-cache","tokens": {"master": "token_value"}}}'
client1:
image: consul
restart: always
container_name: client1
ports:
- 18104:8300
- 18204:8301
- 18304:8302
- 18404:8500
- 18504:8600
expose:
- 8300
- 8301
- 8302
- 8500
- 8600
depends_on:
- server1
command: agent -node=client1 -bind=0.0.0.0 -client=0.0.0.0 -retry-join=server1
environment:
CONSUL_LOCAL_CONFIG: '{"leave_on_terminate": true}'
client2:
image: consul
restart: always
container_name: client2
ports:
- 18105:8300
- 18205:8301
- 18305:8302
- 18405:8500
- 18505:8600
expose:
- 8300
- 8301
- 8302
- 8500
- 8600
depends_on:
- server2
command: agent -node=client2 -bind=0.0.0.0 -client=0.0.0.0 -retry-join=server2
environment:
CONSUL_LOCAL_CONFIG: '{"leave_on_terminate": true}'
client3:
image: consul
restart: always
container_name: client3
ports:
- 18106:8300
- 18206:8301
- 18306:8302
- 18406:8500
- 18506:8600
expose:
- 8300
- 8301
- 8302
- 8500
- 8600
depends_on:
- server3
command: agent -node=client3 -bind=0.0.0.0 -client=0.0.0.0 -retry-join=server3
environment:
CONSUL_LOCAL_CONFIG: '{"leave_on_terminate": true}'
docker-compose.yml
然后可以使用docker-compose来启动和停止
# 启动
sudo docker-compose up -d
# 停止
sudo docker-compose down
启动后,如:
同样的,这时可以在浏览器上访问数组机上对应server节点的8500端口的端口,比如这里的18401,18402,18403,就是打开consul的web管理页面了,如果需要token,就是文件中配置的token参数
使用docker快速部署一个consul集群的更多相关文章
- 第3章:快速部署一个Kubernetes集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点$ kubeadm in ...
- 快速部署一个Kubernetes集群
官方提供的三种部署方式 minikube Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,仅用于尝试Kubernetes或日常开发的用户使用. 部署地址:https:// ...
- 用Docker swarm快速部署Nebula Graph集群
用Docker swarm快速部署Nebula Graph集群 一.前言 本文介绍如何使用 Docker Swarm 来部署 Nebula Graph 集群. 二.nebula集群搭建 2.1 环境准 ...
- 手把手教你用Docker部署一个MongoDB集群
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中最像关系数据库的.支持类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引 ...
- Docker简单部署Ceph测试集群
通过docker可以快速部署小规模Ceph集群的流程,可用于开发测试. 以下的安装流程是通过linux shell来执行的;假设你只有一台机器,装了linux(如Ubuntu)系统和docker环境, ...
- docker swarm快速部署redis分布式集群
环境准备 四台虚拟机 192.168.2.38(管理节点) 192.168.2.81(工作节点) 192.168.2.100(工作节点) 192.168.2.102(工作节点) 时间同步 每台机器都执 ...
- Kubernetes 学习笔记(二):本地部署一个 kubernetes 集群
前言 前面用到过的 minikube 只是一个单节点的 k8s 集群,这对于学习而言是不够的.我们需要有一个多节点集群,才能用到各种调度/监控功能.而且单节点只能是一个加引号的"集群&quo ...
- kubeadm部署一个Kubernetes集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具.这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 $ kubeadm in ...
- 用kubeadm+dashboard部署一个k8s集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: 1. 安装要求 在开始之前,部署Kubernetes集群 ...
随机推荐
- Templates and Static variables in C++
Function templates and static variables: Each instantiation of function template has its own copy of ...
- SQL模糊查询语句和Escape转义字符
通配符描述示例%包含零个或更多字符的任意字符串.WHERE title LIKE '%computer%' 将查找处于书名任意位置的包含单词 computer 的所有书名._(下划线)任何单个字符.W ...
- velocity示例
创建maven项目 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns ...
- Vue.js 学习
一,Vue.js 介绍 Vue 是一套用于构建用户界面的渐进式javascript框架,与其它大型框架不同的是:Vue被设计为可以自底向上逐层应用.Vue的核心库只关注视图层,不仅易于上手,还便于与第 ...
- js实现点击不同按钮切换内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- mybtis入门
1.编写持久化对象 public class User { private String id;//用户编号 private String username;//用户名 private String ...
- 程序员Meme 第01期
- Nginx安全检查
1.检查是否配置Nginx账号锁定策略 描述 1.执行系统命令passwd -S nginx来查看锁定状态 出现Password locked证明锁定成功 如:nginx LK ..... (Pass ...
- Windows通过计划任务定时执行bat文件
第一步 第二步 第三步 第四步 第五步 第六步
- CF1082A Vasya and Book 题解
Content 给定 \(T\) 组数据,每组数据给出四个整数 \(n,x,y,d\).小 V 有一本 \(n\) 页的书,每次可以恰好翻 \(d\) 页,求从第 \(x\) 页恰好翻到第 \(y\) ...