Skip to content

高可用

简介

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服务的负载均衡

tacport.conf
nginx
# 注意,本配置文件是被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),输出的内容类似于:

shell
$> 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:

nginx.conf
nginx
...
...

http {
   ...
   include conf.d/*;
}

# 与 http 同级,新增 stream 配置段(注意检查您的 Nginx 配置是否已经有
# 了 stream 段,不要重复添加)。
stream {
  include stream.d/*;
}

在 nginx 配置文件目录下创建一个 stream.d 的目录(与 conf.d同级),然后在 stream.d 目录下创建配置文件 tacport-stream.conf。

tacport-stream.conf
nginx
# 设置上游节点服务组 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 对外暴露的端口,以本例来说,则是:

shell
ssh_mapping_port: 52001
shell
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-1Nginx-2Nginx-3Nginx-4TacPort节点

配置的主要区别在于面向用户的最前端一层,连接到 TacPort 节点的最后一层,以及其它的中间层。

各 Nginx 节点的配置需要调整如下:

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
# 假设 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
# 假设此 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://域名 的方式安全访问,提升整个系统的安全性。