4.10. 为客户端连接配置基于 Operator 的代理部署


4.10.1. 配置接受者

要在 OpenShift 部署中启用到代理 Pod 的客户端连接,为部署定义 acceptors。acceptors 定义代理 Pod 如何接受连接。您可以在用于代理部署的主自定义资源(CR)中定义 acceptors。当您创建接受者时,您可以指定在接受者上启用的消息协议等信息,以及代理 Pod 上的端口用于这些协议。

以下流程演示了如何在 CR 中为代理部署定义新的接受者。

流程

  1. 在初始安装过程中下载和提取的 Operator 归档的 deploy/crs 目录中,打开 broker_activemqartemis_cr.yaml 自定义资源(CR)文件。
  2. acceptors 元素中,添加命名 acceptor。添加 protocolsport 参数。设置值以指定接受者和使用的消息协议,以及每个代理 Pod 上的端口,以用于这些协议。例如:

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp
        port: 5672
    ...

    配置的 acceptor 将端口 5672 公开给 AMQP 客户端。表中显示了您可以为 protocol 参数指定的完整值集合。

    协议

    核心协议

    core

    AMQP

    amqp

    OpenWire

    OpenWire

    MQTT

    mqtt

    STOMP

    stomp

    所有支持的协议

    all

    注意
    • 对于部署中的每个代理 Pod,Operator 还会创建一个使用端口 61616 的默认 acceptor。代理集群需要这个默认接受程序,并启用核心协议。
    • 默认情况下,AMQ Broker 管理控制台使用代理 Pod 上的端口 8161。部署中的每个代理 Pod 都有一个专用的服务,提供对控制台的访问。更多信息请参阅 第 5 章 为基于 Operator 的代理部署连接到 AMQ 管理控制台
  3. 要在同一接收器中使用另一个协议,请修改 protocol 参数。指定以逗号分隔的协议列表。例如:

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp,openwire
        port: 5672
    ...

    配置的 acceptor 现在向 AMQP 和 OpenWire 客户端公开端口 5672。

  4. 要指定接受器允许的并发客户端连接数量,请添加 connectionsAllowed 参数并设置值。例如:

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp,openwire
        port: 5672
        connectionsAllowed: 5
    ...
  5. 默认情况下,接受者仅公开给与代理部署相同的 OpenShift 集群中的客户端。要同时向 OpenShift 外部的客户端公开接受者,请添加 expose 参数,并将值设为 true

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp,openwire
        port: 5672
        connectionsAllowed: 5
        expose: true
        ...
    ...

    当您向 OpenShift 外部的客户端公开接受器时,Operator 会自动为部署中的每个代理 Pod 创建专用服务和路由。

  6. 要启用来自 OpenShift 之外的客户端的安全连接,请添加 sslEnabled 参数并将值设为 true

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp,openwire
        port: 5672
        connectionsAllowed: 5
        expose: true
        sslEnabled: true
        ...
    ...

    当您在接受器(或连接器)中启用 SSL (即安全套接字层)安全时,您可以添加相关的配置,例如:

    • 用于在 OpenShift 集群中存储身份验证凭据的 secret 名称。当您在 acceptor 上启用 SSL 时需要 secret。有关生成此 secret 的更多信息,请参阅 第 4.10.2 节 “保护 broker-client 连接”
    • 用于安全网络通信的传输层安全性(TLS)协议。TLS 是一个更新的、更加安全的 SSL 版本。您可以在 enabledProtocols 参数中指定 TLS 协议。
    • acceptor 是否在代理和客户端之间使用双向 TLS (也称为 mutual 身份验证 )。您可以通过将 needClientAuth 参数的值设置为 true 来指定。

其他资源

4.10.2. 保护 broker-client 连接

如果您在接受器或连接器上启用了安全性(即,通过将 sslEnabled 设置为 true),您必须配置传输层安全(TLS),以允许代理和客户端之间的基于证书的验证。TLS 是一个更新的、更加安全的 SSL 版本。有两个主要 TLS 配置:

单向 TLS
只有代理才会显示证书。证书供客户端用于验证代理。这是最常见的配置。
双向 TLS
代理和客户端都存在证书。这有时被称为 mutual 身份验证
注意

以下流程描述了如何使用自签名证书来配置单向和双向 TLS。如果自签名证书在 Java 虚拟机(JVM)信任存储中被列为可信证书,则 JVM 不会验证证书的到期日期。在生产环境中,红帽建议您使用证书颁发机构签名的证书。

后续描述的部分:

对于单向和双向 TLS,您可以通过生成存储代理和客户端之间成功 TLS 握手所需的凭证的 secret 来完成配置。这是您必须在安全接受器或连接器的 sslSecret 参数中指定的 secret 名称。secret 必须包含以 Base64 编码的代理密钥存储(单向和双向 TLS)、一个 Base64 编码的代理信任存储(仅双向 TLS)以及这些文件的对应密码,也采用 Base64 编码的代理信任存储。单向和双向 TLS 配置流程演示了如何生成此 secret。

注意

如果您没有在安全接受器或连接器的 sslSecret 参数中明确指定 secret 名称,则 acceptor 或 connector 会假定默认 secret 名称。默认 secret 名称使用 < custom_resource_name> - <acceptor_name> -secret 或 < custom_resource_name> - &lt;connector_name>-secret。例如,my-broker-deployment-my-acceptor-secret

即使 acceptor 或 connector 假定默认 secrete 名称,您仍必须自行生成此 secret。它不会被自动创建。

4.10.2.1. 为主机名验证配置代理证书

注意

本节论述了在配置单向或双向 TLS 时必须生成的代理证书的一些要求。

当客户端尝试连接到部署中的代理 Pod 时,客户端连接 URL 中的 verifyHost 选项会决定客户端是否将代理证书的 Common Name (CN)与主机名进行比较,以验证它们是否匹配。如果您指定了 verifyHost=true 或与客户端连接 URL 类似,客户端会执行此验证。

在个别情况下,您可能会省略此验证,例如,如果您对连接的安全性没有问题,例如,代理部署在隔离网络中的 OpenShift 集群上。否则,对于安全连接,建议客户端执行此验证。在这种情况下,正确的代理密钥存储证书的配置是确保成功客户端连接非常重要。

通常,当客户端使用主机验证时,生成代理证书时指定的 CN 必须与客户端连接的代理 Pod 上 Route 的完整主机名匹配。例如,如果您使用单个代理 Pod 部署,CN 可能类似如下:

CN=my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain

为确保 CN 可以解析带有多个代理的的代理 Pod 中的任何代理,您可以指定一个星号(*)通配符字符来代替普通的代理 Pod。例如:

CN=my-broker-deployment-*-svc-rte-my-openshift-project.my-openshift-domain

上例中显示的 CN 成功解析为 my-broker-deployment 部署中的任何代理 Pod。

另外,您在生成代理证书时指定的主题备用名称(SAN) 必须单独列出 部署中的所有代理 Pod,作为以逗号分隔的列表。例如:

"SAN=DNS:my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain,DNS:my-broker-deployment-1-svc-rte-my-openshift-project.my-openshift-domain,..."

4.10.2.2. 配置单向 TLS

本节中的步骤演示了如何配置单向传输层安全(TLS)来保护代理客户端连接。

在单向 TLS 中,只有代理会显示证书。客户端使用此证书来验证代理。

先决条件

流程

  1. 为代理密钥存储生成自签名证书。

    $ keytool -genkey -alias broker -keyalg RSA -keystore ~/broker.ks
  2. 从代理密钥存储导出证书,使其可以与客户端共享。以 Base64 编码的 .pem 格式导出证书。例如:

    $ keytool -export -alias broker -keystore ~/broker.ks -file ~/broker_cert.pem
  3. 在客户端上,创建一个导入代理证书的客户端信任存储。

    $ keytool -import -alias broker -keystore ~/client.ts -file ~/broker_cert.pem
  4. 以管理员身份登录 OpenShift Container Platform。例如:

    $ oc login -u system:admin
  5. 切换到包含代理部署的项目。例如:

    $ oc project <my_openshift_project>
  6. 创建用于存储 TLS 凭据的 secret。例如:

    $ oc create secret generic my-tls-secret \
    --from-file=broker.ks=~/broker.ks \
    --from-file=client.ts=~/client.ks \
    --from-literal=keyStorePassword=<password> \
    --from-literal=trustStorePassword=<password>
    注意

    在生成 secret 时,OpenShift 要求您同时指定密钥存储和信任存储。信任存储密钥通常被命名为 client.ts。对于代理和客户端之间的单向 TLS,实际上不需要信任存储。但是,要成功生成 secret,您需要将 一些 有效的存储文件指定为 client.ts 的值。上一步通过重新使用之前生成的代理密钥存储文件来为 client.ts 提供"dummy"值。这足以生成一个 secret,其中包含单向 TLS 所需的所有凭证。

  7. 将 secret 链接到安装 Operator 时创建的服务帐户。例如:

    $ oc secrets link sa/amq-broker-operator secret/my-tls-secret
  8. 在安全接受器或连接器的 sslSecret 参数中指定 secret 名称。例如:

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp,openwire
        port: 5672
        sslEnabled: true
        sslSecret: my-tls-secret
        expose: true
        connectionsAllowed: 5
    ...

4.10.2.3. 配置双向 TLS

本节中的步骤演示了如何配置双向传输层安全(TLS)来保护代理客户端连接。

在双向 TLS 中,代理和客户端都会显示证书。代理和客户端使用这些证书在有时称为 mutual authentication 的过程中相互进行身份验证。

先决条件

流程

  1. 为代理密钥存储生成自签名证书。

    $ keytool -genkey -alias broker -keyalg RSA -keystore ~/broker.ks
  2. 从代理密钥存储导出证书,使其可以与客户端共享。以 Base64 编码的 .pem 格式导出证书。例如:

    $ keytool -export -alias broker -keystore ~/broker.ks -file ~/broker_cert.pem
  3. 在客户端上,创建一个导入代理证书的客户端信任存储。

    $ keytool -import -alias broker -keystore ~/client.ts -file ~/broker_cert.pem
  4. 在客户端上,为客户端密钥存储生成自签名证书。

    $ keytool -genkey -alias broker -keyalg RSA -keystore ~/client.ks
  5. 在客户端上,从客户端密钥存储导出证书,以便可以与代理共享证书。以 Base64 编码的 .pem 格式导出证书。例如:

    $ keytool -export -alias broker -keystore ~/client.ks -file ~/client_cert.pem
  6. 创建导入客户端证书的代理信任存储。

    $ keytool -import -alias broker -keystore ~/broker.ts -file ~/client_cert.pem
  7. 以管理员身份登录 OpenShift Container Platform。例如:

    $ oc login -u system:admin
  8. 切换到包含代理部署的项目。例如:

    $ oc project <my_openshift_project>
  9. 创建用于存储 TLS 凭据的 secret。例如:

    $ oc create secret generic my-tls-secret \
    --from-file=broker.ks=~/broker.ks \
    --from-file=client.ts=~/broker.ts \
    --from-literal=keyStorePassword=<password> \
    --from-literal=trustStorePassword=<password>
    注意

    在生成 secret 时,OpenShift 要求您同时指定密钥存储和信任存储。信任存储密钥通常被命名为 client.ts。对于代理和客户端之间的双向 TLS,您必须生成一个包含代理信任存储的 secret,因为这包含客户端证书。因此,在上一步中,您为 client.ts 键指定的值实际上是 代理 信任存储文件。

  10. 将 secret 链接到安装 Operator 时创建的服务帐户。例如:

    $ oc secrets link sa/amq-broker-operator secret/my-tls-secret
  11. 在安全接受器或连接器的 sslSecret 参数中指定 secret 名称。例如:

    spec:
    ...
      acceptors:
      - name: my-acceptor
        protocols: amqp,openwire
        port: 5672
        sslEnabled: true
        sslSecret: my-tls-secret
        expose: true
        connectionsAllowed: 5
    ...

4.10.3. 代理部署中的网络服务

在用于代理部署的 OpenShift Container Platform Web 控制台的 Networking 窗格中,有两个正在运行的服务: 无头服务ping 服务。无头服务的默认名称使用 < custom_resource_name> -hdls-svc,如 my-broker-deployment-hdls-svc。ping 服务的默认名称使用 < custom_resource_name> -ping-svc,例如 'my-broker-deployment-ping-svc

无头服务提供对端口 61616 的访问,用于内部代理集群。

ping 服务供代理用来发现,并允许代理在 OpenShift 环境中组成集群。在内部,这个服务公开端口 8888。

4.10.4. 从内部和外部客户端连接到代理

本节中的示例演示了如何从内部客户端(即,与代理部署相同的 OpenShift 集群中的客户端)和外部客户端(即 OpenShift 集群外的客户端)连接到代理。

4.10.4.1. 从内部客户端连接到代理

要将内部客户端连接到代理,在客户端连接详情中指定代理 pod 的 DNS 可解析名称。例如:

$ tcp://ex–aao-ss-0:<port>

如果内部客户端使用 Core 协议,且连接 URL 中没有设置 useTopologyForLoadBalancing=false 密钥,在客户端第一次连接到代理后,代理可以告知客户端集群中所有代理的地址。然后,客户端可以在所有代理间负载均衡连接。

如果您的代理有危险的订阅队列或请求/回复队列,请注意在客户端连接负载负载均衡时使用这些队列关联的注意事项。更多信息请参阅 第 4.10.4.4 节 “当您有危险订阅队列或回复/请求队列时,用于负载均衡客户端连接的注意事项”

4.10.4.2. 从外部客户端连接到代理

当您向外部客户端公开接受器(即,通过将 expose 参数的值设置为 true),Operator 会自动为部署中的每个代理 pod 创建专用服务和路由。

外部客户端可以通过指定为代理 pod 创建的路由的完整主机名来连接到代理。您可以使用基本的 curl 命令来测试对这个完整主机名的外部访问。例如:

$ curl https://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain

代理 pod 的路由的完整主机名必须解析为托管 OpenShift 路由器的节点。OpenShift 路由器使用主机名来确定在 OpenShift 内部网络内发送流量的位置。默认情况下,OpenShift 路由器侦听端口 80 用于非安全(即非 SSL)流量和端口 443 的安全(即 SSL 加密)流量。对于 HTTP 连接,如果您指定了安全连接 URL (即 https),或者如果您指定了非安全连接 URL (即 http),路由器会自动将流量定向到端口 443。

如果您希望外部客户端在集群中代理之间负载均衡连接:

  • 通过在每个代理 Pod 的 OpenShift 路由上配置 haproxy.router.openshift.io/balance roundrobin 选项来启用负载均衡。
  • 如果外部客户端使用 Core 协议,请在客户端连接 URL 中设置 useTopologyForLoadBalancing=false 键。

    设置 useTopologyForLoadBalancing=false 键可防止客户端使用代理提供的集群拓扑信息中的 AMQ Broker Pod DNS 名称。Pod DNS 名称解析为内部 IP 地址,外部客户端无法访问。

如果您的代理有危险的订阅队列或请求/回复队列,请注意在负载均衡客户端连接时使用这些队列关联的注意事项。更多信息请参阅 第 4.10.4.4 节 “当您有危险订阅队列或回复/请求队列时,用于负载均衡客户端连接的注意事项”

如果您不希望外部客户端在集群中的不同代理间进行负载均衡连接:

  • 在每个客户端的连接 URL 中,指定每个代理 pod 的路由的完整主机名。客户端会尝试连接到连接 URL 中的第一个主机名。但是,如果第一个主机名不可用,客户端会自动连接到连接 URL 中的下一个主机名,以此类推。
  • 如果外部客户端使用 Core 协议,在客户端的连接 URL 中设置 useTopologyForLoadBalancing=false 键,以防止客户端使用代理提供的集群拓扑信息。

对于非 HTTP 连接:

  • 客户端必须明确指定端口号(如端口 443)作为连接 URL 的一部分。
  • 对于单向 TLS,客户端必须指定信任存储的路径,以及对应的密码,作为连接 URL 的一部分。
  • 对于双向 TLS,客户端必须指定其密钥存储的路径和对应的密码,作为连接 URL 的一部分。

对于支持的消息传递协议,一些客户端连接 URL 示例如下所示。

外部核心客户端,使用单向 TLS

tcp://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain:443?useTopologyForLoadBalancing=false&sslEnabled=true \
&trustStorePath=~/client.ts&trustStorePassword=<password>

注意

连接 URL 中的 useTopologyForLoadBalancing 键明确设置为 false,因为外部核心客户端无法使用代理返回的拓扑信息。如果此键设为 true,或者您没有指定值,它会生成 DEBUG 日志消息。

外部核心客户端,使用双向 TLS

tcp://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain:443?useTopologyForLoadBalancing=false&sslEnabled=true \
&keyStorePath=~/client.ks&keyStorePassword=<password> \
&trustStorePath=~/client.ts&trustStorePassword=<password>

外部 OpenWire 客户端,使用单向 TLS

ssl://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain:443"

# Also, specify the following JVM flags
-Djavax.net.ssl.trustStore=~/client.ts -Djavax.net.ssl.trustStorePassword=<password>

外部 OpenWire 客户端,使用双向 TLS

ssl://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain:443"

# Also, specify the following JVM flags
-Djavax.net.ssl.keyStore=~/client.ks -Djavax.net.ssl.keyStorePassword=<password> \
-Djavax.net.ssl.trustStore=~/client.ts -Djavax.net.ssl.trustStorePassword=<password>

外部 AMQP 客户端,使用单向 TLS

amqps://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain:443?transport.verifyHost=true \
&transport.trustStoreLocation=~/client.ts&transport.trustStorePassword=<password>

外部 AMQP 客户端,使用双向 TLS

amqps://my-broker-deployment-0-svc-rte-my-openshift-project.my-openshift-domain:443?transport.verifyHost=true \
&transport.keyStoreLocation=~/client.ks&transport.keyStorePassword=<password> \
&transport.trustStoreLocation=~/client.ts&transport.trustStorePassword=<password>

4.10.4.3. 使用 NodePort 连接到代理

作为使用路由的替代选择,OpenShift 管理员可以配置 NodePort,以便从 OpenShift 外部的客户端连接到代理 pod。NodePort 应该映射到为代理配置的 acceptors 指定的协议特定端口之一。

默认情况下,NodePort 在 30000 到 32767 范围内,这意味着 NodePort 通常与代理 Pod 上的预期端口不匹配。

要通过 NodePort 从 OpenShift 外部客户端连接到代理,您需要以 <protocol>://<ocp_node_ip>:<node_port_number> 格式指定一个 URL。

4.10.4.4. 当您有危险订阅队列或回复/请求队列时,用于负载均衡客户端连接的注意事项

可运行的订阅

一个 durable 订阅在代理上以队列表示,并在持久订阅者首先连接到代理时创建。此队列存在并接收消息,直到客户端未订阅为止。如果客户端重新连接到不同的代理,则在那个代理上创建另一个可存活的订阅队列。这可能导致以下问题。

问题缓解方案

消息可能会在原始订阅队列中出现。

确保启用了消息重新发布。如需更多信息,请参阅启用消息重新发布

消息可能会以错误的顺序收到,因为在仍路由其他消息时,在重新发布消息期间会出现一个窗口。

无。

当客户端取消订阅时,它只删除它最后一次连接的代理中的队列。这意味着其他队列仍然可以存在并接收消息。

要删除可能适用于未订阅的客户端的其他空队列,请配置这两个属性:

auto-delete-queues-message-count 属性设置为 0, 以便在队列中没有消息时才能删除队列。设置 auto-delete-queues-delay 属性,以删除在未用于指定数量的毫秒后没有消息的队列。

如需更多信息,请参阅配置自动创建和删除地址和队列

请求/恢复队列

当 JMS Producer 创建临时回复队列时,会在代理上创建队列。如果从工作队列消耗并回复临时队列的客户端连接到不同的代理,则可能会出现以下问题。

问题缓解方案

由于客户端连接的代理中不存在回复队列,因此客户端可能会生成错误。

确保 auto-create-queues 属性设置为 true。如需更多信息,请参阅配置自动创建和删除地址和队列

发送到工作队列的消息可能无法分发。

通过将 message-load-balancing 属性设置为 ON-DEMAND 来确保消息按需负载平衡。此外,确保启用消息重新发布。如需更多信息,请参阅启用消息重新发布

其他资源

  • 有关使用路由和 NodePort 等方法从 OpenShift 集群与外部与集群中运行的服务进行通信的更多信息,请参阅:

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.