本文架构为Nginx+Consul+Consul Template+Registrator
负责接受clint端来的请求
是一个分布式高可用的服务发现和配置共享的软件,支持服务发现与注册、多数据中心、健康检查和分布式键/值存储, 内嵌实现了服务发现系统,不需要构建自己的系统或使用第三方系统,客户只需要注册服务,并通过DNS或HTTP接口执行服务发现
特性:
官网的介绍也就是这些 , 具体的可以去官网文档去看看 , 地址是https://www.consul.io/intro/index.html
consul中有些概念先理解
先理解consul的架构
上图中:
consul集群是B/S架构 , 一个集群有N个server和N个clinet组成
clinet表示consul的clinet模式 , 这种模式下, 所有注册到clinet的服务都会被转发到server上 , clinet节点不会做持久化存储
server表示consul的server模式,表明这个consul是个server节点。这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地
server leader中间那个SERVER下面有LEADER的描述,表明这个SERVER节点是它们的leader。和其它SERVER不一样的一点是,它需要负责同步注册信息给其它的SERVER,同时也要负责各个节点的健康监测。
可以看到上图 , client端互相通信用8301端口 , server互相通信用8300端口 , client向server端通信业用8300端口
Registrator是一个独立于服务注册表的自动服务注册/注销组件,一般以Docker container的方式进行部署。Registrator会自动侦测它所在的宿主机上的所有Docker容器状态(启用/销毁),并根据容器状态到对应的服务注册列表注册/注销服务。
事实上,Registrator通过读取同一台宿主机的其他容器Container的环境变量进行服务注册、健康检查定义等操作。
Registrator支持可插拔式的服务注册表配置,目前支持包括Consul, etcd和SkyDNS 2三种注册工具。
具体详情点我了解——->consul入门指南
Consul Template 提供一个方便的方式从Consul获取数据通过consul-template的后台程序保存到文件系统.
这个后台进程监控Consul示例的变化并更新任意数量的模板到文件系统.作为一个附件功能,模板更新完成后consul-template可以运行任何命令.可以查看示例部分看这个功能将会对哪些应用场景产生帮助.
部署分为2种 , 一种是docker化的部署 , 和非docker化的部署, 采用简单的部署方式主要是看效果 , 没有做高可用和集群化, 如果想做的话也是非常简单的 ,无非是增加几台机器和增加几个docker或者几个服务而已
主机 | IP | 功用 |
---|---|---|
node01 | 192.168.200.138 | registrator、helloworld、consul-server、consul-template、nginx |
node02 | 192.168.200.139 | registrator、helloworld |
在node01上部署服务
采用docker-compose的方式
vim docker-compose.yml
web:
image: liberalman/helloworld:latest
environment:
SERVICE_80_NAME: my-web-server
SERVICE_TAGS: backend-1
MY_HOST: host-1
ports:
- "80"
lb:
image: liberalman/nginx-consul-template:latest
hostname: lb
links:
- consulserver:consul
ports:
- "80:80"
consulserver:
image: consul:latest
environment:
SERVICE_TAGS: consul servers
hostname: consul_server_master
ports:
- "8300:8300"
- "8301:8301"
- "8302:8302"
- "8400:8400"
- "8500:8500"
- "8600:8600"
command: consul agent -server -bootstrap-expect 1 -advertise 192.168.200.148 -node consul_server_master -data-dir /tmp/data-dir -client 0.0.0.0 -ui
registrator:
image: gliderlabs/registrator:master
hostname: registrator-1
volumes:
- "/var/run/docker.sock:/tmp/docker.sock"
command: --net=host -ip=192.168.200.148 consul://192.168.200.148:8500
在node02上编写docker-compose
vim docker-compose.yml
web:
image: liberalman/helloworld:latest
environment:
SERVICE_80_NAME: my-web-server
SERVICE_TAGS: backend-2
MY_HOST: host-2
ports:
- "80"
registrator:
image: gliderlabs/registrator:master
hostname: registrator-1
volumes:
- "/var/run/docker.sock:/tmp/docker.sock"
command: --net=host -ip=192.168.200.148 consul://192.168.200.148:8500
部署完成之后 , 访问consul的web ui 地址: http://192.168.200.148:8500/ui (就是consul绑定地址的8500端口)
可以看到服务已经全部自动发现 ,访问主机ip的80端口 , 可以看到web服务正常,是随机出现的
健康状态检测也ok
服务也是后端2个随机
非docker化部署很简单, 就是把各个服务部署起来即可
yum -y install nginx
启动Nginx
systemctl start nginx
consul
的安装可以安装成集群形式 , 用来防止单点故障 , 不过用来测试的 , 可以只安装一个
wget https://releases.hashicorp.com/consul/1.4.0/consul_1.4.0_linux_amd64.zip
unzip consul_1.4.0_linux_amd64.zip
mv consul /usr/local/bin/
mkdir /etc/consul.d #创建配置文件目录
启动consul
# 在开发者模式中启动Consul代理 一个单节点的consul,如果网络有多个ip, 那么就明确写出 其中-clinet的指的是启动web页面的时候, 谁可以访问, 0.0.0.0就是谁都可以访问,-config-dir指定配置文件目录
consul agent -server -bind=192.168.200.148 -client 0.0.0.0 -config-dir /etc/consul.d/
# 创建一个服务定义配置文件,假设有一个名为web服务,它运行在80端口。
echo '{"service": {"name": "web", "tags": ["web"], "port": 80}}' >/etc/consul.d/web.json
打开web页面 http://IP:8500/ui
wget https://releases.hashicorp.com/consul-template/0.19.5/consul-template_0.19.5_linux_amd64.zip
unzip consul-template_0.19.5_linux_amd64.zip
mv consul-template /usr/local/bin/
consul-template -h //获取帮助
-consul-auth=<username[:password]> 设置基本的认证用户名和密码。
-consul-addr=<address> 设置Consul实例的地址。
-max-stale=<duration> 查询过期的最大频率,默认是1s。
-dedup 启用重复数据删除,当许多consul template实例渲染一个模板的时候可以降低consul的负载。
-consul-ssl 使用https连接Consul。
-consul-ssl-verify 通过SSL连接的时候检查证书。
-consul-ssl-cert SSL客户端证书发送给服务器。
-consul-ssl-key 客户端认证时使用的SSL/TLS私钥。
-consul-ssl-ca-cert 验证服务器的CA证书列表。
-consul-token=<token> 设置Consul API的token。
-syslog 把标准输出和标准错误重定向到syslog,syslog的默认级别是local0。
-syslog-facility=<facility> 设置syslog级别,默认是local0,必须和-syslog配合使用。
-template=<template> 增加一个需要监控的模板,格式是:'templatePath:outputPath(:command)',多个模板则可以设置多次。
-wait=<duration> 当呈现一个新的模板到系统和触发一个命令的时候,等待的最大最小时间。如果最大值被忽略,默认是最小值的4倍。
-retry=<duration> 当在和consul api交互的返回值是error的时候,等待的时间,默认是5s。
-config=<path> 配置文件或者配置目录的路径。
-pid-file=<path> PID文件的路径。
-log-level=<level> 设置日志级别,可以是"debug","info", "warn" (default), and "err"。
-dry Dump生成的模板到标准输出,不会生成到磁盘。
-once 运行consul-template一次后退出,不以守护进程运行。
$ vim nginx.conf.ctmpl
{{range services}} {{$name := .Name}} {{$service := service .Name}}
upstream {{$name}} {
zone upstream-{{$name}} 64k;
{{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
{{else}}server 127.0.0.1:65535; # force a 502{{end}}
} {{end}}
server {
listen 80 default_server;
location / {
root /usr/share/nginx/html/;
index index.html;
}
location /stub_status {
stub_status;
}
{{range services}} {{$name := .Name}}
location /{{$name}} {
proxy_pass http://{{$name}};
}
{{end}}
}
consul-template -consul-addr IP:8500 -template="nginx.conf.ctmpl:/usr/local/nginx/conf/conf.d/default.conf:service nginx reload"
这种是用命令行来启动服务, 也可以使用指定配置文件来加载服务 , 配置文件里写上各种参数, 各种具体的参数意义可以去官方样式中看, 地址是: https://github.com/hashicorp/consul-template#configuration-file-format
官方的配置文件为:
consul {
auth {
enabled = true
username = "test"
password = "test"
}
address = "192.168.2.210:8500"
token = "abcd1234"
retry {
enabled = true
attempts = 5
backoff = "250ms"
}
ssl {
enabled = true
verify = false
cert = "/path/to/client/cert"
key = "/path/to/client/key"
ca_cert = "/path/to/ca"
ca_path = "path/to/certs/"
server_name = "my-server.com"
}
}
reload_signal = "SIGHUP"
dump_signal = "SIGQUIT"
kill_signal = "SIGINT"
max_stale = "10m"
log_level = "warn"
pid_file = "/path/to/pid"
wait {
min = "5s"
max = "10s"
}
vault {
address = "https://vault.service.consul:8200"
token = "abcd1234"
unwrap_token = true
renew_token = true
retry {
# ...
}
ssl {
# ...
}
}
syslog {
enabled = true
facility = "LOCAL5"
}
deduplicate {
enabled = true
prefix = "consul-template/dedup/"
}
exec {
command = "/usr/bin/app"
splay = "5s"
env {
pristine = false
custom = ["PATH=$PATH:/etc/myapp/bin"]
whitelist = ["CONSUL_*"]
blacklist = ["VAULT_*"]
}
reload_signal = ""
kill_signal = "SIGINT"
kill_timeout = "2s"
}
template {
source = "/path/on/disk/to/template.ctmpl"
destination = "/path/on/disk/where/template/will/render.txt"
contents = "{{ keyOrDefault \"service/redis/maxconns@east-aws\" \"5\" }}"
command = "restart service foo"
command_timeout = "60s"
perms = 0600
backup = true
left_delimiter = "{{"
right_delimiter = "}}"
wait {
min = "2s"
max = "10s"
}
}
下面写一个简单的配置文件
$ vim nginx.hcl
consul {
address = "192.168.2.210:8500"
}
template {
source = "nginx.conf.ctmpl"
destination = "/usr/local/nginx/conf/conf.d/default.conf"
command = "service nginx reload"
}
执行命令即可让其重新配置
consul-template -config "nginx.hcl"
registrator就是docker化部署了 , 它的作用就是不依靠第三方组件 就能发现所在宿主机上的docker服务 , 可以指定consul , 让其自动注册 , 不过registrator和其他的组件不一样 , 要在每个宿主机上要部署一个 , 用来自动发现所在宿主机上的docker服务
docker pull gliderlabs/registrator:latest //拉取镜像
docker run -d --name=registrator \
-v /var/run/docker.sock:/tmp/docker.sock \
--net=host \
gliderlabs/registrator -ip="192.168.200.148" consul://192.168.200.148:8500
写一个docker化的http服务
我们用python起一个简单的http访问 , 我们用dockerfile写一个
FROM python2.7.14-alpine
EXPOSE 80
CMD ["python","-m","SimpleHTTPServer"]
构建此Dockerfile
docker build -t python/server .
运行
docker run -it \
-p 8000:80 python/server
用curl
访问是不是正常curl IP:80
即可