如何设置 Consul
Consul 集群由服务器和客户端代理组成。 服务器在它们自己的节点上运行,而客户端在其它节点上运行,而这些节点又与服务器进行通信。
专业版包含捆绑版本的 Consul,这是一种服务网络解决方案,您可以使用 /etc/gitlab/gitlab.rb
进行管理。
必要条件
在配置 Consul 之前:
配置 Consul 节点
在每个 Consul 服务器节点上:
- 按照说明安装极狐GitLab,选择您喜欢的平台,但不要在询问时提供
EXTERNAL_URL
值。 -
编辑
/etc/gitlab/gitlab.rb
,并通过替换retry_join
部分中注明的值来添加以下内容。在下面的示例中,有三个节点,两个用它们的 IP 表示,一个用它的 FQDN,您可以使用任一表示法:# Disable all components except Consul roles ['consul_role'] # Consul nodes: can be FQDN or IP, separated by a whitespace consul['configuration'] = { server: true, retry_join: %w(10.10.10.1 consul1.gitlab.example.com 10.10.10.2) } # Disable auto migrations gitlab_rails['auto_migrate'] = false
- 重新配置极狐GitLab 使更改生效。
-
运行以下命令以确保 Consul 配置正确并验证所有服务器节点都在通信:
sudo /opt/gitlab/embedded/bin/consul members
输出应类似于:
Node Address Status Type Build Protocol DC CONSUL_NODE_ONE XXX.XXX.XXX.YYY:8301 alive server 0.9.2 2 gitlab_consul CONSUL_NODE_TWO XXX.XXX.XXX.YYY:8301 alive server 0.9.2 2 gitlab_consul CONSUL_NODE_THREE XXX.XXX.XXX.YYY:8301 alive server 0.9.2 2 gitlab_consul
如果结果显示任何节点的状态不是
alive
,或者三个节点中的任何一个缺失,请参阅故障排查部分。
加固 Consul 节点安全
有两种可以加固 Consul 节点之间通信安全的方法,即使用 TLS 或 gossip 加密。
TLS 加密
默认情况下,Consul 集群并未启用 TLS,默认的配置选项和默认值如下:
consul['use_tls'] = false
consul['tls_ca_file'] = nil
consul['tls_certificate_file'] = nil
consul['tls_key_file'] = nil
consul['tls_verify_client'] = nil
这些配置选项对客户端和服务器节点均适用。
以 consul['use_tls'] = true
来在 Consul 节点上开启 TLS。取决于节点的角色(客户端还是服务器),您需要提供以下配置:
- 在服务器节点上,您必须至少指定
tls_ca_file
、tls_certificate_file
和tls_key_file
。 - 在客户端节点上,如果在服务器节点上禁用了客户端 TLS 认证(默认启用),则您必须至少指定
tls_ca_file
,否则,您不得不用tls_certificate_file
、tls_key_file
来传递客户端 TLS 证书。
当启用 TLS 时,默认情况下,服务器使用 mTLS 并同时监听 HTTPS 和 HTTP(对应 TLS 和非 TLS RPC)。它期望客户端使用 TLS 认证。您可以通过设置 consul['tls_verify_client'] = false
来禁用客户端 TLS 认证。
另一方面,客户端仅为向服务器节点的出站连接使用 TLS,并仅为入站请求监听 HTTP(对应非 TLS RPC)。您可以通过将 consul['https_port']
设置为非负整数(8501
是 Consul 的默认 HTTPS 端口)来强制客户端使用 TLS。您还必须传递 tls_certificate_file
和 tls_key_file
,以便此设置生效。当服务器节点使用客户端 TLS 认证时,客户端 TLS 证书和密钥用于 TLS 身份验证和入站 HTTPS 连接。
默认情况下,Consul 客户端节点不使用 TLS 客户端认证(服务器端正好相反),因此您需要通过设置 consul['tls_verify_client'] = true
来显式启用此功能。
以下是一些 TLS 加密的示例:
最小 TLS 支持
在下面的例子中,服务器为入站连接使用 TLS(无客户端 TLS 认证)。
::Tabs
:::TabTitle Consul 服务器节点
-
Edit
/etc/gitlab/gitlab.rb
:consul['enable'] = true consul['configuration'] = { 'server' => true } consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/server.crt.pem' consul['tls_key_file'] = '/path/to/server.key.pem' consul['tls_verify_client'] = false
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
:::TabTitle Consul 客户端节点
下面的示例可以在 Patroni 节点上进行配置。
-
编辑
/etc/gitlab/gitlab.rb
:consul['enable'] = true consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' patroni['consul']['url'] = 'http://localhost:8500'
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
Patroni 跟那些不为入站连接使用 TLS 的本地 Consul 代理进行通信。因为 HTTP URL 为 patroni['consul']['url']
。
::EndTabs
默认 TLS 支持
在下面的示例中,服务器使用 mTLS 认证。
::Tabs
:::TabTitle Consul 服务器节点
-
Edit
/etc/gitlab/gitlab.rb
:consul['enable'] = true consul['configuration'] = { 'server' => true } consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/server.crt.pem' consul['tls_key_file'] = '/path/to/server.key.pem'
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
:::TabTitle Consul 客户端节点
下面的示例可以在 Patroni 节点上进行配置。
-
Edit
/etc/gitlab/gitlab.rb
:consul['enable'] = true consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/client.crt.pem' consul['tls_key_file'] = '/path/to/client.key.pem' patroni['consul']['url'] = 'http://localhost:8500'
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
Patroni 跟那些不为入站连接使用 TLS 的本地 Consul 代理进行通信,即使它自身使用 TLS 认证来和 Consul 服务器节点进行通信。因此 HTTP URL 为 patroni['consul']['url']
。
::EndTabs
完全的 TLS 支持
下面的示例中,服务器和客户端都使用 mTLS 认证。
为了让 mTLS 认证工作,Consul 服务器、客户端和 Patroni 客户端节点必须使用相同的 CA 证书来颁发证书。
::Tabs
:::TabTitle Consul 服务器节点
-
编辑
/etc/gitlab/gitlab.rb
:consul['enable'] = true consul['configuration'] = { 'server' => true } consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/server.crt.pem' consul['tls_key_file'] = '/path/to/server.key.pem'
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
:::TabTitle Consul 客户端节点
下面的示例可以在 Patroni 节点上进行配置。
-
编辑
/etc/gitlab/gitlab.rb
:consul['enable'] = true consul['use_tls'] = true consul['tls_verify_client'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/client.crt.pem' consul['tls_key_file'] = '/path/to/client.key.pem' consul['https_port'] = 8501 patroni['consul']['url'] = 'https://localhost:8501' patroni['consul']['cacert'] = '/path/to/ca.crt.pem' patroni['consul']['cert'] = '/opt/tls/patroni.crt.pem' patroni['consul']['key'] = '/opt/tls/patroni.key.pem' patroni['consul']['verify'] = true
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
::EndTabs
Gossip 加密
Gossip 协议可以被加密以加固 Consul 代理之间的安全通信。默认情况下加密未启用,如要启用加密,则需要一个共享的加密 key。为了方便,key 可以使用 gitlab-ctl consul keygen
命令来生成。key 必需是 32 字节长,Base 64 编码的,并且共享在所有代理上。
以下选项在客户端和服务器节点上都可工作。
启用 gossip 加密:
-
编辑
/etc/gitlab/gitlab.rb
:consul['encryption_key'] = <base-64-key> consul['encryption_verify_incoming'] = true consul['encryption_verify_outgoing'] = true
-
重新配置GitLab:
sudo gitlab-ctl reconfigure
要为既有的数据中心启用加密,请为滚动更新手动设置这些选项。
升级 Consul 节点
要升级您的 Consul 节点,请升级 GitLab 包。
节点应该:
- 在升级 Linux 软件包之前是健康集群的成员。
- 一次升级一个节点。
通过在每个节点中运行以下命令来识别集群中的任何现有健康问题。如果集群健康,该命令将返回一个空数组:
curl "http://127.0.0.1:8500/v1/health/state/critical"
如果 Consul 版本发生了变化,你会在 gitlab-ctl reconfigure
的末尾看到一条通知,通知你需要重新启动 Consul 才能使用新版本。
一次重启一个节点:
sudo gitlab-ctl restart consul
Consul 节点使用 raft 协议进行通信。如果当前 leader 下线,则需要进行 leader 选举。必须存在 leader 节点以促进跨集群的同步。如果同时下线的节点过多,集群将失去法定人数,并且由于破坏共识而无法选举 leader。
如果集群在升级后无法恢复,请参阅故障排查部分。
GitLab 使用 Consul 仅存储易于重新生成的瞬态数据。如果捆绑的 Consul 没有被 GitLab 本身以外的任何进程使用,您可以从头开始重建集群。
故障排查
如果您需要调试任何问题,以下是一些有用的操作。您可以通过运行来查看任何错误日志:
sudo gitlab-ctl tail consul
检查集群成员
要确定哪些节点是集群的一部分,请在集群中的任何成员上运行以下命令:
sudo /opt/gitlab/embedded/bin/consul members
输出应类似于:
Node Address Status Type Build Protocol DC
consul-b XX.XX.X.Y:8301 alive server 0.9.0 2 gitlab_consul
consul-c XX.XX.X.Y:8301 alive server 0.9.0 2 gitlab_consul
consul-c XX.XX.X.Y:8301 alive server 0.9.0 2 gitlab_consul
db-a XX.XX.X.Y:8301 alive client 0.9.0 2 gitlab_consul
db-b XX.XX.X.Y:8301 alive client 0.9.0 2 gitlab_consul
理想情况下,所有节点的 Status
都是 alive
。
重启 Consul
如果有必要重新启动 Consul,那么以受控的方式执行此操作以保持法定人数是很重要的。如果仲裁丢失,要恢复集群,请遵循 Consul 中断恢复流程。
为安全起见,建议您一次仅在一个节点中重新启动 Consul,以确保集群保持完整。对于较大的集群,可以一次重新启动多个节点。其可容忍的失败次数见 Consul 共识文档。这将是它可以维持的同时重启次数。
要重启 Consul:
sudo gitlab-ctl restart consul
Consul 节点无法通信
默认情况下,Consul 尝试 bind 到 0.0.0.0
,但它会为其他 Consul 节点与之交流而通告该节点上的第一个私有 IP 地址。如果其它节点无法与此地址上的节点通信,则集群处于失败状态。
如果您遇到此问题,则在 gitlab-ctl tail consul
中会输出如下消息:
2017-09-25_19:53:39.90821 2017/09/25 19:53:39 [WARN] raft: no known peers, aborting election
2017-09-25_19:53:41.74356 2017/09/25 19:53:41 [ERR] agent: failed to sync remote state: No cluster leader
要解决此问题:
- 在每个节点上选择一个地址,所有其他节点都可以通过该地址到达该节点。
-
更新您的
/etc/gitlab/gitlab.rb
consul['configuration'] = { ... bind_addr: 'IP ADDRESS' }
-
重新配置极狐GitLab
gitlab-ctl reconfigure
如果您仍然看到错误,您可能需要在受影响的节点上擦除 Consul 数据库并重新初始化。
Consul 未启动 - 多个私有 IP
如果一个节点有多个私有 IP,Consul 不知道要通告哪个私有地址,然后它在启动时立即退出。
gitlab-ctl tail consul
中输出如下消息:
2017-11-09_17:41:45.52876 ==> Starting Consul agent...
2017-11-09_17:41:45.53057 ==> Error creating agent: Failed to get advertise address: Multiple private IPs found. Please configure one.
要解决此问题:
- 在节点上选择一个地址,所有其它节点都可以通过该地址到达该节点。
-
更新您的
/etc/gitlab/gitlab.rb
consul['configuration'] = { ... bind_addr: 'IP ADDRESS' }
-
重新配置极狐GitLab
gitlab-ctl reconfigure
中断恢复
如果在集群中丢失了足够多的 Consul 节点来破坏仲裁,那么集群就被认为已经失败,没有人工干预就无法运行。在这种情况下,您可以从头开始重新创建节点或尝试恢复。
从头开始重新创建
默认情况下,GitLab 不会在 Consul 节点中存储任何无法重新创建的内容。擦除 Consul 数据库并重新初始化:
sudo gitlab-ctl stop consul
sudo rm -rf /var/opt/gitlab/consul/data
sudo gitlab-ctl start consul
在此之后,节点应该开始备份,其余的服务器代理重新加入。不久之后,客户端代理也应该重新加入。
恢复故障节点
如果您已经利用 Consul 存储其他数据并希望恢复故障节点,请按照 Consul 指南来恢复故障集群。