惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
Forbes - Security
Forbes - Security
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
S
Securelist
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AWS News Blog
AWS News Blog
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
Last Week in AI
Last Week in AI
Engineering at Meta
Engineering at Meta
Spread Privacy
Spread Privacy
博客园_首页
T
Tor Project blog
The Cloudflare Blog
博客园 - 聂微东
罗磊的独立博客
Cyberwarzone
Cyberwarzone
腾讯CDC
T
The Exploit Database - CXSecurity.com
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Privacy International News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
U
Unit 42
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
A
About on SuperTechFans
G
GRAHAM CLULEY
K
Kaspersky official blog
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
T
Tenable Blog
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
TaoSecurity Blog
TaoSecurity Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
MongoDB | Blog
MongoDB | Blog
T
The Blog of Author Tim Ferriss
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 司徒正美
O
OpenAI News
Recent Announcements
Recent Announcements

博客园 - 小得盈满

Hudi 时间旅行与增量查询的区别分析 NATS 的基本安装及使用 Doris 和 StarRocks 性能测试对比 ClickHouse 添加磁盘扩容存储 使用 Docker 部署 Elasticsearch 集群 Qdrant 单机和集群的安装方法 ClickHouse UDF 的基本用法 StarRocks 容器镜像构建 Kafka 线上性能调优 StarRocks 集群安装 Kafka 的分片和副本机制 Flink 自定义 ClickHouse Table Connector 的简单实现 Redis 性能优化实战 记一次 Go 调用系统命令出现的问题分析 APISIX proxy-cache 插件用法 etcd 历史版本回溯的方法 APISIX 简单的自定义插件开发步骤 Kafka 集群副本数量调整 使用 Docker Compose 安装 APISIX etcd 集群安装
Consul 集群安装
小得盈满 · 2023-09-24 · via 博客园 - 小得盈满

1.介绍

Consul 是一款服务网络平台,主要实现服务注册、服务发现、服务网格、服务网关、安全网络以及配置管理等多类服务,非常适合做为微服务架构的底层网络平台。

配置中心其实就是一个 KV 存储,我们如果做配置中心的话其实主要就是用 KV 存储部分,但是为了以后的可扩展性,我们可能会使用各种服务网格的能力,因此选择 Consul 相比 etcd 来说是可以使用很多扩展的功能,不需要自己再进行额外的开发了。

2.部署架构

Consul 推荐的部署方式是采用多个可用区实现部署,因为采用 Raft 一致性的算法,所以一般部署奇数个节点,官方建议生产环境部署 5 节点,分布于 3 个可用区,每个可用区内最多两个节点,这样可以承受两个节点或者 1 个可用区的丢失。多个可用区一般是多个机房,如果没有条件也可以部署在 1~2 个可用区内,如果只有 1 个机房,那么这里的可用区可以看作是机架,尽量使服务分布于不同的机架,这样可以容忍最多两个机架完全丢失。

对于小型环境建议将 Consul 代理部署在多个物理服务器上,至少运行 3 个节点,如下图所示:

image

这样可以允许 1 个节点故障,从而具备一定的容错性。

3.安装配置

3.1.前提准备

我们下面以 3 个节点为例进行部署,机器列表如下:

172.16.0.5  ec1
172.16.0.6  ec2
172.16.0.7  ec3

每个节点的操作系统都是 Ubuntu 22.04,不过我们这里选择使用二进制的安装包进行安装,和具体哪个平台的关系不大,访问下载链接:https://developer.hashicorp.com/consul/downloads 下载安装包,最新的稳定版安装包名称为:consul_1.16.1_linux_amd64.zip,也就是我们当前安装 Consul 的版本是:1.16.1

3.2.安装到节点

我们在每个节点上都通过相同的步骤进行安装:

# 解压并放到 PATH 下
unzip consul_1.16.1_linux_amd64.zip
mv consul /usr/local/bin/
# 查看版本
consul --version
# 开启命令自动提示 可以用 tab 看到多级命令
consul -autocomplete-install
complete -C /usr/local/bin/consul consul
# 创建用户
useradd --system --home /etc/consul.d --shell /bin/false consul
# 创建数据目录并授权
mkdir --parents /data/consul
chown --recursive consul:consul /data/consul
# 创建证书目录
mkdir -p /etc/consul.d/certs

这样的话每个机器都安装上了,我们这里的数据目录放在 /data/consul 下,生产环境部署时一般放到单独的数据盘下面。

3.3.生成密钥和证书

然后我们在其中一个节点,比如第一个节点生成 GOSSIP 密钥,用于客户端之间通信的加密,客户端通信采用对称加密,因此每个节点都需要使用相同的密钥:

consul keygen

生成之后会返回密钥的 base64 编码,我们将这串密钥保存好,等下配置要用。

然后我们生成用于 RPC 加密的 TLS 证书,这个用于在客户端和服务端之间通信进行加密,首先需要生成 CA,同样是在第一个节点执行:

# 进入证书目录
cd /etc/consul.d/certs/
consul tls ca create

执行之后会输出:

==> Saved consul-agent-ca.pem
==> Saved consul-agent-ca-key.pem

这样就生成了 consul-agent-ca.pemconsul-agent-ca-key.pem ,前者是公钥,后者是私钥,然后我们基于 CA 创建证书:

consul tls cert create -server -dc dc1 -domain consul

由于我们是 1 个集群,因此数据中心指定为 dc1,这样执行之后默认会生成 dc1-server-consul-0.pemdc1-server-consul-0-key.pem 证书文件。

因为接下来我们将采用客户端证书自动生成的方式,所以我们不用再手动生成客户端证书了,然后我们将生成好的 CA 和证书发送到另外两个节点:

scp -r /etc/consul.d/certs/ ec2:/etc/consul.d/
scp -r /etc/consul.d/certs/ ec3:/etc/consul.d/

其实我们这里也可以只发送 consul-agent-ca-key.pem 即可,证书可以在每个节点基于 CA 单独生成,这里全部发送过去其实是为了操作简单,每个节点都是采用相同的证书。

3.4.集群配置

现在我们开始在第 1 个节点上编写配置文件:

touch /etc/consul.d/consul.hcl
chmod 640 /etc/consul.d/consul.hcl

然后我们编辑 /etc/consul.d/consul.hcl 写入下面的配置:

datacenter = "dc1"
data_dir = "/data/consul"
encrypt = "AU4FQ/rbbxqMQXRN5vA1QP1UHoDb8lubANa9llmXOEQ="

tls {
   defaults {
      ca_file = "/etc/consul.d/certs/consul-agent-ca.pem"
      cert_file = "/etc/consul.d/certs/dc1-server-consul-0.pem"
      key_file = "/etc/consul.d/certs/dc1-server-consul-0-key.pem"

      verify_incoming = true
      verify_outgoing = true
   }

   internal_rpc {
      verify_server_hostname = true
   }
}

auto_encrypt {
  allow_tls = true
}

retry_join = ["172.16.0.6", "172.16.0.7"]

acl {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
}

其中的配置需要注意的有:

  1. datacenter 和上面生成证书时配置一致,即:dc1
  2. data_dir 配置我们实际的数据目录,即:/data/consul
  3. encrypt 就是刚才生成的 gossip 密钥值
  4. 证书的路径注意配置正确
  5. retry_join 配置自动发现的节点,这样初始化的时候就不需要手动加入了。

配置好之后保存并退出。

然后继续创建服务配置文件:

touch /etc/consul.d/server.hcl
chmod 640 /etc/consul.d/server.hcl

然后编辑 /etc/consul.d/server.hcl 添加内容如下:

server = true
bootstrap_expect = 3
bind_addr = "172.16.0.5"
client_addr = "0.0.0.0"
performance {
  raft_multiplier = 1
}
connect {
  enabled = true
}

addresses {
  grpc = "127.0.0.1"
}

ports {
  grpc  = 8502
  grpc_tls = 8503
  http = 8500
}

其中需要注意的配置有:

  1. server 设置为 true 表示处于服务模式。
  2. bootstrap_expect 表示预期的节点数量,这里配置为 3
  3. bind_addr 表示服务绑定的地址,默认不配置也可以,默认值是:0.0.0.0
  4. client_addr 表示客户端绑定的地址,也就是 HTTP 和 DNS 绑定的地址,这个默认是 127.0.0.1 ,因此必须要设置下。
  5. addresses.grpc 表示绑定 gRPC API 的地址,由于我们使用了 TLS 的 gRPC,因此这里为了安全改为了 127.0.0.1
  6. ports 下面配置端口,其中 grpc 默认是 8502,grpc_tls 默认是 8503,http 默认是 8500

配置好之后保存并退出。

然后我们同步配置文件到另外的节点:

scp /etc/consul.d/*.hcl ec2:/etc/consul.d/
scp /etc/consul.d/*.hcl ec3:/etc/consul.d/

然后所有节点都重新设置下配置目录的权限:

# 所有节点都执行
chown --recursive consul:consul /etc/consul.d

然后我们分别在 ec2 和 ec3 上修改配置,主要是改几个和 IP 相关的:

ec2 上面修改 consul.hcl,修改 retry_join 改为另外两个节点的:

retry_join = ["172.16.0.5", "172.16.0.7"]

然后修改 server.hcl,修改 bind_addr

bind_addr = "172.16.0.6"

同样修改 ec3 上面的 consul.hcl:

retry_join = ["172.16.0.5", "172.16.0.6"]

修改 server.hcl:

bind_addr = "172.16.0.7"

最后修改完毕都保存一下。

我们需要选 1 个节点启动 Web UI 服务,一般不用每个节点都启动,这里选择第一个节点 ec1 编辑 server.hcl 配置,添加内容如下:

ui_config {
  enabled = true
}

添加后保存配置。

3.5.服务启动

然后在每个机器上都创建 service 服务文件:/etc/systemd/system/consul.service 填写内容如下:

[Unit]
Description="HashiCorp Consul - A service mesh solution"
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/consul.d/consul.hcl

[Service]
EnvironmentFile=-/etc/consul.d/consul.env
User=consul
Group=consul
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d/
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

每个机器都填写好并且保存,然后启动前先验证下配置文件的正确性:

consul validate /etc/consul.d/

如果校验失败会提示错误,比如上面的 grpc_tls 配置文档没写,但是校验不通过,因此这些报错都需要根据具体的提示进行修改,最终校验通过说明配置基本没有问题。

然后我们在所有节点上依次启动服务:

systemctl start consul

启动后查看状态和日志是否正常:

systemctl status consul
journalctl -u consul.service -f

有个别的报错一般没什么影响,比如离线环境可能远程更新会报错,以及个别连接断开的问题。在全部启动之前每个启动的节点都会等待发现的节点启动,直到所有的节点完全启动集群运行就正常了。

如果需要也可以设置开机自动启动:

systemctl enable consul

3.6.生成访问密钥

启动之后我们需要生成 SecretID 用于客户端或者 UI 的访问:

consul acl bootstrap

这个命令只能执行 1 次后续无法继续执行,创建后返回的内容要保存好,之后访问时都会用到,具体还可以设置访问策略,这里就不再详细说了,放到后续的使用文档中再来整理。

然后需要设置环境变量,建议添加到用户环境变量配置中:

# 这个 token 就是上面生成的 SecretID
export CONSUL_HTTP_TOKEN="d8004e40-7621-fb51-14de-48d9339e65e0"

然后可以查看集群的状态:

consul info
# 查看集群节点
consul members

然后我们还可以访问 Web UI,地址为:http://172.16.0.5:8500,访问之后输入上面的 token 就可以登录上去,然后就可以通过页面进行服务、Key/Value 相关的操作了。

我们如果使用 HTTP API 访问,需要在 Header 里面加上 X-Consul-Token ,比如:

curl --header "X-Consul-Token: d8004e40-7621-fb51-14de-48d9339e65e0" http://127.0.0.1:8500/v1/kv/a/b

和使用 cli 访问是类似的,比如:

consul kv get a/b

这样 Consul 集群就基本上安装完毕了。

3.7.Web UI 开启 HTTPS 配置

到上面已经部署完成了,不过默认情况下 Consul 是采用 HTTP 方式访问 Web UI 或者 API,如果有需要也可以开启 HTTPS 访问的方式,我们首先修改 Web UI 配置节点的配置文件:/etc/consul.d/consul.hcl 修改 tls 块下面的配置如下:

tls {
   defaults {
      ca_file = "/etc/consul.d/certs/consul-agent-ca.pem"
      cert_file = "/etc/consul.d/certs/dc1-server-consul-0.pem"
      key_file = "/etc/consul.d/certs/dc1-server-consul-0-key.pem"

      verify_incoming = false
      verify_outgoing = true
   }

   internal_rpc {
      verify_server_hostname = true
      verify_incoming = true
   }
}

我们将 defaults 中 verify_incoming 的值改为 false ,这样就不会拒绝 HTTPS 和 RPC 连接了,然后我们在 internal_rpc 中再添加 verify_incoming = true 的配置表示对 RPC 进行验证,这样就可以只对 HTTPS 放行了,然后我们保存配置文件。

如果我们只想 Web UI 通过 HTTPS 访问,而不使用 HTTPS API 访问其他节点,那么这个配置不需要同步,但是如果我们需要在所有的节点都想通过 HTTPS API 的方式访问服务,那么每个节点都需要按照上面进行同步修改,否则除了 Web UI 无法通过其他节点无法访问。

然后编辑 /etc/consul.d/server.hcl 配置文件,在 ports 中添加 HTTPS 访问端口:

ports {
  grpc  = 8502
  grpc_tls = 8503
  http = 8500
  https = 8501
}

这里推荐使用约定的 8501 作为 HTTPS 的端口,与此同时 HTTP 也同时开着,如果我们想关闭 HTTP 需要设置如下:

ports {
  grpc  = 8502
  grpc_tls = 8503
  http = -1
  https = 8501
}

这样就只提供 HTTPS 访问了,然后保存配置并且同步到所有的节点,以保证都开启一致的服务,也就是每个节点都需要开启 HTTPS。

上面两个配置修改完成后,所有节点依次重启 Consul 服务,然后通过 HTTPS 访问 Web UI 就可以了。

如果使用命令行方式访问,需要指定本地公钥签名的位置或者放到根证书目录中,否则 curl 认为不安全会报错:

curl --header "X-Consul-Token: d8004e40-7621-fb51-14de-48d9339e65e0" --cacert /etc/consul.d/certs/consul-agent-ca.pem https://127.0.0.1:8501/v1/kv/a/b

这样 HTTPS 服务就开启成功了。

Reference:

  1. 集群安装
  2. https://developer.hashicorp.com/consul/tutorials/production-deploy/security
  3. https://developer.hashicorp.com/consul/tutorials/security-operations/tls-encryption-openssl-secure#configure-the-consul-ui-for-https