高可用
简介
TacPort 从 4.x 开始内建支持高可用——即使仅部署单一的 TacPort 服务节点,也能支持狭义上的高可用。
- 狭义上的高可用:在单一的服务节点上,节点主控进程可以为每个内置服务(如API服务、SSH协议转发服务)创建多个实例,来对外提供不间断服务。
- 广义上的高可用:可以部署多个 TacPort 服务节点,并将其分布到不同的物理主机上,这样即使某台物理主机宕机,其余主机上的服务节点依然可以对外提供不间断服务。
如果您对 TacPort 的服务架构感兴趣,可以查阅开发手册的 服务架构 一文。
部署为高可用
常规部署方式
按 常规部署 的方式部署多个 TacPort 服务节点,注意,各个服务节点配置项中的 节点ID必须唯一。
因为有多个服务节点,需要在这些服务节点前放置一套负载均衡服务,例如 Nginx,具体方式请参考本文的 负载均衡 一节。
容器化部署方式
当需要容器化运行多个 TacPort 服务节点时,可以考虑使用 Docker Swarm (Docker官方提供的容器编排工具) 或者 Kubernetes(K8s)。在部署时需要注意两点:
- 确保每个服务节点的 节点ID唯一,否则,后启动的带有重复节点ID的容器会报错停止;
- 正确地配置容器内的服务监听端口与宿主机的映射端口,否则外部访问节点服务时会失败。
容器化部署模式下,可以使用容器编排工具自身提供的负载均衡工具,如 ingress 等,也可以如常规部署方式那样,额外部署专用的负载均衡服务。
负载均衡
我们以 Nginx 为例说明如何对 TacPort 服务进行负载均衡。
提示
我们只需要对 TacPort 的 API 服务进行负载均衡。
其它的各协议转发服务,在需要建立远程连接的时候,已由 API 服务根据各服务节点负载情况进行了处理,给出可用的协议转发服务地址时已经是经过了负载均衡后的结果。
如果您的网络环境中各种后端服务必须通过nginx进行负载均衡/流量转发,则需要配置nginx的 stream 转发,详见后文 业务服务的负载均衡。
API服务的负载均衡
# 注意,本配置文件是被nginx的主配置文件引用的,类似这样:
# -- nginx主配置文件:nginx.conf --
# http {
# ...
# include conf.d/*;
# }
#
# 本配置文件放在nginx配置文件同目录下的 conf.d 目录下,会被自动引用
#
# 设置上游节点服务组 tp_web,注意,仅需加入提供了前端UI服务的节点。
upstream tp_web {
server 192.168.10.23:52100;
server 192.168.10.24:52100;
}
# 设置上游节点服务组 tp_api,注意,仅需加入提供了API服务的节点。
upstream tp_api {
server 192.168.10.23:52100;
server 192.168.10.24:52100;
server 192.168.10.25:52100;
}
server {
listen 80;
server_name tp.my-domain.com;
root /opt/tacport/web;
index index.html index.htm;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://tp_web;
}
location ~ ^/api/ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://tp_api;
# 以下三行是 websocket 需要的
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
之后您就可以通过 http://tp.my-domain.com
来访问 TacPort 的服务了。
业务服务的负载均衡
要对TacPort的各项业务服务(即,各种协议的转发服务)进行负载均衡/流量转发,需要使用 nginx 的 stream 转发功能。首先需要确认您部署的 nginx 是否开启了 tcp-stream 转发功能,请执行命令nginx -V
(注意大写V),输出的内容类似于:
$> nginx -V
nginx version: nginx/1.27.2
built by clang 15.0.0 (clang-1500.3.9.4)
built with OpenSSL 3.3.2 3 Sep 2024
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.27.2 \
--sbin-path=/usr/local/Cellar/nginx/1.27.2/bin/nginx \
--conf-path=/usr/local/etc/nginx/nginx.conf \
... \
--with-http_sub_module --with-http_v2_module --with-http_v3_module --with-ipv6 \
--with-pcre --with-pcre-jit \
... \
--with-stream \ <-- 注意这个
...
如果输出内容的configure
一项中包含--with-stream
,则 stream 转发功能可用。
先修改 nginx 的主配置文件 nginx.conf:
...
...
http {
...
include conf.d/*;
}
# 与 http 同级,新增 stream 配置段(注意检查您的 Nginx 配置是否已经有
# 了 stream 段,不要重复添加)。
stream {
include stream.d/*;
}
在 nginx 配置文件目录下创建一个 stream.d 的目录(与 conf.d同级),然后在 stream.d 目录下创建配置文件 tacport-stream.conf。
# 设置上游节点服务组 tcp_tp_ssh,注意,仅需加入提供了SSH转发服务的节点。
upstream tcp_tp_ssh {
server 192.168.10.25:52101;
server 192.168.10.26:52201;
server 192.168.10.28:52301;
server 192.168.10.29:52301;
}
server {
# 对外暴露一个端口 52001,访问此端口的请求会被转发到
# 上述上游节点服务组 tcp_tp_ssh 中的某一个节点上。
listen 52001;
proxy_pass tcp_tp_ssh;
}
最后,需要修改您的 TacPort 配置(配置文件或者docker-compose配置文件)中各业务服务的映射端口为 nginx 对外暴露的端口,以本例来说,则是:
ssh_mapping_port: 52001
TP_SSH_MAPPING_PORT=52001
注意
不同的Linux发行版中,Nginx的部署方式可能有差异,例如,Alpine Linux中使用 apk 安装的 Nginx 服务,其 stream 模块是动态加载的,需要额外安装相应的模块才能使用。
此外,一些Linux发行版的Nginx配置文件中已经预先设置了 stream 段(例如 Alpine Linux中,使用 apk add nginx-mod-stream
安装 stream 模块后,或自动生成含 stream 段的配置文件),请在配置 stream 段时注意不要重复设置,而是将 TacPort 所需的 stream 转发配置项写入到已经存在的 stream 段中。
多层Nginx转发
某些情况下您的环境可能需要多层Nginx转发,此时需要对 Nginx 做一点额外的配置,才能让 TacPort 服务获取到正确的来源IP,否则,一些根据来源IP进行访问控制的策略将工作不正常(例如远程运维授权策略中的访问来源限制)。
下面以 4 层 Nginx 转发为例进行说明。
用户
→ Nginx-1
→ Nginx-2
→ Nginx-3
→ Nginx-4
→ TacPort节点
配置的主要区别在于面向用户的最前端一层,连接到 TacPort 节点的最后一层,以及其它的中间层。
各 Nginx 节点的配置需要调整如下:
# 假设 Nginx-1 节点 IP 为 10.1.23.8
# 请在每一处 proxy_set_header X-Real-IP $remote_addr; 之后增加一行:
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
server {
listen 52100;
location / {
# ...
proxy_set_header X-Real-IP $remote_addr;
# 增加下面这一行
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ...
proxy_pass http://tp_web_end;
}
location ~ ^/api/ {
# ...
proxy_set_header X-Real-IP $remote_addr;
# 增加下面这一行
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ...
proxy_pass http://tp_api_end;
# ...
}
}
# 假设 Nginx-2 节点 IP 为 10.8.2.163
# 假设 Nginx-3 节点 IP 为 10.120.126.14
# 中间层的设置比第一层要多一些,请注意注释说明
# 1. 增加 real_ip_header 与 set_real_ip_from;
# 2. 请在每一处 proxy_set_header X-Real-IP $remote_addr; 之后增加一行:
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 增加下面两行,注意不要放到 server 段中,其中,set_real_ip_from 的值为上一个 Nginx 节
# 点的地址,对本示例来说,
# Nginx-2 的上一级 Nginx-1 节点的地址,即 10.1.23.8
# Nginx-3 的上一级 Nginx-2 节点的地址,即 10.8.2.163
real_ip_header x-Forwarded-For;
# 对Nginx-2节点来说,需要增加下面这行:
set_real_ip_from 10.1.23.8;
# 对Nginx-3节点来说,需要增加下面这行:
set_real_ip_from 10.8.2.163;
server {
listen 52100;
location / {
# ...
proxy_set_header X-Real-IP $remote_addr;
# 增加下面这一行
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ...
proxy_pass http://tp_web_end;
}
location ~ ^/api/ {
# ...
proxy_set_header X-Real-IP $remote_addr;
# 增加下面这一行
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ...
proxy_pass http://tp_api_end;
# ...
}
}
# 假设此 Nginx 节点 IP 为 192.168.1.23
# 最后一层只需要增加 real_ip_header 与 set_real_ip_from。
# 增加下面两行,注意不要放到 server 段中,其中,set_real_ip_from 的值为上一个 Nginx 节
# 点的地址,对本示例来说,
# Nginx-4 的上一级 Nginx-3 节点的地址,即 10.120.126.14
real_ip_header x-Forwarded-For;
set_real_ip_from 10.120.126.14;
# server 段中的内容不用改动
server {
listen 52100;
location / {
# ...
proxy_set_header X-Real-IP $remote_addr;
# ...
proxy_pass http://tp_web_end;
}
location ~ ^/api/ {
# ...
proxy_set_header X-Real-IP $remote_addr;
# ...
proxy_pass http://tp_api_end;
# ...
}
}
注意
多层 Nginx 转发的配置略显繁琐,需要仔细配置,特别要注意填写各层Nginx的地址时不要混淆,否则会无法正常访问。
重要
注意为各协议转发服务配置对应的 stream 流量转发,否则将只能访问 web 界面,而无法进行远程运维连接。
配置完成后,用户即可访问第一层 Nginx 的 52100 端口,即本示例中的 http://10.1.23.8:52100
来访问 TacPort WEB 界面了。
提示
可以在第一层 Nginx 中配置域名和证书,这样用户即可以 https://域名
的方式安全访问,提升整个系统的安全性。