在 OpenShift 中部署和管理 AMQ Streams
在 OpenShift Container Platform 中部署和管理 AMQ Streams 2.5
摘要
使开源包含更多
红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。有关更多详情,请参阅我们的首席技术官 Chris Wright 提供的消息。
第 1 章 部署概述
AMQ Streams 简化了在 OpenShift 集群中运行 Apache Kafka 的过程。
本指南提供有关部署和管理 AMQ Streams 的说明。部署选项和步骤使用 AMQ Streams 中包含的示例安装文件进行。虽然指南突出显示了重要的配置注意事项,但它并不涵盖所有可用选项。要深入了解 Kafka 组件配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
除了部署说明外,指南还提供了部署前和部署后指导。它涵盖了设置并保护对 Kafka 集群的客户端访问。另外,它探索额外的部署选项,如指标集成、分布式追踪和集群管理工具,如 Cruise Control 和 AMQ Streams Drain Cleaner。您还将发现有关管理 AMQ Streams 和微调 Kafka 配置的建议,以获得最佳性能。
AMQ Streams 和 Kafka 都提供了升级说明,以帮助保持部署最新。
AMQ Streams 设计为与所有类型的 OpenShift 集群兼容,无论其发行版无关。无论您的部署涉及公有云或私有云,还是要设置本地开发环境,本指南中的说明适用于所有情况。
1.1. AMQ Streams 自定义资源
使用 AMQ Streams 将 Kafka 组件部署到 OpenShift 集群可以通过自定义资源的应用程序进行配置。这些自定义资源作为自定义资源定义(CRD)添加的 API 实例创建,以扩展 OpenShift 资源。
CRD 充当描述 OpenShift 集群中的自定义资源的配置说明,由 AMQ Streams 提供,用于部署中使用的每个 Kafka 组件,以及用户和主题。CRD 和自定义资源被定义为 YAML 文件。AMQ Streams 发行版提供了 YAML 文件示例。
CRD 还允许 AMQ Streams 资源从原生 OpenShift 功能中获益,如 CLI 访问和配置验证。
1.1.1. AMQ Streams 自定义资源示例
CRD 需要在集群中进行一次性安装,以定义用于实例化和管理 AMQ Streams 特定资源的模式。
在安装 CRD 中添加新的自定义资源类型后,您可以根据规格创建资源实例。
根据集群设置,安装通常需要集群管理员特权。
管理自定义资源的访问权限仅限于 AMQ Streams 管理员。如需更多信息,请参阅 第 4.5 节 “设计 AMQ Streams 管理员”。
在 OpenShift 集群中,CRD 定义了一个新的资源 kind
,如 kind:Kafka
。
Kubernetes API 服务器允许根据类型
创建自定义资源,并通过 CRD 了解在添加到 OpenShift 时如何验证和存储自定义资源。
删除 CustomResourceDefinition
时,该类型的自定义资源也会被删除。另外,自定义资源创建的 OpenShift 资源也会被删除,如 Deployment
、Pod
、Service
和 ConfigMap
资源。
每个 AMQ Streams 特定的自定义资源符合为资源的类型
的 CRD 定义的架构。AMQ Streams 组件的自定义资源具有通用配置属性,它们在 spec
下定义。
要了解 CRD 和自定义资源之间的关系,请参阅 Kafka 主题的 CRD 示例。
Kafka 主题 CRD
apiVersion: kafka.strimzi.io/v1beta2 kind: CustomResourceDefinition metadata: 1 name: kafkatopics.kafka.strimzi.io labels: app: strimzi spec: 2 group: kafka.strimzi.io versions: v1beta2 scope: Namespaced names: # ... singular: kafkatopic plural: kafkatopics shortNames: - kt 3 additionalPrinterColumns: 4 # ... subresources: status: {} 5 validation: 6 openAPIV3Schema: properties: spec: type: object properties: partitions: type: integer minimum: 1 replicas: type: integer minimum: 1 maximum: 32767 # ...
- 1
- 主题 CRD 的元数据、名称和标签来标识 CRD。
- 2
- 此 CRD 的规格,包括组(域)名称、复数名称和受支持的模式版本,它们用于 URL 用于访问主题的 API。其他名称用于识别 CLI 中的实例资源。例如,
oc get kafkatopic my-topic
或oc get kafkatopics
。 - 3
- CLI 命令可以使用短名称。例如,
oc get kt
是oc get kafkatopic
的缩写形式。 - 4
- 对自定义资源使用
get
命令时显示的信息。 - 5
- CRD 的当前状态,如资源的 schema 引用 中所述。
- 6
- openAPIV3Schema 验证提供了创建主题自定义资源的验证。例如,主题至少需要一个分区和一个副本。
您可以识别 AMQ Streams 安装文件提供的 CRD YAML 文件,因为文件名包含一个索引号,后跟 'Crd'。
以下是 KafkaTopic
自定义资源的对应示例。
Kafka 主题自定义资源
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic 1 metadata: name: my-topic labels: strimzi.io/cluster: my-cluster 2 spec: 3 partitions: 1 replicas: 1 config: retention.ms: 7200000 segment.bytes: 1073741824 status: conditions: 4 lastTransitionTime: "2019-08-20T11:37:00.706Z" status: "True" type: Ready observedGeneration: 1 / ...
自定义资源可以通过平台 CLI 应用到集群。创建自定义资源时,它会使用与 Kubernetes API 内置资源相同的验证。
创建 KafkaTopic
自定义资源后,主题 Operator 会通知,并在 AMQ Streams 中创建相应的 Kafka 主题。
1.2. AMQ Streams operator
AMQ Streams operator 是专门构建的,具有专家操作知识,以便在 OpenShift 上有效地管理 Kafka。每个操作器都执行不同的功能。
- Cluster Operator
- Cluster Operator 在 OpenShift 上处理 Apache Kafka 集群的部署和管理。它自动设置 Kafka 代理和其他 Kafka 组件和资源。
- Topic Operator
- 主题 Operator 管理 Kafka 集群中的创建、配置和删除主题。
- User Operator
- User Operator 管理需要访问 Kafka 代理的 Kafka 用户。
部署 AMQ Streams 时,您首先部署 Cluster Operator。然后,Cluster Operator 已准备好处理 Kafka 的部署。您还可以使用 Cluster Operator (推荐)或独立 Operator 部署 Topic Operator 和 User Operator。您可以将独立 Operator 与不是由 Cluster Operator 管理的 Kafka 集群一起使用。
主题 Operator 和 User Operator 是实体 Operator 的一部分。Cluster Operator 可以基于 Entity Operator 配置部署一个或多个 Operator。
要部署独立 Operator,您需要设置环境变量以连接到 Kafka 集群。如果您使用 Cluster Operator 部署 Operator,则不需要设置这些环境变量,因为它们将由 Cluster Operator 设置。
1.2.1. 在 OpenShift 命名空间中观察 AMQ Streams 资源
Operator 在 OpenShift 命名空间中观察和管理 AMQ Streams 资源。Cluster Operator 可以监控单个命名空间、多个命名空间或 OpenShift 集群中的所有命名空间。主题 Operator 和用户 Operator 可以监视单个命名空间。
-
Cluster Operator 监视
Kafka
资源 -
主题 Operator 监视
KafkaTopic
资源 -
User Operator 监视
KafkaUser
资源
主题 Operator 和 User Operator 只能监视命名空间中的单个 Kafka 集群。它们只能连接到单个 Kafka 集群。
如果多个主题 Operator 监视同一命名空间,则可能会出现名称冲突和主题删除。这是因为每个 Kafka 集群都使用具有相同名称的 Kafka 主题(如 __consumer_offsets
)。请确定只有一个主题 Operator 会监视给定的命名空间。
当将多个用户 Operator 与单个命名空间一起使用时,带有给定用户名的用户可在多个 Kafka 集群中存在。
如果使用 Cluster Operator 部署 Topic Operator 和 User Operator,它们默认监控 Cluster Operator 部署的 Kafka 集群。您还可以使用 operator 配置中的 watchedNamespace
指定命名空间。
对于每个 Operator 的独立部署,您可以指定一个命名空间和与 Kafka 集群的连接,以便在配置中监视。
1.2.2. 管理 RBAC 资源
Cluster Operator 为需要访问 OpenShift 资源的 AMQ Streams 组件创建和管理基于角色的访问控制(RBAC)资源。
要使 Cluster Operator 正常工作,OpenShift 集群中的权限需要与 Kafka 资源交互,如 Kafka
和 KafkaConnect
,以及 ConfigMap
、Pod
、Deployment
和 Service
等受管资源。
通过以下 OpenShift RBAC 资源指定权限:
-
ServiceAccount
-
Role
和ClusterRole
-
RoleBinding
和ClusterRoleBinding
1.2.2.1. 将权限委派给 AMQ Streams 组件
Cluster Operator 在名为 strimzi-cluster-operator
的服务帐户下运行。分配了集群角色,授予其为 AMQ Streams 组件创建 RBAC 资源的权限。角色绑定将集群角色绑定与服务帐户关联。
OpenShift 可防止在一个 ServiceAccount
下运行的组件授予授予 ServiceAccount
没有的另一个 ServiceAccount
特权。因为 Cluster Operator 会创建它管理的资源所需的 RoleBinding
和 ClusterRoleBinding
RBAC 资源,所以它需要一个赋予同一权限的角色。
下表描述了 Cluster Operator 创建的 RBAC 资源。
名称 | 使用的 |
---|---|
| Kafka 代理 pod |
| ZooKeeper pod |
| Kafka Connect pod |
| MirrorMaker pod |
| MirrorMaker 2 pod |
| Kafka Bridge pod |
| Entity Operator |
名称 | 使用的 |
---|---|
| Cluster Operator |
| Cluster Operator |
| Cluster Operator |
| Cluster Operator,机架功能(使用时) |
| Cluster Operator, Topic Operator, User Operator |
| Cluster Operator,用于机架感知的 Kafka 客户端 |
名称 | 使用的 |
---|---|
| Cluster Operator |
| Cluster Operator,用于机架感知的 Kafka 代理 |
| Cluster Operator,用于机架感知的 Kafka 客户端 |
名称 | 使用的 |
---|---|
| Cluster Operator |
| Cluster Operator,用于机架感知的 Kafka 代理 |
1.2.2.2. 使用一个 ServiceAccount
运行 Cluster Operator
Cluster Operator 最好使用 ServiceAccount
运行。
Cluster Operator 的 ServiceAccount
示例
apiVersion: v1 kind: ServiceAccount metadata: name: strimzi-cluster-operator labels: app: strimzi
然后,Operator 的部署需要在 spec.template.spec.serviceAccountName
中指定。
Cluster Operator 的 Deployment
的部分示例
apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-cluster-operator labels: app: strimzi spec: replicas: 1 selector: matchLabels: name: strimzi-cluster-operator strimzi.io/kind: cluster-operator template: metadata: labels: name: strimzi-cluster-operator strimzi.io/kind: cluster-operator spec: serviceAccountName: strimzi-cluster-operator # ...
1.2.2.3. ClusterRole
资源
Cluster Operator 使用 ClusterRole
资源来提供对资源所需的访问权限。根据 OpenShift 集群设置,可能需要集群管理员来创建集群角色。
只有在创建 ClusterRole
资源时才需要集群管理员权限。Cluster Operator 不会在集群管理员帐户下运行。
ClusterRole
资源遵循 最小特权原则,并只包含 Cluster Operator 操作 Kafka 组件集群所需的权限。第一个分配的权限集允许 Cluster Operator 管理 OpenShift 资源,如 Deployment
、Pod
和 ConfigMap
。
Cluster Operator 需要所有集群角色才能委派权限。
Cluster Operator 使用 strimzi-cluster-operator-namespaced
和 strimzi-cluster-operator-global
集群角色来授予命名空间范围的资源级别和集群范围的资源级别的权限。
Cluster Operator 的带有命名空间资源的 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-cluster-operator-namespaced labels: app: strimzi rules: # Resources in this role are used by the operator based on an operand being deployed in some namespace. When needed, you # can deploy the operator as a cluster-wide operator. But grant the rights listed in this role only on the namespaces # where the operands will be deployed. That way, you can limit the access the operator has to other namespaces where it # does not manage any clusters. - apiGroups: - "rbac.authorization.k8s.io" resources: # The cluster operator needs to access and manage rolebindings to grant Strimzi components cluster permissions - rolebindings verbs: - get - list - watch - create - delete - patch - update - apiGroups: - "rbac.authorization.k8s.io" resources: # The cluster operator needs to access and manage roles to grant the entity operator permissions - roles verbs: - get - list - watch - create - delete - patch - update - apiGroups: - "" resources: # The cluster operator needs to access and delete pods, this is to allow it to monitor pod health and coordinate rolling updates - pods # The cluster operator needs to access and manage service accounts to grant Strimzi components cluster permissions - serviceaccounts # The cluster operator needs to access and manage config maps for Strimzi components configuration - configmaps # The cluster operator needs to access and manage services and endpoints to expose Strimzi components to network traffic - services - endpoints # The cluster operator needs to access and manage secrets to handle credentials - secrets # The cluster operator needs to access and manage persistent volume claims to bind them to Strimzi components for persistent data - persistentvolumeclaims verbs: - get - list - watch - create - delete - patch - update - apiGroups: - "apps" resources: # The cluster operator needs to access and manage deployments to run deployment based Strimzi components - deployments - deployments/scale - deployments/status # The cluster operator needs to access and manage stateful sets to run stateful sets based Strimzi components - statefulsets # The cluster operator needs to access replica-sets to manage Strimzi components and to determine error states - replicasets verbs: - get - list - watch - create - delete - patch - update - apiGroups: - "" # legacy core events api, used by topic operator - "events.k8s.io" # new events api, used by cluster operator resources: # The cluster operator needs to be able to create events and delegate permissions to do so - events verbs: - create - apiGroups: # Kafka Connect Build on OpenShift requirement - build.openshift.io resources: - buildconfigs - buildconfigs/instantiate - builds verbs: - get - list - watch - create - delete - patch - update - apiGroups: - networking.k8s.io resources: # The cluster operator needs to access and manage network policies to lock down communication between Strimzi components - networkpolicies # The cluster operator needs to access and manage ingresses which allow external access to the services in a cluster - ingresses verbs: - get - list - watch - create - delete - patch - update - apiGroups: - route.openshift.io resources: # The cluster operator needs to access and manage routes to expose Strimzi components for external access - routes - routes/custom-host verbs: - get - list - watch - create - delete - patch - update - apiGroups: - image.openshift.io resources: # The cluster operator needs to verify the image stream when used for Kafka Connect image build - imagestreams verbs: - get - apiGroups: - policy resources: # The cluster operator needs to access and manage pod disruption budgets this limits the number of concurrent disruptions # that a Strimzi component experiences, allowing for higher availability - poddisruptionbudgets verbs: - get - list - watch - create - delete - patch - update
Cluster Operator 的带有集群范围资源的 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-cluster-operator-global labels: app: strimzi rules: - apiGroups: - "rbac.authorization.k8s.io" resources: # The cluster operator needs to create and manage cluster role bindings in the case of an install where a user # has specified they want their cluster role bindings generated - clusterrolebindings verbs: - get - list - watch - create - delete - patch - update - apiGroups: - storage.k8s.io resources: # The cluster operator requires "get" permissions to view storage class details # This is because only a persistent volume of a supported storage class type can be resized - storageclasses verbs: - get - apiGroups: - "" resources: # The cluster operator requires "list" permissions to view all nodes in a cluster # The listing is used to determine the node addresses when NodePort access is configured # These addresses are then exposed in the custom resource states - nodes verbs: - list
strimzi-cluster-operator-leader-election
集群角色代表领导选举机制所需的权限。
带有领导选举权限的 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-cluster-operator-leader-election labels: app: strimzi rules: - apiGroups: - coordination.k8s.io resources: # The cluster operator needs to access and manage leases for leader election # The "create" verb cannot be used with "resourceNames" - leases verbs: - create - apiGroups: - coordination.k8s.io resources: # The cluster operator needs to access and manage leases for leader election - leases resourceNames: # The default RBAC files give the operator only access to the Lease resource names strimzi-cluster-operator # If you want to use another resource name or resource namespace, you have to configure the RBAC resources accordingly - strimzi-cluster-operator verbs: - get - list - watch - delete - patch - update
strimzi-kafka-broker
集群角色代表使用机架感知的 Kafka pod 中 init 容器所需的访问。
名为 strimzi-<cluster_name>-kafka-init
的角色绑定会为 <cluster_name>-kafka
服务账户分配访问集群内使用 strimzi-kafka-broker
角色的节点。如果没有使用 rack 功能,且集群没有通过 nodeport
公开,则不会创建绑定。
Cluster Operator 的 ClusterRole
允许它将 OpenShift 节点的访问权限委派给 Kafka 代理 pod
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-kafka-broker labels: app: strimzi rules: - apiGroups: - "" resources: # The Kafka Brokers require "get" permissions to view the node they are on # This information is used to generate a Rack ID that is used for High Availability configurations - nodes verbs: - get
strimzi-entity-operator
集群角色代表 Topic Operator 和 User Operator 所需的访问权限。
主题 Operator 生成带有状态信息的 OpenShift 事件,因此 & lt;cluster_name> -entity-operator
服务帐户绑定到 strimzi-entity-operator
角色,该角色通过 strimzi-entity-operator
角色绑定授予此访问权限。
Cluster Operator 的 ClusterRole
允许它将对事件的访问权限委派给主题和用户 Operator
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-entity-operator labels: app: strimzi rules: - apiGroups: - "kafka.strimzi.io" resources: # The entity operator runs the KafkaTopic assembly operator, which needs to access and manage KafkaTopic resources - kafkatopics - kafkatopics/status # The entity operator runs the KafkaUser assembly operator, which needs to access and manage KafkaUser resources - kafkausers - kafkausers/status verbs: - get - list - watch - create - patch - update - delete - apiGroups: - "" resources: - events verbs: # The entity operator needs to be able to create events - create - apiGroups: - "" resources: # The entity operator user-operator needs to access and manage secrets to store generated credentials - secrets verbs: - get - list - watch - create - delete - patch - update
strimzi-kafka-client
集群角色代表使用机架感知的 Kafka 客户端所需的访问。
Cluster Operator 的 ClusterRole
允许它将对 OpenShift 节点的访问权限委派给基于 Kafka 客户端的 pod
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-kafka-client labels: app: strimzi rules: - apiGroups: - "" resources: # The Kafka clients (Connect, Mirror Maker, etc.) require "get" permissions to view the node they are on # This information is used to generate a Rack ID (client.rack option) that is used for consuming from the closest # replicas when enabled - nodes verbs: - get
1.2.2.4. ClusterRoleBinding
资源
Cluster Operator 使用 ClusterRoleBinding
和 RoleBinding
资源将其 ClusterRole
与 ServiceAccount
相关联:包含集群范围资源的集群角色需要集群角色绑定。
Cluster Operator 的 ClusterRoleBinding
示例
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: strimzi-cluster-operator labels: app: strimzi subjects: - kind: ServiceAccount name: strimzi-cluster-operator namespace: myproject roleRef: kind: ClusterRole name: strimzi-cluster-operator-global apiGroup: rbac.authorization.k8s.io
委派权限时使用的集群角色还需要集群角色绑定:
Cluster Operator 和 Kafka 代理机架意识的 ClusterRoleBinding
示例
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: strimzi-cluster-operator-kafka-broker-delegation labels: app: strimzi # The Kafka broker cluster role must be bound to the cluster operator service account so that it can delegate the cluster role to the Kafka brokers. # This must be done to avoid escalating privileges which would be blocked by Kubernetes. subjects: - kind: ServiceAccount name: strimzi-cluster-operator namespace: myproject roleRef: kind: ClusterRole name: strimzi-kafka-broker apiGroup: rbac.authorization.k8s.io
Cluster Operator 和 Kafka 客户端的 ClusterRoleBinding
示例
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: strimzi-cluster-operator-kafka-client-delegation labels: app: strimzi # The Kafka clients cluster role must be bound to the cluster operator service account so that it can delegate the # cluster role to the Kafka clients using it for consuming from closest replica. # This must be done to avoid escalating privileges which would be blocked by Kubernetes. subjects: - kind: ServiceAccount name: strimzi-cluster-operator namespace: myproject roleRef: kind: ClusterRole name: strimzi-kafka-client apiGroup: rbac.authorization.k8s.io
仅包含命名空间的资源的集群角色仅使用角色绑定绑定。
Cluster Operator 的 RoleBinding
示例
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: strimzi-cluster-operator labels: app: strimzi subjects: - kind: ServiceAccount name: strimzi-cluster-operator namespace: myproject roleRef: kind: ClusterRole name: strimzi-cluster-operator-namespaced apiGroup: rbac.authorization.k8s.io
Cluster Operator 和 Kafka 代理机架感知的 RoleBinding
示例
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: strimzi-cluster-operator-entity-operator-delegation labels: app: strimzi # The Entity Operator cluster role must be bound to the cluster operator service account so that it can delegate the cluster role to the Entity Operator. # This must be done to avoid escalating privileges which would be blocked by Kubernetes. subjects: - kind: ServiceAccount name: strimzi-cluster-operator namespace: myproject roleRef: kind: ClusterRole name: strimzi-entity-operator apiGroup: rbac.authorization.k8s.io
1.3. 使用 Kafka Bridge 与 Kafka 集群连接
您可以使用 AMQ Streams Kafka Bridge API 创建和管理消费者,并通过 HTTP 发送和接收记录,而不是原生 Kafka 协议。
设置 Kafka Bridge 时,您可以配置对 Kafka 集群的 HTTP 访问。然后,您可以使用 Kafka Bridge 来生成和消费来自集群的消息,以及通过其 REST 接口执行其他操作。
其他资源
- 有关安装和使用 Kafka Bridge 的详情,请参考使用 AMQ Streams Kafka Bridge。
1.4. 无缝 FIPS 支持
联邦信息处理标准(FIPS)是计算机安全和互操作性的标准。当在启用了 FIPS 的 OpenShift 集群上运行 AMQ Streams 时,AMQ Streams 容器镜像中使用的 OpenJDK 会自动切换到 FIPS 模式。在版本 2.4 中,AMQ Streams 可以在启用了 FIPS 的 OpenShift 集群上运行,而无需更改或特殊配置。它只使用 OpenJDK 中的 FIPS 兼容安全库。
最小密码长度
在 FIPS 模式下运行时,SCRAM-SHA-512 密码至少需要 32 个字符。从 AMQ Streams 2.4 中,AMQ Streams User Operator 中的默认密码长度也被设置为 32 个字符。如果您的 Kafka 集群带有使用小于 32 个字符的密码长度的自定义配置,则需要更新您的配置。如果您有少于 32 个字符的密码,则需要重新生成具有所需长度的密码。例如,您可以通过删除用户 secret 并等待 User Operator 创建具有适当长度的新密码来完成此操作。
如果使用启用了 FIPS 的 OpenShift 集群,与常规 OpenShift 集群相比,可能会遇到更高的内存消耗。为了避免任何问题,我们建议将内存请求增加到至少 512Mi。
1.5. 文档约定
用户替换的值
用户替换的值(也称为 可替换值 )以尖括号(< >)一同显示。下划线(_)用于多词值。如果值引用代码或命令,也使用 monospace
。
例如,以下代码显示 < ;my_namespace
> 必须替换为正确的命名空间名称:
sed -i 's/namespace: .*/namespace: <my_namespace>' install/cluster-operator/*RoleBinding*.yaml
1.6. 其他资源
第 2 章 AMQ Streams 安装方法
您可以通过两种方式将 AMQ Streams 在 OpenShift 4.10 上安装到 4.14。
安装方法 | Description |
---|---|
从 AMQ Streams 软件下载页面下载 Red Hat AMQ Streams 2.5 OpenShift Installation and Example Files。使用
您还可以使用
| |
使用 OperatorHub 中的 AMQ Streams Operator 将 AMQ Streams 部署到单个命名空间或所有命名空间。 |
要获得最大的灵活性,请选择安装工件方法。OperatorHub 方法提供了一个标准配置,可让您利用自动更新。
不支持使用 Helm 安装 AMQ Streams。
第 3 章 使用 AMQ Streams 部署的内容
为使用 AMQ Streams 分发的 OpenShift 提供了 Apache Kafka 组件。Kafka 组件通常作为集群运行,以实现高可用性。
使用 Kafka 组件的典型部署可能包括:
- 代理节点的 Kafka 集群
- 复制 ZooKeeper 实例的 zookeeper 集群
- 用于外部数据连接的 Kafka 连接 集群
- Kafka MirrorMaker 集群在二级集群中镜像 Kafka 集群
- Kafka Exporter 来提取额外的 Kafka 指标数据以进行监控。
- Kafka Bridge 为 Kafka 集群发出基于 HTTP 的请求
- Cruise Control 在代理节点间重新平衡主题分区
并非所有组件都是必须的,但最少需要 Kafka 和 ZooKeeper。有些组件可以在没有 Kafka 的情况下部署,如 MirrorMaker 或 Kafka Connect。
3.1. 部署顺序
部署到 OpenShift 集群所需的顺序如下:
- 部署 Cluster Operator 来管理 Kafka 集群
- 使用 ZooKeeper 集群部署 Kafka 集群,并在部署中包含 Topic Operator 和 User Operator
(可选)部署:
- 如果没有使用 Kafka 集群部署它们,则主题 Operator 和用户 Operator
- Kafka Connect
- Kafka MirrorMaker
- Kafka Bridge
- 用于监控指标的组件
Cluster Operator 为组件创建 OpenShift 资源,如 Deployment
、Service
和 Pod
资源。部署时,OpenShift 资源的名称会附加为组件指定的名称。例如,名为 my-kafka-cluster
的 Kafka 集群有一个名为 my-kafka-cluster-kafka
的服务。
第 4 章 准备 AMQ Streams 部署
通过完成任何必要的部署前任务,准备 AMQ Streams 部署。根据您的具体要求执行必要的准备步骤,如下所示:
要在本指南中运行命令,您的集群用户必须有权管理基于角色的访问控制(RBAC)和 CRD。
4.1. 部署先决条件
要部署 AMQ Streams,您需要以下内容:
OpenShift 4.10 到 4.14 集群。
AMQ Streams 基于 Strimzi 0.36.x。
-
oc
命令行工具已安装并配置为连接到正在运行的集群。
4.2. 下载 AMQ Streams 发行工件
要使用部署文件安装 AMQ Streams,请从 AMQ Streams 软件下载页面 下载并解压文件。
AMQ Streams 发行版本工件包括示例 YAML 文件,可帮助您将 AMQ Streams 组件部署到 OpenShift,执行通用操作和配置 Kafka 集群。
使用 oc
从下载的 ZIP 文件的 install/cluster-operator
文件夹中部署 Cluster Operator。有关部署和配置 Cluster Operator 的更多信息,请参阅 第 6.2 节 “部署 Cluster Operator”。
另外,如果要使用带有不是由 AMQ Streams Cluster Operator 管理的 Kafka 集群的独立安装主题和用户 Operator,您可以从 install/topic-operator
和 install/user-operator
文件夹部署它们。
AMQ Streams 容器镜像也通过 红帽生态系统目录 提供。但是,我们建议您使用提供的 YAML 文件来部署 AMQ Streams。
4.3. 将容器镜像推送到您自己的 registry
AMQ Streams 的容器镜像 Red Hat Ecosystem Catalog 提供。AMQ Streams 提供的安装 YAML 文件将直接 从红帽生态系统目录拉取镜像。
如果您无法访问 红帽生态系统目录 或希望使用您自己的容器存储库,请执行以下操作:
- 拉取此处列出的 所有容器镜像
- 将其推送到您自己的 registry 中
- 更新安装 YAML 文件中的镜像名称
发行版本支持的每个 Kafka 版本均有单独的镜像。
容器镜像 | namespace/Repository | Description |
---|---|---|
Kafka |
| 用于运行 Kafka 的 AMQ Streams 镜像,包括:
|
Operator |
| 用于运行 Operator 的 AMQ Streams 镜像:
|
Kafka Bridge |
| 用于运行 AMQ Streams Kafka Bridge 的 AMQ Streams 镜像 |
AMQ Streams Drain Cleaner |
| 用于运行 AMQ Streams Drain Cleaner 的 AMQ Streams 镜像 |
4.4. 创建用于向容器镜像 registry 进行身份验证的 pull secret
AMQ Streams 提供的安装 YAML 文件直接 从红帽生态系统目录拉取容器镜像。如果 AMQ Streams 部署需要身份验证,请在 secret 中配置身份验证凭据并将其添加到安装 YAML 中。
通常不需要身份验证,但可能会在某些平台上请求。
先决条件
- 您需要您的红帽用户名和密码或红帽 registry 服务帐户中的登录详情。
您可以使用您的红帽订阅 从红帽客户门户 创建 registry 服务帐户。
流程
创建包含登录详情和从中拉取 AMQ Streams 镜像的容器 registry 的 pull secret:
oc create secret docker-registry <pull_secret_name> \ --docker-server=registry.redhat.io \ --docker-username=<user_name> \ --docker-password=<password> \ --docker-email=<email>
添加您的用户名和密码。电子邮件地址是可选的。
编辑
install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
部署文件,以使用STRIMZI_IMAGE_PULL_SECRET
环境变量指定 pull secret:apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-cluster-operator spec: # ... template: spec: serviceAccountName: strimzi-cluster-operator containers: # ... env: - name: STRIMZI_IMAGE_PULL_SECRETS value: "<pull_secret_name>" # ...
secret 适用于 Cluster Operator 创建的所有 pod。
4.5. 设计 AMQ Streams 管理员
AMQ Streams 提供用于配置部署的自定义资源。默认情况下,查看、创建、编辑和删除这些资源的权限仅限于 OpenShift 集群管理员。AMQ Streams 提供了两个集群角色,可用于为其他用户分配这些权限:
-
strimzi-view
允许用户查看和列出 AMQ Streams 资源。 -
strimzi-admin
还允许用户创建、编辑或删除 AMQ Streams 资源。
安装这些角色时,它们将自动聚合(添加)这些权限到默认的 OpenShift 集群角色。strimzi-view
聚合到 view
角色,strimzi-admin
聚合到 edit
和 admin
角色。由于聚合,您可能不需要将这些角色分配给已经具有类似权限的用户。
以下流程演示了如何分配允许非集群管理员管理 AMQ Streams 资源的 strimzi-admin
角色。
系统管理员可在部署 Cluster Operator 后指定 AMQ Streams 管理员。
先决条件
- 用于管理 CRD 的 AMQ Streams 自定义资源定义(CRD)和基于角色的访问控制(RBAC)资源已使用 Cluster Operator 部署。
流程
在 OpenShift 中创建
strimzi-view
和strimzi-admin
集群角色。oc create -f install/strimzi-admin
如果需要,请为需要它们的用户分配提供访问权限的角色。
oc create clusterrolebinding strimzi-admin --clusterrole=strimzi-admin --user=user1 --user=user2
第 5 章 使用 Web 控制台从 OperatorHub 安装 AMQ Streams
在 OpenShift Container Platform Web 控制台中,从 OperatorHub 安装 AMQ Streams Operator。
本节中的步骤演示了如何:
5.1. 从 OperatorHub 安装 AMQ Streams Operator
您可以使用 OpenShift Container Platform Web 控制台中的 OperatorHub 安装并订阅 AMQ Streams Operator。
此流程描述了如何创建项目,并将 AMQ Streams Operator 安装到该项目中。项目是命名空间的表示。对于可管理性,最好使用命名空间来分隔功能。
确保使用正确的更新频道。如果您位于受支持的 OpenShift 版本,则默认 stable 频道安装 AMQ Streams 通常是安全的。但是,我们不推荐在 stable 频道中启用自动更新。自动升级将在升级前跳过所有必要的步骤。仅在特定于版本的频道中使用自动升级。
先决条件
-
使用具有
cluster-admin
或strimzi-admin
权限的账户访问 OpenShift Container Platform Web 控制台。
流程
在 OpenShift Web 控制台中进入到 Home > Projects 页面,再创建一个用于安装的项目(命名空间)。
在这个示例中,我们使用名为
amq-streams-kafka
的项目。- 进入 Operators > OperatorHub 页面。
在 Filter by keyword 框中滚动或输入关键字以查找 AMQ Streams operator。
operator 位于 Streaming 和 Messaging 目录中。
- 点 AMQ Streams 显示 Operator 信息。
- 阅读有关 Operator 的信息,再点 Install。
在 Install Operator 页面中,从以下安装和更新选项中选择:
更新频道 :选择 Operator 的更新频道。
- (默认) stable 频道包含所有最新的更新和发行版本,包括主版本、次版本和微版本,这些版本被认为经过充分测试和稳定。
- amq-streams-X.x 频道包含主发行版本的次要和微版本更新,其中 X 是主版本的版本号。
- amq-streams-X.Y.x 频道包含次要发行本版本的微版本更新,其中 X 是主版本的版本号,Y 是次版本号。
Installation Mode :选择您创建的项目,以便在特定命名空间中安装 Operator。
您可以将 AMQ Streams Operator 安装到集群中的所有命名空间(默认选项)或特定命名空间。我们建议您将特定命名空间专用于 Kafka 集群和其他 AMQ Streams 组件。
- 更新批准 :默认情况下,AMQ Streams Operator 由 Operator Lifecycle Manager (OLM)自动升级到最新的 AMQ Streams 版本。另外,如果您希望手动批准将来的升级,请选择 Manual。如需有关操作器的更多信息,请参阅 OpenShift 文档。
点 Install 将 Operator 安装到所选命名空间中。
AMQ Streams Operator 将 Cluster Operator、CRD 和基于角色的访问控制(RBAC)资源部署到所选命名空间中。
Operator 就绪可用后,进入 Operators > Installed Operators 来验证 Operator 是否已安装到所选命名空间中。
状态将显示为 Succeeded。
现在,您可以使用 AMQ Streams operator 部署 Kafka 组件,从 Kafka 集群开始。
如果您进入到 Workloads > Deployments,您可以查看 Cluster Operator 和 Entity Operator 的部署详情。Cluster Operator 的名称包含一个版本号:amq-streams-cluster-operator-<version>
。使用 AMQ Streams 安装工件部署 Cluster Operator 时的名称不同。在本例中,名称是 strimzi-cluster-operator
。
5.2. 使用 AMQ Streams operator 部署 Kafka 组件
在 Openshift 上安装时,AMQ Streams Operator 使 Kafka 组件可从用户界面安装。
以下 Kafka 组件可用于安装:
- Kafka
- Kafka Connect
- Kafka MirrorMaker
- Kafka MirrorMaker 2
- Kafka 主题
- Kafka 用户
- Kafka Bridge
- Kafka Connector
- Kafka Rebalance
您可以选择组件并创建实例。您至少创建一个 Kafka 实例。这个步骤描述了如何使用默认设置创建 Kafka 实例。您可以在执行安装前配置默认安装规格。
创建其他 Kafka 组件实例的过程相同。
先决条件
- AMQ Streams Operator 安装在 OpenShift 集群上。
流程
在 Web 控制台中导航到 Operators > ; Installed Operators 页面,然后点击 AMQ Streams 来显示 Operator 详情。
在 Provided APIs 中,您可以创建 Kafka 组件的实例。
点 Kafka 下的 Create instance 创建 Kafka 实例。
默认情况下,您将创建一个名为
my-cluster
的 Kafka 集群,它有三个 Kafka 代理节点和三个 ZooKeeper 节点。集群使用临时存储。点 Create 开始安装 Kafka。
等待状态变为 Ready。
第 6 章 使用安装工件部署 AMQ Streams
为部署 AMQ Streams 准备您的环境,您可以将 AMQ Streams 部署到 OpenShift 集群。使用由发行工件提供的安装文件。
AMQ Streams 基于 Strimzi 0.36.x。您可以将 AMQ Streams 2.5 在 OpenShift 4.10 上部署到 4.14。
使用安装文件部署 AMQ Streams 的步骤如下:
- 部署 Cluster Operator
使用 Cluster Operator 部署以下内容:
另外,还可根据要求部署以下 Kafka 组件:
要在本指南中运行命令,OpenShift 用户必须具有管理基于角色的访问控制(RBAC)和 CRD 的权限。
6.1. 基本部署路径
您可以设置一个部署,其中 AMQ Streams 管理同一命名空间中的单个 Kafka 集群。您可以使用此配置进行开发或测试。或者,您可以在生产环境中使用 AMQ Streams 来管理不同命名空间中的多个 Kafka 集群。
任何 AMQ Streams 部署的第一步是使用 install/cluster-operator
文件安装 Cluster Operator。
单个命令应用 cluster-operator
文件夹中的所有安装文件: oc apply -f ./install/cluster-operator
。
该命令设置您需要创建和管理 Kafka 部署的所有内容,包括:
-
Cluster Operator (
部署
、ConfigMap
) -
AMQ Streams CRD (
CustomResourceDefinition
) -
RBAC 资源(
ClusterRole
、ClusterRoleBinding
、RoleBinding
) -
Service account (
ServiceAccount
)
基本部署路径如下:
- 下载发行工件
- 创建用于部署 Cluster Operator 的 OpenShift 命名空间
-
更新
install/cluster-operator
文件,以使用为 Cluster Operator 创建的命名空间 - 安装 Cluster Operator 以监视一个、多个命名空间或所有命名空间
-
更新
- 创建 Kafka 集群
之后,您可以部署其他 Kafka 组件并设置对部署的监控。
6.2. 部署 Cluster Operator
Cluster Operator 负责在 OpenShift 集群中部署和管理 Kafka 集群。
当 Cluster Operator 运行时,它将开始监视 Kafka 资源的更新。
默认情况下,部署了 Cluster Operator 的单一副本。您可以使用领导选举机制添加副本,以便在出现问题时有其他 Cluster Operator 处于待机状态。如需更多信息,请参阅 第 8.5.3 节 “使用领导选举机制运行多个 Cluster Operator 副本”。
6.2.1. 指定 Cluster Operator 监视的命名空间
Cluster Operator 监视部署了 Kafka 资源的命名空间中的更新。部署 Cluster Operator 时,您可以指定要在 OpenShift 集群中监视的命名空间。您可以指定以下命名空间:
- 单个所选命名空间 (包含 Cluster Operator 的同一命名空间)
- 多个所选命名空间
- 集群中的所有命名空间
监视多个所选命名空间会因为增加处理开销而对性能有影响。要优化命名空间监控的性能,通常建议监视单个命名空间或监控整个集群。监控单个命名空间允许集中监控特定于命名空间的资源,而监控所有命名空间则提供所有命名空间中集群资源的全面视图。
Cluster Operator 监视对以下资源的更改:
-
Kafka
集群的 Kafka。 -
Kafka Connect 集群的
KafkaConnect
。 -
KafkaConnector
用于在 Kafka Connect 集群中创建和管理连接器。 -
Kafka MirrorMaker
实例的 KafkaMirrorMaker。 -
Kafka MirrorMaker 2 实例的
KafkaMirrorMaker2
。 -
Kafka Bridge 实例的
KafkaBridge
。 -
Cruise Control 优化请求的
KafkaRebalance
。
在 OpenShift 集群中创建其中一个资源时,Operator 会从资源获取集群描述,并通过创建必要的 OpenShift 资源(如 Deployment、Pod、服务和 ConfigMap)开始为资源创建新集群。
每次更新 Kafka 资源时,Operator 都会对为资源组成集群的 OpenShift 资源执行对应的更新。
资源会被修补或删除,然后重新创建,以便资源反映集群的所需状态。此操作可能会导致滚动更新可能会导致服务中断。
删除资源时,操作器会取消部署集群并删除所有相关 OpenShift 资源。
虽然 Cluster Operator 可以监控 OpenShift 集群中的一个、多个或所有命名空间,但主题 Operator 和 User Operator 会监视单个命名空间中的 KafkaTopic
和 KafkaUser
资源。如需更多信息,请参阅 第 1.2.1 节 “在 OpenShift 命名空间中观察 AMQ Streams 资源”。
6.2.2. 部署 Cluster Operator 以观察单个命名空间
此流程演示了如何部署 Cluster Operator 以监视 OpenShift 集群中的单个命名空间中的 AMQ Streams 资源。
先决条件
-
您需要具有权限的帐户来创建和管理
CustomResourceDefinition
和 RBAC (ClusterRole
和RoleBinding
)资源。
流程
编辑 AMQ Streams 安装文件,以使用 Cluster Operator 将安装到的命名空间。
例如,在此过程中,Cluster Operator 被安装到命名空间
my-cluster-operator-namespace
中。在 Linux 中,使用:
sed -i 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
在 MacOS 中,使用:
sed -i '' 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
部署 Cluster Operator:
oc create -f install/cluster-operator -n my-cluster-operator-namespace
检查部署的状态:
oc get deployments -n my-cluster-operator-namespace
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE strimzi-cluster-operator 1/1 1 1
READY
显示就绪/预期的副本数。当AVAILABLE
输出显示为1
时,部署成功。
6.2.3. 部署 Cluster Operator 以观察多个命名空间
此流程演示了如何部署 Cluster Operator,以便在 OpenShift 集群中的多个命名空间中监视 AMQ Streams 资源。
先决条件
-
您需要具有权限的帐户来创建和管理
CustomResourceDefinition
和 RBAC (ClusterRole
和RoleBinding
)资源。
流程
编辑 AMQ Streams 安装文件,以使用 Cluster Operator 将安装到的命名空间。
例如,在此过程中,Cluster Operator 被安装到命名空间
my-cluster-operator-namespace
中。在 Linux 中,使用:
sed -i 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
在 MacOS 中,使用:
sed -i '' 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
编辑
install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
文件,以添加 Cluster Operator 将监视到STRIMZI_NAMESPACE
环境变量的所有命名空间的列表。例如,在此过程中,Cluster Operator 会监视
watched-namespace-1
,watched-namespace-2
,watched-namespace-3
。apiVersion: apps/v1 kind: Deployment spec: # ... template: spec: serviceAccountName: strimzi-cluster-operator containers: - name: strimzi-cluster-operator image: registry.redhat.io/amq-streams/strimzi-rhel8-operator:2.5.1 imagePullPolicy: IfNotPresent env: - name: STRIMZI_NAMESPACE value: watched-namespace-1,watched-namespace-2,watched-namespace-3
对于列出的每个命名空间,请安装
RoleBindings
。在这个示例中,将这些命令的
watched-namespace
替换为在前一步中列出的命名空间,为watched-namespace-1
,watched-namespace-2
,watched-namespace-3
重复这个操作:oc create -f install/cluster-operator/020-RoleBinding-strimzi-cluster-operator.yaml -n <watched_namespace> oc create -f install/cluster-operator/023-RoleBinding-strimzi-cluster-operator.yaml -n <watched_namespace> oc create -f install/cluster-operator/031-RoleBinding-strimzi-cluster-operator-entity-operator-delegation.yaml -n <watched_namespace>
部署 Cluster Operator:
oc create -f install/cluster-operator -n my-cluster-operator-namespace
检查部署的状态:
oc get deployments -n my-cluster-operator-namespace
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE strimzi-cluster-operator 1/1 1 1
READY
显示就绪/预期的副本数。当AVAILABLE
输出显示为1
时,部署成功。
6.2.4. 部署 Cluster Operator 以监视所有命名空间
此流程演示了如何部署 Cluster Operator,以便在 OpenShift 集群中的所有命名空间中监视 AMQ Streams 资源。
在这个模式中运行时,Cluster Operator 会自动管理创建的任何新命名空间中的集群。
先决条件
-
您需要具有权限的帐户来创建和管理
CustomResourceDefinition
和 RBAC (ClusterRole
和RoleBinding
)资源。
流程
编辑 AMQ Streams 安装文件,以使用 Cluster Operator 将安装到的命名空间。
例如,在此过程中,Cluster Operator 被安装到命名空间
my-cluster-operator-namespace
中。在 Linux 中,使用:
sed -i 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
在 MacOS 中,使用:
sed -i '' 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
编辑
install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
文件,将STRIMZI_NAMESPACE
环境变量的值设置为sVirt
。apiVersion: apps/v1 kind: Deployment spec: # ... template: spec: # ... serviceAccountName: strimzi-cluster-operator containers: - name: strimzi-cluster-operator image: registry.redhat.io/amq-streams/strimzi-rhel8-operator:2.5.1 imagePullPolicy: IfNotPresent env: - name: STRIMZI_NAMESPACE value: "*" # ...
创建
ClusterRoleBindings
,为 Cluster Operator 为所有命名空间赋予集群范围的访问权限。oc create clusterrolebinding strimzi-cluster-operator-namespaced --clusterrole=strimzi-cluster-operator-namespaced --serviceaccount my-cluster-operator-namespace:strimzi-cluster-operator oc create clusterrolebinding strimzi-cluster-operator-watched --clusterrole=strimzi-cluster-operator-watched --serviceaccount my-cluster-operator-namespace:strimzi-cluster-operator oc create clusterrolebinding strimzi-cluster-operator-entity-operator-delegation --clusterrole=strimzi-entity-operator --serviceaccount my-cluster-operator-namespace:strimzi-cluster-operator
将 Cluster Operator 部署到 OpenShift 集群。
oc create -f install/cluster-operator -n my-cluster-operator-namespace
检查部署的状态:
oc get deployments -n my-cluster-operator-namespace
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE strimzi-cluster-operator 1/1 1 1
READY
显示就绪/预期的副本数。当AVAILABLE
输出显示为1
时,部署成功。
6.3. 部署 Kafka
为了可以使用 Cluster Operator 管理 Kafka 集群,您必须将它部署为 Kafka
资源。AMQ Streams 提供示例部署文件来执行此操作。您可以使用这些文件同时部署主题 Operator 和 User Operator。
部署 Cluster Operator 后,使用 Kafka
资源来部署以下组件:
安装 Kafka 时,AMQ Streams 还会安装 ZooKeeper 集群并添加将 Kafka 与 ZooKeeper 连接所需的配置。
如果要尝试节点池功能的预览,您可以使用一个或多个节点池部署 Kafka 集群。节点池为一组 Kafka 节点提供配置。通过使用节点池,节点可以在同一 Kafka 集群中有不同的配置。
节点池不会被默认启用,因此您必须在使用 KafkaNodePools 功能门前启用 KafkaNodePools
功能门。
如果您还没有将 Kafka 集群部署为 Kafka
资源,则无法使用 Cluster Operator 管理它。例如,这会应用到在 OpenShift 外部运行的 Kafka 集群。但是,您可以通过将其 部署为独立组件,使用 Topic Operator 和 User Operator 及 不是由 AMQ Streams 管理的 Kafka 集群。您还可以将其他 Kafka 组件与不是由 AMQ Streams 管理的 Kafka 集群部署并使用。
6.3.1. 部署 Kafka 集群
此流程演示了如何使用 Cluster Operator 将 Kafka 集群部署到 OpenShift 集群。
部署使用 YAML 文件来提供规格来创建 Kafka
资源。
AMQ Streams 提供以下示例 文件来创建 Kafka 集群:
kafka-persistent.yaml
- 使用三个 ZooKeeper 和三个 Kafka 节点部署持久集群。
kafka-jbod.yaml
- 部署具有三个 ZooKeeper 和三个 Kafka 节点的持久集群(每个都使用多个持久性卷)。
kafka-persistent-single.yaml
- 使用单个 ZooKeeper 节点和一个 Kafka 节点部署持久集群。
kafka-ephemeral.yaml
- 使用三个 ZooKeeper 和三个 Kafka 节点部署临时集群。
kafka-ephemeral-single.yaml
- 使用三个 ZooKeeper 节点和一个 Kafka 节点部署临时集群。
在此过程中,我们对 ephemeral(临时)和persistent(持久) Kafka 集群部署使用示例。
- 临时集群
-
通常,临时(或临时)Kafka 集群适合开发和测试目的,不适用于生产环境。此部署使用
emptyDir
卷来存储代理信息(用于 ZooKeeper)和主题或分区(用于 Kafka)。使用emptyDir
卷意味着其内容严格与 pod 生命周期相关,并在 pod 停机时被删除。 - 持久性集群
持久的 Kafka 集群使用持久性卷来存储 ZooKeeper 和 Kafka 数据。使用
PersistentVolumeClaim
获取PersistentVolume
,使其独立于PersistentVolume
的实际类型。PersistentVolumeClaim
可以使用StorageClass
来触发自动卷置备。如果没有指定StorageClass
,OpenShift 将尝试使用默认StorageClass
。以下示例显示了一些常见的持久性卷类型:
- 如果您的 OpenShift 集群在 Amazon AWS 上运行,OpenShift 可以置备 Amazon EBS 卷
- 如果您的 OpenShift 集群在 Microsoft Azure 上运行,OpenShift 可以置备 Azure Disk Storage 卷
- 如果您的 OpenShift 集群在 Google Cloud 上运行,OpenShift 可以置备 Persistent Disk 卷
- 如果您的 OpenShift 集群在裸机上运行,OpenShift 可以置备本地持久性卷
YAML 文件示例指定最新支持的 Kafka 版本,以及其支持的日志消息格式版本和 inter-broker 协议版本的配置。Kafka config
的 inter.broker.protocol.version
属性必须是指定的 Kafka 版本 (spec.kafka.version
) 支持的版本。属性表示 Kafka 集群中使用的 Kafka 协议版本。
从 Kafka 3.0.0 开始,当将 inter.broker.protocol.version
设置为 3.0
或更高版本时,log.message.format.version
选项将被忽略,不需要设置。
在升级 Kafka 时,需要对 inter.broker.protocol.version
的更新。
示例集群默认命名为 my-cluster
。集群名称由资源名称定义,在部署集群后无法更改。要在部署集群前更改集群名称,请编辑相关 YAML 文件中的 Kafka
资源的 Kafka.metadata.name
属性。
默认集群名称和指定的 Kafka 版本
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: version: 3.5.0 #... config: #... log.message.format.version: "3.5" inter.broker.protocol.version: "3.5" # ...
流程
创建并部署临时或持久集群。
创建和部署临时集群:
oc apply -f examples/kafka/kafka-ephemeral.yaml
创建和部署持久集群:
oc apply -f examples/kafka/kafka-persistent.yaml
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示 pod 名称和就绪状态
NAME READY STATUS RESTARTS my-cluster-entity-operator 3/3 Running 0 my-cluster-kafka-0 1/1 Running 0 my-cluster-kafka-1 1/1 Running 0 my-cluster-kafka-2 1/1 Running 0 my-cluster-zookeeper-0 1/1 Running 0 my-cluster-zookeeper-1 1/1 Running 0 my-cluster-zookeeper-2 1/1 Running 0
my-cluster
是 Kafka 集群的名称。从
0
开始的连续索引号标识每个 Kafka 和 ZooKeeper pod。使用默认部署,您可以创建一个 Entity Operator 集群、3 个 Kafka pod 和 3 ZooKeeper pod。
READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。
其他资源
6.3.2. (预览)部署 Kafka 节点池
此流程演示了如何使用 Cluster Operator 将 Kafka 节点池部署到 OpenShift 集群。节点池代表 Kafka 集群中共享相同配置的 Kafka 节点组。对于节点池中的每个 Kafka 节点,节点池中没有定义的任何配置都会继承 kafka
资源中的集群配置。
节点池功能作为技术预览提供。节点池不会被默认启用,因此您必须在使用 KafkaNodePools 功能门前启用 KafkaNodePools
功能门。
部署使用 YAML 文件来提供规格来创建 KafkaNodePool
资源。您可以将节点池与 Kafka 集群一起使用,该集群使用 KRaft (Kafka Raft metadata)模式或 ZooKeeper 进行集群管理。
KRaft 模式在 Apache Kafka 或 AMQ Streams 中不适用于生产环境。
AMQ Streams 提供以下 示例文件,您可以使用它来创建 Kafka 节点池:
kafka.yaml
- 使用 3 个节点和 2 个不同的 Kafka 代理池部署 ZooKeeper。每个池都有 3 个代理。示例中的池使用不同的存储配置。
kafka-with-dual-role-kraft-nodes.yaml
- 使用共享代理和控制器角色的 KRaft 节点池部署 Kafka 集群。
kafka-with-kraft.yaml
- 部署 Kafka 集群,具有一个控制器节点池和一个代理节点池。
您不需要立即开始使用节点池。如果您决定使用它们,您可以执行此处概述的步骤,以使用 KafkaNodePool
资源部署新的 Kafka 集群,或 迁移现有的 Kafka 集群。
如果要将现有 Kafka 集群迁移到使用节点池,请参阅 迁移现有 Kafka 集群的步骤。
流程
从命令行启用
KafkaNodePools
功能门:oc set env deployment/strimzi-cluster-operator STRIMZI_FEATURE_GATES="+KafkaNodePools"
或者,通过编辑 Cluster Operator Deployment 并更新
STRIMZI_FEATURE_GATES
环境变量:env - name: STRIMZI_FEATURE_GATES value: +KafkaNodePools
这会更新 Cluster Operator。
如果使用 KRaft 模式,还要启用
UseKRaft
功能门。创建节点池。
使用三个代理的两个节点池部署 Kafka 集群和 ZooKeeper 集群:
oc apply -f examples/kafka/nodepools/kafka.yaml
使用使用 dual-role 节点的单一节点池,以 KRaft 模式部署 Kafka 集群:
oc apply -f examples/kafka/nodepools/kafka-with-dual-role-kraft-nodes.yaml
使用 KRaft 模式部署 Kafka 集群,对于代理和控制节点有独立的节点池,:
oc apply -f examples/kafka/nodepools/kafka-with-kraft.yaml
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示节点池名称和就绪
NAME READY STATUS RESTARTS my-cluster-entity-operator 3/3 Running 0 my-cluster-pool-a-kafka-0 1/1 Running 0 my-cluster-pool-a-kafka-1 1/1 Running 0 my-cluster-pool-a-kafka-4 1/1 Running 0
-
my-cluster
是 Kafka 集群的名称。 pool-a
是节点池的名称。以
0
开始的连续索引号标识每个创建的 Kafka pod。如果使用 ZooKeeper,您还会看到 ZooKeeper pod。READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。有关部署的信息也会显示在
KafkaNodePool
资源的状态中,包括池中节点的 ID 列表。注意节点 ID 按顺序分配自集群中所有节点池中的 0 (零)。这意味着节点 ID 可能无法在特定节点池中按顺序运行。如果集群中节点 ID 序列出现差距,则会为要添加的下一个节点分配一个填充空白的 ID。缩减时,池中具有最高节点 ID 的节点会被删除。
-
其他资源
6.3.3. 使用 Cluster Operator 部署主题 Operator
此流程描述了如何使用 Cluster Operator 部署主题 Operator。可以部署主题 Operator 以在双向模式或单向模式中使用。要了解更多有关双向和单向主题管理的信息,请参阅 第 9.1 节 “主题管理模式”。
单向主题管理作为技术预览提供。默认情况下,不启用单向主题管理,因此您必须 启用 UnidirectionalTopicOperator
功能门 才能使用它。
您可以将 Kafka
资源的 entityOperator
属性配置为包含 topicOperator
。默认情况下,Topic Operator 会监视 Cluster Operator 部署的 Kafka 集群命名空间中的 KafkaTopic
资源。您还可以使用 Topic Operator spec
中的 watchedNamespace
指定一个命名空间。单个主题 Operator 可以监视单个命名空间。一个命名空间应该只被一个主题 Operator 监视。
如果您使用 AMQ Streams 将多个 Kafka 集群部署到同一命名空间中,请只为一个 Kafka 集群启用 Topic Operator,或使用 watchedNamespace
属性配置 Topic Operator 以监视其他命名空间。
如果要将 Topic Operator 与不是由 AMQ Streams 管理的 Kafka 集群搭配使用,您必须将 Topic Operator 部署为独立组件。
有关配置 entityOperator
和 topicOperator
属性的更多信息,请参阅配置 Entity Operator。
流程
编辑
Kafka
资源的entityOperator
属性,使其包含topicOperator
:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: #... entityOperator: topicOperator: {} userOperator: {}
使用
EntityTopicOperatorSpec
schema reference 中所述的属性配置 Topic Operatorspec
。如果您希望所有属性使用默认值,请使用空对象(
{}
)。创建或更新资源:
oc apply -f <kafka_configuration_file>
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示 pod 名称和就绪度
NAME READY STATUS RESTARTS my-cluster-entity-operator 3/3 Running 0 # ...
my-cluster
是 Kafka 集群的名称。READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。
6.3.4. 使用 Cluster Operator 部署 User Operator
此流程描述了如何使用 Cluster Operator 部署 User Operator。
您可以将 Kafka
资源的 entityOperator
属性配置为包含 userOperator
。默认情况下,User Operator 会监视 Kafka 集群部署命名空间中的 KafkaUser
资源。您还可以使用 User Operator spec
中的 watchedNamespace
指定命名空间。单个用户 Operator 可以监视单个命名空间。一个命名空间应该只被一个 User Operator 监视。
如果要将 User Operator 与不是由 AMQ Streams 管理的 Kafka 集群搭配使用,您必须将 User Operator 部署为独立组件。
有关配置 entityOperator
和 userOperator
属性的更多信息,请参阅配置 Entity Operator。
流程
编辑
Kafka
资源的entityOperator
属性,使其包含userOperator
:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: #... entityOperator: topicOperator: {} userOperator: {}
使用
EntityUserOperatorSpec
schema reference 中所述的属性配置 User Operatorspec
。如果您希望所有属性使用默认值,请使用空对象(
{}
)。创建或更新资源:
oc apply -f <kafka_configuration_file>
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示 pod 名称和就绪度
NAME READY STATUS RESTARTS my-cluster-entity-operator 3/3 Running 0 # ...
my-cluster
是 Kafka 集群的名称。READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。
6.3.5. Kafka 集群资源列表
以下资源由 OpenShift 集群中的 Cluster Operator 创建:
共享资源
cluster-name-cluster-ca
- 带有用于加密集群通信的 Cluster CA 私钥的 secret。
cluster-name-cluster-ca-cert
- 带有集群 CA 公钥的 secret。此密钥可用于验证 Kafka 代理的身份。
cluster-name-clients-ca
- 带有用于签署用户证书的 Clients CA 私钥的 secret
cluster-name-clients-ca-cert
- 带有客户端 CA 公钥的 secret。此密钥可用于验证 Kafka 用户的身份。
cluster-name-cluster-operator-certs
- 带有 Cluster operator 密钥的 secret,用于与 Kafka 和 ZooKeeper 通信。
Zookeeper 节点
cluster-name-zookeeper
提供给以下 ZooKeeper 资源的名称:
- 用于管理 ZooKeeper 节点 pod 的 StrimziPodSet。
- ZooKeeper 节点使用的服务帐户。
- 为 ZooKeeper 节点配置 PodDisruptionBudget。
cluster-name-zookeeper-idx
- StrimziPodSet 创建的 Pod。
cluster-name-zookeeper-nodes
- 无头服务需要使 DNS 直接解析 ZooKeeper pod IP 地址。
cluster-name-zookeeper-client
- Kafka 代理使用的服务作为客户端连接到 ZooKeeper 节点。
cluster-name-zookeeper-config
- 包含 ZooKeeper 辅助配置的 ConfigMap,由 ZooKeeper 节点 pod 挂载为卷。
cluster-name-zookeeper-nodes
- 使用 ZooKeeper 节点密钥的 secret。
cluster-name-network-policy-zookeeper
- 网络策略管理对 ZooKeeper 服务的访问。
data-cluster-name-zookeeper-idx
-
用于为 ZooKeeper 节点 pod
idx
存储数据的卷的持久性卷声明。只有在选择了持久性存储来存储数据时,才会创建此资源。
Kafka 代理
cluster-name-kafka
提供给以下 Kafka 资源的名称:
- 用于管理 Kafka 代理 pod 的 StrimziPodSet。
- Kafka pod 使用的服务帐户。
- 为 Kafka 代理配置 PodDisruptionBudget。
cluster-name-kafka-idx
提供给以下 Kafka 资源的名称:
- StrimziPodSet 创建的 Pod。
- 带有 Kafka 代理配置的 ConfigMap。
cluster-name-kafka-brokers
- 服务需要 DNS 解析 Kafka 代理 pod IP 地址。
cluster-name-kafka-bootstrap
- 服务可用作从 OpenShift 集群内连接的 Kafka 客户端的 bootstrap 服务器。
cluster-name-kafka-external-bootstrap
-
从 OpenShift 集群外部连接的客户端的 bootstrap 服务。只有在启用外部监听程序时,才会创建此资源。当监听器名称为
external
且端口为9094
时,旧的服务名称将用于向后兼容。 cluster-name-kafka-pod-id
-
用于将流量从 OpenShift 集群外部路由到各个容器集的服务。只有在启用外部监听程序时,才会创建此资源。当监听器名称为
external
且端口为9094
时,旧的服务名称将用于向后兼容。 cluster-name-kafka-external-bootstrap
-
从 OpenShift 集群外部连接的客户端的 bootstrap 路由。只有在启用了外部监听程序并设置为 type
路由
时,才会创建此资源。当监听器名称为external
且端口为9094
时,旧的路由名称将用于向后兼容。 cluster-name-kafka-pod-id
-
将来自 OpenShift 集群外的流量路由到各个容器集。只有在启用了外部监听程序并设置为 type
路由
时,才会创建此资源。当监听器名称为external
且端口为9094
时,旧的路由名称将用于向后兼容。 cluster-name-kafka-listener-name-bootstrap
- 从 OpenShift 集群外部连接的客户端的 bootstrap 服务。只有在启用外部监听程序时,才会创建此资源。新的服务名称将用于所有其他外部监听程序。
cluster-name-kafka-listener-name-pod-id
- 用于将流量从 OpenShift 集群外部路由到各个容器集的服务。只有在启用外部监听程序时,才会创建此资源。新的服务名称将用于所有其他外部监听程序。
cluster-name-kafka-listener-name-bootstrap
-
从 OpenShift 集群外部连接的客户端的 bootstrap 路由。只有在启用了外部监听程序并设置为 type
路由
时,才会创建此资源。新路由名称将用于所有其他外部监听程序。 cluster-name-kafka-listener-name-pod-id
-
将来自 OpenShift 集群外的流量路由到各个容器集。只有在启用了外部监听程序并设置为 type
路由
时,才会创建此资源。新路由名称将用于所有其他外部监听程序。 cluster-name-kafka-config
-
包含 Kafka 辅助配置的 ConfigMap,当禁用
UseStrimziPodSets
功能门时,代理 pod 会作为卷挂载。 cluster-name-kafka-brokers
- 带有 Kafka 代理密钥的 secret。
cluster-name-network-policy-kafka
- 网络策略管理对 Kafka 服务的访问。
strimzi-namespace-name-cluster-name-kafka-init
- Kafka 代理使用的集群角色绑定。
cluster-name-jmx
- 带有 JMX 用户名和密码的 secret,用于保护 Kafka 代理端口。只有在 Kafka 中启用 JMX 时,才会创建此资源。
data-cluster-name-kafka-idx
-
用于存储 Kafka 代理 pod
idx
数据的卷的持久性卷声明。只有选择了持久性存储来存储数据时,才会创建此资源。 data-id-cluster-name-kafka-idx
-
卷
id
的持久性卷声明用于存储 Kafka 代理 podidx
的数据。只有在置备持久性卷来存储数据时,才会为 JBOD 卷选择持久性存储来创建此资源。
Entity Operator
只有在使用 Cluster Operator 部署 Entity Operator 时,才会创建这些资源。
cluster-name-entity-operator
提供给以下实体 Operator 资源的名称:
- 使用主题和用户 Operator 部署。
- Entity Operator 使用的服务帐户。
- 网络策略管理对实体 Operator 指标的访问。
cluster-name-entity-operator-random-string
- 由实体 Operator 部署创建的 Pod。
cluster-name-entity-topic-operator-config
- 带有主题 Operator 的辅助配置的 ConfigMap。
cluster-name-entity-user-operator-config
- 带有用户 Operator 的辅助配置的 ConfigMap。
cluster-name-entity-topic-operator-certs
- 带有主题 Operator 密钥的 secret,用于与 Kafka 和 ZooKeeper 通信。
cluster-name-entity-user-operator-certs
- 带有用户 Operator 密钥的 secret,用于与 Kafka 和 ZooKeeper 通信。
strimzi-cluster-name-entity-topic-operator
- Entity Topic Operator 使用的角色绑定。
strimzi-cluster-name-entity-user-operator
- Entity User Operator 使用的角色绑定。
Kafka Exporter
只有在使用 Cluster Operator 部署 Kafka Exporter 时,才会创建这些资源。
cluster-name-kafka-exporter
提供给以下 Kafka 导出器资源的名称:
- 使用 Kafka 导出器进行部署。
- 用于收集消费者滞后指标的服务。
- Kafka Exporter 使用的服务帐户。
- 网络策略用于管理对 Kafka 导出器指标的访问。
cluster-name-kafka-exporter-random-string
- 由 Kafka Exporter 部署创建的 Pod。
Sything Control
只有在使用 Cluster Operator 部署 Cruise Control 时,才会创建这些资源。
cluster-name-cruise-control
给定以下 Cruise 控制资源的名称:
- 使用 Cruise Control 部署。
- 用于与 Cruise Control 进行通信的服务。
- Cruise Control 使用的服务帐户。
cluster-name-cruise-control-random-string
- 由 Cruise Control 部署创建的 Pod。
cluster-name-cruise-control-config
- 包含 Cruise Control 辅助配置的 ConfigMap,并由 Cruise Control pod 挂载为卷。
cluster-name-cruise-control-certs
- 带有 Cruise Control 密钥的 secret,用于与 Kafka 和 ZooKeeper 通信。
cluster-name-network-policy-cruise-control
- 网络策略管理对 Cruise Control 服务的访问。
6.4. 部署 Kafka 连接
Kafka Connect 是一个使用连接器插件在 Kafka 代理和其他系统间流传输数据的集成工具包。Kafka Connect 提供了一个框架,用于将 Kafka 与外部数据源或目标(如数据库或消息传递系统)集成,用于使用连接器导入或导出数据。连接器是提供所需的连接配置的插件。
在 AMQ Streams 中,Kafka Connect 部署为分布式模式。Kafka Connect 也可以以独立模式工作,但 AMQ Streams 不支持它。
使用 连接器 的概念,Kafka Connect 提供了一个框架,用于将大量数据移到 Kafka 集群中,同时保持可扩展性和可靠性。
Cluster Operator 管理使用 KafkaConnector 资源部署的 Kafka Connect
集群,以及利用 KafkaConnector
资源创建的连接器。
要使用 Kafka Connect,您需要执行以下操作。
术语 连接器 会互换使用,以表示在 Kafka Connect 集群或连接器类中运行的连接器实例。在本指南中,当含义从上下文中清除时,会使用术语 连接器。
6.4.1. 将 Kafka Connect 部署到 OpenShift 集群
此流程演示了如何使用 Cluster Operator 将 Kafka Connect 集群部署到 OpenShift 集群。
Kafka Connect 集群部署使用可配置的节点数(也称为 worker),将连接器工作负载作为 任务 分发,以便消息流高度可扩展且可靠。
部署使用 YAML 文件来提供规格来创建 KafkaConnect
资源。
AMQ Streams 提供 示例配置文件。在此过程中,我们使用以下示例文件:
-
examples/connect/kafka-connect.yaml
流程
部署 Kafka 连接到 OpenShift 集群。使用
examples/connect/kafka-connect.yaml
文件来部署 Kafka Connect。oc apply -f examples/connect/kafka-connect.yaml
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示部署名称和就绪度
NAME READY STATUS RESTARTS my-connect-cluster-connect-<pod_id> 1/1 Running 0
my-connect-cluster
是 Kafka Connect 集群的名称。pod ID 标识创建的每个 pod。
使用默认部署,您可以创建一个 Kafka Connect pod。
READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。
其他资源
6.4.2. 为多个实例配置 Kafka 连接
如果您运行多个 Kafka Connect 实例,您必须更改以下配置属性 的默认配置
:
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect spec: # ... config: group.id: connect-cluster 1 offset.storage.topic: connect-cluster-offsets 2 config.storage.topic: connect-cluster-configs 3 status.storage.topic: connect-cluster-status 4 # ... # ...
对于具有相同 group.id
的所有 Kafka Connect 实例,这三个主题的值必须相同。
除非更改默认设置,否则每个连接到同一 Kafka 集群的 Kafka Connect 实例都使用相同的值部署。实际上,所有实例都是在集群中运行并使用相同的主题的所有实例。
如果多个 Kafka Connect 集群尝试使用相同的主题,Kafka Connect 将无法正常工作,并生成错误。
如果要运行多个 Kafka Connect 实例,请更改每个实例的这些属性值。
6.4.3. 添加连接器
Kafka Connect 使用连接器与其他系统集成来流传输数据。连接器是 Kafka Connector
类的实例,可以是以下类型之一:
- 源连接器
- 源连接器是一个运行时实体,它从外部系统获取数据并将其传送到 Kafka 作为信息。
- sink 连接器
- sink 连接器是一个运行时实体,它从 Kafka 主题获取信息并将其传送到外部系统。
Kafka Connect 使用插件架构为连接器提供实施工件。插件允许连接到其他系统,并提供额外的配置来操作数据。插件包括连接器和其他组件,如数据转换器和转换。连接器使用特定类型的外部系统运行。每个连接器都定义了其配置架构。您提供到 Kafka Connect 的配置,以在 Kafka Connect 中创建连接器实例。然后,连接器实例定义了一组用于在系统之间移动数据的任务。
使用以下方法之一将连接器插件添加到 Kafka Connect 中:
将插件添加到容器镜像后,您可以使用以下方法启动、停止和管理连接器实例:
您还可以使用这些选项创建新的连接器实例。
6.4.3.1. 自动使用连接器插件构建新容器镜像
配置 Kafka Connect,以便 AMQ Streams 会自动使用额外的连接器构建新容器镜像。您可以使用 KafkaConnect
自定义资源的 .spec.build.plugins
属性定义连接器插件。AMQ Streams 将自动下载连接器插件并将其添加到新容器镜像中。容器被推送到 .spec.build.output
中指定的容器存储库中,并在 Kafka Connect 部署中自动使用。
先决条件
- 必须部署 Cluster Operator。
- 容器 registry。
您需要提供自己的容器 registry,其中可将镜像推送到、存储和拉取镜像。AMQ Streams 支持私有容器 registry 以及公共 registry,如 Quay 或 Docker Hub。
流程
通过在
.spec.build.output
中指定容器 registry 来配置KafkaConnect
自定义资源,并在.spec.build.plugins
中指定其他连接器:apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster spec: 1 #... build: output: 2 type: docker image: my-registry.io/my-org/my-connect-cluster:latest pushSecret: my-registry-credentials plugins: 3 - name: debezium-postgres-connector artifacts: - type: tgz url: https://repo1.maven.org/maven2/io/debezium/debezium-connector-postgres/2.1.3.Final/debezium-connector-postgres-2.1.3.Final-plugin.tar.gz sha512sum: c4ddc97846de561755dc0b021a62aba656098829c70eb3ade3b817ce06d852ca12ae50c0281cc791a5a131cb7fc21fb15f4b8ee76c6cae5dd07f9c11cb7c6e79 - name: camel-telegram artifacts: - type: tgz url: https://repo.maven.apache.org/maven2/org/apache/camel/kafkaconnector/camel-telegram-kafka-connector/0.11.5/camel-telegram-kafka-connector-0.11.5-package.tar.gz sha512sum: d6d9f45e0d1dbfcc9f6d1c7ca2046168c764389c78bc4b867dab32d24f710bb74ccf2a007d7d7a8af2dfca09d9a52ccbc2831fc715c195a3634cca055185bd91 #...
创建或更新资源:
$ oc apply -f <kafka_connect_configuration_file>
- 等待新容器镜像构建,并且部署 Kafka Connect 集群。
-
使用 Kafka Connect REST API 或
KafkaConnector
自定义资源使用您添加的连接器插件。
6.4.3.2. 使用 Kafka Connect 基础镜像中的连接器插件构建新容器镜像
使用 Kafka Connect 基础镜像中的连接器插件创建自定义 Docker 镜像,将自定义镜像添加到 /opt/kafka/plugins
目录中。
您可以使用 Red Hat Ecosystem Catalog 上的 Kafka 容器镜像作为基础镜像,使用额外的连接器插件创建自己的自定义镜像。
在启动时,Kafka Connect 的 AMQ Streams 版本会加载 /opt/kafka/plugins
目录中包含的任何第三方连接器插件。
流程
使用
registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1
作为基础镜像,创建一个新的Dockerfile
:FROM registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 USER root:root COPY ./my-plugins/ /opt/kafka/plugins/ USER 1001
插件文件示例
$ tree ./my-plugins/ ./my-plugins/ ├── debezium-connector-mongodb │ ├── bson-<version>.jar │ ├── CHANGELOG.md │ ├── CONTRIBUTE.md │ ├── COPYRIGHT.txt │ ├── debezium-connector-mongodb-<version>.jar │ ├── debezium-core-<version>.jar │ ├── LICENSE.txt │ ├── mongodb-driver-core-<version>.jar │ ├── README.md │ └── # ... ├── debezium-connector-mysql │ ├── CHANGELOG.md │ ├── CONTRIBUTE.md │ ├── COPYRIGHT.txt │ ├── debezium-connector-mysql-<version>.jar │ ├── debezium-core-<version>.jar │ ├── LICENSE.txt │ ├── mysql-binlog-connector-java-<version>.jar │ ├── mysql-connector-java-<version>.jar │ ├── README.md │ └── # ... └── debezium-connector-postgres ├── CHANGELOG.md ├── CONTRIBUTE.md ├── COPYRIGHT.txt ├── debezium-connector-postgres-<version>.jar ├── debezium-core-<version>.jar ├── LICENSE.txt ├── postgresql-<version>.jar ├── protobuf-java-<version>.jar ├── README.md └── # ...
COPY 命令指向要复制到容器镜像的插件文件。
本例为 Debezium 连接器(MongoDB、MySQL 和 PostgreSQL)添加了插件,但并非所有文件都被列为 brevity。在 Kafka Connect 中运行的 Debezium 与任何其他 Kafka Connect 任务相同。
- 构建容器镜像。
- 将自定义镜像推送到容器 registry。
指向新容器镜像。
您可以使用以下方法之一指向镜像:
编辑
KafkaConnect
自定义资源的KafkaConnect.spec.image
属性。如果设置,此属性会覆盖 Cluster Operator 中的
STRIMZI_KAFKA_CONNECT_IMAGES
环境变量。apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster spec: 1 #... image: my-new-container-image 2 config: 3 #...
-
编辑
install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
文件中的STRIMZI_KAFKA_CONNECT_IMAGES
环境变量,然后重新安装 Cluster Operator。
6.4.3.3. 部署 KafkaConnector 资源
部署 KafkaConnector
资源来管理连接器。KafkaConnector
自定义资源提供了一种 OpenShift 原生方法来管理 Cluster Operator 连接器。您不需要发送 HTTP 请求来管理连接器,就像 Kafka Connect REST API 一样。您可以通过更新对应的 KafkaConnector
资源来管理正在运行的连接器实例,然后应用更新。Cluster Operator 更新正在运行的连接器实例的配置。您可以通过删除对应的 KafkaConnector
来删除连接器。
KafkaConnector
资源必须部署到与其链接到的 Kafka Connect 集群相同的命名空间中。
在此过程中显示的配置中,autoRestart
属性被设置为 true
。这可让自动重启失败的连接器和任务。最多进行 7 个重启尝试,之后必须手动重新启动。您可以注解 KafkaConnector
资源来 重启连接器 或 手动重启连接器任务。
连接器示例
您可以使用您自己的连接器,或尝试 AMQ Streams 提供的示例。直到 Apache Kafka 3.1.0 之前,Apache Kafka 中包含文件连接器插件示例。从 Apache Kafka 的 3.1.1 和 3.2.0 版本开始,需要将示例 添加到插件路径中,作为任何其他连接器。
AMQ Streams 为示例文件连接器插件提供了一个 示例 KafkaConnector
配置文件 (examples/connect/source-connector.yaml
) ,它会创建以下连接器实例作为 KafkaConnector
资源:
-
从 Kafka 许可证文件(源)读取每行的
FileStreamSourceConnector
实例,并将数据作为信息写入单个 Kafka 主题。 -
从 Kafka 主题读取消息的
FileStreamSinkConnector
实例,并将信息写入临时文件(接收器)。
我们使用此流程使用示例文件创建连接器。
示例连接器不应在生产环境中使用。
先决条件
- Kafka Connect 部署
- Cluster Operator 正在运行
流程
使用以下方法之一将
FileStreamSourceConnector
和FileStreamSinkConnector
插件添加到 Kafka Connect 中:在 Kafka Connect 配置中,将
strimzi.io/use-connector-resources 注解设置为
true
。apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster annotations: strimzi.io/use-connector-resources: "true" spec: # ...
启用
KafkaConnector
资源后,Cluster Operator 会监视它们。编辑
examples/connect/source-connector.yaml
文件:apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-source-connector 1 labels: strimzi.io/cluster: my-connect-cluster 2 spec: class: org.apache.kafka.connect.file.FileStreamSourceConnector 3 tasksMax: 2 4 autoRestart: 5 enabled: true config: 6 file: "/opt/kafka/LICENSE" 7 topic: my-topic 8 # ...
- 1
KafkaConnector
资源的名称,用作连接器的名称。使用对 OpenShift 资源有效的任何名称。- 2
- 在其中创建连接器实例的 Kafka Connect 集群的名称。连接器必须部署到它们所链接的 Kafka Connect 集群相同的命名空间中。
- 3
- 连接器类的完整名称或别名。这应该存在于 Kafka Connect 集群使用的镜像中。
- 4
- 连接器可创建的最大 Kafka Connect 任务数量。
- 5
- 启用自动重启失败的连接器和任务。
- 6
- 连接器配置 作为键值对。
- 7
- 这个示例源连接器配置从
/opt/kafka/LICENSE
文件中读取数据。 - 8
- 将源数据发布到的 Kafka 主题。
在 OpenShift 集群中创建源
KafkaConnector
:oc apply -f examples/connect/source-connector.yaml
创建
examples/connect/sink-connector.yaml
文件:touch examples/connect/sink-connector.yaml
将以下 YAML 粘贴到
sink-connector.yaml
文件中:apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-sink-connector labels: strimzi.io/cluster: my-connect spec: class: org.apache.kafka.connect.file.FileStreamSinkConnector 1 tasksMax: 2 config: 2 file: "/tmp/my-file" 3 topics: my-topic 4
在 OpenShift 集群中创建 sink
KafkaConnector
:oc apply -f examples/connect/sink-connector.yaml
检查是否创建了连接器资源:
oc get kctr --selector strimzi.io/cluster=<my_connect_cluster> -o name my-source-connector my-sink-connector
将 <my_connect_cluster> 替换为 Kafka Connect 集群的名称。
在容器中,执行
kafka-console-consumer.sh
来读取源连接器写入主题的消息:oc exec <my_kafka_cluster>-kafka-0 -i -t -- bin/kafka-console-consumer.sh --bootstrap-server <my_kafka_cluster>-kafka-bootstrap.NAMESPACE.svc:9092 --topic my-topic --from-beginning
将 <my_kafka_cluster> 替换为 Kafka 集群的名称。
源和接收器连接器配置选项
连接器配置在 KafkaConnector
资源的 spec.config
属性中定义。
FileStreamSourceConnector
和 FileStreamSinkConnector
类支持与 Kafka Connect REST API 相同的配置选项。其他连接器支持不同的配置选项。
名称 | 类型 | 默认值 | Description |
---|---|---|---|
| 字符串 | null | 要写入消息的源文件。如果没有指定,则使用标准输入。 |
| list | null | 将数据发布到的 Kafka 主题。 |
名称 | 类型 | 默认值 | Description |
---|---|---|---|
| 字符串 | null | 要写入消息的目标文件。如果没有指定,则使用标准输出。 |
| list | null | 从中读取数据的一个或多个 Kafka 主题。 |
| 字符串 | null | 与一个或多个 Kafka 主题匹配的正则表达式,以便从中读取数据。 |
6.4.3.4. 手动重启连接器
如果您使用 KafkaConnector
资源来管理连接器,请使用 restart
注解来手动触发连接器重启。
先决条件
- Cluster Operator 正在运行。
流程
查找控制您要重启的 Kafka 连接器的
KafkaConnector
自定义资源的名称:oc get KafkaConnector
通过在 OpenShift 中注解
KafkaConnector
资源来重启连接器。oc annotate KafkaConnector <kafka_connector_name> strimzi.io/restart=true
restart
注解设置为true
。等待下一个协调发生(默认为两分钟)。
Kafka 连接器会重启,只要协调过程检测到注解。当 Kafka Connect 接受重启请求时,注解会从
KafkaConnector
自定义资源中删除。
6.4.3.5. 手动重启 Kafka 连接器任务
如果您使用 KafkaConnector
资源来管理连接器,请使用 restart-task
注解来手动触发连接器任务的重启。
先决条件
- Cluster Operator 正在运行。
流程
查找控制您要重启的 Kafka 连接器任务的
KafkaConnector
自定义资源的名称:oc get KafkaConnector
从
KafkaConnector
自定义资源查找要重启的任务 ID。任务 ID 是非负整数,从 0 开始:oc describe KafkaConnector <kafka_connector_name>
通过在 OpenShift 中注解
KafkaConnector
资源,使用 ID 重启连接器任务:oc annotate KafkaConnector <kafka_connector_name> strimzi.io/restart-task=0
在本例中,任务
0
被重启。等待下一个协调发生(默认为两分钟)。
只要协调过程检测到注解,Kafka 连接器任务会被重启。当 Kafka Connect 接受重启请求时,注解会从
KafkaConnector
自定义资源中删除。
6.4.3.6. 公开 Kafka Connect API
使用 Kafka Connect REST API 作为使用 KafkaConnector
资源管理连接器的替代选择。Kafka Connect REST API 作为一个运行在 <connect_cluster_name>-connect-api:8083
的服务其中 <connect_cluster_name> 是 Kafka Connect 集群的名称。服务在创建 Kafka Connect 实例时创建。
Kafka Connect REST API 支持的操作请参考 Apache Kafka Connect API 文档。
strimzi.io/use-connector-resources
注解启用 KafkaConnectors。如果您将注解应用到 KafkaConnect
资源配置,则需要将其删除以使用 Kafka Connect API。否则,Cluster Operator 会恢复使用 Kafka Connect REST API 进行的手动更改。
您可以将连接器配置添加为 JSON 对象。
添加连接器配置的 curl 请求示例
curl -X POST \ http://my-connect-cluster-connect-api:8083/connectors \ -H 'Content-Type: application/json' \ -d '{ "name": "my-source-connector", "config": { "connector.class":"org.apache.kafka.connect.file.FileStreamSourceConnector", "file": "/opt/kafka/LICENSE", "topic":"my-topic", "tasksMax": "4", "type": "source" } }'
该 API 仅在 OpenShift 集群中访问。如果要使 Kafka Connect API 可供 OpenShift 集群中运行的应用程序访问,您可以通过创建以下功能之一来手动公开它:
-
LoadBalancer
或NodePort
类型服务 -
Ingress
资源(仅限 Kubernetes) - OpenShift 路由(仅限 OpenShift)
连接是不安全的,因此建议进行外部访问。
如果您决定创建服务,请使用 < connect_cluster_name>-connect-api
服务 选择器
中的标签来配置服务将流量路由到的 pod:
服务的选择器配置
# ... selector: strimzi.io/cluster: my-connect-cluster 1 strimzi.io/kind: KafkaConnect strimzi.io/name: my-connect-cluster-connect 2 #...
您还必须创建一个允许来自外部客户端的 HTTP 请求的 NetworkPolicy
。
允许请求 Kafka Connect API 的 NetworkPolicy 示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-custom-connect-network-policy
spec:
ingress:
- from:
- podSelector: 1
matchLabels:
app: my-connector-manager
ports:
- port: 8083
protocol: TCP
podSelector:
matchLabels:
strimzi.io/cluster: my-connect-cluster
strimzi.io/kind: KafkaConnect
strimzi.io/name: my-connect-cluster-connect
policyTypes:
- Ingress
- 1
- 允许连接到 API 的 pod 标签。
要在集群外添加连接器配置,请使用 curl 命令中公开 API 的资源 URL。
6.4.3.7. 限制对 Kafka Connect API 的访问
仅将对 Kafka Connect API 的访问限制为可信用户,以防止未经授权的操作和潜在的安全问题。Kafka Connect API 提供了大量更改连接器配置的功能,这有助于采取安全措施。有权访问 Kafka Connect API 的人员可能会获得管理员可能假设的敏感信息是安全的。
Kafka Connect REST API 可以被经过身份验证访问 OpenShift 集群的任何人访问,并知道端点 URL,其中包括主机名/IP 地址和端口号。
例如,假设机构使用 Kafka Connect 集群和连接器将客户数据库的敏感数据流传输到中央数据库。管理员使用配置供应商插件存储与连接到客户数据库和中央数据库(如数据库连接详情和身份验证凭据)相关的敏感信息。配置提供程序保护此敏感信息无法向未授权用户公开。但是,有权访问 Kafka Connect API 的用户仍然可以获得对客户数据库的访问权限,而无需经过管理员的批准。他们可以通过设置一个假的数据库并将连接器配置为连接它。然后,他们可以修改连接器配置以指向客户数据库,但不是将数据发送到中央数据库,而是将其发送到假的数据库。通过将连接器配置为连接到假的数据库,可以截获连接到客户端数据库的登录详情和凭证,即使它们被安全地存储在配置提供程序中。
如果您使用 KafkaConnector
自定义资源,默认情况下,OpenShift RBAC 规则只允许 OpenShift 集群管理员更改连接器。您还可以指定非集群管理员来管理 AMQ Streams 资源。在 Kafka Connect 配置中启用 KafkaConnector
资源后,Cluster Operator 会恢复使用 Kafka Connect REST API 所做的更改。如果您不使用 KafkaConnector
资源,默认的 RBAC 规则不会限制对 Kafka Connect API 的访问。如果要使用 OpenShift RBAC 限制对 Kafka Connect REST API 的直接访问,则需要启用和使用 KafkaConnector
资源。
为了提高安全性,我们建议为 Kafka Connect API 配置以下属性:
org.apache.kafka.disallowed.login.modules
(Kafka 3.4 或更高版本)设置
org.apache.kafka.disallowed.login.modules
Java 系统属性,以防止使用不安全的登录模块。例如,指定com.sun.security.auth.module.JndiLoginModule
可防止使用 KafkaJndiLoginModule
。禁止登录模块的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster annotations: strimzi.io/use-connector-resources: "true" spec: # ... jvmOptions: javaSystemProperties: - name: org.apache.kafka.disallowed.login.modules value: com.sun.security.auth.module.JndiLoginModule, org.apache.kafka.common.security.kerberos.KerberosLoginModule # ...
只允许可信登录模块,并按照您使用的版本的 Kafka 的最新建议进行操作。作为最佳实践,您应该通过使用
org.apache.kafka.disallowed.login.modules
系统属性明确禁止 Kafka Connect 配置中不安全的登录模块。connector.client.config.override.policy
将
connector.client.config.override.policy
属性设置为None
,以防止连接器配置覆盖 Kafka Connect 配置及其使用的用户和制作者。指定连接器覆盖策略的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster annotations: strimzi.io/use-connector-resources: "true" spec: # ... config: connector.client.config.override.policy: None # ...
6.4.3.8. 从 Kafka Connect API 切换到使用 KafkaConnector 自定义资源
您可以从使用 Kafka Connect API 切换到使用 KafkaConnector
自定义资源来管理连接器。要进行交换机,请按照所示的顺序执行以下操作:
-
使用配置部署
KafkaConnector
资源,以创建您的连接器实例。 -
通过将
strimzi.io/use-connector-resources
注解设置为true
,在 Kafka Connect 配置中启用KafkaConnector
资源。
如果在创建 KafkaConnector
资源前启用 KafkaConnector 资源,则删除所有连接器。
要从使用 KafkaConnector
资源切换到使用 Kafka Connect API,首先从 Kafka Connect 配置中删除启用 KafkaConnector
资源的注解。否则,Cluster Operator 会恢复使用 Kafka Connect REST API 进行的手动更改。
在进行交换机时 ,检查 KafkaConnect
资源的状态。metadata.generation
的值(当前版本的部署)必须与 status.observedGeneration
(资源最新协调)匹配。当 Kafka Connect 集群为 Ready
时,您可以删除 KafkaConnector
资源。
6.4.4. Kafka Connect 集群资源列表
以下资源由 OpenShift 集群中的 Cluster Operator 创建:
- connect-cluster-name-connect
提供给以下 Kafka Connect 资源的名称:
-
创建 Kafka Connect worker 节点 pod 的部署(当
StableConnectIdentities
功能门被禁用时)。 -
StrimziPodSet 创建 Kafka Connect worker 节点 pod (当启用了
StableConnectIdentities
功能门时)。 -
为 Connect pod 提供稳定 DNS 名称的无头服务(启用了
StableConnectIdentities
功能门时)。 - 为 Kafka Connect worker 节点配置的 Pod Disruption Budget。
-
创建 Kafka Connect worker 节点 pod 的部署(当
- connect-cluster-name-connect-idx
-
由 Kafka Connect StrimziPodSet 创建的 Pod (当启用了
StableConnectIdentities
功能门时)。 - connect-cluster-name-connect-api
- 公开用于管理 Kafka Connect 集群的 REST 接口的服务。
- connect-cluster-name-config
- 包含 Kafka Connect 辅助配置的 ConfigMap,并由 Kafka 代理 pod 挂载为卷。
6.5. 部署 Kafka MirrorMaker
Kafka MirrorMaker 在两个或多个 Kafka 集群之间复制数据,并在数据中心之间复制数据。此过程称为镜像(mirror),以避免与 Kafka 分区复制概念混淆。MirrorMaker 使用来自源集群的消息,并将这些消息重新发布到目标集群。
集群间的数据复制支持以下场景:
- 在系统失败时恢复数据
- 从多个源集群整合数据以进行集中分析
- 对特定集群的数据访问限制
- 在特定位置置备数据以提高延迟
6.5.1. 将 Kafka MirrorMaker 部署到 OpenShift 集群中
此流程演示了如何使用 Cluster Operator 将 Kafka MirrorMaker 集群部署到 OpenShift 集群。
部署使用 YAML 文件来提供规格,根据部署的 MirrorMaker 版本创建 KafkaMirrorMaker
或 KafkaMirrorMaker2
资源。
Kafka MirrorMaker 1 (称为文档中的 MirrorMaker )已在 Apache Kafka 3.0.0 中弃用,并将在 Apache Kafka 4.0.0 中删除。因此,在 AMQ Streams 中还已弃用了用于部署 Kafka MirrorMaker
1 的 KafkaMirrorMaker 自定义资源。当使用 Apache Kafka 4.0.0 时,KafkaMirrorMaker
资源将从 AMQ Streams 中删除。作为替代方法,在 IdentityReplicationPolicy
中使用 KafkaMirrorMaker2
自定义资源。
AMQ Streams 提供 示例配置文件。在此过程中,我们使用以下示例文件:
-
examples/mirror-maker/kafka-mirror-maker.yaml
-
examples/mirror-maker/kafka-mirror-maker-2.yaml
流程
将 Kafka MirrorMaker 部署到 OpenShift 集群中:
对于 MirrorMaker:
oc apply -f examples/mirror-maker/kafka-mirror-maker.yaml
对于 MirrorMaker 2:
oc apply -f examples/mirror-maker/kafka-mirror-maker-2.yaml
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示部署名称和就绪度
NAME READY STATUS RESTARTS my-mirror-maker-mirror-maker-<pod_id> 1/1 Running 1 my-mm2-cluster-mirrormaker2-<pod_id> 1/1 Running 1
my-mirror-maker
是 Kafka MirrorMaker 集群的名称。my-mm2-cluster
是 Kafka MirrorMaker 2 集群的名称。pod ID 标识创建的每个 pod。
使用默认部署,您要安装单个 MirrorMaker 或 MirrorMaker 2 pod。
READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。
6.5.2. Kafka MirrorMaker 集群资源列表
以下资源由 OpenShift 集群中的 Cluster Operator 创建:
- <mirror-maker-name>-mirror-maker
- 负责创建 Kafka MirrorMaker Pod 的部署。
- <mirror-maker-name>-config
- 包含 Kafka MirrorMaker 的辅助配置的 ConfigMap,由 Kafka 代理 pod 挂载为卷。
- <mirror-maker-name>-mirror-maker
- 为 Kafka MirrorMaker worker 节点配置的 Pod Disruption Budget。
6.6. 部署 Kafka Bridge
Kafka Bridge 提供了一个 API,用于将基于 HTTP 的客户端与 Kafka 集群集成。
6.6.1. 在 OpenShift 集群中部署 Kafka Bridge
此流程演示了如何使用 Cluster Operator 将 Kafka Bridge 集群部署到 OpenShift 集群。
部署使用 YAML 文件来提供规格来创建 KafkaBridge
资源。
AMQ Streams 提供 示例配置文件。在此过程中,我们使用以下示例文件:
-
examples/bridge/kafka-bridge.yaml
流程
将 Kafka Bridge 部署到 OpenShift 集群:
oc apply -f examples/bridge/kafka-bridge.yaml
检查部署的状态:
oc get pods -n <my_cluster_operator_namespace>
输出显示部署名称和就绪度
NAME READY STATUS RESTARTS my-bridge-bridge-<pod_id> 1/1 Running 0
my-bridge
是 Kafka Bridge 集群的名称。pod ID 标识创建的每个 pod。
使用默认部署,您会安装单个 Kafka Bridge pod。
READY
显示就绪/预期的副本数。当STATUS
显示为Running
时,部署成功。
6.6.2. 将 Kafka Bridge 服务公开给本地机器
使用端口转发将 AMQ Streams Kafka Bridge 服务公开给 http://localhost:8080 中的本地机器。
端口转发仅适用于开发和测试目的。
流程
列出 OpenShift 集群中的 pod 的名称:
oc get pods -o name pod/kafka-consumer # ... pod/my-bridge-bridge-<pod_id>
在端口
8080
上连接到 Kafka Bridge pod:oc port-forward pod/my-bridge-bridge-<pod_id> 8080:8080 &
注意如果本地计算机上的端口 8080 已在使用中,请使用其他 HTTP 端口,如
8008
。
API 请求现在从本地机器上的端口 8080 转发到 Kafka Bridge pod 的端口 8080。
6.6.3. 在 OpenShift 之外访问 Kafka Bridge
部署后,AMQ Streams Kafka Bridge 只能由在同一 OpenShift 集群中运行的应用程序访问。这些应用程序使用 < ;kafka_bridge_name> -bridge-service
服务来访问 API。
如果要使 Kafka Bridge 可供 OpenShift 集群中运行的应用程序访问,您可以通过创建以下功能之一来手动公开它:
-
LoadBalancer
或NodePort
类型服务 -
Ingress
资源(仅限 Kubernetes) - OpenShift 路由(仅限 OpenShift)
如果您决定创建服务,请使用 < kafka_bridge_name>-bridge-service
服务 选择器
中的标签来配置服务将流量路由到的 pod:
# ...
selector:
strimzi.io/cluster: kafka-bridge-name 1
strimzi.io/kind: KafkaBridge
#...
- 1
- OpenShift 集群中的 Kafka Bridge 自定义资源的名称。
6.6.4. Kafka Bridge 集群资源列表
以下资源由 OpenShift 集群中的 Cluster Operator 创建:
- bridge-cluster-name-bridge
- 用于创建 Kafka Bridge worker 节点 pod 的部署。
- bridge-cluster-name-bridge-service
- 公开 Kafka Bridge 集群的 REST 接口的服务。
- bridge-cluster-name-bridge-config
- 包含 Kafka Bridge acillary 配置的 ConfigMap,并由 Kafka 代理 pod 挂载为卷。
- bridge-cluster-name-bridge
- 为 Kafka Bridge worker 节点配置的 Pod Disruption Budget。
6.7. AMQ Streams operator 的替代独立部署选项
您可以对 Topic Operator 和 User Operator 执行独立部署。如果使用不是由 Cluster Operator 管理的 Kafka 集群,请考虑这些 Operator 的独立部署。
您将操作器部署到 OpenShift。Kafka 可以在 OpenShift 外部运行。例如,您可以使用 Kafka 作为受管服务。您可以调整独立 Operator 的部署配置,以匹配 Kafka 集群的地址。
6.7.1. 部署独立主题 Operator
此流程演示了如何将主题 Operator 部署为主题管理的独立组件。您可以将独立主题 Operator 与不由 Cluster Operator 管理的 Kafka 集群一起使用。
独立部署可以处理任何 Kafka 集群。
独立部署文件由 AMQ Streams 提供。使用 05-Deployment-strimzi-topic-operator.yaml
部署文件来部署主题 Operator。添加或设置环境变量来连接 Kafka 集群。
主题 Operator 监视单一命名空间中的 KafkaTopic
资源。您可以在 Topic Operator 配置中指定要监视的命名空间以及与 Kafka 集群的连接。单个主题 Operator 可以监视单个命名空间。一个命名空间应该只被一个主题 Operator 监视。如果要使用多个主题 Operator,请配置每个主题来监视不同的命名空间。这样,您可以将主题 Operator 与多个 Kafka 集群一起使用。
先决条件
您正在运行一个 Kafka 集群,供主题 Operator 连接。
只要为连接正确配置独立主题 Operator,则 Kafka 集群可以在裸机环境、虚拟机或受管云应用程序服务上运行。
流程
编辑
install/topic-operator/05-Deployment-strimzi-topic-operator.yaml
独立部署文件中的env
属性。独立主题 Operator 部署配置示例
apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-topic-operator labels: app: strimzi spec: # ... template: # ... spec: # ... containers: - name: strimzi-topic-operator # ... env: - name: STRIMZI_NAMESPACE 1 valueFrom: fieldRef: fieldPath: metadata.namespace - name: STRIMZI_KAFKA_BOOTSTRAP_SERVERS 2 value: my-kafka-bootstrap-address:9092 - name: STRIMZI_RESOURCE_LABELS 3 value: "strimzi.io/cluster=my-cluster" - name: STRIMZI_ZOOKEEPER_CONNECT 4 value: my-cluster-zookeeper-client:2181 - name: STRIMZI_ZOOKEEPER_SESSION_TIMEOUT_MS 5 value: "18000" - name: STRIMZI_FULL_RECONCILIATION_INTERVAL_MS 6 value: "120000" - name: STRIMZI_TOPIC_METADATA_MAX_ATTEMPTS 7 value: "6" - name: STRIMZI_LOG_LEVEL 8 value: INFO - name: STRIMZI_TLS_ENABLED 9 value: "false" - name: STRIMZI_JAVA_OPTS 10 value: "-Xmx=512M -Xms=256M" - name: STRIMZI_JAVA_SYSTEM_PROPERTIES 11 value: "-Djavax.net.debug=verbose -DpropertyName=value" - name: STRIMZI_PUBLIC_CA 12 value: "false" - name: STRIMZI_TLS_AUTH_ENABLED 13 value: "false" - name: STRIMZI_SASL_ENABLED 14 value: "false" - name: STRIMZI_SASL_USERNAME 15 value: "admin" - name: STRIMZI_SASL_PASSWORD 16 value: "password" - name: STRIMZI_SASL_MECHANISM 17 value: "scram-sha-512" - name: STRIMZI_SECURITY_PROTOCOL 18 value: "SSL"
- 1
- 主题 Operator 的 OpenShift 命名空间,以监视
KafkaTopic
资源。指定 Kafka 集群的命名空间。 - 2
- bootstrap 代理地址的主机和端口对,以发现并连接到 Kafka 集群中的所有代理。在服务器停机时,使用以逗号分隔的列表指定两个或多个代理地址。
- 3
- 用于标识主题 Operator 管理的
KafkaTopic
资源的标签。这不一定是 Kafka 集群的名称。它可以是分配给KafkaTopic
资源的标签。如果您部署多个主题 Operator,则标签必须是唯一的。也就是说,Operator 无法管理同一资源。 - 4
- (ZooKeeper)用于连接到 ZooKeeper 集群的地址的主机和端口对。这必须是 Kafka 集群正在使用的同一 ZooKeeper 集群。
- 5
- (ZooKeeper) ZooKeeper 会话超时,以毫秒为单位。默认值为
18000
(18 秒)。 - 6
- 定期协调之间的间隔,以毫秒为单位。默认值为
120000
(2 分钟)。 - 7
- 从 Kafka 获取主题元数据的尝试次数。每次尝试之间的时间定义为指数 backoff。由于分区或副本数,当主题创建需要更长的时间时,请考虑增加这个值。默认值为
6
个尝试。 - 8
- 打印日志记录消息的级别。您可以将级别设置为
ERROR
、WARNING
、INFO
、DEBUG
或TRACE
。 - 9
- 启用 TLS 支持与 Kafka 代理的加密通信。
- 10
- (可选)运行主题 Operator 的 JVM 使用的 Java 选项。
- 11
- (可选)为主题 Operator 设置的调试(
-D
)选项。 - 12
- (可选)如果通过
STRIMZI_TLS_ENABLED
启用 TLS,请跳过信任存储证书的生成。如果启用了此环境变量,代理必须使用公共可信证书颁发机构作为其 TLS 证书。默认值为false
。 - 13
- (可选)为 mTLS 身份验证生成密钥存储证书。把它设置为
false
可禁用 mTLS 到 Kafka 代理的客户端身份验证。默认值是true
。 - 14
- (可选)在连接到 Kafka 代理时启用对客户端身份验证的 SASL 支持。默认值为
false
。 - 15
- (可选)客户端身份验证的 SASL 用户名。只有通过
STRIMZI_SASL_ENABLED
启用 SASL 时才强制。 - 16
- (可选)客户端身份验证的 SASL 密码。只有通过
STRIMZI_SASL_ENABLED
启用 SASL 时才强制。 - 17
- (可选)客户端身份验证的 SASL 机制。只有通过
STRIMZI_SASL_ENABLED
启用 SASL 时才强制。您可以将值设为plain
,scram-sha-256
, 或scram-sha-512
。 - 18
- (可选)用于与 Kafka 代理通信的安全协议。默认值为 "PLAINTEXT"。您可以将值设为
PLAINTEXT
、SSL
、SASL_PLAINTEXT
或SASL_SSL
。
-
如果要连接到使用来自公共证书颁发机构证书的 Kafka 代理,请将
STRIMZI_PUBLIC_CA
设置为true
。将此属性设置为true
,例如,如果您使用 Amazon AWS MSK 服务。 如果您使用
STRIMZI_TLS_ENABLED
环境变量启用了 mTLS,请指定用于验证与 Kafka 集群的连接的密钥存储和信任存储。mTLS 配置示例
# .... env: - name: STRIMZI_TRUSTSTORE_LOCATION 1 value: "/path/to/truststore.p12" - name: STRIMZI_TRUSTSTORE_PASSWORD 2 value: "TRUSTSTORE-PASSWORD" - name: STRIMZI_KEYSTORE_LOCATION 3 value: "/path/to/keystore.p12" - name: STRIMZI_KEYSTORE_PASSWORD 4 value: "KEYSTORE-PASSWORD" # ...
部署主题 Operator。
oc create -f install/topic-operator
检查部署的状态:
oc get deployments
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE strimzi-topic-operator 1/1 1 1
READY
显示就绪/预期的副本数。当AVAILABLE
输出显示为1
时,部署成功。
6.7.1.1. (预览)为单向主题管理部署独立主题 Operator
单向主题管理仅通过 KafkaTopic
资源维护主题。有关单向主题管理的详情,请参考 第 9.1 节 “主题管理模式”。
如果要尝试单向主题管理的预览,请按照以下步骤部署独立主题 Operator。
流程
取消部署当前独立主题 Operator。
保留
KafkaTopic
资源,这些资源由主题 Operator 再次部署时获取。编辑独立主题 Operator 的
Deployment
配置,以删除任何与 ZooKeeper 相关的环境变量:-
STRIMZI_ZOOKEEPER_CONNECT
-
STRIMZI_ZOOKEEPER_SESSION_TIMEOUT_MS
-
TC_ZK_CONNECTION_TIMEOUT_MS
STRIMZI_USE_ZOOKEEPER_TOPIC_STORE
它是定义是否使用 unidirectional Topic Operator 的 ZooKeeper 变量是否存在。单向主题管理不使用 ZooKeeper。如果没有 ZooKeeper 环境变量,则使用 unidirectional Topic Operator。否则会使用双向主题 Operator。
如果存在时可以删除的其他未使用的环境变量:
-
STRIMZI_REASSIGN_THROTTLE
-
STRIMZI_REASSIGN_VERIFY_INTERVAL_MS
-
STRIMZI_TOPIC_METADATA_MAX_ATTEMPTS
-
STRIMZI_TOPICS_PATH
-
STRIMZI_STORE_TOPIC
-
STRIMZI_STORE_NAME
-
STRIMZI_APPLICATION_ID
-
STRIMZI_STALE_RESULT_TIMEOUT_MS
-
(可选)将
STRIMZI_USE_FINALIZERS
环境变量设置为false
:其他单向主题管理配置
# ... env: - name: STRIMZI_USE_FINALIZERS value: "false"
如果您不想使用终结器来控制 删除主题,请将此环境变量设置为
false
。单向主题管理的独立主题 Operator 部署配置示例
apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-topic-operator labels: app: strimzi spec: # ... template: # ... spec: # ... containers: - name: strimzi-topic-operator # ... env: - name: STRIMZI_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: STRIMZI_KAFKA_BOOTSTRAP_SERVERS value: my-kafka-bootstrap-address:9092 - name: STRIMZI_RESOURCE_LABELS value: "strimzi.io/cluster=my-cluster" - name: STRIMZI_FULL_RECONCILIATION_INTERVAL_MS value: "120000" - name: STRIMZI_LOG_LEVEL value: INFO - name: STRIMZI_TLS_ENABLED value: "false" - name: STRIMZI_JAVA_OPTS value: "-Xmx=512M -Xms=256M" - name: STRIMZI_JAVA_SYSTEM_PROPERTIES value: "-Djavax.net.debug=verbose -DpropertyName=value" - name: STRIMZI_PUBLIC_CA value: "false" - name: STRIMZI_TLS_AUTH_ENABLED value: "false" - name: STRIMZI_SASL_ENABLED value: "false" - name: STRIMZI_SASL_USERNAME value: "admin" - name: STRIMZI_SASL_PASSWORD value: "password" - name: STRIMZI_SASL_MECHANISM value: "scram-sha-512" - name: STRIMZI_SECURITY_PROTOCOL value: "SSL" - name: STRIMZI_USE_FINALIZERS value: "true"
- 以标准的方式部署独立主题 Operator。
6.7.2. 部署独立用户 Operator
此流程演示了如何将 User Operator 部署为用户管理的独立组件。您可以将独立的 User Operator 与不由 Cluster Operator 管理的 Kafka 集群一起使用。
独立部署可以处理任何 Kafka 集群。
独立部署文件由 AMQ Streams 提供。使用 05-Deployment-strimzi-user-operator.yaml
部署文件来部署 User Operator。添加或设置环境变量来连接 Kafka 集群。
User Operator 监视单个命名空间中的 KafkaUser
资源。您可以在 User Operator 配置中指定要监视的命名空间以及与 Kafka 集群的连接。单个用户 Operator 可以监视单个命名空间。一个命名空间应该只被一个 User Operator 监视。如果要使用多个 User Operator,请配置每个 User Operator 以监视不同的命名空间。这样,您可以将 User Operator 与多个 Kafka 集群一起使用。
先决条件
您正在运行一个 Kafka 集群,供 User Operator 连接。
只要为连接正确配置独立用户 Operator,则 Kafka 集群可以在裸机环境、虚拟机或受管云应用程序服务上运行。
流程
编辑
install/user-operator/05-Deployment-strimzi-user-operator.yaml
独立部署文件中的以下env
属性。独立用户 Operator 部署配置示例
apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-user-operator labels: app: strimzi spec: # ... template: # ... spec: # ... containers: - name: strimzi-user-operator # ... env: - name: STRIMZI_NAMESPACE 1 valueFrom: fieldRef: fieldPath: metadata.namespace - name: STRIMZI_KAFKA_BOOTSTRAP_SERVERS 2 value: my-kafka-bootstrap-address:9092 - name: STRIMZI_CA_CERT_NAME 3 value: my-cluster-clients-ca-cert - name: STRIMZI_CA_KEY_NAME 4 value: my-cluster-clients-ca - name: STRIMZI_LABELS 5 value: "strimzi.io/cluster=my-cluster" - name: STRIMZI_FULL_RECONCILIATION_INTERVAL_MS 6 value: "120000" - name: STRIMZI_WORK_QUEUE_SIZE 7 value: 10000 - name: STRIMZI_CONTROLLER_THREAD_POOL_SIZE 8 value: 10 - name: STRIMZI_USER_OPERATIONS_THREAD_POOL_SIZE 9 value: 4 - name: STRIMZI_LOG_LEVEL 10 value: INFO - name: STRIMZI_GC_LOG_ENABLED 11 value: "true" - name: STRIMZI_CA_VALIDITY 12 value: "365" - name: STRIMZI_CA_RENEWAL 13 value: "30" - name: STRIMZI_JAVA_OPTS 14 value: "-Xmx=512M -Xms=256M" - name: STRIMZI_JAVA_SYSTEM_PROPERTIES 15 value: "-Djavax.net.debug=verbose -DpropertyName=value" - name: STRIMZI_SECRET_PREFIX 16 value: "kafka-" - name: STRIMZI_ACLS_ADMIN_API_SUPPORTED 17 value: "true" - name: STRIMZI_MAINTENANCE_TIME_WINDOWS 18 value: '* * 8-10 * * ?;* * 14-15 * * ?' - name: STRIMZI_KAFKA_ADMIN_CLIENT_CONFIGURATION 19 value: | default.api.timeout.ms=120000 request.timeout.ms=60000
- 1
- User Operator 的 OpenShift 命名空间,用于监视
KafkaUser
资源。只能指定一个命名空间。 - 2
- bootstrap 代理地址的主机和端口对,以发现并连接到 Kafka 集群中的所有代理。在服务器停机时,使用以逗号分隔的列表指定两个或多个代理地址。
- 3
- 包含为 mTLS 身份验证签名的 CA (certificate 授权)的公钥(
ca.crt
)值的 OpenShiftSecret
。 - 4
- 包含 CA 的私钥(
ca.key
)值的 OpenShiftSecret
,用于为 mTLS 身份验证为新用户证书签名。 - 5
- 用于标识由 User Operator 管理的
KafkaUser
资源的标签。这不一定是 Kafka 集群的名称。它可以是分配给KafkaUser
资源的标签。如果部署多个 User Operator,则标签必须是唯一的。也就是说,Operator 无法管理同一资源。 - 6
- 定期协调之间的间隔,以毫秒为单位。默认值为
120000
(2 分钟)。 - 7
- 控制器事件队列的大小。队列的大小应至少与您希望 User Operator 操作的最大用户量一样。默认值为
1024
。 - 8
- 用于协调用户的 worker 池大小。较大的池可能需要更多资源,但它也会处理更多
KafkaUser
资源,默认值为50
。 - 9
- Kafka Admin API 和 OpenShift 操作的 worker 池大小。较大的池可能需要更多资源,但它也会处理更多的
KafkaUser
资源。默认为4
。 - 10
- 打印日志记录消息的级别。您可以将级别设置为
ERROR
、WARNING
、INFO
、DEBUG
或TRACE
。 - 11
- 启用垃圾回收(GC)日志记录。默认值是
true
。 - 12
- CA 的有效性周期。默认值为
365
天。 - 13
- CA 的续订周期。续订周期从当前证书的到期日期后衡量。默认值为
30
天,以在旧证书过期前启动证书续订。 - 14
- (可选)运行用户 Operator 的 JVM 使用的 Java 选项
- 15
- (可选)为 User Operator 设置的调试(
-D
)选项 - 16
- (可选)由 User Operator 创建的 OpenShift secret 名称的前缀。
- 17
- (可选)指示 Kafka 集群是否支持使用 Kafka Admin API 管理授权 ACL 规则。当设置为
false
时,User Operator 将拒绝具有simple
授权 ACL 规则的所有资源。这有助于避免 Kafka 集群日志中不必要的异常。默认值是true
。 - 18
- (可选) Semi-colon 分隔 Cron Expressions 列表,用于定义维护时间窗,其中过期用户证书。
- 19
- (可选)配置 User Operator 以属性格式使用的 Kafka Admin 客户端的配置选项。
如果您使用 mTLS 连接到 Kafka 集群,请指定用于验证连接的 secret。否则,进入下一步。
mTLS 配置示例
# .... env: - name: STRIMZI_CLUSTER_CA_CERT_SECRET_NAME 1 value: my-cluster-cluster-ca-cert - name: STRIMZI_EO_KEY_SECRET_NAME 2 value: my-cluster-entity-operator-certs # ..."
部署 User Operator。
oc create -f install/user-operator
检查部署的状态:
oc get deployments
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE strimzi-user-operator 1/1 1 1
READY
显示就绪/预期的副本数。当AVAILABLE
输出显示为1
时,部署成功。
第 7 章 启用 AMQ Streams 功能门
AMQ Streams operator 使用功能门来启用或禁用特定功能和功能。通过启用功能门,您可以更改对应 Operator 的行为,从而向 AMQ Streams 部署引入了该功能。
功能门可能会被默认启用或禁用,具体取决于其成熟度等级。
要修改功能门的默认状态,请使用 Operator 配置中的 STRIMZI_FEATURE_GATES
环境变量。您可以使用这个单一环境变量修改多个功能门。指定以逗号分隔的功能门名称和前缀列表。+
前缀启用功能门和 -
前缀禁用它。
启用 FeatureGate1
并禁用 FeatureGate2
的功能门配置示例
env: - name: STRIMZI_FEATURE_GATES value: +FeatureGate1,-FeatureGate2
7.1. ControlPlaneListener 功能门
ControlPlaneListener
功能门已移到 GA,这意味着它现已永久启用且无法禁用。启用 ControlPlaneListener
后,Kafka 控制器和代理之间的连接使用端口 9090 上的内部 control plane 侦听程序。在代理间复制数据,以及来自 AMQ Streams operator、Cruise Control 或 Kafka Exporter 的内部连接,在端口 9091 上使用 复制监听程序。
永久启用 ControlPlaneListener
功能门后,现在可以在 AMQ Streams 1.7 及更早版本和 AMQ Streams 2.3 及更新版本之间直接升级或降级。您必须首先升级或降级 AMQ Streams 版本 in-between,禁用 ControlPlaneListener
功能门,然后降级或升级(启用了功能门)到目标版本。
7.2. ServiceAccountPatching 功能门
ServiceAccountPatching
功能门已移到 GA,这意味着它现已永久启用且无法禁用。启用 ServiceAccountPatching
后,Cluster Operator 始终协调服务帐户并根据需要更新它们。例如,当您使用自定义资源的 template
属性更改服务帐户标签或注解时,Operator 会在现有服务帐户资源中自动更新它们。
7.3. UseStrimziPodSets 功能门
UseStrimziPodSets
功能门已移到 GA,这意味着它现已永久启用且无法禁用。对 StatefulSets
的支持已被删除,AMQ Streams 现在始终使用 StrimziPodSets
来管理 Kafka 和 ZooKeeper pod。
永久启用 UseStrimziPodSets
功能门后,无法再直接从 AMQ Streams 2.4 及更新版本降级到 AMQ Streams 2.0 或更早版本。您必须首先通过一个 AMQ Streams 版本( in-between)进行降级,禁用 UseStrimziPodSets
功能门,然后降级到 AMQ Streams 2.0 或更早版本。
7.4. (Preview) UseKRaft 功能门
UseKRaft
功能门具有 禁用的 默认状态。
UseKRaft
功能门在没有 ZooKeeper 的情况下在 KRaft (Kafka Raft 元数据)模式中部署 Kafka 集群。ZooKeeper 和 KRaft 是用于管理 Kafka 集群中元数据和协调操作的机制。KRaft 模式消除了对 ZooKeeper 等外部协调服务的需求。在 KRaft 模式中,Kafka 节点使用代理、控制器或两者的角色。它们一起管理元数据,该元数据在分区之间复制。控制器负责协调操作和维护集群的状态。
此功能门目前仅适用于开发和测试。
KRaft 模式在 Apache Kafka 或 AMQ Streams 中不适用于生产环境。
启用 UseKRaft
功能门需要启用 KafkaNodePools
功能门。要以 KRaft 模式部署 Kafka 集群,您必须使用 KafkaNodePool
资源。如需了解更多详细信息和示例,请参阅 第 6.3.2 节 “(预览)部署 Kafka 节点池”。
当启用 UseKRaft
功能门时,Kafka 集群会在没有 ZooKeeper 的情况下部署。Kafka
自定义资源中的 .spec.zookeeper
属性会被忽略,但仍然需要存在。UseKRaft
功能门提供了一个 API,用于配置 Kafka 集群节点及其角色。API 仍在开发中,预期在 KRaft 模式为生产环境就绪前有所变化。
目前,AMQ Streams 中的 KRaft 模式有以下主要限制:
- 不支持从 ZooKeeper 移动到 KRaft 集群或其他方法。
- 只有 controller-only 节点无法单独进行滚动更新或单独更新。
- 不支持升级和降级 Apache Kafka 版本或 AMQ Streams operator。用户可能需要删除集群,升级 Operator 并部署一个新的 Kafka 集群。
-
KRaft 模式 只支持 Un idirectional Topic Operator。您可以使用
UnidirectionalTopicOperator
功能门启用它。不支持 Bidirectional Topic Operator,当没有启用UnidirectionalTopicOperator
功能门时,spec.entityOperator.topicOperator
属性 必须从Kafka
自定义资源中删除。 -
不支持 JBOD 存储。可以使用
type: jbod
存储,但 JBOD 数组只能包含一个磁盘。
启用 UseKRaft 功能门
要启用 UseKRaft
功能门,在 Cluster Operator 配置中的 STRIMZI_FEATURE_GATES
环境变量中指定 +UseKRaft,+KafkaNodePools
。
7.5. StableConnectIdentities 功能门
StableConnectIdentities
功能门的默认状态 被禁用。
StableConnectIdentities
功能门使用 StrimziPodSet
资源来管理 Kafka Connect 和 Kafka MirrorMaker 2 pod,而不使用 OpenShift Deployment
资源。StrimziPodSets
为 pod 提供稳定的名称和稳定地址,在滚动升级过程中不会改变。这有助于最小化连接器任务的重新平衡数量。
启用 StableConnectIdentities
功能门
要启用 StableConnectIdentities
功能门,请在 Cluster Operator 配置中的 STRIMZI_FEATURE_GATES
环境变量中指定 +StableConnectIdentities
。
在降级到 AMQ Streams 2.3 及更早的版本时,必须禁用 StableConnectIdentities
功能门。
7.6. (预览) KafkaNodePools 功能门
KafkaNodePools
功能门具有 禁用的 默认状态。
KafkaNodePools
功能门引入了一个新的 KafkaNodePool
自定义资源,该资源启用配置不同 Apache Kafka 节点池。
节点池指的是 Kafka 集群中不同的 Kafka 节点组。每个池都有自己的唯一的配置,其中包括强制设置,如副本数、存储配置和分配的角色列表。您可以将 控制器 角色、代理 角色或两个角色都分配给 .spec.roles
字段中池中的所有节点。当与基于 ZooKeeper 的 Apache Kafka 集群一起使用时,必须将其设置为 broker
角色。与 UseKRaft
功能门一起使用时,它可以设置为 代理
、控制器
或两者。
此外,节点池可以自行配置资源请求和限值、Java JVM 选项和资源模板。没有在 KafkaNodePool
资源中设置的配置选项从 Kafka
自定义资源继承。
KafkaNodePool
资源使用 strimzi.io/cluster
标签来指示它们所属的 Kafka 集群。该标签必须设置为 Kafka
自定义资源的名称。
KafkaNodePool
资源的示例可在 AMQ Streams 提供 的示例配置文件 中找到。
启用 KafkaNodePools 功能门
要启用 KafkaNodePools
功能门,在 Cluster Operator 配置中的 STRIMZI_FEATURE_GATES
环境变量中指定 +KafkaNodePools
。使用节点池的 Kafka
自定义资源还必须具有注解 strimzi.io/node-pools: enabled
。
7.7. (预览)UnidirectionalTopicOperator 功能门
UnidirectionalTopicOperator
功能门 禁用 默认状态。
UnidirectionalTopicOperator
功能门引入了一个单向主题管理模式,用于使用 KafkaTopic
资源创建 Kafka 主题。单向模式与使用 KRaft 进行集群管理兼容。使用单向模式,您可以使用 KafkaTopic
资源创建 Kafka 主题,然后由 Topic Operator 管理。对 KafkaTopic
资源之外的主题的任何配置更改都会被恢复。有关主题管理的详情,请参考 第 9.1 节 “主题管理模式”。
启用 UnidirectionalTopicOperator 功能门
要启用 UnidirectionalTopicOperator
功能门,在 Cluster Operator 配置中的 STRIMZI_FEATURE_GATES
环境变量中指定 +UnidirectionalTopicOperator
。要使 KafkaTopic
自定义资源使用此功能,strimzi.io/managed
注解默认设置为 true
。
7.8. 功能门版本
功能门有三个成熟度阶段:
- alpha - 通常默认禁用
- beta - 通常默认启用
- GA (GA)- 通常始终启用
alpha 阶段功能可能是实验性或不稳定的,可能随时更改或尚未针对生产环境进行了测试。Beta 阶段功能经过良好测试,其功能可能不会改变。GA 阶段功能稳定,将来不应改变。如果 alpha 和 beta 阶段功能没有很有用,则它们会被删除。
-
ControlPlaneListener
功能门在 AMQ Streams 2.3 中移到 GA 阶段。它现已永久启用且无法禁用。 -
ServiceAccountPatching
功能门在 AMQ Streams 2.3 中移到 GA 阶段。它现已永久启用且无法禁用。 -
UseStrimziPodSets
功能门移到 AMQ Streams 2.5 中的 GA 阶段,并完全删除对 StatefulSets 的支持。它现已永久启用且无法禁用。 -
UseKRaft
功能门仅适用于开发,目前没有计划迁移至 beta 阶段的版本。 -
StableConnectIdentities
功能门处于 alpha 阶段,默认是禁用的。 -
KafkaNodePools
功能门处于 alpha 阶段,默认是禁用的。 -
UnidirectionalTopicOperator
功能门处于 alpha 阶段,默认是禁用的。
当功能门到达 GA 时,可能会删除功能门。这意味着该功能已合并到 AMQ Streams 核心功能中,且无法禁用。
功能门 | Alpha | Beta | GA |
---|---|---|---|
| 1.8 | 2.0 | 2.3 |
| 1.8 | 2.0 | 2.3 |
| 2.1 | 2.3 | 2.5 |
| 2.2 | - | - |
| 2.4 | - | - |
| 2.5 | - | - |
| 2.5 | - | - |
如果启用了功能门,您可能需要在从特定的 AMQ Streams 版本升级或降级前禁用它。下表显示了在升级或降级 AMQ Streams 版本时需要禁用哪些功能门。
禁用功能门 | 从 AMQ Streams 版本升级 | 降级到 AMQ Streams 版本 |
---|---|---|
| 1.7 及更早版本 | 1.7 及更早版本 |
| - | 2.0 及更早版本 |
| - | 2.3 及更早版本 |
第 8 章 配置部署
使用 AMQ Streams 自定义资源配置和管理 AMQ Streams 部署。AMQ Streams 为每个发行版本提供示例自定义资源,允许您配置和创建支持的 Kafka 组件实例。通过将自定义资源配置为根据您的特定要求包含其他功能来微调部署。对于 Kafka Connect 连接器的特定配置区域,如指标、日志记录和外部配置,您还可以使用 ConfigMap
资源。通过使用 ConfigMap
资源来融合配置,您可以集中维护。您还可以使用配置供应商从外部来源加载配置,我们建议提供 Kafka Connect 连接器配置的凭证。
使用自定义资源配置并创建以下组件的实例:
- Kafka 集群
- Kafka Connect 集群
- Kafka MirrorMaker
- Kafka Bridge
- Sything Control
您还可以使用自定义资源配置来管理实例或修改部署,以引入其他功能。这可能包括支持以下配置:
- (预览)指定节点池
- 保护对 Kafka 代理的客户端访问
- 从集群外部访问 Kafka 代理
- 创建主题
- 创建用户(客户端)
- 控制功能门
- 更改日志频率
- 分配资源限值和请求
- 引入功能,如 AMQ Streams Drain Cleaner、Cruise Control 或 distributed tracing。
AMQ Streams 自定义资源 API 参考 描述了您可以在配置中使用的属性。
应用到自定义资源的标签也会应用到组成集群的 OpenShift 资源。这为资源提供了一个方便的机制来根据需要进行标记。
将更改应用到自定义资源配置文件
您可以使用 spec
属性将配置添加到自定义资源中。添加配置后,您可以使用 oc
将更改应用到自定义资源配置文件:
oc apply -f <kafka_configuration_file>
8.1. 使用示例配置文件
通过纳入其他支持的配置来进一步增强部署。从 AMQ Streams 软件下载页 提供了可下载发行工件的示例配置文件。
默认情况下,示例文件仅包含自定义资源的基本属性和值。您可以使用 oc
命令行工具下载并应用示例。在为部署构建自己的 Kafka 组件配置时,示例可作为起点。
如果使用 Operator 安装 AMQ Streams,您仍然可以下载示例文件并使用它们上传配置。
发行版本工件包括一个包含配置示例 的示例
目录。
AMQ Streams 提供的配置文件示例
examples ├── user 1 ├── topic 2 ├── security 3 │ ├── tls-auth │ ├── scram-sha-512-auth │ └── keycloak-authorization ├── mirror-maker 4 ├── metrics 5 ├── kafka 6 │ └── nodepools 7 ├── cruise-control 8 ├── connect 9 └── bridge 10
- 1
KafkaUser
自定义资源配置,由 User Operator 管理。- 2
KafkaTopic
自定义资源配置,由 Topic Operator 管理。- 3
- Kafka 组件的身份验证和授权配置。包括 TLS 和 SCRAM-SHA-512 身份验证的示例配置。Red Hat Single Sign-On 示例包括
Kafka
自定义资源配置和 Red Hat Single Sign-On 域规格。您可以使用示例尝试 Red Hat Single Sign-On 授权服务。另外,还有一个启用了oauth
身份验证和keycloak
授权指标的示例。 - 4
- 用于部署 Mirror Maker 的
Kafka
自定义资源配置。包括复制策略和同步频率配置示例。 - 5
- 指标配置,包括 Prometheus 安装和 Grafana 仪表板文件。
- 6
Kafka
自定义资源配置,用于部署 Kafka。包括临时或持久单节点部署的示例配置。- 7
- (预览) Kafka 集群中 Kafka 节点的
KafkaNodePool
配置。包括使用 KRaft (Kafka Raft metadata)模式或 ZooKeeper 的集群中节点配置示例。 - 8
- 使用 Cruise Control 的部署配置的
Kafka
自定义资源。包含KafkaRebalance
自定义资源,从 Cruise Control 生成优化提议,以及示例配置,以使用默认或用户优化目标。 - 9
KafkaConnect
和KafkaConnector
自定义资源配置用于部署 Kafka Connect。包括单节点或多节点部署的配置示例。- 10
- Kafka Bridge 部署的
KafkaBridge
自定义资源配置。
8.2. 配置 Kafka
更新 Kafka
自定义资源的 spec
属性来配置 Kafka 部署。
另外,您还可以为 ZooKeeper 和 AMQ Streams Operator 添加配置。各个组件都独立配置通用配置属性,如日志记录和健康检查。
特别重要的配置选项包括:
- 资源请求(CPU / Memory)
- 最多和最小内存分配的 JVM 选项
- 将客户端连接到 Kafka 代理的监听程序(以及客户端的身份验证)
- 身份验证
- 存储
- 机架感知
- 指标
- 用于集群重新平衡的 Cruise Control
要深入了解 Kafka 集群配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
Kafka 版本
Kafka config
的 inter.broker.protocol.version
属性必须是指定的 Kafka 版本 (spec.kafka.version
) 支持的版本。属性表示 Kafka 集群中使用的 Kafka 协议版本。
从 Kafka 3.0.0 开始,当将 inter.broker.protocol.version
设置为 3.0
或更高版本时,log.message.format.version
选项将被忽略,不需要设置。
当升级 Kafka 版本时,需要对 inter.broker.protocol.version
进行更新。如需更多信息,请参阅升级 Kafka。
管理 TLS 证书
在部署 Kafka 时,Cluster Operator 会自动设置和更新 TLS 证书,以便在集群中启用加密和身份验证。如果需要,您可以在续订周期开始前手动续订集群和客户端 CA 证书。您还可以替换集群和客户端 CA 证书使用的密钥。如需更多信息,请参阅 手动续订 CA 证书和替换私钥。
Kafka
自定义资源配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: replicas: 3 1 version: 3.5.0 2 logging: 3 type: inline loggers: kafka.root.logger.level: INFO resources: 4 requests: memory: 64Gi cpu: "8" limits: memory: 64Gi cpu: "12" readinessProbe: 5 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 jvmOptions: 6 -Xms: 8192m -Xmx: 8192m image: my-org/my-image:latest 7 listeners: 8 - name: plain 9 port: 9092 10 type: internal 11 tls: false 12 configuration: useServiceDnsDomain: true 13 - name: tls port: 9093 type: internal tls: true authentication: 14 type: tls - name: external 15 port: 9094 type: route tls: true configuration: brokerCertChainAndKey: 16 secretName: my-secret certificate: my-certificate.crt key: my-key.key authorization: 17 type: simple config: 18 auto.create.topics.enable: "false" offsets.topic.replication.factor: 3 transaction.state.log.replication.factor: 3 transaction.state.log.min.isr: 2 default.replication.factor: 3 min.insync.replicas: 2 inter.broker.protocol.version: "3.5" storage: 19 type: persistent-claim 20 size: 10000Gi rack: 21 topologyKey: topology.kubernetes.io/zone metricsConfig: 22 type: jmxPrometheusExporter valueFrom: configMapKeyRef: 23 name: my-config-map key: my-key # ... zookeeper: 24 replicas: 3 25 logging: 26 type: inline loggers: zookeeper.root.logger: INFO resources: requests: memory: 8Gi cpu: "2" limits: memory: 8Gi cpu: "2" jvmOptions: -Xms: 4096m -Xmx: 4096m storage: type: persistent-claim size: 1000Gi metricsConfig: # ... entityOperator: 27 tlsSidecar: 28 resources: requests: cpu: 200m memory: 64Mi limits: cpu: 500m memory: 128Mi topicOperator: watchedNamespace: my-topic-namespace reconciliationIntervalSeconds: 60 logging: 29 type: inline loggers: rootLogger.level: INFO resources: requests: memory: 512Mi cpu: "1" limits: memory: 512Mi cpu: "1" userOperator: watchedNamespace: my-topic-namespace reconciliationIntervalSeconds: 60 logging: 30 type: inline loggers: rootLogger.level: INFO resources: requests: memory: 512Mi cpu: "1" limits: memory: 512Mi cpu: "1" kafkaExporter: 31 # ... cruiseControl: 32 # ...
- 1
- 副本节点的数量。
- 2
- Kafka 版本,可按照升级步骤将其改为受支持的版本。
- 3
- Kafka 日志记录器和日志级别直接(
内联
)或通过 ConfigMap 间接添加(外部
)。自定义 Log4j 配置必须放在 ConfigMap 中的log4j.properties
键下。对于 Kafkakafka.root.logger.level
日志记录器,您可以将日志级别设置为 INFO, ERROR, WARN, TRACE, DEBUG,FATAL 或 OFF。 - 4
- 用于保留支持的资源、当前
cpu
和内存
以及限制的请求,以指定可消耗的最大资源。 - 5
- 健康检查以了解何时重启容器(持续)以及容器可以接受流量(就绪状态)。
- 6
- JVM 配置选项,用于优化运行 Kafka 的虚拟机(VM)的性能。
- 7
- ADVANCED OPTION:容器镜像配置,这只在特殊情况下建议使用。
- 8
- 侦听器配置客户端如何通过 bootstrap 地址连接到 Kafka 集群。监听器被配置为 internal 或 external 监听程序,用于来自 OpenShift 集群内部或外的连接。
- 9
- 用于标识监听程序的名称。在 Kafka 集群中必须是唯一的。
- 10
- Kafka 中监听程序使用的端口号。端口号必须在给定的 Kafka 集群中唯一。允许端口号为 9092 及更高版本,但端口 9404 和 9999 除外,它们已用于 Prometheus 和 JMX。根据监听程序类型,端口号可能与连接 Kafka 客户端的端口号不同。
- 11
- 监听程序指定为
internal
或cluster-ip
(使用每个代理的ClusterIP
服务公开 Kafka),或为外部监听程序指定为route
(只限 OpenShift),loadbalancer
,nodeport
或ingress
(只限 Kubernetes)。 - 12
- 为每个监听程序启用 TLS 加密。默认为
false
。需要启用 TLS 加密,将它设置为true
, 对于route
和ingress
类型的监听器。 - 13
- 定义是否分配了包括集群服务后缀(通常为
.cluster.local
)的完全限定 DNS 名称。 - 14
- 侦听器身份验证机制指定为 mTLS、SCRAM-SHA-512 或基于令牌的 OAuth 2.0。
- 15
- 外部监听程序配置指定 Kafka 集群如何在 OpenShift 外部公开,如通过
路由
,loadbalancer
或nodeport
。 - 16
- 由外部 CA (证书颁发机构)管理的 Kafka 侦听器证书的可选配置。
brokerCertChainAndKey
指定包含服务器证书和私钥的Secret
。您可以在任何启用了 TLS 加密的监听程序中配置 Kafka 侦听器证书。 - 17
- 授权在 Kafka 代理上启用 simple、OAUTH 2.0 或 OPA 授权。简单授权使用
AclAuthorizer
Kafka 插件。 - 18
- 代理配置。标准 Apache Kafka 配置可能会提供,仅限于不直接由 AMQ Streams 管理的属性。
- 19
- 持久性卷的存储大小可能会增加,并可以添加额外的卷到 JBOD 存储中。
- 20
- 持久性存储具有额外的配置选项,如用于动态卷置备的存储
id
和class
。 - 21
- 机架感知配置,将副本分散到不同的机架、数据中心或可用性区域。
topologyKey
必须与包含机架 ID 的节点标签匹配。此配置中使用的示例使用标准topology.kubernetes.io/zone
标签指定区。 - 22
- 启用 Prometheus 指标。在本例中,为 Prometheus JMX Exporter (默认指标导出器)配置了指标。
- 23
- 通过 Prometheus JMX Exporter 将指标数据导出到 Grafana 仪表板的规则,通过引用包含 Prometheus JMX exporter 配置的 ConfigMap 来启用。您可以使用对
metricsConfig.valueFrom.configMapKeyRef.key
下包含空文件的 ConfigMap 的引用来启用指标。 - 24
- 特定于 ZooKeeper 的配置,其中包含与 Kafka 配置类似的属性。
- 25
- ZooKeeper 节点数量。ZooKeeper 集群通常有奇数个节点,一般为三个、五个或七个。大多数节点都必须可用,才能保持有效的仲裁。如果 ZooKeeper 集群丢失了其仲裁,它将停止响应客户端,并且 Kafka 代理将停止工作。拥有稳定且高度可用的 ZooKeeper 集群对于 AMQ Streams 至关重要。
- 26
- ZooKeeper 日志记录器和日志级别。
- 27
- Entity Operator 配置,用于指定主题 Operator 和 User Operator 的配置。
- 28
- 实体 Operator TLS sidecar 配置。实体 Operator 使用 TLS sidecar 与 ZooKeeper 安全通信。
- 29
- 指定主题 Operator 日志记录器和日志级别。这个示例使用
内联
日志记录。 - 30
- 指定 User Operator 日志记录器和日志级别。
- 31
- Kafka 导出程序配置。Kafka Exporter 是一个可选组件,用于在特定消费者滞后数据中从 Kafka 代理中提取指标数据。要使 Kafka Exporter 能够正常工作,消费者组需要使用。
- 32
- Cruise Control 的可选配置,用于重新平衡 Kafka 集群。
8.2.1. 使用 Kafka 静态配额插件设置代理限制
使用 Kafka 静态配额插件在 Kafka 集群中的代理上设置吞吐量和存储限制。您可以通过配置 Kafka
资源来启用插件和设置限制。您可以设置字节阈值和存储配额,以在与代理交互的客户端上放置限制。
您可以为制作者和消费者带宽设置字节阈值。总限制在访问代理的所有客户端间分布。例如,您可以为制作者设置字节阈值 40 MBps。如果两个制作者正在运行,它们各自限制为 20 MBps 的吞吐量。
存储配额在软限制和硬限制之间节流 Kafka 磁盘存储限制。限制适用于所有可用磁盘空间。生产者在软限制和硬限制之间逐渐慢。限制可防止磁盘填满速度超过其容量。完整磁盘可能会导致难以重新处理的问题。硬限制是最大存储限制。
对于 JBOD 存储,限制适用于所有磁盘。如果代理使用两个 1 TB 磁盘,并且配额为 1.1 TB,则一个磁盘可能会填满,另一个磁盘将几乎为空。
先决条件
- 管理 Kafka 集群的 Cluster Operator 正在运行。
流程
为
Kafka
资源的config
添加插件属性。此示例配置中显示了插件属性。
Kafka 静态配额插件配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... config: client.quota.callback.class: io.strimzi.kafka.quotas.StaticQuotaCallback 1 client.quota.callback.static.produce: 1000000 2 client.quota.callback.static.fetch: 1000000 3 client.quota.callback.static.storage.soft: 400000000000 4 client.quota.callback.static.storage.hard: 500000000000 5 client.quota.callback.static.storage.check-interval: 5 6
更新资源。
oc apply -f <kafka_configuration_file>
其他资源
8.2.2. 默认 ZooKeeper 配置值
当使用 AMQ Streams 部署 ZooKeeper 时,AMQ Streams 设置的一些默认配置与标准 ZooKeeper 默认值不同。这是因为 AMQ Streams 设置多个 ZooKeeper 属性,其值在 OpenShift 环境中运行 ZooKeeper。
AMQ Streams 中密钥 ZooKeeper 属性的默认配置如下:
属性 | 默认值 | Description |
---|---|---|
| 2000 | 以毫秒为单位的单空长度,它决定了会话超时的长度。 |
| 5 | 在 ZooKeeper 集群中允许后续者获得的最大 tick 数量。 |
| 2 | 后续允许不与 ZooKeeper 集群中的领导不同步的最大 tick 数量。 |
| 1 |
启用 |
| false | 禁用 ZooKeeper admin 服务器的标记。AMQ Streams 不使用 admin 服务器。 |
修改这些默认值作为 Kafka
自定义资源中的 zookeeper.config
可能会影响 ZooKeeper 集群的行为和性能。
8.3. (预览)配置节点池
更新 KafkaNodePool
自定义资源的 spec
属性来配置节点池部署。
节点池功能作为技术预览提供。节点池不会被默认启用,因此您必须在使用 KafkaNodePools 功能门前启用 KafkaNodePools
功能门。
节点池指的是 Kafka 集群中不同的 Kafka 节点组。每个池都有自己的唯一的配置,其中包括副本、角色和存储分配数量的强制设置。
另外,您还可以为以下属性指定值:
-
指定内存和 cpu 请求和限值
的资源
-
模板
为 Pod 和其他 OpenShift 资源指定自定义配置 -
jvmOptions
,用于指定堆大小、运行时和其他选项的自定义 JVM 配置
Kafka
资源代表 Kafka 集群中所有节点的配置。KafkaNodePool
资源仅代表节点池中的节点的配置。如果没有在 KafkaNodePool
中指定配置属性,它将继承自 Kafka
资源。如果在两个资源中设置,则 KafkaNodePool
资源中指定的配置具有优先权。例如,如果节点池和 Kafka 配置都包含 jvmOptions
,则使用节点池配置中指定的值。当在 KafkaNodePool.spec.jvmOptions
中设置了 -Xmx: 1024m
,在 Kafka.spec.kafka.jvmOptions
中设置了 -Xms: 512m
,节点会使用其节点池配置中的值。
Kafka
和 KafkaNodePool
模式的属性不会被合并。为了说明,如果 KafkaNodePool.spec.template
只包含 podSet.metadata.labels
,并且 Kafka.spec.kafka.template
包含 podSet.metadata.annotations
和 pod.metadata.labels
,则 Kafka 配置中的模板值会被忽略,因为节点池配置中有一个模板值。
节点池可用于以 KRaft 模式(使用 Kafka Raft 元数据)运行的 Kafka 集群,或使用 ZooKeeper 进行集群管理。如果使用 KRaft 模式,您可以为节点池中的所有节点指定角色,以作为代理、控制器或两者运行。如果使用 ZooKeeper,则节点必须设置为代理。
KRaft 模式在 Apache Kafka 或 AMQ Streams 中不适用于生产环境。
要深入了解节点池配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
虽然启用节点池的 KafkaNodePools
功能门处于 alpha 阶段,但 KafkaNodePool
资源中的副本和存储配置属性还必须存在于 Kafka
资源中。当使用节点池时,Kafka
资源中的配置会被忽略。同样,在使用 KRaft 模式时,在 Kafka
资源中也必须存在 ZooKeeper 配置属性。这些属性也会被忽略。
使用 ZooKeeper 在集群中节点池的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaNodePool metadata: name: pool-a 1 labels: strimzi.io/cluster: my-cluster 2 spec: replicas: 3 3 roles: - broker 4 storage: 5 type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false resources: 6 requests: memory: 64Gi cpu: "8" limits: memory: 64Gi cpu: "12"
使用 KRaft 模式的集群中节点池的配置示例
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: kraft-dual-role
labels:
strimzi.io/cluster: my-cluster
spec:
replicas: 3
roles: 1
- controller
- broker
storage:
type: jbod
volumes:
- id: 0
type: persistent-claim
size: 20Gi
deleteClaim: false
resources:
requests:
memory: 64Gi
cpu: "8"
limits:
memory: 64Gi
cpu: "12"
- 1
- 节点池中的节点的角色。在本例中,节点具有双角色作为控制器和代理。
Kafka
资源的配置必须适合 KRaft 模式。目前,KRaft 模式有很多限制。
8.3.1. (预览)将 ID 分配给节点池以进行扩展操作
此流程描述了如何在节点池中执行扩展操作时,Cluster Operator 对高级节点 ID 处理使用注解。您可以按顺序使用下一个 ID 来指定要使用的节点 ID,而不是 Cluster Operator。以这种方式管理节点 ID 可提供更多控制。
要添加一系列 ID,您可以为 KafkaNodePool
资源分配以下注解:
-
strimzi.io/next-node-ids
来添加用于新代理的 ID 范围 -
strimzi.io/remove-node-ids
来添加一系列 ID 以删除现有代理
您可以指定单个节点 ID、ID 范围或两者的组合。例如,您可以指定以下 ID 范围: [0, 1, 2, 10-20, 30]
来扩展 Kafka 节点池。通过这种格式,您可以指定单个节点 ID (0
、1
、2
、30
)以及一系列 ID (10-20
)。
在典型的场景中,您可以指定一个 ID 范围来向上扩展和单一节点 ID,以便在缩减时删除特定节点。
在此过程中,我们将扩展注解添加到节点池中,如下所示:
-
为
pool-a
分配一系列 ID 进行扩展 -
为
pool-b
分配一系列 ID 用于缩减
在扩展操作过程中,使用 ID,如下所示:
- 扩展获取新节点范围内的最低可用 ID。
- 缩减会删除范围中具有最高可用 ID 的节点。
如果在节点池中分配的节点 ID 序列中有差距,则要添加的下一个节点会被分配一个填充空白的 ID。
每次扩展操作后,不需要更新注解。任何未使用的 ID 仍对下一个扩展事件有效。
Cluster Operator 允许您以升序或降序指定 ID 范围,以便您可以按照节点扩展的顺序定义它们。例如,在扩展时,您可以指定一个范围,如 [1000-1999]
,并且新节点分配下一个最低 ID: 1000
、1001
、1002
、1003
等。相反,当缩减时,您可以指定一个范围,如 [1999-1000]
,确保具有下一个最高 ID 的节点已被删除 :100
3、1002
、1001
、1000
等。
如果没有使用注解指定 ID 范围,Cluster Operator 遵循其在扩展操作期间处理 ID 的默认行为。节点 ID 以 0 (零)开始,并在 Kafka 集群中按顺序运行。下一个最低 ID 分配给新节点。在集群中填充节点 ID 的差距。这意味着它们可能无法在节点池中按顺序运行。扩展的默认行为是在集群中添加下一个最低可用节点 ID;在缩减时,它会删除具有最高可用节点 ID 的节点。如果分配的 ID 范围被误格式化,则扩展范围没有 ID,或者缩减范围不适用于任何正在使用的节点,则应用默认方法。
流程
使用 ID 为节点池添加在扩展或缩减时要使用的 ID,如下例所示。
用于向上扩展的 ID 会被分配给节点
池池
:为扩展分配 ID
oc annotate kafkanodepool pool-a strimzi.io/next-node-ids="[0,1,2,10-20,30]"
将节点添加到
池
时使用此范围内的最低可用 ID。用于缩减的 ID 分配给节点池
pool-b
:为缩减分配 ID
oc annotate kafkanodepool pool-b strimzi.io/remove-node-ids="[60-50,9,8,7]"
缩减
pool-b
时会删除此范围内的最高可用 ID。现在,您可以扩展节点池。
如需更多信息,请参阅以下:
在协调时,如果注解被错误格式化,则会提供一个警告。
8.3.2. (预览)将节点添加到节点池中
这个步骤描述了如何扩展节点池来添加新节点。
在此过程中,我们从三个节点池( 池
)开始:
节点池中的 Kafka 节点
NAME READY STATUS RESTARTS my-cluster-pool-a-kafka-0 1/1 Running 0 my-cluster-pool-a-kafka-1 1/1 Running 0 my-cluster-pool-a-kafka-2 1/1 Running 0
节点 ID 在创建时附加到节点的名称中。我们添加节点 my-cluster-pool-a-kafka-3
,节点 ID 为 3
。
在此过程中,保存分区副本的节点 ID 会改变。考虑引用节点 ID 的任何依赖项。
先决条件
- 必须部署 Cluster Operator。
(可选)要扩展操作 ,您可以指定要使用的节点 ID 范围。
如果您为操作分配了一系列节点 ID,正在添加的节点 ID 由给定的节点序列决定。否则,会使用集群中的最低可用节点 ID。
流程
在节点池中创建新节点。
例如,节点池
pool-a
有三个副本。我们通过增加副本数量来添加节点:oc scale kafkanodepool pool-a --replicas=4
检查部署的状态,并等待节点池中的 pod 创建,并且状态为
READY
。oc get pods -n <my_cluster_operator_namespace>
输出显示节点池中的四个 Kafka 节点
NAME READY STATUS RESTARTS my-cluster-pool-a-kafka-0 1/1 Running 0 my-cluster-pool-a-kafka-1 1/1 Running 0 my-cluster-pool-a-kafka-2 1/1 Running 0 my-cluster-pool-a-kafka-3 1/1 Running 0
在增加节点池中的节点数后重新分配分区。
在扩展节点池后,您可以使用 Cruise Control
add-brokers
模式将分区副本从现有代理移到新添加的代理中。
8.3.3. (预览)从节点池中删除节点
这个步骤描述了如何缩减节点池来删除节点。
在此过程中,我们从四个节点池( 池
)开始:
节点池中的 Kafka 节点
NAME READY STATUS RESTARTS my-cluster-pool-a-kafka-0 1/1 Running 0 my-cluster-pool-a-kafka-1 1/1 Running 0 my-cluster-pool-a-kafka-2 1/1 Running 0 my-cluster-pool-a-kafka-3 1/1 Running 0
节点 ID 在创建时附加到节点的名称中。我们删除节点 my-cluster-pool-a-kafka-3
,节点 ID 为 3
。
在此过程中,保存分区副本的节点 ID 会改变。考虑引用节点 ID 的任何依赖项。
先决条件
- 必须部署 Cluster Operator。
(可选)为了缩减操作 ,您可以指定要在操作中使用的节点 ID 范围。
如果您为操作分配了一系列节点 ID,则要删除的节点的 ID 由给定的节点序列决定。否则,节点池中具有最高可用 ID 的节点会被删除。
流程
在减少节点池中的节点数前重新分配分区。
在缩减节点池前,您可以使用 Cruise Control
remove-brokers
模式将分区副本移出要删除的代理。在重新分配过程完成后,删除的节点没有实时分区,从而减少节点池中的 Kafka 节点数量。
例如,节点池
pool-a
有四个副本。我们通过减少副本数来删除节点:oc scale kafkanodepool pool-a --replicas=3
输出显示节点池中的三个 Kafka 节点
NAME READY STATUS RESTARTS my-cluster-pool-b-kafka-0 1/1 Running 0 my-cluster-pool-b-kafka-1 1/1 Running 0 my-cluster-pool-b-kafka-2 1/1 Running 0
8.3.4. (预览)在节点池之间移动节点
这个步骤描述了如何在不停机的情况下在源和目标 Kafka 节点池之间移动节点。您可以在目标节点池中创建新节点并重新分配分区,以便从源节点池中的旧节点移动数据。当新节点上的副本同步时,您可以删除旧节点。
在此过程中,我们从两个节点池开始:
-
具有三个副本的池
是目标节点池 -
带有四个副本的
pool-b
是源节点池
我们扩展 pool-a
,并重新分配分区并缩减 pool-b
,这会导致以下内容:
-
pool-a
带有四个副本 -
带有三个副本的
pool-b
在此过程中,保存分区副本的节点 ID 会改变。考虑引用节点 ID 的任何依赖项。
先决条件
- 必须部署 Cluster Operator。
(可选)要扩展和缩减操作 ,您可以指定要使用的节点 ID 范围。
如果您为操作分配了节点 ID,正在添加或删除的节点 ID 由给定的节点序列决定。否则,在添加节点时会使用集群中可用的最低节点 ID;并删除节点池中可用 ID 的节点。
流程
在目标节点池中创建新节点。
例如,节点池
pool-a
有三个副本。我们通过增加副本数量来添加节点:oc scale kafkanodepool pool-a --replicas=4
检查部署的状态,并等待节点池中的 pod 创建,并且状态为
READY
。oc get pods -n <my_cluster_operator_namespace>
输出显示目标节点池中的四个 Kafka 节点
NAME READY STATUS RESTARTS my-cluster-pool-a-kafka-0 1/1 Running 0 my-cluster-pool-a-kafka-1 1/1 Running 0 my-cluster-pool-a-kafka-4 1/1 Running 0 my-cluster-pool-a-kafka-5 1/1 Running 0
节点 ID 在创建时附加到节点的名称中。我们添加节点
my-cluster-pool-a-kafka-5
,其节点 ID 为5
。将分区从旧节点重新分配给新节点。
在缩减源节点池前,您可以使用 Cruise Control
remove-brokers
模式将分区副本移出要删除的代理。重新分配过程完成后,减少源节点池中的 Kafka 节点数量。
例如,节点池
pool-b
具有四个副本。我们通过减少副本数来删除节点:oc scale kafkanodepool pool-b --replicas=3
池中具有最高 ID 的节点已被删除。
输出显示源节点池中的三个 Kafka 节点
NAME READY STATUS RESTARTS my-cluster-pool-b-kafka-2 1/1 Running 0 my-cluster-pool-b-kafka-3 1/1 Running 0 my-cluster-pool-b-kafka-6 1/1 Running 0
8.3.5. (预览)迁移现有 Kafka 集群以使用 Kafka 节点池
这个步骤描述了如何迁移现有 Kafka 集群以使用 Kafka 节点池。更新 Kafka 集群后,您可以使用节点池来管理每个池中的节点配置。
虽然启用节点池的 KafkaNodePools
功能门处于 alpha 阶段,但 KafkaNodePool
资源中的副本和存储配置还必须存在于 Kafka
资源中。使用节点池时会忽略配置。
流程
创建新的
KafkaNodePool
资源。-
将资源命名为
kafka
。 -
将
strimzi.io/cluster
标签指向现有的Kafka
资源。 - 设置副本数和存储配置以匹配您当前的 Kafka 集群。
-
将角色设置为
代理
。
迁移 Kafka 集群的节点池配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaNodePool metadata: name: kafka labels: strimzi.io/cluster: my-cluster spec: replicas: 3 roles: - broker storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false
-
将资源命名为
应用
KafkaNodePool
资源:oc apply -f <node_pool_configuration_file>
通过应用此资源,您可以将 Kafka 切换到使用节点池。
没有更改或滚动更新和资源与之前的资源相同。
更新 Cluster Operator 配置中的
STRIMZI_FEATURE_GATES
环境变量,使其包含+KafkaNodePools
。env: - name: STRIMZI_FEATURE_GATES value: +KafkaNodePools
使用
strimzi.io/node-pools: enabled
注解,在Kafka
资源中启用KafkaNodePools
功能门。使用 ZooKeeper 在集群中节点池的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster annotations: strimzi.io/node-pools: enabled spec: kafka: version: 3.5.0 replicas: 3 # ... storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false
应用
Kafka
资源:oc apply -f <kafka_configuration_file>
8.4. 配置实体 Operator
使用 Kafka.spec
中的 entityOperator
属性来配置实体 Operator。Entity Operator 用于管理在 Kafka 集群中运行的与 Kafka 相关的实体。它由以下 Operator 组成:
- 管理 Kafka 主题的主题 Operator
- 用于管理 Kafka 用户的用户 Operator
通过配置 Kafka
资源,Cluster Operator 可以部署 Entity Operator,包括一个或多个 Operator。部署后,Operator 会自动配置为处理 Kafka 集群的主题和用户。
每个 operator 只能监控单个命名空间。如需更多信息,请参阅 第 1.2.1 节 “在 OpenShift 命名空间中观察 AMQ Streams 资源”。
entityOperator
属性支持多个子属性:
-
tlsSidecar
-
topicOperator
-
userOperator
-
模板
tlsSidecar
属性包含 TLS sidecar 容器的配置,用于与 ZooKeeper 通信。
template
属性包含 Entity Operator pod 的配置,如标签、注解、关联性和容限。有关配置模板的详情,请参考 第 8.16 节 “自定义 OpenShift 资源”。
topicOperator
属性包含主题 Operator 的配置。当缺少这个选项时,在没有 Topic Operator 的情况下部署 Entity Operator。
userOperator
属性包含 User Operator 的配置。当缺少这个选项时,会在没有 User Operator 的情况下部署 Entity Operator。
有关配置实体 Operator 的属性的更多信息,请参阅 EntityUserOperatorSpec
schema 参考。
启用这两个 Operator 的基本配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... zookeeper: # ... entityOperator: topicOperator: {} userOperator: {}
如果将空对象({}
)用于 topicOperator
和 userOperator
,则所有属性都使用其默认值。
当缺少 topicOperator
和 userOperator
属性时,实体 Operator 不会被部署。
8.4.1. 配置主题 Operator
使用 Kafka.spec.entityOperator
中的 topicOperator
属性来配置 Topic Operator。
如果您使用单向主题管理的预览,则不会使用以下属性,并会被忽略: Kafka.spec.entityOperator.zookeeperSessionTimeoutSeconds
和 Kafka.spec.entityOperator.topicOperator.topicMetadataMaxAttempts
。有关单向主题管理的详情,请参考 第 9.1 节 “主题管理模式”。
支持以下属性:
watchedNamespace
-
主题 Operator 监视
KafkaTopic
资源的 OpenShift 命名空间。default 是部署 Kafka 集群的命名空间。 reconciliationIntervalSeconds
-
定期协调之间的间隔(以秒为单位)。默认
120
。 zookeeperSessionTimeoutSeconds
-
ZooKeeper 会话超时(以秒为单位)。默认
18
。 topicMetadataMaxAttempts
-
从 Kafka 获取主题元数据的尝试次数。每次尝试之间的时间都定义为指数避退。当主题创建可能会因为分区或副本数增加时,请考虑增加这个值。默认
6
。 image
-
image
属性可用于配置要使用的容器镜像。如需更多信息,请参阅有关配置镜像
属性 提供的信息。 资源
-
resources
属性配置分配给 Topic Operator 的资源数量。您可以为内存和
cpu
资源指定请求和限值。请求应该足以确保操作器的稳定性能。 logging
-
logging
属性配置 Topic Operator 的日志记录。如需更多信息,请参阅 主题 Operator 日志记录 上提供的信息。
主题 Operator 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... zookeeper: # ... entityOperator: # ... topicOperator: watchedNamespace: my-topic-namespace reconciliationIntervalSeconds: 60 resources: requests: cpu: "1" memory: 500Mi limits: cpu: "1" memory: 500Mi # ...
8.4.2. 配置用户 Operator
使用 Kafka.spec.entityOperator
中的 userOperator
属性来配置 User Operator。支持以下属性:
watchedNamespace
-
User Operator 监视
KafkaUser
资源的 OpenShift 命名空间。default 是部署 Kafka 集群的命名空间。 reconciliationIntervalSeconds
-
定期协调之间的间隔(以秒为单位)。默认
120
。 image
-
image
属性可用于配置要使用的容器镜像。如需更多信息,请参阅有关配置镜像
属性 提供的信息。 资源
-
resources
属性配置分配给 User Operator 的资源数量。您可以为内存和
cpu
资源指定请求和限值。请求应该足以确保操作器的稳定性能。 logging
-
logging
属性配置 User Operator 的日志记录。如需更多信息,请参阅 User Operator 日志记录 上提供的信息。 secretPrefix
-
secretPrefix
属性在 KafkaUser 资源创建的所有 Secret 的名称中添加前缀。例如,secretPrefix: kafka-
会将所有 Secret 名称的前缀为kafka-
。因此,名为my-user
的 KafkaUser 会创建一个名为kafka-my-user
的 Secret。
User Operator 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... zookeeper: # ... entityOperator: # ... userOperator: watchedNamespace: my-user-namespace reconciliationIntervalSeconds: 60 resources: requests: cpu: "1" memory: 500Mi limits: cpu: "1" memory: 500Mi # ...
8.5. 配置 Cluster Operator
使用环境变量配置 Cluster Operator。在 Deployment
配置文件中,指定 Cluster Operator 的容器镜像的环境变量。
AMQ Streams 发行工件提供的 Deployment
配置文件为 install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
。
您可以使用以下环境变量来配置 Cluster Operator。如果您以待机模式运行 Cluster Operator 副本,则需要额外的 环境变量来启用领导选举机制。
STRIMZI_NAMESPACE
以逗号分隔的 Operator 运行的命名空间列表。如果没有设置,则为空字符串,或设置为
*
,Cluster Operator 在所有命名空间中运行。Cluster Operator 部署可能会使用 Downward API 来自动将其设置为部署了 Cluster Operator 的命名空间。
Cluster Operator 命名空间的配置示例
env: - name: STRIMZI_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace
STRIMZI_FULL_RECONCILIATION_INTERVAL_MS
- 可选,默认为 120000 ms。定期协调 之间的间隔,以毫秒为单位。
STRIMZI_OPERATION_TIMEOUT_MS
- 可选,默认的 300000 ms。内部操作的超时时间,以毫秒为单位。当在常规 OpenShift 操作中使用 AMQ Streams 的时间超过通常时,增加这个值(例如下载 Docker 镜像的速度较慢)。
STRIMZI_ZOOKEEPER_ADMIN_SESSION_TIMEOUT_MS
-
可选,默认的 10000 ms。Cluster Operator 的 ZooKeeper admin 客户端的会话超时,以毫秒为单位。如果 Cluster Operator 的 ZooKeeper 请求因为超时问题定期失败,请增加这个值。通过
maxSessionTimeout
配置在 ZooKeeper 服务器端设置最大允许会话时间。默认情况下,最大会话超时值为 20 倍,即默认tickTime
(其默认值为 2000)为 40000 ms。如果您需要更高的超时,请更改maxSessionTimeout
ZooKeeper 服务器配置值。 STRIMZI_OPERATIONS_THREAD_POOL_SIZE
- 可选,默认 10。worker 线程池大小,用于各种异步和阻止由 Cluster Operator 运行的操作。
STRIMZI_OPERATOR_NAME
- 可选,默认为 pod 的主机名。在发出 OpenShift 事件时,Operator 名称标识 AMQ Streams 实例。
STRIMZI_OPERATOR_NAMESPACE
运行 Cluster Operator 的命名空间的名称。不要手动配置此变量。使用 Downward API。
env: - name: STRIMZI_OPERATOR_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace
STRIMZI_OPERATOR_NAMESPACE_LABELS
可选。运行 AMQ Streams Cluster Operator 的命名空间标签。使用命名空间标签在 网络策略 中配置命名空间选择器。网络策略只允许 AMQ Streams Cluster Operator 从带有这些标签的命名空间中访问操作对象。如果没有设置,则网络策略中的命名空间选择器被配置为允许从 OpenShift 集群中的任何命名空间中访问 Cluster Operator。
env: - name: STRIMZI_OPERATOR_NAMESPACE_LABELS value: label1=value1,label2=value2
STRIMZI_LABELS_EXCLUSION_PATTERN
可选,默认的正则表达式为
^app.kubernetes.io/(?!part-of).*
。用于过滤从主自定义资源传播到其子资源的正则表达式排除模式。标签排除过滤器不适用于模板部分中的标签,如spec.kafka.template.pod.metadata.labels
。env: - name: STRIMZI_LABELS_EXCLUSION_PATTERN value: "^key1.*"
STRIMZI_CUSTOM_{COMPONENT_NAME}_LABELS
可选。一个或多个自定义标签,应用到
{COMPONENT_NAME}
自定义资源创建的所有 pod。Cluster Operator 在创建自定义资源或下一次协调时会标记 pod。标签可应用到以下组件:
-
KAFKA
-
KAFKA_CONNECT
-
KAFKA_CONNECT_BUILD
-
ZOOKEEPER
-
ENTITY_OPERATOR
-
KAFKA_MIRROR_MAKER2
-
KAFKA_MIRROR_MAKER
-
CRUISE_CONTROL
-
KAFKA_BRIDGE
-
KAFKA_EXPORTER
-
STRIMZI_CUSTOM_RESOURCE_SELECTOR
可选。用于过滤 Cluster Operator 处理的自定义资源的标签选择器。Operator 仅在设置了指定标签的自定义资源上运行。Operator 不会看到没有这些标签的资源。标签选择器适用于
Kafka
,KafkaConnect
,KafkaBridge
,KafkaMirrorMaker
, 和KafkaMirrorMaker2
资源。只有在对应的 Kafka 和 Kafka Connect 集群具有匹配的标签时,才会执行KafkaRebalance
和KafkaConnector
资源。env: - name: STRIMZI_CUSTOM_RESOURCE_SELECTOR value: label1=value1,label2=value2
STRIMZI_KAFKA_IMAGES
-
必需。从 Kafka 版本到包含该版本的 Kafka 代理的对应 Docker 镜像的映射。所需的语法为空格或以逗号分隔的 <
version> = <image>
对。例如3.4.0=registry.redhat.io/amq-streams/kafka-34-rhel8:2.5.1, 3.5.0=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1
。当指定了属性Kafka.spec.kafka.version
但没有在Kafka
资源的Kafka.spec.kafka.image
时使用这个。 STRIMZI_DEFAULT_KAFKA_INIT_IMAGE
-
可选,默认
registry.redhat.io/amq-streams/strimzi-rhel8-operator:2.5.1
。如果没有将镜像指定为Kafka
资源中的kafka-init-image
,则用作 init 容器的默认镜像名称。init 容器在代理进行初始配置工作之前启动,如机架支持。 STRIMZI_KAFKA_CONNECT_IMAGES
-
必需。从 Kafka 版本映射到那个版本的 Kafka Connect 的对应 Docker 镜像。所需的语法为空格或以逗号分隔的 <
version> = <image>
对。例如3.4.0=registry.redhat.io/amq-streams/kafka-34-rhel8:2.5.1, 3.5.0=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1
。当指定KafkaConnect.spec.version
属性但没有KafkaConnect.spec.image
时,会使用它。 STRIMZI_KAFKA_MIRROR_MAKER_IMAGES
-
必需。此版本从 Kafka 版本到 MirrorMaker 的对应 Docker 镜像的映射。所需的语法为空格或以逗号分隔的 <
version> = <image>
对。例如3.4.0=registry.redhat.io/amq-streams/kafka-34-rhel8:2.5.1, 3.5.0=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1
。当指定KafkaMirrorMaker.spec.version
属性但没有KafkaMirrorMaker.spec.image
时,会使用它。 STRIMZI_DEFAULT_TOPIC_OPERATOR_IMAGE
-
可选,默认
registry.redhat.io/amq-streams/strimzi-rhel8-operator:2.5.1
。如果没有将镜像指定为Kafka
资源中的Kafka.spec.entityOperator.topicOperator.image
,则部署 Topic Operator 时使用的镜像名称作为默认镜像。 STRIMZI_DEFAULT_USER_OPERATOR_IMAGE
-
可选,默认
registry.redhat.io/amq-streams/strimzi-rhel8-operator:2.5.1
。如果没有将镜像指定为 Kafka 资源中的Kafka.spec.entityOperator.userOperator.image
,则部署 User Operator 时使用的镜像名称
。 STRIMZI_DEFAULT_TLS_SIDECAR_ENTITY_OPERATOR_IMAGE
-
可选,默认
registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1
。如果没有将镜像指定为 Kafka 资源中的Kafka.spec.entityOperator.tlsSidecar.image
,则用作实体 Operator 的 sidecar 容器时使用的镜像名称
。sidecar 提供 TLS 支持。 STRIMZI_IMAGE_PULL_POLICY
-
可选。应用到 Cluster Operator 管理的所有 pod 中的容器的
ImagePullPolicy
。有效值为Always
、ifNotP
resent 和Never
。如果未指定,则使用 OpenShift 默认值。更改策略将导致所有 Kafka、Kafka Connect 和 Kafka MirrorMaker 集群的滚动更新。 STRIMZI_IMAGE_PULL_SECRETS
-
可选。以逗号分隔的
Secret
名称列表。此处引用的 secret 包含从中拉取容器镜像的容器 registry 的凭证。secret 在 Cluster Operator 创建的所有 pod 的imagePullSecrets
属性中指定。更改此列表会导致所有 Kafka、Kafka Connect 和 Kafka MirrorMaker 集群的滚动更新。 STRIMZI_KUBERNETES_VERSION
可选。覆盖从 API 服务器检测到的 OpenShift 版本信息。
OpenShift 版本覆盖配置示例
env: - name: STRIMZI_KUBERNETES_VERSION value: | major=1 minor=16 gitVersion=v1.16.2 gitCommit=c97fe5036ef3df2967d086711e6c0c405941e14b gitTreeState=clean buildDate=2019-10-15T19:09:08Z goVersion=go1.12.10 compiler=gc platform=linux/amd64
KUBERNETES_SERVICE_DNS_DOMAIN
可选。覆盖默认的 OpenShift DNS 域名后缀。
默认情况下,OpenShift 集群中分配的服务具有使用默认后缀
cluster.local
的 DNS 域名。例如,对于 broker kafka-0 :
<cluster-name>-kafka-0.<cluster-name>-kafka-brokers.<namespace>.svc.cluster.local
DNS 域名添加到用于主机名验证的 Kafka 代理证书中。
如果您在集群中使用不同的 DNS 域名后缀,请将
KUBERNETES_SERVICE_DNS_DOMAIN
环境变量改为您用来与 Kafka 代理建立连接。STRIMZI_CONNECT_BUILD_TIMEOUT_MS
- 可选,默认的 300000 ms。使用额外连接器构建新 Kafka Connect 镜像的超时时间,以毫秒为单位。当使用 AMQ Streams 来构建包含许多连接器的容器镜像或使用较慢的容器 registry 时,请考虑增加这个值。
STRIMZI_NETWORK_POLICY_GENERATION
可选,默认为
true
。资源的网络策略。网络策略允许 Kafka 组件间的连接。将此环境变量设置为
false
以禁用网络策略生成。例如,您可能需要使用自定义网络策略,您可能需要执行此操作。自定义网络策略可让更多地控制组件间的连接。STRIMZI_DNS_CACHE_TTL
-
可选,默认的
30
。在本地 DNS 解析器中缓存成功名称查找的秒数。任何负值都表示缓存永久缓存。zero 意味着不会缓存,这可用于避免因为应用长缓存策略而连接错误。 STRIMZI_POD_SET_RECONCILIATION_ONLY
-
可选,默认为
false
。当设置为true
时,Cluster Operator 只协调StrimziPodSet
资源,以及其它自定义资源(Kafka
、KafkaConnect
等)的任何更改。此模式可用于确保根据需要重新创建 pod,但不会对集群进行其他更改。 STRIMZI_FEATURE_GATES
- 可选。启用或禁用由 功能门控制的功能和功能。
STRIMZI_POD_SECURITY_PROVIDER_CLASS
-
可选。配置可插拔
PodSecurityProvider
类,可用于为 Pod 和容器提供安全上下文配置。
8.5.1. 使用网络策略限制对 Cluster Operator 的访问
使用 STRIMZI_OPERATOR_NAMESPACE_LABELS
环境变量,使用命名空间标签为 Cluster Operator 建立网络策略。
Cluster Operator 可以在与它管理的资源相同的命名空间中运行,也可以在单独的命名空间中运行。默认情况下,STRIMZI_OPERATOR_NAMESPACE
环境变量被配置为使用 Downward API 查找运行 Cluster Operator 的命名空间。如果 Cluster Operator 在与资源相同的命名空间中运行,则 AMQ Streams 只需要本地访问。
如果 Cluster Operator 在单独命名空间中运行,则 OpenShift 集群中的任何命名空间都可以访问 Cluster Operator,除非配置了网络策略。通过添加命名空间标签,对 Cluster Operator 的访问仅限于指定的命名空间。
为 Cluster Operator 部署配置的网络策略
#... env: # ... - name: STRIMZI_OPERATOR_NAMESPACE_LABELS value: label1=value1,label2=value2 #...
8.5.2. 配置 Cluster Operator 的定期协调
使用 STRIMZI_FULL_RECONCILIATION_INTERVAL_MS
变量设置 Cluster Operator 定期协调的时间间隔。将其值替换为所需间隔(以毫秒为单位)。
为 Cluster Operator 部署配置的协调周期
#... env: # ... - name: STRIMZI_FULL_RECONCILIATION_INTERVAL_MS value: "120000" #...
Cluster Operator 对从 OpenShift 集群接收的适用集群资源的所有通知做出反应。如果操作器没有运行,或者因为某种原因没有收到通知,资源将从正在运行的 OpenShift 集群状态不同步。为了正确处理故障转移,Cluster Operator 会执行定期协调过程,以便它可以将资源的状态与当前集群部署进行比较,以便在所有这些部署之间具有一致的状态。
其他资源
8.5.3. 使用领导选举机制运行多个 Cluster Operator 副本
默认 Cluster Operator 配置可让领导选举机制运行 Cluster Operator 的多个并行副本。一个副本被选为活跃领导值,并运行部署的资源。其他副本以待机模式运行。当领导停止或失败时,其中一个备用副本被选为新领导,并开始操作部署的资源。
默认情况下,AMQ Streams 使用单个 Cluster Operator 副本运行,该副本始终是领导副本。当单个 Cluster Operator 副本停止或失败时,OpenShift 会启动新的副本。
运行具有多个副本的 Cluster Operator 并不重要。但是,在出现重大故障导致的大规模中断时,在待机时具有副本非常有用。例如,假设多个 worker 节点或整个可用区失败。故障可能会导致 Cluster Operator pod 和许多 Kafka pod 同时停机。如果后续的 pod 调度导致资源丢失,这可能会在运行单个 Cluster Operator 时延迟操作。
8.5.3.1. 为 Cluster Operator 副本启用领导选举机制
在运行额外的 Cluster Operator 副本时,配置领导选举环境变量。支持以下环境变量:
STRIMZI_LEADER_ELECTION_ENABLED
-
可选,
默认禁用
(默认为 )。启用或禁用领导选举机制,允许额外的 Cluster Operator 副本在待机上运行。
默认禁用领导选举机制。只有在安装时应用此环境变量时才启用。
STRIMZI_LEADER_ELECTION_LEASE_NAME
-
启用领导选举机制时需要。用于领导选举的 OpenShift
Lease
资源的名称。 STRIMZI_LEADER_ELECTION_LEASE_NAMESPACE
启用领导选举机制时需要。创建用于领导选举 OpenShift
Lease
资源的命名空间。您可以使用 Downward API 将其配置为部署 Cluster Operator 的命名空间。env: - name: STRIMZI_LEADER_ELECTION_LEASE_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace
STRIMZI_LEADER_ELECTION_IDENTITY
启用领导选举机制时需要。配置在领导选举过程中使用的给定 Cluster Operator 实例的身份。对于每个 operator 实例,身份必须是唯一的。您可以使用 Downward API 将其配置为部署 Cluster Operator 的 pod 的名称。
env: - name: STRIMZI_LEADER_ELECTION_IDENTITY valueFrom: fieldRef: fieldPath: metadata.name
STRIMZI_LEADER_ELECTION_LEASE_DURATION_MS
- 可选,默认 15000 ms。指定获取租期有效的持续时间。
STRIMZI_LEADER_ELECTION_RENEW_DEADLINE_MS
- 可选,默认的 10000 ms。指定领导应尝试维护领导期。
STRIMZI_LEADER_ELECTION_RETRY_PERIOD_MS
- 可选,默认的 2000 ms。指定领导到租期锁定的更新频率。
8.5.3.2. 配置 Cluster Operator 副本
要以待机模式运行额外的 Cluster Operator 副本,您需要增加副本数并启用领导选举机制。要配置领导选举机制,请使用领导选举环境变量。
要进行所需的更改,请配置位于 install/cluster-operator/
中的以下 Cluster Operator 安装文件:
- 060-Deployment-strimzi-cluster-operator.yaml
- 022-ClusterRole-strimzi-cluster-operator-role.yaml
- 022-RoleBinding-strimzi-cluster-operator.yaml
领导选举具有自己的 ClusterRole
和 RoleBinding
RBAC 资源,这些资源以 Cluster Operator 运行的命名空间为目标,而不是它监视的命名空间。
默认部署配置在与 Cluster Operator 相同的命名空间中创建一个名为 strimzi-cluster-operator
的 Lease
资源。Cluster Operator 使用租期来管理领导选举机制。RBAC 资源提供使用 Lease
资源的权限。如果您使用不同的 Lease
名称或命名空间,请相应地更新 ClusterRole
和 RoleBinding
文件。
先决条件
-
您需要具有权限的帐户来创建和管理
CustomResourceDefinition
和 RBAC (ClusterRole
和RoleBinding
)资源。
流程
编辑用于部署 Cluster Operator 的 Deployment
资源,该资源在 060-Deployment-strimzi-cluster-operator.yaml
文件中定义。
将
replicas
属性从 default (1)更改为与所需副本数匹配的值。增加 Cluster Operator 副本的数量
apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-cluster-operator labels: app: strimzi spec: replicas: 3
检查是否设置了 leader election
env
属性。如果没有设置,请配置它们。
要启用领导选举机制,
STRIMZI_LEADER_ELECTION_ENABLED
必须设置为true
(默认)。在本例中,租期的名称改为
my-strimzi-cluster-operator
。为 Cluster Operator 配置领导选举环境变量
# ... spec containers: - name: strimzi-cluster-operator # ... env: - name: STRIMZI_LEADER_ELECTION_ENABLED value: "true" - name: STRIMZI_LEADER_ELECTION_LEASE_NAME value: "my-strimzi-cluster-operator" - name: STRIMZI_LEADER_ELECTION_LEASE_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: STRIMZI_LEADER_ELECTION_IDENTITY valueFrom: fieldRef: fieldPath: metadata.name
有关可用环境变量的描述,请参阅 第 8.5.3.1 节 “为 Cluster Operator 副本启用领导选举机制”。
如果您为领导选举机制中使用的
Lease
资源指定了不同的名称或命名空间,请更新 RBAC 资源。(可选)在
022-ClusterRole-strimzi-cluster-operator-role.yaml
文件中编辑ClusterRole
资源。使用
Lease
资源的名称更新resourceNames
。将 ClusterRole 引用更新为租期
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: strimzi-cluster-operator-leader-election labels: app: strimzi rules: - apiGroups: - coordination.k8s.io resourceNames: - my-strimzi-cluster-operator # ...
(可选)在
022-RoleBinding-strimzi-cluster-operator.yaml
文件中编辑RoleBinding
资源。使用
Lease
资源的名称以及创建它的命名空间更新subjects.name
和subjects.namespace
。将 RoleBinding 引用更新为租期
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: strimzi-cluster-operator-leader-election labels: app: strimzi subjects: - kind: ServiceAccount name: my-strimzi-cluster-operator namespace: myproject # ...
部署 Cluster Operator:
oc create -f install/cluster-operator -n myproject
检查部署的状态:
oc get deployments -n myproject
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE strimzi-cluster-operator 3/3 3 3
READY
显示就绪/预期的副本数。当AVAILABLE
输出显示正确的副本数时,部署可以成功。
8.5.4. 配置 Cluster Operator HTTP 代理设置
如果您在 HTTP 代理后运行 Kafka 集群,您仍然可以在集群内和移出数据。例如,您可以使用连接器运行 Kafka Connect,该连接器从代理外推送和拉取镜像。或者,您可以使用代理与授权服务器连接。
配置 Cluster Operator 部署以指定代理环境变量。Cluster Operator 接受标准代理配置(HTTP_PROXY
、HTTPS_PROXY
和 NO_PROXY
)作为环境变量。代理设置适用于所有 AMQ Streams 容器。
代理地址的格式为 http://<ip_address>:<port_number>。要使用名称和密码设置代理,格式为 http://<username>:<password>@<ip-address>:<port_number>。
先决条件
-
您需要具有权限的帐户来创建和管理
CustomResourceDefinition
和 RBAC (ClusterRole
和RoleBinding
)资源。
流程
要在 Cluster Operator 中添加代理环境变量,请更新其
部署
配置 (install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
)。Cluster Operator 的代理配置示例
apiVersion: apps/v1 kind: Deployment spec: # ... template: spec: serviceAccountName: strimzi-cluster-operator containers: # ... env: # ... - name: "HTTP_PROXY" value: "http://proxy.com" 1 - name: "HTTPS_PROXY" value: "https://proxy.com" 2 - name: "NO_PROXY" value: "internal.com, other.domain.com" 3 # ...
或者,直接编辑
部署
:oc edit deployment strimzi-cluster-operator
如果您更新了 YAML 文件而不是直接编辑
Deployment
,请应用更改:oc create -f install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
其他资源
8.5.5. 使用 Cluster Operator 配置禁用 FIPS 模式
当在启用了 FIPS 的 OpenShift 集群中运行时,AMQ Streams 会自动切换到 FIPS 模式。通过在 Cluster Operator 的部署配置中将 FIPS_MODE
环境变量设置为 禁用
FIPS 模式。禁用 FIPS 模式后,AMQ Streams 会在 OpenJDK 中为所有组件禁用 FIPS。禁用 FIPS 模式后,AMQ Streams 不兼容 FIPS。AMQ Streams operator 以及所有操作对象的运行方式与在启用了 FIPS 的 OpenShift 集群中运行的方式相同。
流程
要在 Cluster Operator 中禁用 FIPS 模式,更新其
部署
配置install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
) 并增加FIPS_MODE
环境变量。Cluster Operator 的 FIPS 配置示例
apiVersion: apps/v1 kind: Deployment spec: # ... template: spec: serviceAccountName: strimzi-cluster-operator containers: # ... env: # ... - name: "FIPS_MODE" value: "disabled" 1 # ...
- 1
- 禁用 FIPS 模式。
或者,直接编辑
部署
:oc edit deployment strimzi-cluster-operator
如果您更新了 YAML 文件而不是直接编辑
Deployment
,请应用更改:oc apply -f install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
8.6. 配置 Kafka Connect
更新 KafkaConnect
自定义资源的 spec
属性来配置 Kafka Connect 部署。
使用 Kafka Connect 为 Kafka 集群设置外部数据连接。使用 KafkaConnect
资源的属性来配置 Kafka Connect 部署。
要深入了解 Kafka Connect 集群配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
KafkaConnector 配置
KafkaConnector
资源允许您以 OpenShift 原生的方式创建和管理 Kafka Connect 的连接器实例。
在 Kafka Connect 配置中,您可以通过添加 strimzi.io/use-connector-resources
注解来为 Kafka Connect 集群启用 KafkaConnectors。您还可以添加 构建配置
,以便 AMQ Streams 自动使用您数据连接所需的连接器插件构建容器镜像。Kafka Connect 连接器的外部配置通过 externalConfiguration
属性指定。
要管理连接器,您可以使用 KafkaConnector
自定义资源或 Kafka Connect REST API。KafkaConnector
资源必须部署到它们所链接的 Kafka Connect 集群相同的命名空间中。有关使用这些方法创建、重新配置或删除连接器的更多信息,请参阅 添加连接器。
连接器配置作为 HTTP 请求的一部分传递给 Kafka Connect,并存储在 Kafka 本身中。ConfigMap 和机密是用于存储配置和机密数据的标准 OpenShift 资源。您可以使用 ConfigMap 和 Secret 来配置连接器的特定元素。然后,您可以在 HTTP REST 命令中引用配置值,这样可保持配置独立且更安全。此方法特别适用于机密数据,如用户名、密码或证书。
处理大量信息
您可以调整配置以处理大量信息。如需更多信息,请参阅处理大量信息。
KafkaConnect
自定义资源配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect 1 metadata: name: my-connect-cluster annotations: strimzi.io/use-connector-resources: "true" 2 spec: replicas: 3 3 authentication: 4 type: tls certificateAndKey: certificate: source.crt key: source.key secretName: my-user-source bootstrapServers: my-cluster-kafka-bootstrap:9092 5 tls: 6 trustedCertificates: - secretName: my-cluster-cluster-cert certificate: ca.crt - secretName: my-cluster-cluster-cert certificate: ca2.crt config: 7 group.id: my-connect-cluster offset.storage.topic: my-connect-cluster-offsets config.storage.topic: my-connect-cluster-configs status.storage.topic: my-connect-cluster-status key.converter: org.apache.kafka.connect.json.JsonConverter value.converter: org.apache.kafka.connect.json.JsonConverter key.converter.schemas.enable: true value.converter.schemas.enable: true config.storage.replication.factor: 3 offset.storage.replication.factor: 3 status.storage.replication.factor: 3 build: 8 output: 9 type: docker image: my-registry.io/my-org/my-connect-cluster:latest pushSecret: my-registry-credentials plugins: 10 - name: debezium-postgres-connector artifacts: - type: tgz url: https://repo1.maven.org/maven2/io/debezium/debezium-connector-postgres/2.1.3.Final/debezium-connector-postgres-2.1.3.Final-plugin.tar.gz sha512sum: c4ddc97846de561755dc0b021a62aba656098829c70eb3ade3b817ce06d852ca12ae50c0281cc791a5a131cb7fc21fb15f4b8ee76c6cae5dd07f9c11cb7c6e79 - name: camel-telegram artifacts: - type: tgz url: https://repo.maven.apache.org/maven2/org/apache/camel/kafkaconnector/camel-telegram-kafka-connector/0.11.5/camel-telegram-kafka-connector-0.11.5-package.tar.gz sha512sum: d6d9f45e0d1dbfcc9f6d1c7ca2046168c764389c78bc4b867dab32d24f710bb74ccf2a007d7d7a8af2dfca09d9a52ccbc2831fc715c195a3634cca055185bd91 externalConfiguration: 11 env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: aws-creds key: awsAccessKey - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: aws-creds key: awsSecretAccessKey resources: 12 requests: cpu: "1" memory: 2Gi limits: cpu: "2" memory: 2Gi logging: 13 type: inline loggers: log4j.rootLogger: INFO readinessProbe: 14 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 metricsConfig: 15 type: jmxPrometheusExporter valueFrom: configMapKeyRef: name: my-config-map key: my-key jvmOptions: 16 "-Xmx": "1g" "-Xms": "1g" image: my-org/my-image:latest 17 rack: topologyKey: topology.kubernetes.io/zone 18 template: 19 pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: application operator: In values: - postgresql - mongodb topologyKey: "kubernetes.io/hostname" connectContainer: 20 env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry 21
- 1
- 使用
KafkaConnect
。 - 2
- 为 Kafka Connect 集群启用 KafkaConnectors。
- 3
- 运行任务的 worker 的副本节点数量。
- 4
- Kafka Connect 集群的身份验证,指定为 mTLS、基于令牌的 OAuth、基于 SASL 的 SCRAM-SHA-256/SCRAM-SHA-512 或 PLAIN。默认情况下,Kafka Connect 使用纯文本连接连接到 Kafka 代理。
- 5
- 用于连接到 Kafka 集群的 bootstrap 服务器。
- 6
- TLS 加密,使用密钥名称,其中 TLS 证书存储为集群的 X.509 格式。如果证书存储在同一 secret 中,则可以多次列出。
- 7
- worker 的 Kafka 连接配置(而不是连接器)。标准 Apache Kafka 配置可能会提供,仅限于不直接由 AMQ Streams 管理的属性。
- 8
- 构建用于自动使用连接器插件构建容器镜像的配置属性。
- 9
- (必需)推送新镜像的容器 registry 的配置。
- 10
- (必需)添加到新容器镜像的连接器插件及其工件列表。每个插件必须配置至少一个
工件
。 - 11
- 使用环境变量的连接器的外部配置,如此处或卷所示。您还可以使用配置供应商插件从外部来源加载配置值。
- 12
- 用于保留支持的资源、当前
cpu
和内存
以及限制的请求,以指定可消耗的最大资源。 - 13
- 指定 Kafka Connect 日志记录器和日志级别直接(
内联
)或通过 ConfigMap 间接(外部
)。自定义 Log4j 配置必须放在 ConfigMap 中的log4j.properties
或log4j2.properties
键下。对于 Kafka Connectlog4j.rootLogger
日志记录器,您可以将日志级别设置为 INFO, ERROR, WARN, TRACE, DEBUG,FATAL 或 OFF。 - 14
- 健康检查以了解何时重启容器(持续)以及容器可以接受流量(就绪状态)。
- 15
- Prometheus 指标,通过引用包含在此示例中 Prometheus JMX 导出器配置的 ConfigMap 启用。您可以使用对
metricsConfig.valueFrom.configMapKeyRef.key
下包含空文件的 ConfigMap 的引用来启用指标。 - 16
- JVM 配置选项,用于优化运行 Kafka Connect 的虚拟机(VM)的性能。
- 17
- ADVANCED OPTION:容器镜像配置,这只在特殊情况下建议使用。
- 18
- SPECIALIZED OPTION:部署的机架感知配置。这是用于在同一位置(而非跨地区)部署的专用选项。如果您希望连接器从最接近的副本而不是领导副本使用,则使用此选项。在某些情况下,使用来自最接近的副本的消耗可以提高网络利用率或降低成本。
topologyKey
必须与包含机架 ID 的节点标签匹配。此配置中使用的示例使用标准topology.kubernetes.io/zone
标签指定区。要从最接近的副本使用,请在 Kafka 代理配置中启用RackAwareReplicaSelector
。 - 19
- 模板自定义。此处的 pod 使用反关联性调度,因此 pod 不会调度到具有相同主机名的节点。
- 20
- 为分布式追踪设置环境变量。
- 21
- 使用 OpenTelemetry 启用分布式追踪。
8.6.1. 配置 Kafka Connect 用户授权
这个步骤描述了如何授权用户对 Kafka Connect 的访问。
当在 Kafka 中使用任何类型的授权时,Kafka Connect 用户需要对消费者组和 Kafka Connect 的内部主题的读/写权限。
消费者组和内部主题的属性由 AMQ Streams 自动配置,也可以在 KafkaConnect
资源的 spec
中明确指定。
KafkaConnect
资源中的配置属性示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect spec: # ... config: group.id: my-connect-cluster 1 offset.storage.topic: my-connect-cluster-offsets 2 config.storage.topic: my-connect-cluster-configs 3 status.storage.topic: my-connect-cluster-status 4 # ... # ...
此流程演示了如何在使用 简单
授权时提供访问权限。
简单授权使用由 Kafka AclAuthorizer
插件处理的 ACL 规则,以提供正确的访问级别。有关将 KafkaUser
资源配置为使用简单授权的更多信息,请参阅 AclRule
模式参考。
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
流程
编辑
KafkaUser
资源中的authorization
属性,为用户提供访问权限。在以下示例中,使用
字面
名称值为 Kafka Connect 主题和消费者组配置访问权限:属性 名称 offset.storage.topic
connect-cluster-offsets
status.storage.topic
connect-cluster-status
config.storage.topic
connect-cluster-configs
group
connect-cluster
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: # ... authorization: type: simple acls: # access to offset.storage.topic - resource: type: topic name: connect-cluster-offsets patternType: literal operations: - Create - Describe - Read - Write host: "*" # access to status.storage.topic - resource: type: topic name: connect-cluster-status patternType: literal operations: - Create - Describe - Read - Write host: "*" # access to config.storage.topic - resource: type: topic name: connect-cluster-configs patternType: literal operations: - Create - Describe - Read - Write host: "*" # consumer group - resource: type: group name: connect-cluster patternType: literal operations: - Read host: "*"
创建或更新资源。
oc apply -f KAFKA-USER-CONFIG-FILE
8.7. 配置 Kafka MirrorMaker 2
更新 KafkaMirrorMaker2
自定义资源的 spec
属性,以配置 MirrorMaker 2 部署。MirrorMaker 2 使用源集群配置进行数据消耗和目标集群配置进行数据输出。
MirrorMaker 2 基于 Kafka Connect 框架,连接器 管理集群之间的数据传输。
您可以配置 MirrorMaker 2 以定义 Kafka Connect 部署,包括源和目标集群的连接详情,然后运行 MirrorMaker 2 连接器的集合来进行连接。
MirrorMaker 2 支持源和目标集群之间的主题配置同步。您可以在 MirrorMaker 2 配置中指定源主题。MirrorMaker 2 监控源主题。MirrorMaker 2 会检测并将更改传播到源主题到远程主题。更改可能包括自动创建缺少的主题和分区。
在大多数情况下,您写入本地主题并从远程主题读取。虽然对远程主题不阻止写操作,但应该避免使用它们。
配置必须指定:
- 每个 Kafka 集群
- 每个集群的连接信息,包括身份验证
复制流和方向
- 集群到集群
- topic 的主题
要深入了解 Kafka MirrorMaker 2 集群配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
MirrorMaker 2 资源配置与之前的 MirrorMaker 版本不同,它现已弃用。当前不支持旧支持,因此任何资源都必须手动转换为新格式。
默认配置
MirrorMaker 2 为复制因素等属性提供默认配置值。最小配置保持不变,默认值如下:
MirrorMaker 2 的最小配置
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker2 spec: version: 3.5.0 connectCluster: "my-cluster-target" clusters: - alias: "my-cluster-source" bootstrapServers: my-cluster-source-kafka-bootstrap:9092 - alias: "my-cluster-target" bootstrapServers: my-cluster-target-kafka-bootstrap:9092 mirrors: - sourceCluster: "my-cluster-source" targetCluster: "my-cluster-target" sourceConnector: {}
您可以使用 mTLS 或 SASL 身份验证为源和目标集群配置访问控制。此流程演示了如何为源和目标集群使用 TLS 加密和 mTLS 身份验证的配置。
您可以在 KafkaMirrorMaker2
资源中指定您要从源集群复制的主题和消费者组。您可以使用 topicsPattern
和 groupsPattern
属性进行此操作。您可以提供名称列表或使用正则表达式。默认情况下,如果您未设置 topicsPattern
和 groupsPattern
属性,则会复制所有主题和消费者组。您可以使用 ".*"
正则表达式来复制所有主题和消费者组。但是,尝试只指定您需要指定主题和消费者组,以避免在集群中造成不必要的额外负载。
处理大量信息
您可以调整配置以处理大量信息。如需更多信息,请参阅处理大量信息。
KafkaMirrorMaker2
自定义资源配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker2 spec: version: 3.5.0 1 replicas: 3 2 connectCluster: "my-cluster-target" 3 clusters: 4 - alias: "my-cluster-source" 5 authentication: 6 certificateAndKey: certificate: source.crt key: source.key secretName: my-user-source type: tls bootstrapServers: my-cluster-source-kafka-bootstrap:9092 7 tls: 8 trustedCertificates: - certificate: ca.crt secretName: my-cluster-source-cluster-ca-cert - alias: "my-cluster-target" 9 authentication: 10 certificateAndKey: certificate: target.crt key: target.key secretName: my-user-target type: tls bootstrapServers: my-cluster-target-kafka-bootstrap:9092 11 config: 12 config.storage.replication.factor: 1 offset.storage.replication.factor: 1 status.storage.replication.factor: 1 tls: 13 trustedCertificates: - certificate: ca.crt secretName: my-cluster-target-cluster-ca-cert mirrors: 14 - sourceCluster: "my-cluster-source" 15 targetCluster: "my-cluster-target" 16 sourceConnector: 17 tasksMax: 10 18 autoRestart: 19 enabled: true config: replication.factor: 1 20 offset-syncs.topic.replication.factor: 1 21 sync.topic.acls.enabled: "false" 22 refresh.topics.interval.seconds: 60 23 replication.policy.class: "org.apache.kafka.connect.mirror.IdentityReplicationPolicy" 24 heartbeatConnector: 25 autoRestart: enabled: true config: heartbeats.topic.replication.factor: 1 26 replication.policy.class: "org.apache.kafka.connect.mirror.IdentityReplicationPolicy" checkpointConnector: 27 autoRestart: enabled: true config: checkpoints.topic.replication.factor: 1 28 refresh.groups.interval.seconds: 600 29 sync.group.offsets.enabled: true 30 sync.group.offsets.interval.seconds: 60 31 emit.checkpoints.interval.seconds: 60 32 replication.policy.class: "org.apache.kafka.connect.mirror.IdentityReplicationPolicy" topicsPattern: "topic1|topic2|topic3" 33 groupsPattern: "group1|group2|group3" 34 resources: 35 requests: cpu: "1" memory: 2Gi limits: cpu: "2" memory: 2Gi logging: 36 type: inline loggers: connect.root.logger.level: INFO readinessProbe: 37 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 jvmOptions: 38 "-Xmx": "1g" "-Xms": "1g" image: my-org/my-image:latest 39 rack: topologyKey: topology.kubernetes.io/zone 40 template: 41 pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: application operator: In values: - postgresql - mongodb topologyKey: "kubernetes.io/hostname" connectContainer: 42 env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry 43 externalConfiguration: 44 env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: aws-creds key: awsAccessKey - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: aws-creds key: awsSecretAccessKey
- 1
- Kafka Connect 和 Mirror Maker 2.0 版本,它们始终是相同的。
- 2
- 运行任务的 worker 的副本节点数量。
- 3
- Kafka Connect 的 Kafka 集群别名,它必须 指定目标 Kafka 集群。Kafka Connect 使用 Kafka 集群用于其内部主题。
- 4
- 正在同步的 Kafka 集群的规格。
- 5
- 源 Kafka 集群的集群别名。
- 6
- 源集群的身份验证,指定为 mTLS、基于令牌的 OAuth、基于 SASL 的 SCRAM-SHA-256/SCRAM-SHA-512 或 PLAIN。
- 7
- 用于连接到源 Kafka 集群的 Bootstrap 服务器。
- 8
- TLS 加密,使用密钥名称,其中 TLS 证书存储为源 Kafka 集群的 X.509 格式。如果证书存储在同一 secret 中,则可以多次列出。
- 9
- 目标 Kafka 集群的集群别名。
- 10
- 目标 Kafka 集群的身份验证配置方式与源 Kafka 集群相同。
- 11
- 用于连接到目标 Kafka 集群的 bootstrap 服务器。
- 12
- Kafka Connect 配置。标准 Apache Kafka 配置可能会提供,仅限于不直接由 AMQ Streams 管理的属性。
- 13
- 目标 Kafka 集群的 TLS 加密配置方式与源 Kafka 集群相同。
- 14
- MirrorMaker 2 连接器。
- 15
- MirrorMaker 2 连接器使用的源集群的集群别名。
- 16
- MirrorMaker 2 连接器使用的目标集群的集群别名。
- 17
MirrorSourceConnector
的配置,用于创建远程主题。配置会覆盖
默认配置选项。- 18
- 连接器可创建的最大任务数量。任务处理数据复制并并行运行。如果基础架构支持处理开销,增加这个值可以提高吞吐量。Kafka Connect 在集群成员间分发任务。如果任务数量超过 worker,则 worker 会被分配多个任务。对于 sink 连接器,旨在为每个主题分区消耗一个任务。对于源连接器,可以并行运行的任务数量也可能依赖于外部系统。如果无法实现并行性,则连接器会创建少于最大任务数。
- 19
- 启用自动重启失败的连接器和任务。最多进行 7 个重启尝试,之后必须手动重新启动。
- 20
- 在目标集群中创建的镜像主题的复制因素。
- 21
MirrorSourceConnector
offset-syncs
内部主题的复制因素,用于映射源和目标集群的偏移。- 22
- 启用 ACL 规则同步后,会将 ACL 应用到同步主题。默认值是
true
。此功能与 User Operator 不兼容。如果使用 User Operator,请将此属性设置为false
。 - 23
- 可选设置,用于更改新主题的检查频率。默认值为每 10 分钟进行一次检查。
- 24
- 添加可覆盖远程主题自动重命名的策略。该主题不会用源集群的名称来附加名称,而是保留其原始名称。此可选设置可用于主动/被动备份和数据迁移。必须为所有连接器指定属性。对于双向(active/active)复制,请使用
DefaultReplicationPolicy
类自动重命名远程主题,并为所有连接器指定replication.policy.separator
属性来添加自定义分隔符。 - 25
- 执行连接检查的
MirrorHeartbeatConnector
的配置。配置会覆盖
默认配置选项。 - 26
- 在目标集群中创建的心跳主题的复制因素。
- 27
- 用于跟踪偏移的
MirrorCheckpointConnector
的配置。配置会覆盖
默认配置选项。 - 28
- 在目标集群中创建的检查点主题的复制因素。
- 29
- 可选设置,用于更改新消费者组的检查频率。默认值为每 10 分钟进行一次检查。
- 30
- 用于同步消费者组偏移的可选设置,这对于在主动/被动配置中恢复非常有用。默认不启用同步。
- 31
- 如果启用了使用者组偏移的同步,您可以调整同步的频率。
- 32
- 调整检查偏移跟踪的频率。如果您更改了偏移同步的频率,您可能需要调整这些检查的频率。
- 33
- 定义为以逗号分隔的列表或正则表达式模式的源集群的主题复制。源连接器复制指定的主题。checkpoint 连接器跟踪指定主题的偏移。此处我们按名称请求三个主题。
- 34
- 从以逗号分隔列表或正则表达式模式定义的源集群的消费者组复制。checkpoint 连接器复制指定的消费者组。此处我们按名称请求三个消费者组。
- 35
- 用于保留支持的资源、当前
cpu
和内存
以及限制的请求,以指定可消耗的最大资源。 - 36
- 指定 Kafka Connect 日志记录器和日志级别直接(
内联
)或通过 ConfigMap 间接(外部
)。自定义 Log4j 配置必须放在 ConfigMap 中的log4j.properties
或log4j2.properties
键下。对于 Kafka Connectlog4j.rootLogger
日志记录器,您可以将日志级别设置为 INFO, ERROR, WARN, TRACE, DEBUG,FATAL 或 OFF。 - 37
- 健康检查以了解何时重启容器(持续)以及容器可以接受流量(就绪状态)。
- 38
- JVM 配置选项,用于优化运行 Kafka MirrorMaker 的虚拟机(VM)的性能。
- 39
- ADVANCED OPTION:容器镜像配置,这只在特殊情况下建议使用。
- 40
- SPECIALIZED OPTION:部署的机架感知配置。这是用于在同一位置(而非跨地区)部署的专用选项。如果您希望连接器从最接近的副本而不是领导副本使用,则使用此选项。在某些情况下,使用来自最接近的副本的消耗可以提高网络利用率或降低成本。
topologyKey
必须与包含机架 ID 的节点标签匹配。此配置中使用的示例使用标准topology.kubernetes.io/zone
标签指定区。要从最接近的副本使用,请在 Kafka 代理配置中启用RackAwareReplicaSelector
。 - 41
- 模板自定义。此处的 pod 使用反关联性调度,因此 pod 不会调度到具有相同主机名的节点。
- 42
- 为分布式追踪设置环境变量。
- 43
- 使用 OpenTelemetry 启用分布式追踪。
- 44
- 作为环境变量挂载到 Kafka MirrorMaker 的 OpenShift Secret 的外部配置。您还可以使用配置供应商插件从外部来源加载配置值。
8.7.1. 配置主动/主动或主动/被动模式
您可以在主动/被动或主动/主动集群配置中使用 MirrorMaker 2。
- 主动/主动集群配置
- 主动/主动配置有两个主动集群双向复制数据。应用程序可以使用任一集群。每个集群都可以提供相同的数据。这样,您可以在不同的地理位置提供相同的数据。因为消费者组在两个集群中都活跃,复制主题的使用者偏移不会重新同步到源集群。
- 主动/被动集群配置
- 主动/被动配置具有主动集群将数据复制到被动集群。被动集群保持在待机状态。在出现系统失败时,您可以使用被动集群进行数据恢复。
预期的结构是,生成者和消费者仅连接到活跃集群。每个目标目的地都需要一个 MirrorMaker 2 集群。
8.7.1.1. 双向复制(主动/主动)
MirrorMaker 2 架构支持 主动/主动集群配置中 的双向复制。
每个集群使用 source 和 remote 主题的概念复制其他集群的数据。由于同一主题存储在每个集群中,因此远程主题由 MirrorMaker 2 自动重命名,以代表源集群。原始集群的名称前面是主题名称的前面。
图 8.1. 主题重命名

通过标记原始集群,主题不会复制到该集群。
在配置需要数据聚合的架构时,通过 远程主题 复制的概念非常有用。消费者可以订阅同一集群中的源和目标主题,而无需单独的聚合集群。
8.7.1.2. 单向复制(主动/被动)
MirrorMaker 2 架构支持 主动/被动集群 配置中的单向复制。
您可以使用 主动/被动集群 配置来备份或将数据迁移到另一个集群。在这种情况下,您可能不希望自动重命名远程主题。
您可以通过将 IdentityReplicationPolicy
添加到源连接器配置来覆盖自动重命名。应用此配置后,主题会保留其原始名称。
8.7.2. 配置 MirrorMaker 2 连接器
将 MirrorMaker 2 连接器配置用于编配 Kafka 集群之间的数据同步的内部连接器。
MirrorMaker 2 由以下连接器组成:
MirrorSourceConnector
-
源连接器将主题从源集群复制到目标集群。它还复制 ACL,且是
MirrorCheckpointConnector
才能运行所必需的。 MirrorCheckpointConnector
- checkpoint 连接器会定期跟踪偏移。如果启用,它还在源和目标集群之间同步消费者组偏移。
MirrorHeartbeatConnector
- heartbeat 连接器会定期检查源和目标集群之间的连接。
下表描述了连接器属性以及您配置为使用它们的连接器。
属性 | sourceConnector | checkpointConnector | heartbeatConnector |
---|---|---|---|
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | |
| ✓ | ✓ | |
| ✓ | ✓ | |
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ | ||
| ✓ |
8.7.2.1. 更改消费者组偏移主题的位置
MirrorMaker 2 使用内部主题跟踪消费者组的偏移。
offset-syncs
主题-
offset-syncs
主题映射复制主题元数据的源和目标偏移。 checkpoints
主题-
checkpoints
主题映射源和目标集群中每个消费者组中复制的主题分区的最后提交偏移量。
因为它们被 MirrorMaker 2 内部使用,所以您不会直接与这些主题交互。
MirrorCheckpointConnector
为偏移跟踪发出 检查点。checkpoints
主题的偏移通过配置以预先确定的间隔进行跟踪。这两个主题都允许从故障转移上的正确偏移位置完全恢复复制。
offset-syncs
主题的位置是 源集群
。您可以使用 offset-syncs.topic.location
连接器配置将其更改为 目标集群
。您需要对包含该主题的集群进行读/写访问。使用目标集群作为 offset-syncs
主题的位置,您也可以使用 MirrorMaker 2,即使您只有对源集群的读访问权限。
8.7.2.2. 同步消费者组偏移
__consumer_offsets
主题存储各个消费者组的提交偏移信息。偏移同步会定期将源集群的消费者组的使用者偏移转移到目标集群的使用者偏移量中。
偏移同步在主动/被动配置中特别有用。如果主动集群停机,消费者应用程序可以切换到被动(standby)集群,并从最后一个传输的偏移位置获取。
要使用主题偏移同步,请通过将 sync.group.offsets.enabled
添加到检查点连接器配置来启用同步,并将属性设置为 true
。默认情况下禁用同步。
在源连接器中使用 IdentityReplicationPolicy
时,还必须在检查点连接器配置中进行配置。这样可确保为正确的主题应用镜像的消费者偏移。
消费者偏移仅针对目标集群中未激活的消费者组同步。如果消费者组位于目标集群中,则无法执行同步,并返回 UNKNOWN_MEMBER_ID
错误。
如果启用,则会定期从源集群同步偏移。您可以通过在检查点连接器配置中添加 sync.group.offsets.interval.seconds
和 emit.checkpoints.interval.seconds
来更改频率。属性指定同步消费者组偏移的频率,以及为偏移跟踪发送检查点的频率。这两个属性的默认值为 60 秒。您还可以使用 refresh.groups.interval.seconds
属性更改检查新消费者组的频率,该属性默认为每 10 分钟执行。
由于同步基于时间,因此消费者到被动集群的任何切换都可能会导致一些消息重复。
如果您有使用 Java 编写的应用程序,您可以使用 RemoteClusterUtils.java
工具通过应用同步偏移。实用程序从 checkpoints
主题获取消费者组的远程偏移。
8.7.2.3. 决定使用 heartbeat 连接器的时间
heartbeat 连接器发出心跳来检查源和目标 Kafka 集群之间的连接。内部 心跳
主题从源集群复制,这意味着 heartbeat 连接器必须连接到源集群。heartbeat
主题位于目标集群上,它允许它执行以下操作:
- 识别它要从中镜像数据的所有源集群
- 验证镜像进程的存活度和延迟
这有助于确保进程不会因为任何原因而卡住或已停止。虽然 heartbeat 连接器是监控 Kafka 集群之间的镜像进程的有价值的工具,但并非总是需要使用它。例如,如果您的部署具有低网络延迟或少量主题,您可能需要使用日志消息或其他监控工具来监控镜像过程。如果您决定不使用 heartbeat 连接器,只需从 MirrorMaker 2 配置中省略它。
8.7.2.4. 对齐 MirrorMaker 2 连接器的配置
为确保 MirrorMaker 2 连接器正常工作,请确保在连接器之间保持一致某些配置设置。具体来说,请确保以下属性在所有适用的连接器中具有相同的值:
-
replication.policy.class
-
replication.policy.separator
-
offset-syncs.topic.location
-
topic.filter.class
例如,source、检查点和 heartbeat 连接器的 replication.policy.class
的值必须相同。不匹配或缺失的设置会导致数据复制或偏移同步出现问题,因此必须使用同一设置保持所有相关连接器配置。
8.7.3. 配置 MirrorMaker 2 连接器制作者和消费者
MirrorMaker 2 连接器使用内部生产者和消费者。如果需要,您可以配置这些制作者和消费者来覆盖默认设置。
例如,您可以增加源制作者的 batch.size
,将主题发送到目标 Kafka 集群,以更好地容纳大量信息。
生产者和消费者配置选项取决于 MirrorMaker 2 的实施,并可能随时更改。
下表描述了每个连接器的生产者和消费者,以及您可以添加配置的位置。
类型 | Description | 配置 |
---|---|---|
制作者 | 将主题信息发送到目标 Kafka 集群。在处理大量数据时,请考虑调整此制作者的配置。 |
|
制作者 |
写入 |
|
消费者 | 从源 Kafka 集群检索主题信息。 |
|
类型 | Description | 配置 |
---|---|---|
制作者 | 发送消费者偏移检查点。 |
|
消费者 |
加载 |
|
您可以将 offset-syncs.topic.location
设置为 target
来使用目标 Kafka 集群作为 offset-syncs
主题的位置。
类型 | Description | 配置 |
---|---|---|
制作者 | 发送心跳。 |
|
以下示例演示了如何配置制作者和消费者。
连接器制作者和消费者的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker2 spec: version: 3.5.0 # ... mirrors: - sourceCluster: "my-cluster-source" targetCluster: "my-cluster-target" sourceConnector: tasksMax: 5 config: producer.override.batch.size: 327680 producer.override.linger.ms: 100 producer.request.timeout.ms: 30000 consumer.fetch.max.bytes: 52428800 # ... checkpointConnector: config: producer.override.request.timeout.ms: 30000 consumer.max.poll.interval.ms: 300000 # ... heartbeatConnector: config: producer.override.request.timeout.ms: 30000 # ...
8.7.4. 指定最大数据复制任务数
连接器创建负责在 Kafka 中移动数据的任务。每个连接器由一个或多个任务组成,它们分布到运行任务的一组 worker pod 中。在复制大量分区或同步大量消费者组的偏移时,增加任务数量可以帮助解决性能问题。
任务并行运行。为 worker 分配一个或多个任务。单个任务由一个 worker pod 处理,因此您不需要多个 worker pod 超过任务。如果有多个任务,worker 会处理多个任务。
您可以使用 tasksMax
属性指定 MirrorMaker 配置中的最大连接器任务数量。在不指定最大任务数量的情况下,默认设置是单个任务。
heartbeat 连接器始终使用单个任务。
为源和检查点连接器启动的任务数量是最大可能任务数和 tasksMax
的值之间的较低值。对于源连接器,可能的最大任务数是从源集群复制的每个分区。对于检查点连接器,可能的最大任务数都是从源集群复制的每个消费者组。在设置最多任务数量时,请考虑分区数量和支持进程的硬件资源。
如果基础架构支持处理开销,增加任务数量可以提高吞吐量和延迟。例如,添加更多任务可减少在有大量分区或消费者组时轮询源集群所需的时间。
当您有大量分区时,为源连接器增加任务数量很有用。
为源连接器增加任务数量
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker2 spec: # ... mirrors: - sourceCluster: "my-cluster-source" targetCluster: "my-cluster-target" sourceConnector: tasksMax: 10 # ...
当您有大量消费者组时,为检查点连接器增加任务数量很有用。
增加检查点连接器的任务数量
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker2 spec: # ... mirrors: - sourceCluster: "my-cluster-source" targetCluster: "my-cluster-target" checkpointConnector: tasksMax: 10 # ...
默认情况下,MirrorMaker 2 每 10 分钟检查新消费者组。您可以调整 refresh.groups.interval.seconds
配置以更改频率。在调整降低时请小心。更频繁的检查可能会对性能造成负面影响。
8.7.4.1. 检查连接器任务操作
如果使用 Prometheus 和 Grafana 监控部署,您可以检查 MirrorMaker 2 性能。AMQ Streams 提供的 MirrorMaker 2 Grafana 仪表板示例显示了与任务和延迟相关的以下指标。
- 任务数量
- 复制延迟
- 偏移同步延迟
8.7.5. 为远程主题同步 ACL 规则
将 MirrorMaker 2 与 AMQ Streams 搭配使用时,可以同步远程主题的 ACL 规则。但是,只有在您没有使用 User Operator 时,此功能才可用。
如果您使用 类型:在没有 User Operator 的情况下进行简单
授权,管理对代理的访问的 ACL 规则也适用于远程主题。这意味着,对源主题具有读取访问权限的用户也可以读取其远程等效内容。
OAuth 2.0 授权不支持以这种方式访问远程主题。
8.7.6. 保护 Kafka MirrorMaker 2 部署
此流程描述了概述保护 MirrorMaker 2 部署所需的配置。
源 Kafka 集群和目标 Kafka 集群需要单独的配置。您还需要单独的用户配置来提供 MirrorMaker 连接到源和目标 Kafka 集群所需的凭证。
对于 Kafka 集群,您可以为 OpenShift 集群内的安全连接指定内部监听程序,以及用于 OpenShift 集群外的连接的外部监听程序。
您可以配置身份验证和授权机制。为源和目标 Kafka 集群实施的安全选项必须与为 MirrorMaker 2 实施的安全选项兼容。
创建集群和用户身份验证凭证后,您可以在 MirrorMaker 配置中指定它们以进行安全连接。
在此过程中,会使用 Cluster Operator 生成的证书,但 您可以通过安装自己的证书 来替换它们。您还可以将监听程序 配置为使用由外部 CA (证书颁发机构)管理的 Kafka 侦听器证书。
开始前
在开始这个过程前,请查看 AMQ Streams 提供的示例配置文件。它们包括使用 mTLS 或 SCRAM-SHA-512 身份验证保护 MirrorMaker 2 部署的示例。示例指定用于在 OpenShift 集群内连接的内部监听程序。
这个示例提供了完整的授权配置,包括 MirrorMaker 2 所需的所有 ACL,以允许对源和目标 Kafka 集群的操作。
先决条件
- AMQ Streams 正在运行
- 源和目标集群的独立命名空间
此流程假设将源和目标集群安装到单独的命名空间,如果要使用 Topic Operator,则需要这样做。主题 Operator 只监视指定命名空间中的单个集群。
通过将集群划分为命名空间,您需要复制集群 secret,以便可以在命名空间外访问它们。您需要引用 MirrorMaker 配置中的 secret。
流程
配置两个
Kafka
资源,一个用于保护源 Kafka 集群,另一个用于保护目标 Kafka 集群。您可以为身份验证和启用授权添加监听程序配置。
在本例中,为带有 TLS 加密和 mTLS 身份验证的 Kafka 集群配置了内部监听程序。启用 Kafka
简单
授权。使用 TLS 加密和 mTLS 身份验证的源 Kafka 集群配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-source-cluster spec: kafka: version: 3.5.0 replicas: 1 listeners: - name: tls port: 9093 type: internal tls: true authentication: type: tls authorization: type: simple config: offsets.topic.replication.factor: 1 transaction.state.log.replication.factor: 1 transaction.state.log.min.isr: 1 default.replication.factor: 1 min.insync.replicas: 1 inter.broker.protocol.version: "3.5" storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false zookeeper: replicas: 1 storage: type: persistent-claim size: 100Gi deleteClaim: false entityOperator: topicOperator: {} userOperator: {}
使用 TLS 加密和 mTLS 身份验证的目标 Kafka 集群配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-target-cluster spec: kafka: version: 3.5.0 replicas: 1 listeners: - name: tls port: 9093 type: internal tls: true authentication: type: tls authorization: type: simple config: offsets.topic.replication.factor: 1 transaction.state.log.replication.factor: 1 transaction.state.log.min.isr: 1 default.replication.factor: 1 min.insync.replicas: 1 inter.broker.protocol.version: "3.5" storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false zookeeper: replicas: 1 storage: type: persistent-claim size: 100Gi deleteClaim: false entityOperator: topicOperator: {} userOperator: {}
在单独的命名空间中创建或更新
Kafka
资源。oc apply -f <kafka_configuration_file> -n <namespace>
Cluster Operator 创建监听程序并设置集群和客户端证书颁发机构(CA)证书,以便在 Kafka 集群中启用身份验证。
证书在 secret <
cluster_name> -cluster-ca-cert
中创建。配置两个
KafkaUser
资源,一个用于源 Kafka 集群的用户,另一个用于目标 Kafka 集群的用户。-
配置与对应的源和目标 Kafka 集群相同的身份验证和授权类型。例如,如果您在源 Kafka 集群的
Kafka
配置中使用了tls
验证和simple
授权类型,请在KafkaUser
配置中使用相同的。 配置 MirrorMaker 2 所需的 ACL,以允许对源和目标 Kafka 集群执行操作。
内部 MirrorMaker 连接器和底层 Kafka Connect 框架使用 ACL。
mTLS 验证的源用户配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-source-user labels: strimzi.io/cluster: my-source-cluster spec: authentication: type: tls authorization: type: simple acls: # MirrorSourceConnector - resource: # Not needed if offset-syncs.topic.location=target type: topic name: mm2-offset-syncs.my-target-cluster.internal operations: - Create - DescribeConfigs - Read - Write - resource: # Needed for every topic which is mirrored type: topic name: "*" operations: - DescribeConfigs - Read # MirrorCheckpointConnector - resource: type: cluster operations: - Describe - resource: # Needed for every group for which offsets are synced type: group name: "*" operations: - Describe - resource: # Not needed if offset-syncs.topic.location=target type: topic name: mm2-offset-syncs.my-target-cluster.internal operations: - Read
mTLS 验证的目标用户配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-target-user labels: strimzi.io/cluster: my-target-cluster spec: authentication: type: tls authorization: type: simple acls: # Underlying Kafka Connect internal topics to store configuration, offsets, or status - resource: type: group name: mirrormaker2-cluster operations: - Read - resource: type: topic name: mirrormaker2-cluster-configs operations: - Create - Describe - DescribeConfigs - Read - Write - resource: type: topic name: mirrormaker2-cluster-status operations: - Create - Describe - DescribeConfigs - Read - Write - resource: type: topic name: mirrormaker2-cluster-offsets operations: - Create - Describe - DescribeConfigs - Read - Write # MirrorSourceConnector - resource: # Needed for every topic which is mirrored type: topic name: "*" operations: - Create - Alter - AlterConfigs - Write # MirrorCheckpointConnector - resource: type: cluster operations: - Describe - resource: type: topic name: my-source-cluster.checkpoints.internal operations: - Create - Describe - Read - Write - resource: # Needed for every group for which the offset is synced type: group name: "*" operations: - Read - Describe # MirrorHeartbeatConnector - resource: type: topic name: heartbeats operations: - Create - Describe - Write
注意您可以通过将
type
设置为tls-external
来使用 User Operator 外部发布的证书。如需更多信息,请参阅KafkaUserSpec
模式参考。-
配置与对应的源和目标 Kafka 集群相同的身份验证和授权类型。例如,如果您在源 Kafka 集群的
在您为源和目标 Kafka 集群创建的每个命名空间中创建或更新
KafkaUser
资源。oc apply -f <kafka_user_configuration_file> -n <namespace>
User Operator 根据所选的验证类型创建代表客户端(MirrorMaker)的用户,以及用于客户端身份验证的安全凭证。
User Operator 创建一个名称与
KafkaUser
资源相同的新 secret。secret 包含 mTLS 验证的私钥和公钥。公钥包含在用户证书中,该证书由客户端 CA 签名。使用身份验证详情配置
KafkaMirrorMaker2
资源,以连接到源和目标 Kafka 集群。带有 TLS 加密和 mTLS 身份验证的 MirrorMaker 2 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker-2 spec: version: 3.5.0 replicas: 1 connectCluster: "my-target-cluster" clusters: - alias: "my-source-cluster" bootstrapServers: my-source-cluster-kafka-bootstrap:9093 tls: 1 trustedCertificates: - secretName: my-source-cluster-cluster-ca-cert certificate: ca.crt authentication: 2 type: tls certificateAndKey: secretName: my-source-user certificate: user.crt key: user.key - alias: "my-target-cluster" bootstrapServers: my-target-cluster-kafka-bootstrap:9093 tls: 3 trustedCertificates: - secretName: my-target-cluster-cluster-ca-cert certificate: ca.crt authentication: 4 type: tls certificateAndKey: secretName: my-target-user certificate: user.crt key: user.key config: # -1 means it will use the default replication factor configured in the broker config.storage.replication.factor: -1 offset.storage.replication.factor: -1 status.storage.replication.factor: -1 mirrors: - sourceCluster: "my-source-cluster" targetCluster: "my-target-cluster" sourceConnector: config: replication.factor: 1 offset-syncs.topic.replication.factor: 1 sync.topic.acls.enabled: "false" heartbeatConnector: config: heartbeats.topic.replication.factor: 1 checkpointConnector: config: checkpoints.topic.replication.factor: 1 sync.group.offsets.enabled: "true" topicsPattern: "topic1|topic2|topic3" groupsPattern: "group1|group2|group3"
在与目标 Kafka 集群相同的命名空间中创建或更新
KafkaMirrorMaker2
资源。oc apply -f <mirrormaker2_configuration_file> -n <namespace_of_target_cluster>
8.8. 配置 Kafka MirrorMaker (已弃用)
更新 KafkaMirrorMaker
自定义资源的 spec
属性,以配置 Kafka MirrorMaker 部署。
您可以使用 TLS 或 SASL 身份验证为生产者和消费者配置访问控制。此流程演示了如何在消费者和生成器端使用 TLS 加密和 mTLS 身份验证的配置。
要深入了解 Kafka MirrorMaker 集群配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
Kafka MirrorMaker 1 (称为文档中的 MirrorMaker )已在 Apache Kafka 3.0.0 中弃用,并将在 Apache Kafka 4.0.0 中删除。因此,在 AMQ Streams 中还已弃用了用于部署 Kafka MirrorMaker
1 的 KafkaMirrorMaker 自定义资源。当使用 Apache Kafka 4.0.0 时,KafkaMirrorMaker
资源将从 AMQ Streams 中删除。作为替代方法,在 IdentityReplicationPolicy
中使用 KafkaMirrorMaker2
自定义资源。
KafkaMirrorMaker
自定义资源配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker metadata: name: my-mirror-maker spec: replicas: 3 1 consumer: bootstrapServers: my-source-cluster-kafka-bootstrap:9092 2 groupId: "my-group" 3 numStreams: 2 4 offsetCommitInterval: 120000 5 tls: 6 trustedCertificates: - secretName: my-source-cluster-ca-cert certificate: ca.crt authentication: 7 type: tls certificateAndKey: secretName: my-source-secret certificate: public.crt key: private.key config: 8 max.poll.records: 100 receive.buffer.bytes: 32768 producer: bootstrapServers: my-target-cluster-kafka-bootstrap:9092 abortOnSendFailure: false 9 tls: trustedCertificates: - secretName: my-target-cluster-ca-cert certificate: ca.crt authentication: type: tls certificateAndKey: secretName: my-target-secret certificate: public.crt key: private.key config: compression.type: gzip batch.size: 8192 include: "my-topic|other-topic" 10 resources: 11 requests: cpu: "1" memory: 2Gi limits: cpu: "2" memory: 2Gi logging: 12 type: inline loggers: mirrormaker.root.logger: INFO readinessProbe: 13 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 metricsConfig: 14 type: jmxPrometheusExporter valueFrom: configMapKeyRef: name: my-config-map key: my-key jvmOptions: 15 "-Xmx": "1g" "-Xms": "1g" image: my-org/my-image:latest 16 template: 17 pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: application operator: In values: - postgresql - mongodb topologyKey: "kubernetes.io/hostname" mirrorMakerContainer: 18 env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: 19 type: opentelemetry
- 1
- 副本节点的数量。
- 2
- 用于消费者和制作者的 Bootstrap 服务器。
- 3
- 消费者的组 ID。
- 4
- 消费者流的数量。
- 5
- 偏移 auto-commit 间隔(以毫秒为单位)。
- 6
- TLS 加密,使用密钥名称,其中 TLS 证书存储为 X.509 格式,用于消费者或生成者。如果证书存储在同一 secret 中,则可以多次列出。
- 7
- 为消费者或生成者(指定为 mTLS、基于令牌的 OAuth、基于 SASL 的 SCRAM-SHA-256/SCRAM-SHA-512 或 PLAIN)进行身份验证。
- 8
- consumer 和 producer 的 Kafka 配置选项。
- 9
- 如果将
abortOnSendFailure
属性设置为true
,则 Kafka MirrorMaker 将退出,容器将按照消息发送失败重启。 - 10
- 从源镜像到目标 Kafka 集群包含的主题列表。
- 11
- 用于保留支持的资源、当前
cpu
和内存
以及限制的请求,以指定可消耗的最大资源。 - 12
- 指定日志记录器和日志级别直接(
内联
)或通过 ConfigMap 间接添加(外部
)。自定义 Log4j 配置必须放在 ConfigMap 中的log4j.properties
或log4j2.properties
键下。MirrorMaker 只有一个日志记录器,名为mirrormaker.root.logger
。您可以将日志级别设置为 INFO, ERROR, WARN, TRACE, DEBUG, FATAL 或 OFF。 - 13
- 健康检查以了解何时重启容器(持续)以及容器可以接受流量(就绪状态)。
- 14
- Prometheus 指标,通过引用包含在此示例中 Prometheus JMX 导出器配置的 ConfigMap 启用。您可以使用对
metricsConfig.valueFrom.configMapKeyRef.key
下包含空文件的 ConfigMap 的引用来启用指标。 - 15
- JVM 配置选项,用于优化运行 Kafka MirrorMaker 的虚拟机(VM)的性能。
- 16
- ADVANCED OPTION:容器镜像配置,这只在特殊情况下建议使用。
- 17
- 模板自定义。此处的 pod 使用反关联性调度,因此 pod 不会调度到具有相同主机名的节点。
- 18
- 为分布式追踪设置环境变量。
- 19
- 使用 OpenTelemetry 启用分布式追踪。警告
将
abortOnSendFailure
属性设置为false
时,生产者会尝试在主题中发送下一个消息。原始消息可能会丢失,因为没有尝试重新发送失败的消息。
8.9. 配置 Kafka Bridge
更新 KafkaBridge
自定义资源的 spec
属性来配置 Kafka Bridge 部署。
为了防止在不同 Kafka Bridge 实例处理客户端消费者请求时出现问题,必须使用基于地址的路由来确保将请求路由到正确的 Kafka Bridge 实例。另外,每个独立的 Kafka Bridge 实例都必须有副本。Kafka Bridge 实例有自己的状态,它不与另一个实例共享。
要深入了解 Kafka Bridge 集群配置选项,请参阅 AMQ Streams 自定义资源 API 参考。
KafkaBridge
自定义资源配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: replicas: 3 1 bootstrapServers: <cluster_name>-cluster-kafka-bootstrap:9092 2 tls: 3 trustedCertificates: - secretName: my-cluster-cluster-cert certificate: ca.crt - secretName: my-cluster-cluster-cert certificate: ca2.crt authentication: 4 type: tls certificateAndKey: secretName: my-secret certificate: public.crt key: private.key http: 5 port: 8080 cors: 6 allowedOrigins: "https://strimzi.io" allowedMethods: "GET,POST,PUT,DELETE,OPTIONS,PATCH" consumer: 7 config: auto.offset.reset: earliest producer: 8 config: delivery.timeout.ms: 300000 resources: 9 requests: cpu: "1" memory: 2Gi limits: cpu: "2" memory: 2Gi logging: 10 type: inline loggers: logger.bridge.level: INFO # enabling DEBUG just for send operation logger.send.name: "http.openapi.operation.send" logger.send.level: DEBUG jvmOptions: 11 "-Xmx": "1g" "-Xms": "1g" readinessProbe: 12 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 image: my-org/my-image:latest 13 template: 14 pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: application operator: In values: - postgresql - mongodb topologyKey: "kubernetes.io/hostname" bridgeContainer: 15 env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry 16
- 1
- 副本节点的数量。
- 2
- 用于连接到目标 Kafka 集群的 bootstrap 服务器。使用 Kafka 集群的名称作为 < cluster_name>。
- 3
- TLS 加密,使用密钥名称,其中 TLS 证书存储为源 Kafka 集群的 X.509 格式。如果证书存储在同一 secret 中,则可以多次列出。
- 4
- Kafka Bridge 集群的身份验证,指定为 mTLS、基于令牌的 OAuth、基于 SASL 的 SCRAM-SHA-256/SCRAM-SHA-512 或 PLAIN。默认情况下,Kafka Bridge 在没有身份验证的情况下连接到 Kafka 代理。
- 5
- 对 Kafka 代理的 HTTP 访问。
- 6
- CORS 访问指定所选资源和访问方法。请求中的其他 HTTP 标头描述了允许访问 Kafka 集群的源。
- 7
- 消费者配置选项。
- 8
- 制作者配置选项。
- 9
- 用于保留支持的资源、当前
cpu
和内存
以及限制的请求,以指定可消耗的最大资源。 - 10
- 指定 Kafka Bridge 日志记录器和日志级别直接(
内联
)或通过 ConfigMap 间接(外部
)。自定义 Log4j 配置必须放在 ConfigMap 中的log4j.properties
或log4j2.properties
键下。对于 Kafka Bridge loggers,您可以将日志级别设置为 INFO, ERROR, WARN, TRACE, DEBUG, FATAL 或 OFF。 - 11
- JVM 配置选项,用于优化运行 Kafka Bridge 的虚拟机(VM)的性能。
- 12
- 健康检查以了解何时重启容器(持续)以及容器可以接受流量(就绪状态)。
- 13
- 可选:容器镜像配置,仅在特殊情况下推荐。
- 14
- 模板自定义。此处的 pod 使用反关联性调度,因此 pod 不会调度到具有相同主机名的节点。
- 15
- 为分布式追踪设置环境变量。
- 16
- 使用 OpenTelemetry 启用分布式追踪。
8.10. 配置 Kafka 和 ZooKeeper 存储
作为有状态应用程序,Kafka 和 ZooKeeper 将数据存储在磁盘上。对于这个数据,AMQ Streams 支持三种存储类型:
- Ephemeral (推荐只在开发时使用)
- 持久性
- JBOD (仅限 Kafka )
在配置 Kafka
资源时,您可以指定 Kafka 代理及其对应 ZooKeeper 节点使用的存储类型。您可以使用以下资源中的 storage
属性配置存储类型:
-
Kafka.spec.kafka
-
Kafka.spec.zookeeper
存储类型在 type
字段中配置。
有关存储配置属性的更多信息,请参阅 schema 参考:
部署 Kafka 集群后无法更改存储类型。
8.10.1. 数据存储注意事项
要使 AMQ Streams 正常工作,有效的数据存储基础架构至关重要。我们强烈建议您使用块存储。AMQ Streams 仅测试用于块存储。文件存储(如 NFS)没有被测试,无法保证它可以正常工作。
为您的块存储选择以下选项之一:
- 基于云的块存储解决方案,如 Amazon Elastic Block Store (EBS)
- 使用 本地持久性卷的持久性存储
- 由 光纤通道或 iSCSI等协议访问的存储区域网络(SAN)卷
AMQ Streams 不需要 OpenShift 原始块卷。
8.10.1.1. 文件系统
Kafka 使用文件系统来存储信息。AMQ Streams 与 XFS 和 ext4 文件系统兼容,它们通常与 Kafka 一起使用。在选择和设置文件系统时,请考虑部署的底层架构和要求。
如需更多信息,请参阅 Kafka 文档中的 Filesystem Selection。
8.10.1.2. 磁盘用量
为 Apache Kafka 和 ZooKeeper 使用单独的磁盘。
虽然使用固态驱动器 (SSD) 并不是必须的,但它可以在大型集群中提高 Kafka 的性能,其中数据会异步发送到多个主题,并从多个主题接收。SSD 与 ZooKeeper 特别有效,这需要快速、低延迟数据访问。
您不需要置备复制存储,因为 Kafka 和 ZooKeeper 都有内置数据复制。
8.10.2. 临时存储
临时数据存储是临时的。节点上的所有 pod 共享本地临时存储空间。只要使用它的 pod 正在运行,数据就会保留。当 pod 被删除时,数据会丢失。虽然 pod 可以在高可用性环境中恢复数据。
由于其临时性质,仅推荐使用临时存储进行开发和测试。
临时存储使用 emptyDir
卷来存储数据。当 pod 分配给节点时,会创建一个 emptyDir
卷。您可以使用 sizeLimit
属性为 emptyDir
设置存储总量。
临时存储不适用于单节点 ZooKeeper 集群或 Kafka 主题,复制因子为 1。
要使用临时存储,您可以将 Kafka
或 ZooKeeper
资源中的存储类型配置设置为 临时
。
临时存储配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... storage: type: ephemeral # ... zookeeper: # ... storage: type: ephemeral # ...
8.10.2.1. Kafka 日志目录的挂载路径
Kafka 代理使用临时卷来作为挂载到以下路径的日志目录:
/var/lib/kafka/data/kafka-logIDX
其中 IDX
是 Kafka 代理 pod 索引。例如 /var/lib/kafka/data/kafka-log0
。
8.10.3. 持久性存储
持久数据存储在系统中断时保留数据。对于使用持久数据存储的 pod,数据会在 pod 失败后保留,并重启。
动态置备框架可创建带有持久性存储的集群。Pod 配置使用持久性卷声明 (PVC) 在持久性卷 (PV) 上发出存储请求。PV 是代表存储卷的存储资源。PV 独立于使用它们的 pod。PVC 请求创建 pod 时所需的存储量。PV 的底层存储基础架构不需要理解。如果 PV 与存储条件匹配,PVC 会绑定到 PV。
由于其永久性质,建议在生产环境中使用持久性存储。
PVC 可以通过指定 StorageClass 来请求不同类型的持久性存储。存储类定义存储配置集和动态置备 PV。如果没有指定存储类,则使用默认存储类。持久性存储选项可能包括 SAN 存储类型或本地持久性卷。
要使用持久性存储,您可以将 Kafka
或 ZooKeeper
资源中的存储类型配置设置为 persistent-claim
。
在生产环境中,建议进行以下配置:
-
对于 Kafka,使用一个或多个
type: persistent-claim
卷配置type: jbod
-
对于 ZooKeeper,配置
type: persistent-claim
持久性存储还具有以下配置选项:
id
(可选)-
存储标识号。对于 JBOD 存储声明中定义的存储卷,这个选项是必须的。默认值为
0。
Size
(必需)- 持久性卷声明的大小,如 "1000Gi"。
类
(可选)-
用于动态卷置备的 OpenShift StorageClass。
存储类
配置包括详细描述卷配置集的参数。 selector
(可选)- 配置以指定特定 PV。提供 key:value 对,代表所选卷的标签。
deleteClaim
(optional)-
布尔值,用于指定在卸载集群时是否删除 PVC。默认为
false
。
只有在支持持久性卷大小的 OpenShift 版本中才支持增加现有 AMQ Streams 集群中的持久性卷大小。要重新定义大小的持久性卷必须使用支持卷扩展的存储类。对于不支持卷扩展的 OpenShift 和存储类的其他版本,您必须在部署集群前决定必要的存储大小。无法减少现有持久性卷的大小。
Kafka 和 ZooKeeper 持久性存储配置示例
# ... spec: kafka: # ... storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false - id: 1 type: persistent-claim size: 100Gi deleteClaim: false - id: 2 type: persistent-claim size: 100Gi deleteClaim: false # ... zookeeper: storage: type: persistent-claim size: 1000Gi # ...
如果没有指定存储类,则使用默认值。以下示例指定了存储类。
使用特定存储类的持久性存储配置示例
# ... storage: type: persistent-claim size: 1Gi class: my-storage-class # ...
使用选择器 (selector
)来指定提供某些功能的标记的持久性卷,如 SSD。
使用选择器的持久性存储配置示例
# ... storage: type: persistent-claim size: 1Gi selector: hdd-type: ssd deleteClaim: true # ...
8.10.3.1. 存储类覆盖
您可以为一个或多个 Kafka 代理或 ZooKeeper 节点指定不同的存储类,而不是使用默认存储类。例如,当存储类仅限于不同的可用区或数据中心时,这非常有用。您可以使用 overrides
字段来实现这一目的。
在本例中,默认存储类名为 my-storage-class
:
使用存储类覆盖的 AMQ Streams 集群示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: labels: app: my-cluster name: my-cluster namespace: myproject spec: # ... kafka: replicas: 3 storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false class: my-storage-class overrides: - broker: 0 class: my-storage-class-zone-1a - broker: 1 class: my-storage-class-zone-1b - broker: 2 class: my-storage-class-zone-1c # ... # ... zookeeper: replicas: 3 storage: deleteClaim: true size: 100Gi type: persistent-claim class: my-storage-class overrides: - broker: 0 class: my-storage-class-zone-1a - broker: 1 class: my-storage-class-zone-1b - broker: 2 class: my-storage-class-zone-1c # ...
由于配置的 overrides
属性,卷使用以下存储类:
-
ZooKeeper 节点 0 的持久性卷使用
my-storage-class-zone-1a
。 -
ZooKeeper 节点 1 的持久性卷使用
my-storage-class-zone-1b
。 -
ZooKeeepr 节点 2 的持久性卷使用
my-storage-class-zone-1c
。 -
Kafka 代理 0 的持久性卷使用
my-storage-class-zone-1a
。 -
Kafka 代理 1 的持久性卷使用
my-storage-class-zone-1b
。 -
Kafka 代理 2 的持久性卷使用
my-storage-class-zone-1c
。
overrides
属性目前仅用于覆盖存储类配置。目前不支持对其他存储配置属性覆盖。目前不支持其他存储配置属性。
8.10.3.2. 持久性存储的 PVC 资源
使用持久性存储时,它会使用以下名称创建 PVC:
data-cluster-name-kafka-idx
-
用于存储 Kafka 代理 pod
idx
数据的卷的 PVC。 data-cluster-name-zookeeper-idx
-
用于为 ZooKeeper 节点 pod
idx
存储数据的卷的 PVC。
8.10.3.3. Kafka 日志目录的挂载路径
Kafka 代理使用持久性卷作为挂载到以下路径的日志目录:
/var/lib/kafka/data/kafka-logIDX
其中 IDX
是 Kafka 代理 pod 索引。例如 /var/lib/kafka/data/kafka-log0
。
8.10.4. 重新调整持久性卷大小
只要存储基础架构支持,就可以调整集群使用的持久性卷而不造成数据丢失的风险。在配置更新后,AMQ Streams 会指示存储基础架构进行更改。使用 persistent-claim 卷的 AMQ Streams 集群支持存储扩展。
只有在每个代理使用多个磁盘时,才能减少存储。在将磁盘中的所有分区移动到同一代理(intra-broker)或同一集群(集群内)中的其他代理后,您可以删除磁盘。
您无法缩小持久性卷的大小,因为它目前在 OpenShift 中不被支持。
先决条件
- 支持调整大小的 OpenShift 集群。
- Cluster Operator 正在运行。
- 使用支持卷扩展的存储类创建的持久性卷的 Kafka 集群。
流程
编辑集群的
Kafka
资源。更改
size
属性,以增加分配给 Kafka 集群、ZooKeeper 集群或两者的持久性卷大小。-
对于 Kafka 集群,更新
spec.kafka.storage
下的size
属性。 -
对于 ZooKeeper 集群,更新
spec.zookeeper.storage
下的size
属性。
将卷大小增加到
2000Gi
的 Kafka 配置apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... storage: type: persistent-claim size: 2000Gi class: my-storage-class # ... zookeeper: # ...
-
对于 Kafka 集群,更新
创建或更新资源:
oc apply -f <kafka_configuration_file>
OpenShift 增加所选持久性卷的容量,以响应 Cluster Operator 的请求。完成调整大小后,Cluster Operator 会重启所有使用调整大小的持久性卷的 pod。这会自动发生。
验证集群中相关 pod 的存储容量是否已增加:
oc get pv
带有增加存储的 Kafka 代理 pod
NAME CAPACITY CLAIM pvc-0ca459ce-... 2000Gi my-project/data-my-cluster-kafka-2 pvc-6e1810be-... 2000Gi my-project/data-my-cluster-kafka-0 pvc-82dc78c9-... 2000Gi my-project/data-my-cluster-kafka-1
输出显示了与代理 pod 关联的每个 PVC 的名称。
其他资源
- 有关在 OpenShift 中重新定义持久性卷大小的更多信息,请参阅使用 Kubernetes 调整持久卷。
8.10.5. JBOD 存储
您可以将 AMQ Streams 配置为使用 JBOD,这是多个磁盘或卷的数据存储配置。JBOD 是为 Kafka 代理提供增加数据存储的方法。它还可以提高性能。
Kafka 仅支持 JBOD 存储。
JBOD 配置由一个或多个卷描述,每个卷可以是 临时或 持久。JBOD 卷声明的规则和约束与临时存储和持久性存储的规则和约束相同。例如,在置备后,您无法缩小持久性存储卷的大小,或者当类型为 ephemeral
时无法更改 sizeLimit
的值。
要使用 JBOD 存储,您可以将 Kafka
资源中的存储类型配置设置为 jbod
。volumes
属性允许您描述组成 JBOD 存储阵列或配置的磁盘。
JBOD 存储配置示例
# ... storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false - id: 1 type: persistent-claim size: 100Gi deleteClaim: false # ...
创建 JBOD 卷后无法更改 ID。您可以从 JBOD 配置中添加或删除卷。
8.10.5.1. JBOD 存储的 PVC 资源
当持久性存储用于声明 JBOD 卷时,它会创建一个具有以下名称的 PVC:
data-id-cluster-name-kafka-idx
-
用于存储 Kafka 代理 pod
idx
数据的卷的 PVC。id
是用于存储 Kafka 代理 pod 数据的卷的 ID。
8.10.5.2. Kafka 日志目录的挂载路径
Kafka 代理使用 JBOD 卷作为挂载到以下路径的日志目录:
/var/lib/kafka/data-id/kafka-logidx
其中 id
是用于存储 Kafka 代理 pod idx
数据的卷的 ID。例如 /var/lib/kafka/data-0/kafka-log0
。
8.10.6. 将卷添加到 JBOD 存储
此流程描述了如何将卷添加到配置为使用 JBOD 存储的 Kafka 集群中。它不能应用到配置为使用任何其他存储类型的 Kafka 集群。
当在过去和删除的 id
下添加新卷时,您必须确保之前使用的 PersistentVolumeClaims
已被删除。
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
- 具有 JBOD 存储的 Kafka 集群
流程
编辑
Kafka
资源中的spec.kafka.storage.volumes
属性。将新卷添加到volumes
数组中。例如,使用 id2
添加新卷:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false - id: 1 type: persistent-claim size: 100Gi deleteClaim: false - id: 2 type: persistent-claim size: 100Gi deleteClaim: false # ... zookeeper: # ...
创建或更新资源:
oc apply -f <kafka_configuration_file>
创建新主题或将现有分区重新分配给新磁盘。
提示Cruise Control 是一个重新分配分区的有效工具。要执行 intra-broker 磁盘平衡,您可以在
KafkaRebalance.spec
下将rebalanceDisk
设置为true
。
8.10.7. 从 JBOD 存储中删除卷
此流程描述了如何从配置为使用 JBOD 存储的 Kafka 集群中删除卷。它不能应用到配置为使用任何其他存储类型的 Kafka 集群。JBOD 存储始终必须包含至少一个卷。
为了避免数据丢失,您必须在删除卷前移动所有分区。
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
- 具有两个或多个卷的 JBOD 存储的 Kafka 集群
流程
从您要删除的磁盘中重新分配所有分区。分区中的任何数据仍被分配给要删除的磁盘。
提示您可以使用
kafka-reassign-partitions.sh
工具重新分配分区。编辑
Kafka
资源中的spec.kafka.storage.volumes
属性。从 volumes 阵列中删除一个或多个卷
。例如,使用 ids1
和2
删除卷:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... storage: type: jbod volumes: - id: 0 type: persistent-claim size: 100Gi deleteClaim: false # ... zookeeper: # ...
创建或更新资源:
oc apply -f <kafka_configuration_file>
8.11. 配置 CPU 和内存限值和请求
默认情况下,AMQ Streams Cluster Operator 不会为其部署的操作对象指定 CPU 和内存资源请求和限值。确保足够分配资源对于在 Kafka 中保持稳定性并获得最佳性能至关重要。理想的资源分配取决于您的特定要求和用例。
建议通过 设置适当的请求和限值,为每个容器配置 CPU 和内存资源。
8.12. 配置 pod 调度
为了避免同一 OpenShift 节点上调度的应用程序之间的资源冲突导致性能下降,您可以独立于关键工作负载调度 Kafka pod。这可以通过选择特定节点或专门用于 Kafka 的一组节点来实现。
8.12.1. 指定关联性、容限和拓扑分布限制
使用关联性、容限和拓扑分布约束将 kafka 资源的 pod 调度到节点上。关联性、容限和拓扑分布约束使用以下资源中的 关联性
、tolerations
和 topologySpreadConstraint
属性进行配置:
-
Kafka.spec.kafka.template.pod
-
Kafka.spec.zookeeper.template.pod
-
Kafka.spec.entityOperator.template.pod
-
KafkaConnect.spec.template.pod
-
KafkaBridge.spec.template.pod
-
KafkaMirrorMaker.spec.template.pod
-
KafkaMirrorMaker2.spec.template.pod
关联性
、容限
和 topologySpreadConstraint
属性的格式遵循 OpenShift 规格。关联性配置可以包含不同类型的关联性:
- Pod 关联性和反关联性
- 节点关联性
8.12.1.1. 使用 pod 反关联性以避免关键应用程序共享节点
使用 pod 反关联性来确保关键应用程序永远不会调度到同一磁盘上。在运行 Kafka 集群时,建议使用 pod 反关联性来确保 Kafka 代理不与其他工作负载共享节点,如数据库。
8.12.1.2. 使用节点关联性将工作负载调度到特定的节点上
OpenShift 集群通常由许多不同类型的 worker 节点组成。有些工作负载针对 CPU 重度工作负载(某些用于内存)进行了优化,另一个则针对存储(快速本地 SSD)或网络进行了优化。使用不同节点有助于优化成本和性能。要达到最佳可能的性能,务必要调度 AMQ Streams 组件以使用正确的节点。
OpenShift 使用节点关联性将工作负载调度到特定的节点上。节点关联性允许您为要在其上调度 pod 的节点创建调度约束。约束指定为标签选择器。您可以使用内置节点标签(如 beta.kubernetes.io/instance-type
或自定义标签)来指定该标签,以选择正确的节点。
8.12.1.3. 对专用节点使用节点关联性和容限
使用污点来创建专用节点,然后通过配置节点关联性和容限来在专用节点上调度 Kafka pod。
集群管理员可以将所选 OpenShift 节点标记为污点。具有污点的节点不包括在常规调度中,常规 pod 不会被调度到它们上运行。只有可以容许节点上污点集的服务才能调度到该节点上。此类节点上运行的其他服务是唯一一个系统服务,如日志收集器或软件定义的网络。
在专用节点上运行 Kafka 及其组件会有很多优点。没有其他应用程序在同一节点上运行,这可能会导致距离或消耗 Kafka 所需的资源。从而提高了性能和稳定性。
8.12.2. 配置 pod 反关联性,将每个 Kafka 代理调度到不同的 worker 节点上
许多 Kafka 代理或 ZooKeeper 节点可以在同一 OpenShift worker 节点上运行。如果 worker 节点失败,则它们将同时不可用。要提高可靠性,您可以使用 podAntiAffinity
配置在不同的 OpenShift worker 节点上调度每个 Kafka 代理或 ZooKeeper 节点。
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
流程
编辑指定集群部署的资源中的
affinity
属性。要确保 Kafka 代理或 ZooKeeper 节点没有 worker 节点,请使用strimzi.io/name
标签。将topologyKey
设置为kubernetes.io/hostname
,以指定所选 pod 没有调度到具有相同主机名的节点。这仍然允许同一 worker 节点由单个 Kafka 代理和单个 ZooKeeper 节点共享。例如:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... template: pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: strimzi.io/name operator: In values: - CLUSTER-NAME-kafka topologyKey: "kubernetes.io/hostname" # ... zookeeper: # ... template: pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: strimzi.io/name operator: In values: - CLUSTER-NAME-zookeeper topologyKey: "kubernetes.io/hostname" # ...
其中
CLUSTER-NAME
是 Kafka 自定义资源的名称。如果您甚至希望确保 Kafka 代理和 ZooKeeper 节点不共享同一 worker 节点,请使用
strimzi.io/cluster
标签。例如:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... template: pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: strimzi.io/cluster operator: In values: - CLUSTER-NAME topologyKey: "kubernetes.io/hostname" # ... zookeeper: # ... template: pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: strimzi.io/cluster operator: In values: - CLUSTER-NAME topologyKey: "kubernetes.io/hostname" # ...
其中
CLUSTER-NAME
是 Kafka 自定义资源的名称。创建或更新资源。
oc apply -f <kafka_configuration_file>
8.12.3. 在 Kafka 组件中配置 pod 反关联性
Pod 反关联性配置有助于 Kafka 代理的稳定性和性能。通过使用 podAntiAffinity
,OpenShift 不会将 Kafka 代理调度到与其他工作负载相同的节点上。通常,您要避免 Kafka 在与其他网络或存储密集型应用程序(如数据库、存储或其他消息传递平台)相同的 worker 节点上运行。
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
流程
编辑指定集群部署的资源中的
affinity
属性。使用标签指定不应在同一节点上调度的 pod。topologyKey
应设置为kubernetes.io/hostname
,以指定所选 pod 不应调度到具有相同主机名的节点。例如:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... template: pod: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: application operator: In values: - postgresql - mongodb topologyKey: "kubernetes.io/hostname" # ... zookeeper: # ...
创建或更新资源。
这可以通过
oc apply
来完成:oc apply -f <kafka_configuration_file>
8.12.4. 在 Kafka 组件中配置节点关联性
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
流程
标记应调度 AMQ Streams 组件的节点。
这可以通过
oc label
来完成:oc label node NAME-OF-NODE node-type=fast-network
或者,也可以重复使用一些现有标签。
编辑指定集群部署的资源中的
affinity
属性。例如:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... template: pod: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-type operator: In values: - fast-network # ... zookeeper: # ...
创建或更新资源。
这可以通过
oc apply
来完成:oc apply -f <kafka_configuration_file>
8.12.5. 设置专用节点并在其上调度 pod
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
流程
- 选择应用作专用的节点。
- 确保没有在这些节点上调度工作负载。
在所选节点上设置污点:
这可以通过
oc adm taint
来完成:oc adm taint node NAME-OF-NODE dedicated=Kafka:NoSchedule
另外,还要为所选节点添加标签。
这可以通过
oc label
来完成:oc label node NAME-OF-NODE dedicated=Kafka
编辑指定集群部署的资源中的
关联性
和容限
属性。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... template: pod: tolerations: - key: "dedicated" operator: "Equal" value: "Kafka" effect: "NoSchedule" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: dedicated operator: In values: - Kafka # ... zookeeper: # ...
创建或更新资源。
这可以通过
oc apply
来完成:oc apply -f <kafka_configuration_file>
8.13. 配置日志记录级别
在 Kafka 组件和 AMQ Streams operator 的自定义资源中配置日志级别。您可以在自定义资源的 spec.logging
属性中直接指定日志级别。或者,您可以使用 configMapKeyRef
属性在自定义资源中引用的 ConfigMap 中定义日志属性。
使用 ConfigMap 的优点在于,日志记录属性在一个位置维护,并可以被多个资源访问。您还可以为多个资源重复使用 ConfigMap。如果使用 ConfigMap 为 AMQ Streams Operator 指定日志记录器,您也可以附加日志记录规格来添加过滤器。
您可以在日志记录规格中指定 日志类型
:
-
直接指定日志记录级别时的
内联
-
引用 ConfigMap 时的
外部
内联
日志记录配置示例
spec: # ... logging: type: inline loggers: kafka.root.logger.level: INFO
外部日志记录
配置示例
spec: # ... logging: type: external valueFrom: configMapKeyRef: name: my-config-map key: my-config-map-key
ConfigMap 的 name
和 key
的值是必需的。如果没有设置 name
或 key
,则会使用默认日志记录。
8.13.1. Kafka 组件和 Operator 的日志记录选项
有关为特定 Kafka 组件或 Operator 配置日志记录的更多信息,请参阅以下部分。
Kafka 组件日志记录
Operator 日志记录
8.13.2. 为日志创建 ConfigMap
要使用 ConfigMap 定义日志记录属性,您可以创建 ConfigMap,然后将其引用为资源 spec
中的日志记录定义的一部分。
ConfigMap 必须包含适当的日志记录配置。
-
Kafka 组件、ZooZ 和 Kafka Bridge 的
log4j.properties
-
Topic Operator 和 User Operator 的
log4j2.properties
配置必须放在这些属性下。
在此流程中,ConfigMap 为 Kafka 资源定义根日志记录器。
流程
创建 ConfigMap。
您可以将 ConfigMap 创建为 YAML 文件或从属性文件创建。
带有 Kafka 根日志记录器定义的 ConfigMap 示例:
kind: ConfigMap apiVersion: v1 metadata: name: logging-configmap data: log4j.properties: kafka.root.logger.level="INFO"
如果您使用属性文件,请在命令行中指定该文件:
oc create configmap logging-configmap --from-file=log4j.properties
属性文件定义日志配置:
# Define the logger kafka.root.logger.level="INFO" # ...
在资源的
spec
中定义 外部日志记录,将logging.valueFrom.configMapKeyRef.name
设置为 ConfigMap 的名称,并将logging.valueFrom.configMapKeyRef.key
设置为此 ConfigMap 中的键。spec: # ... logging: type: external valueFrom: configMapKeyRef: name: logging-configmap key: log4j.properties
创建或更新资源。
oc apply -f <kafka_configuration_file>
8.13.3. 配置 Cluster Operator 日志
Cluster Operator 日志记录通过名为 strimzi-cluster-operator
的 ConfigMap
来配置。安装 Cluster Operator 时会创建一个包含日志记录配置的 ConfigMap
。文件的 install/cluster-operator/050-
中描述了此 ConfigMap。您可以通过更改此 ConfigMap
-strimzi-cluster-operator.yamlConfigMap
中的 data.log4j2.properties
值来配置 Cluster Operator 日志记录。
要更新日志记录配置,您可以编辑 050-ConfigMap-strimzi-cluster-operator.yaml
文件,然后运行以下命令:
oc create -f install/cluster-operator/050-ConfigMap-strimzi-cluster-operator.yaml
或者,直接编辑 ConfigMap
:
oc edit configmap strimzi-cluster-operator
使用这个 ConfigMap,您可以控制日志记录的各个方面,包括根日志记录器级别、日志输出格式和不同组件的日志级别。monitorInterval
设置决定了日志记录配置重新加载的频率。您还可以控制 Kafka AdminClient
、ZooKTrustManager
、Netty 和 OkHttp 客户端的日志级别。Netnetty 是 AMQ Streams 用于网络通信的框架,而 OkHttp 是用于发出 HTTP 请求的库。
如果在部署 Cluster Operator 时缺少 ConfigMap
,则使用默认的日志记录值。
如果在部署 Cluster Operator 后意外删除 ConfigMap
,则会使用最近载入的日志配置。创建新的 ConfigMap
以加载新的日志记录配置。
不要从 ConfigMap
中删除 monitorInterval
选项。
8.13.4. 在 AMQ Streams operator 中添加日志记录过滤器
如果您使用 ConfigMap 为 AMQ Streams operator 配置(log4j2)日志记录级别,您还可以定义日志记录过滤器来限制日志中返回的内容。
当您有大量日志信息时,日志记录过滤器很有用。假设您将日志记录器的日志级别设置为 DEBUG (rootLogger.level="DEBUG"
)。日志记录过滤器减少了该级别为日志记录器返回的日志数量,以便您可以专注于特定资源。当设置了过滤器时,只会记录与过滤器匹配的日志消息。
过滤器使用 标记来指定 日志中要包含的内容。您可以为标记指定一个 kind、namespace 和 name。例如,如果 Kafka 集群失败,您可以通过将 kind 指定为 Kafka
来隔离日志,并使用故障集群的命名空间和名称。
本例显示了一个名为 my-kafka-cluster
的 Kafka 集群的标记过滤器。
基本日志记录过滤器配置
rootLogger.level="INFO" appender.console.filter.filter1.type=MarkerFilter 1 appender.console.filter.filter1.onMatch=ACCEPT 2 appender.console.filter.filter1.onMismatch=DENY 3 appender.console.filter.filter1.marker=Kafka(my-namespace/my-kafka-cluster) 4
您可以创建一个或多个过滤器。在这里,为两个 Kafka 集群过滤日志。
多个日志记录过滤器配置
appender.console.filter.filter1.type=MarkerFilter appender.console.filter.filter1.onMatch=ACCEPT appender.console.filter.filter1.onMismatch=DENY appender.console.filter.filter1.marker=Kafka(my-namespace/my-kafka-cluster-1) appender.console.filter.filter2.type=MarkerFilter appender.console.filter.filter2.onMatch=ACCEPT appender.console.filter.filter2.onMismatch=DENY appender.console.filter.filter2.marker=Kafka(my-namespace/my-kafka-cluster-2)
在 Cluster Operator 中添加过滤器
要将过滤器添加到 Cluster Operator 中,请更新其日志记录 ConfigMap YAML 文件(install/cluster-operator/050-ConfigMap-strimzi-cluster-operator.yaml
)。
流程
更新
050-ConfigMap-strimzi-cluster-operator.yaml
文件,将过滤器属性添加到 ConfigMap 中。在本例中,过滤器属性只返回
my-kafka-cluster
Kafka 集群的日志:kind: ConfigMap apiVersion: v1 metadata: name: strimzi-cluster-operator data: log4j2.properties: #... appender.console.filter.filter1.type=MarkerFilter appender.console.filter.filter1.onMatch=ACCEPT appender.console.filter.filter1.onMismatch=DENY appender.console.filter.filter1.marker=Kafka(my-namespace/my-kafka-cluster)
或者,直接编辑
ConfigMap
:oc edit configmap strimzi-cluster-operator
如果您更新了 YAML 文件而不是直接编辑
ConfigMap
,请通过部署 ConfigMap 来应用更改:oc create -f install/cluster-operator/050-ConfigMap-strimzi-cluster-operator.yaml
在主题 Operator 或 User Operator 中添加过滤器
要在主题 Operator 或 User Operator 中添加过滤器,请创建或编辑日志记录 ConfigMap。
在此过程中,使用 Topic Operator 的过滤器创建日志记录 ConfigMap。用户 Operator 使用相同的方法。
流程
创建 ConfigMap。
您可以将 ConfigMap 创建为 YAML 文件或从属性文件创建。
在本例中,过滤器属性只返回
my-topic
主题的日志:kind: ConfigMap apiVersion: v1 metadata: name: logging-configmap data: log4j2.properties: rootLogger.level="INFO" appender.console.filter.filter1.type=MarkerFilter appender.console.filter.filter1.onMatch=ACCEPT appender.console.filter.filter1.onMismatch=DENY appender.console.filter.filter1.marker=KafkaTopic(my-namespace/my-topic)
如果您使用属性文件,请在命令行中指定该文件:
oc create configmap logging-configmap --from-file=log4j2.properties
属性文件定义日志配置:
# Define the logger rootLogger.level="INFO" # Set the filters appender.console.filter.filter1.type=MarkerFilter appender.console.filter.filter1.onMatch=ACCEPT appender.console.filter.filter1.onMismatch=DENY appender.console.filter.filter1.marker=KafkaTopic(my-namespace/my-topic) # ...
在资源的
spec
中定义 外部日志记录,将logging.valueFrom.configMapKeyRef.name
设置为 ConfigMap 的名称,并将logging.valueFrom.configMapKeyRef.key
设置为此 ConfigMap 中的键。对于主题 Operator,日志记录在
Kafka
资源的topicOperator
配置中指定。spec: # ... entityOperator: topicOperator: logging: type: external valueFrom: configMapKeyRef: name: logging-configmap key: log4j2.properties
- 通过部署 Cluster Operator 来应用更改:
create -f install/cluster-operator -n my-cluster-operator-namespace
8.14. 使用 ConfigMap 添加配置
使用 ConfigMap
资源在 AMQ Streams 部署中添加特定的配置。ConfigMap 使用键值对来存储非机密数据。添加到 ConfigMap 的配置数据在一个位置维护,并可在组件间重复使用。
ConfigMap 只能存储以下类型的配置数据:
- 日志记录配置
- 指标配置
- Kafka 连接连接器的外部配置
您不能将 ConfigMap 用于其他配置区域。
在配置组件时,您可以使用 configMapKeyRef
属性添加对 ConfigMap 的引用。
例如,您可以使用 configMapKeyRef
引用为日志记录提供配置的 ConfigMap。您可以使用 ConfigMap 传递一个 Log4j 配置文件。您可以添加对 日志记录配置
的引用。
日志的 ConfigMap 示例
spec: # ... logging: type: external valueFrom: configMapKeyRef: name: my-config-map key: my-config-map-key
要将 ConfigMap 用于指标配置,您可以以同样的方式添加对组件的 metricsConfig
配置的引用。
externalConfiguration
属性从挂载到 pod 的 ConfigMap (或 Secret)中的数据作为环境变量或卷提供。您可以将外部配置数据用于 Kafka Connect 使用的连接器。数据可能与外部数据源相关,提供连接器与该数据源通信所需的值。
例如,您可以使用 configMapKeyRef
属性将 ConfigMap 中的配置数据作为环境变量传递。
提供环境变量值的 ConfigMap 示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect spec: # ... externalConfiguration: env: - name: MY_ENVIRONMENT_VARIABLE valueFrom: configMapKeyRef: name: my-config-map key: my-key
如果您使用外部管理的 ConfigMap,请使用配置供应商加载 ConfigMap 中的数据。
8.14.1. 命名自定义 ConfigMap
AMQ Streams 在部署到 OpenShift 时 创建自己的 ConfigMap 和其他资源。ConfigMap 包含运行组件所需的数据。不得编辑 AMQ Streams 创建的 ConfigMap。
确保您创建的任何自定义 ConfigMap 的名称都与这些默认 ConfigMap 的名称相同。如果它们具有相同的名称,则它们将被覆盖。例如,如果您的 ConfigMap 与 Kafka 集群的 ConfigMap 的名称相同,则在对 Kafka 集群有更新时会覆盖它。
其他资源
- Kafka 集群资源列表 (包括 ConfigMap)
- 日志记录配置
-
metricsConfig
-
ExternalConfiguration
模式参考 - 从外部来源加载配置值
8.15. 从外部来源加载配置值
使用配置提供程序从外部来源加载配置数据。供应商独立于 AMQ Streams 运行。您可以使用它们为所有 Kafka 组件加载配置数据,包括制作者和消费者。您可以在组件的配置中引用外部源并提供访问权限。供应商在不需要重启 Kafka 组件或提取文件的情况下加载数据,即使引用新的外部源。例如,使用 provider 为 Kafka Connect 连接器配置提供凭证。该配置必须包含对外部源的任何访问权限。
8.15.1. 启用配置供应商
您可以使用组件的 spec
配置中的 config.providers
属性启用一个或多个配置供应商。
启用配置供应商的示例配置
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect annotations: strimzi.io/use-connector-resources: "true" spec: # ... config: # ... config.providers: env config.providers.env.class: io.strimzi.kafka.EnvVarConfigProvider # ...
- KubernetesSecretConfigProvider
- 从 OpenShift 机密加载配置数据。您可以在存储配置数据的 secret 中指定 secret 的名称和密钥。此提供程序可用于存储敏感配置数据,如密码或其他用户凭据。
- KubernetesConfigMapConfigProvider
- 从 OpenShift 配置映射加载配置数据。您可以在保存配置数据的配置映射中指定配置映射的名称和密钥。此提供程序可用于存储非敏感配置数据。
- EnvVarConfigProvider
- 从环境变量加载配置数据。您可以指定存储数据的环境变量的名称。此提供程序可用于配置容器中运行的应用程序,例如从从 secret 映射的环境变量加载证书或 JAAS 配置。
- FileConfigProvider
- 从文件中加载配置数据。您可以指定存储数据的文件的路径。此提供程序可用于从挂载到容器中的文件中加载配置数据。
- DirectoryConfigProvider
- 从目录中的文件加载配置数据。您可以指定存储配置文件的目录路径。此提供程序可用于加载多个配置文件并将配置数据整理到单独的文件中。
要使用作为 OpenShift Configuration Provider 插件一部分的 KubernetesSecretConfigProvider
和 KubernetesConfigMapConfigProvider
,您必须为包含配置文件的命名空间设置访问权限。
您可以在不设置访问权限的情况下使用其他供应商。您可以通过执行以下操作为 Kafka Connect 或 MirrorMaker 2 提供连接器配置:
- 将配置映射或 secret 挂载到 Kafka Connect pod 中作为环境变量或卷
-
在 Kafka Connect 或 MirrorMaker 2 配置中启用
EnvVarConfigProvider
、FileConfigProvider
或DirectoryConfigProvider
-
使用
KafkaConnect
或KafkaMirrorMaker2
资源spec
中的externalConfiguration
属性传递连接器配置
使用供应商有助于防止通过 Kafka Connect REST 接口传递受限信息。您可以使用以下场景使用此方法:
- 使用连接器用来连接和与数据源通信的值挂载环境变量
- 使用用于配置 Kafka 连接连接器的值挂载属性文件
- 将文件挂载到包含 TLS 信任存储的值和连接器使用的密钥存储值的目录中
在为连接器使用新的 Secret
或 ConfigMap
时,需要重启,这可能会破坏其他连接器。
8.15.2. 从 secret 或配置映射加载配置值
使用 KubernetesSecretConfigProvider
从 secret 或 KubernetesConfigMapConfigProvider
提供配置属性,以便从配置映射中提供配置属性。
在此过程中,配置映射为连接器提供配置属性。属性指定为配置映射的键值。配置映射作为卷挂载到 Kafka Connect pod 中。
先决条件
- Kafka 集群正在运行。
- Cluster Operator 正在运行。
- 您有一个包含连接器配置的配置映射。
带有连接器属性的配置映射示例
apiVersion: v1 kind: ConfigMap metadata: name: my-connector-configuration data: option1: value1 option2: value2
流程
配置
KafkaConnect
资源。-
启用
KubernetesConfigMapConfigProvider
此处显示的规格支持从配置映射和 secret 加载值。
使用配置映射和 secret 的 Kafka Connect 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect annotations: strimzi.io/use-connector-resources: "true" spec: # ... config: # ... config.providers: secrets,configmaps 1 config.providers.configmaps.class: io.strimzi.kafka.KubernetesConfigMapConfigProvider 2 config.providers.secrets.class: io.strimzi.kafka.KubernetesSecretConfigProvider 3 # ...
-
启用
创建或更新资源以启用供应商。
oc apply -f <kafka_connect_configuration_file>
创建一个允许访问外部配置映射中值的角色。
从配置映射中访问值的角色示例
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: connector-configuration-role rules: - apiGroups: [""] resources: ["configmaps"] resourceNames: ["my-connector-configuration"] verbs: ["get"] # ...
规则授予访问
my-connector-configuration
配置映射的角色权限。创建角色绑定,以允许访问包含配置映射的命名空间。
访问包含配置映射的命名空间的角色绑定示例
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: connector-configuration-role-binding subjects: - kind: ServiceAccount name: my-connect-connect namespace: my-project roleRef: kind: Role name: connector-configuration-role apiGroup: rbac.authorization.k8s.io # ...
角色绑定授予访问
my-project
命名空间的角色权限。服务帐户必须是 Kafka Connect 部署使用的相同。服务帐户名称为 <
cluster_name>-connect
,其中 <cluster_name
> 是KafkaConnect
自定义资源的名称。在连接器配置中引用配置映射。
引用配置映射的连接器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-connector labels: strimzi.io/cluster: my-connect spec: # ... config: option: ${configmaps:my-project/my-connector-configuration:option1} # ... # ...
占位符结构是
configmaps:<path_and_file_name>:<property>
。KubernetesConfigMapConfigProvider
从外部配置映射读取并提取option1
属性值。
8.15.3. 从环境变量加载配置值
使用 EnvVarConfigProvider
将配置属性作为环境变量提供。环境变量可以包含配置映射或 secret 的值。
在此过程中,环境变量为连接器提供与 Amazon AWS 通信的配置属性。连接器必须能够读取 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
。环境变量的值派生自挂载到 Kafka Connect pod 的 secret。
用户定义的环境变量的名称不能以 KAFKA_
或 STRIMZI_
开头。
先决条件
- Kafka 集群正在运行。
- Cluster Operator 正在运行。
- 您有一个包含连接器配置的 secret。
带有环境变量值的 secret 示例
apiVersion: v1 kind: Secret metadata: name: aws-creds type: Opaque data: awsAccessKey: QUtJQVhYWFhYWFhYWFhYWFg= awsSecretAccessKey: Ylhsd1lYTnpkMjl5WkE=
流程
配置
KafkaConnect
资源。-
启用
EnvVarConfigProvider
-
使用
externalConfiguration
属性指定环境变量。
使用外部环境变量的 Kafka 连接配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect annotations: strimzi.io/use-connector-resources: "true" spec: # ... config: # ... config.providers: env 1 config.providers.env.class: io.strimzi.kafka.EnvVarConfigProvider 2 # ... externalConfiguration: env: - name: AWS_ACCESS_KEY_ID 3 valueFrom: secretKeyRef: name: aws-creds 4 key: awsAccessKey 5 - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: aws-creds key: awsSecretAccessKey # ...
注意secretKeyRef
属性引用 secret 中的密钥。如果您使用配置映射而不是 secret,请使用configMapKeyRef
属性。-
启用
创建或更新资源以启用供应商。
oc apply -f <kafka_connect_configuration_file>
在连接器配置中引用环境变量。
引用环境变量的连接器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-connector labels: strimzi.io/cluster: my-connect spec: # ... config: option: ${env:AWS_ACCESS_KEY_ID} option: ${env:AWS_SECRET_ACCESS_KEY} # ... # ...
占位符结构是
env:<environment_variable_name>
。EnvVarConfigProvider
从挂载的 secret 中读取并提取环境变量值。
8.15.4. 从目录中的文件加载配置值
使用 FileConfigProvider
从目录中的文件提供配置属性。文件可以是配置映射或 secret。
在此过程中,文件为连接器提供配置属性。数据库用户名和密码被指定为 secret 的属性。secret 作为一个卷挂载到 Kafka Connect pod。卷挂载到路径 /opt/kafka/external-configuration/<volume-name
> 上。
先决条件
- Kafka 集群正在运行。
- Cluster Operator 正在运行。
- 您有一个包含连接器配置的 secret。
带有数据库属性的 secret 示例
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque stringData: connector.properties: |- 1 dbUsername: my-username 2 dbPassword: my-password
流程
配置
KafkaConnect
资源。-
启用
FileConfigProvider
-
使用
externalConfiguration
属性指定该文件。
使用外部属性文件的 Kafka 连接配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect spec: # ... config: config.providers: file 1 config.providers.file.class: org.apache.kafka.common.config.provider.FileConfigProvider 2 #... externalConfiguration: volumes: - name: connector-config 3 secret: secretName: mysecret 4
-
启用
创建或更新资源以启用供应商。
oc apply -f <kafka_connect_configuration_file>
将连接器配置中的文件属性引用为占位符。
引用该文件的连接器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-source-connector labels: strimzi.io/cluster: my-connect-cluster spec: class: io.debezium.connector.mysql.MySqlConnector tasksMax: 2 config: database.hostname: 192.168.99.1 database.port: "3306" database.user: "${file:/opt/kafka/external-configuration/connector-config/mysecret:dbUsername}" database.password: "${file:/opt/kafka/external-configuration/connector-config/mysecret:dbPassword}" database.server.id: "184054" #...
占位符结构是
文件:<path_and_file_name>:<property>
。FileConfigProvider
从挂载的 secret 中读取并提取数据库 username 和 password 属性值。
8.15.5. 从目录中的多个文件加载配置值
使用 DirectoryConfigProvider
从目录中的多个文件中提供配置属性。文件可以是配置映射或 secret。
在此过程中,secret 为连接器提供 TLS 密钥存储和信任存储用户凭证。凭据位于单独的文件中。secret 作为卷挂载到 Kafka Connect pod 中。卷挂载到路径 /opt/kafka/external-configuration/<volume-name
> 上。
先决条件
- Kafka 集群正在运行。
- Cluster Operator 正在运行。
- 您有一个包含用户凭证的 secret。
使用用户凭证的 secret 示例
apiVersion: v1 kind: Secret metadata: name: my-user labels: strimzi.io/kind: KafkaUser strimzi.io/cluster: my-cluster type: Opaque data: ca.crt: <public_key> # Public key of the clients CA user.crt: <user_certificate> # Public key of the user user.key: <user_private_key> # Private key of the user user.p12: <store> # PKCS #12 store for user certificates and keys user.password: <password_for_store> # Protects the PKCS #12 store
my-user
secret 为连接器提供密钥存储凭据(user.crt
和 user.key
)。
在部署 Kafka 集群时生成的 <cluster_name>-cluster-ca-cert
secret 提供集群 CA 证书作为信任存储凭证(ca.crt
)。
流程
配置
KafkaConnect
资源。-
启用
DirectoryConfigProvider
-
使用
externalConfiguration
属性指定文件。
使用外部属性文件的 Kafka 连接配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect spec: # ... config: config.providers: directory 1 config.providers.directory.class: org.apache.kafka.common.config.provider.DirectoryConfigProvider 2 #... externalConfiguration: volumes: 3 - name: cluster-ca 4 secret: secretName: my-cluster-cluster-ca-cert 5 - name: my-user secret: secretName: my-user 6
-
启用
创建或更新资源以启用供应商。
oc apply -f <kafka_connect_configuration_file>
将连接器配置中的文件属性引用为占位符。
引用文件的连接器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-source-connector labels: strimzi.io/cluster: my-connect-cluster spec: class: io.debezium.connector.mysql.MySqlConnector tasksMax: 2 config: # ... database.history.producer.security.protocol: SSL database.history.producer.ssl.truststore.type: PEM database.history.producer.ssl.truststore.certificates: "${directory:/opt/kafka/external-configuration/cluster-ca:ca.crt}" database.history.producer.ssl.keystore.type: PEM database.history.producer.ssl.keystore.certificate.chain: "${directory:/opt/kafka/external-configuration/my-user:user.crt}" database.history.producer.ssl.keystore.key: "${directory:/opt/kafka/external-configuration/my-user:user.key}" #...
占位符结构是
directory:<path>:<file_name>
。DirectoryConfigProvider
从挂载的 secret 中读取并提取凭证。
8.16. 自定义 OpenShift 资源
AMQ Streams 部署会创建 OpenShift 资源,如 Deployment
、Pod
和 Service
资源。这些资源由 AMQ Streams operator 管理。只有负责管理特定 OpenShift 资源的操作器才能更改该资源。如果您尝试手动更改操作器管理的 OpenShift 资源,Operator 将还原您的更改。
如果要执行某些任务,更改 Operator 管理的 OpenShift 资源会很有用,例如:
-
添加自定义标签或注解,以控制 Istio 或其他服务如何处理
Pod
-
管理如何为集群创建
Loadbalancer
-type 服务
要更改 OpenShift 资源,您可以使用各种 AMQ Streams 自定义资源的 spec
部分中的 template
属性。
以下是您可以应用更改的自定义资源列表:
-
Kafka.spec.kafka
-
Kafka.spec.zookeeper
-
Kafka.spec.entityOperator
-
Kafka.spec.kafkaExporter
-
Kafka.spec.cruiseControl
-
KafkaNodePool.spec
-
KafkaConnect.spec
-
KafkaMirrorMaker.spec
-
KafkaMirrorMaker2.spec
-
KafkaBridge.spec
-
KafkaUser.spec
有关这些属性的更多信息,请参阅 AMQ Streams 自定义资源 API 参考。
AMQ Streams 自定义资源 API 参考提供了有关可自定义字段的更多详情。
在以下示例中,template
属性用于修改 Kafka 代理的 pod 中的标签。
模板自定义示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster labels: app: my-cluster spec: kafka: # ... template: pod: metadata: labels: mylabel: myvalue # ...
8.16.1. 自定义镜像拉取策略
AMQ Streams 允许您自定义 Cluster Operator 部署的所有 pod 中容器的镜像拉取策略。镜像拉取策略使用 Cluster Operator 部署中的环境变量 STRIMZI_IMAGE_PULL_POLICY
进行配置。STRIMZI_IMAGE_PULL_POLICY
环境变量可以设置为三个不同的值:
Always
- 每次 pod 启动或重启时,容器镜像都会从 registry 中拉取。
IfNotPresent
- 只有在容器镜像之前没有拉取时才从 registry 中拉取容器镜像。
Never
- 容器镜像从 registry 中拉取。
目前,镜像拉取策略一次只能为所有 Kafka、Kafka Connect 和 Kafka MirrorMaker 集群自定义。更改策略将导致所有 Kafka、Kafka Connect 和 Kafka MirrorMaker 集群的滚动更新。
其他资源
- 中断.
8.16.2. 应用终止宽限期
应用终止宽限期,为 Kafka 集群提供足够时间来完全关闭。
使用 terminationGracePeriodSeconds
属性指定时间。将属性添加到 Kafka
自定义资源的 template.pod
配置中。
您添加的时间将取决于 Kafka 集群的大小。终止宽限期的 OpenShift 默认为 30 秒。如果您发现集群没有完全关闭,您可以提高终止宽限期。
每次 pod 重启时都会应用终止宽限期。当 OpenShift 发送一个 术语 (termination)信号到容器集中运行的进程时,周期开始。周期应反映在终止 pod 停止前将终止 pod 的进程传输到另一个 pod 所需的时间。在周期结束后,kill 信号将停止 pod 中仍在运行的任何进程。
以下示例为 Kafka
自定义资源添加 120 秒的终止宽限期。您还可以在其他 Kafka 组件的自定义资源中指定配置。
终止宽限期配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... template: pod: terminationGracePeriodSeconds: 120 # ... # ...
第 9 章 使用主题 Operator 管理 Kafka 主题
KafkaTopic
资源配置主题,包括分区和复制因素设置。当使用 KafkaTopic
创建、修改或删除主题时,主题 Operator 可确保这些更改反映在 Kafka 集群中。
如需有关 KafkaTopic
资源的更多信息,请参阅 KafkaTopic
模式参考。
9.1. 主题管理模式
KafkaTopic
资源负责管理 Kafka 集群中的单个主题。Topic Operator 提供了两种管理 KafkaTopic
资源和 Kafka 主题的模式:
- 双向模式
- 双向模式需要 ZooKeeper 用于集群管理。在 KRaft 模式中使用 AMQ Streams 不兼容。
- (预览)Unidirectional 模式
- 单向模式不需要 ZooKeeper 进行集群管理。它在 KRaft 模式中使用 AMQ Streams 兼容。
单向主题管理作为技术预览提供。默认情况下,不启用单向主题管理,因此您必须 启用 UnidirectionalTopicOperator
功能门 才能使用它。
9.1.1. 双向主题管理
在双向模式中,主题 Operator 运行如下:
-
当创建、删除或更改
KafkaTopic
时,主题 Operator 会在 Kafka 主题上执行对应的操作。 -
同样,当在 Kafka 集群中创建、删除或更改主题时,主题 Operator 会在
KafkaTopic
资源上执行对应的操作。
尝试坚持管理主题的方法,可以通过 KafkaTopic
资源或在 Kafka 中直接进行。避免在给定主题的两个方法间进行频繁切换。
9.1.2. (预览)Unidirectional 主题管理
在单向模式中,主题 Operator 运行如下:
-
当创建、删除或更改
KafkaTopic
时,主题 Operator 会在 Kafka 主题上执行对应的操作。
如果在 Kafka 集群中直接创建、删除或修改一个主题,且没有对应的 KafkaTopic
资源,则 Topic Operator 不会管理该主题。Topic Operator 只管理与 KafkaTopic
资源关联的 Kafka 主题,不会影响在 Kafka 集群中独立管理的主题。如果 Kafka 主题存在 KafkaTopic
,则会恢复资源外所做的任何配置更改。
9.2. 主题命名约定
KafkaTopic
资源包括主题的名称,以及一个标识它所属的 Kafka 集群名称的标签。
标识 Kafka 集群用于主题处理的标签
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: topic-name-1 labels: strimzi.io/cluster: my-cluster spec: topicName: topic-name-1
该标签提供 Kafka
资源的集群名称。主题 Operator 使用该标签作为确定要管理的 KafkaTopic
资源的机制。如果标签与 Kafka 集群不匹配,则 Topic Operator 无法看到 KafkaTopic
,且不会创建主题。
Kafka 和 OpenShift 都有自己的命名验证规则,Kafka 主题名称在 OpenShift 中可能不是有效的资源名称。如果可能,请尝试并坚持适合两者的命名约定。
请考虑以下指南:
- 使用反映主题性质的主题名称
- 很简洁,并在 63 个字符下保留名称
- 使用所有小写和连字符
- 避免特殊字符、空格或符号
KafkaTopic
资源允许您使用 metadata.name
字段指定 Kafka 主题名称。但是,如果所需的 Kafka 主题名称不是有效的 OpenShift 资源名称,您可以使用 spec.topicName
属性来指定实际名称。spec.topicName
字段是可选的,当不存在时,Kafka 主题名称默认为主题的 metadata.name
。创建主题时,无法稍后更改主题名称。
提供有效 Kafka 主题名称的示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic-1 1 spec: topicName: My.Topic.1 2 # ...
如果多个 KafkaTopic
资源引用同一 Kafka 主题,则首先创建的资源被视为管理该主题的资源。更新较新的资源的状态以指示冲突,并且它们的 Ready
状态更改为 False
。
如果 Kafka 客户端应用程序(如 Kafka Streams)自动创建带有无效 OpenShift 资源名称的主题,则主题 Operator 会在双向模式中使用时生成一个有效的 metadata.name
。它替换无效字符,并将哈希附加到名称中。但是,此行为不适用于(预览)单向模式。
替换无效主题名称的示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic---c55e57fe2546a33f9e603caf57165db4072e827e # ...
如需有关集群中标识符和名称要求的更多信息,请参阅 OpenShift 文档 对象名称和 ID。
9.3. 处理主题的更改
主题 Operator 如何处理对主题的更改取决于 主题管理的模式。
-
对于双向主题管理,配置更改会在 Kafka 主题和
KafkaTopic
资源之间同步。不兼容的更改会优先选择 Kafka 配置,并相应地调整KafkaTopic
资源。 -
对于单向主题管理(当前为预览),配置更改仅进入一个方向:从
KafkaTopic
资源到 Kafka 主题。对KafkaTopic
资源外管理的 Kafka 主题的任何更改都会被恢复。
9.3.1. 双向主题管理的主题存储
对于双向主题管理,当没有单一数据源时,主题 Operator 能够处理对主题的更改。KafkaTopic
资源和 Kafka 主题可以独立修改,其中实时观察更改可能并不总是可行,特别是在 Topic Operator 无法正常工作时。为了解决这个问题,主题 Operator 维护一个主题存储,用于存储有关每个主题的主题配置信息。它将 Kafka 集群和 OpenShift 的状态与主题存储进行比较,以确定同步所需的更改。此评估在启动期间和定期的间隔发生,而主题 Operator 处于活跃状态时。
例如,如果主题 Operator 不活跃,并且在重启后会创建一个名为 my-topic 的新 KafkaTopic
,则主题 Operator 会识别主题存储中没有 my-topic。它识别在最后一次操作后创建的 KafkaTopic
。因此,主题 Operator 生成对应的 Kafka 主题,并将元数据保存在主题存储中。
主题存储可让 Topic Operator 管理在 Kafka 主题和 KafkaTopic
资源中更改主题配置的情况,只要更改兼容。当对 KafkaTopic
自定义资源更新或更改 Kafka 主题配置时,主题存储会在与 Kafka 集群协调后更新,只要更改兼容。
主题存储 基于 Kafka Streams 键值机制,它使用 Kafka 主题来保留状态。主题元数据缓存在内存中,并在主题 Operator 中本地访问。应用到本地内存缓存的操作更新会被保留到磁盘上的备份主题存储中。主题存储会与 Kafka 主题或 OpenShift KafkaTopic
自定义资源的更新同步。操作通过以这种方式设置的主题存储快速处理,但应该崩溃内存缓存崩溃,它会自动从持久性存储中重新填充。
内部主题支持处理主题存储中的主题元数据。
__strimzi_store_topic
- 用于存储主题元数据的输入主题
__strimzi-topic-operator-kstreams-topic-store-changelog
- 保留紧凑主题存储值的日志
不要删除这些主题,因为它们对于 Topic Operator 的运行至关重要。
9.3.2. 将主题元数据从 ZooKeeper 迁移到主题存储
在之前的 AMQ Streams 版本中,主题元数据存储在 ZooKeeper 中。主题存储会删除这个要求,将元数据带到 Kafka 集群,并受 Topic Operator 控制。
当升级到 AMQ Streams 2.5 时,到主题存储的主题 Operator 控制是无缝的。元数据是从 ZooKeeper 查找并迁移,旧存储被删除。
9.3.3. 降级到使用 ZooKeeper 存储主题元数据的 AMQ Streams 版本
如果您要恢复到早于 1.7 的 AMQ Streams 版本,它使用 ZooKeeper 作为主题元数据存储,您仍会将 Cluster Operator 降级到之前的版本,然后将 Kafka 代理和客户端应用程序降级到以前的 Kafka 版本作为标准。
但是,还必须使用 kafka-topics
命令删除为主题存储创建的主题,指定 Kafka 集群的 bootstrap 地址。例如:
oc run kafka-admin -ti --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 --rm=true --restart=Never -- ./bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic __strimzi-topic-operator-kstreams-topic-store-changelog --delete && ./bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic __strimzi_store_topic --delete
该命令必须与用于访问 Kafka 集群的监听程序和身份验证类型对应。
主题 Operator 将从 Kafka 中的主题状态重建 ZooKeeper 主题元数据。
9.3.4. 自动创建主题
应用程序可以在 Kafka 集群中触发自动创建主题。默认情况下,Kafka 代理配置 auto.create.topics.enable
被设置为 true
,允许代理在应用程序尝试从不存在的主题生成或消耗时自动创建主题。应用程序也可能使用 Kafka AdminClient
自动创建主题。当应用程序与 KafkaTopic
资源一起部署时,在主题 Operator 可以响应 KafkaTopic
前,集群中的自动主题创建可能会发生。
对于双向主题管理,主题 Operator 会同步主题和 KafkaTopic
资源之间的更改。
如果您正在尝试单向主题管理预览,这可能意味着最初为应用部署创建的主题最初创建有默认主题配置。如果主题 Operator 会尝试根据应用程序部署中包含的 KafkaTopic
资源规格重新配置主题,则操作可能会失败,因为不允许对配置进行所需的更改。例如,如果更改意味着减少主题分区的数量。因此,在使用单向主题管理时,建议在 Kafka 集群配置中禁用 auto.create.topics.enable
。
9.4. 配置 Kafka 主题
使用 KafkaTopic
资源的属性来配置 Kafka 主题。对 KafkaTopic
中主题配置所做的更改会被传播到 Kafka。
您可以使用 oc apply
创建或修改主题,oc delete
删除现有的主题。
例如:
-
oc apply -f <topic_config_file>
-
oc delete KafkaTopic <topic_name>
要能够删除主题,必须在 Kafka 资源的 spec.kafka.config
中将 delete.topic.enable
设置为 true
(默认)。
此流程演示了如何创建包含 10 个分区和 2 个副本的主题。
该流程与主题管理的双向和(预览)单向模式相同。
开始前
KafkaTopic 资源不允许以下更改:
-
重命名
spec.topicName
中定义的主题。将检测到spec.topicName
和status.topicName
不匹配。 -
使用
spec.partitions
( Kafka 不支持)减少分区数量。 -
修改
spec.replicas
中指定的副本数量。
增加带有键的主题的 spec.partitions
将更改记录分区,这可能会导致问题,特别是在主题使用语义分区时。
先决条件
- 正在运行的 Kafka 集群使用 mTLS 身份验证和 TLS 加密配置 Kafka 代理监听程序。
- 正在运行的主题 Operator (通常使用 Entity Operator 部署)。
-
要删除主题,
delete.topic.enable=true
(默认)在Kafka
资源的spec.kafka.config
中。
流程
配置
KafkaTopic
资源。Kafka 主题配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic-1 labels: strimzi.io/cluster: my-cluster spec: partitions: 10 replicas: 2
提示修改主题时,您可以使用
oc get kafkatopic my-topic-1 -o yaml
获取资源的当前版本。在 OpenShift 中创建
KafkaTopic
资源。oc apply -f <topic_config_file>
等待主题的就绪状态更改为
True
:oc get kafkatopics -o wide -w -n <namespace>
Kafka 主题状态
NAME CLUSTER PARTITIONS REPLICATION FACTOR READY my-topic-1 my-cluster 10 3 True my-topic-2 my-cluster 10 3 my-topic-3 my-cluster 10 3 True
当
READY
输出显示为True
时,主题创建成功。如果
READY
列留空,请从资源 YAML 或 Topic Operator 日志中获取有关状态的更多详细信息。状态信息提供有关当前状态原因的详细信息。
oc get kafkatopics my-topic-2 -o yaml
有关具有
NotReady
状态的主题详情# ... status: conditions: - lastTransitionTime: "2022-06-13T10:14:43.351550Z" message: Number of partitions cannot be decreased reason: PartitionDecreaseException status: "True" type: NotReady
在本例中,主题未就绪的原因是,原始分区数量在
KafkaTopic
配置中被减少。Kafka 不支持此功能。重置主题配置后,status 会显示主题已就绪。
oc get kafkatopics my-topic-2 -o wide -w -n <namespace>
主题的状态更新
NAME CLUSTER PARTITIONS REPLICATION FACTOR READY my-topic-2 my-cluster 10 3 True
获取详情不显示任何信息
oc get kafkatopics my-topic-2 -o yaml
有关具有
READY
状态的主题详情# ... status: conditions: - lastTransitionTime: '2022-06-13T10:15:03.761084Z' status: 'True' type: Ready
9.5. 为复制和分区数量配置主题
由主题 Operator 管理的主题的建议配置是 3 的主题复制因素,最少为 2 个同步副本。
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic labels: strimzi.io/cluster: my-cluster spec: partitions: 10 1 replicas: 3 2 config: min.insync.replicas: 2 3 #...
in-sync 副本与生成者应用程序的 acks
配置一起使用。acks
配置决定了在确认消息被成功收到之前必须复制到的后续分区数量。双向主题 Operator 使用 acks=all
运行,用于其内部主题,其中消息必须被所有同步的副本确认。
当通过添加或删除代理来扩展 Kafka 集群时,复制因素配置不会被更改,且不会自动重新分配副本。但是,您可以使用 kafka-reassign-partitions.sh
工具更改复制因素,并手动将副本重新分配给代理。
另外,虽然 AMQ Streams 的 Cruise Control 集成无法更改主题的复制因素,但为重新平衡 Kafka 生成的优化提议包括传输分区副本和更改分区领导的命令。
9.6. (预览)管理 KafkaTopic 资源,而不影响 Kafka 主题
此流程描述了如何当前通过 KafkaTopic
资源管理的 Kafka 主题转换为非管理的主题。此功能在各种情况下非常有用。例如,您可能想要更新 KafkaTopic
资源的 metadata.name
。您只能通过删除原始 KafkaTopic
资源并重新创建新资源来完成此操作。
通过使用 strimzi.io/managed=false
注解 KafkaTopic
资源,这表示 Topic Operator 应该不再管理该特定主题。这可让您在更改资源的配置或其他管理任务时保留 Kafka 主题。
如果您使用单向主题管理,您可以执行此任务。
单向主题管理作为技术预览提供。默认情况下,不启用单向主题管理,因此您必须 启用 UnidirectionalTopicOperator
功能门 才能使用它。
流程
在 OpenShift 中注解
KafkaTopic
资源,将strimzi.io/managed
设置为false
:oc annotate kafkatopic my-topic-1 strimzi.io/managed=false
在
KafkaTopic
资源中指定主题的metadata.name
,本例中为my-topic-1
。检查
KafkaTopic
资源的状态,以确保请求成功:oc get kafkatopics my-topic-1 -o yaml
具有
Ready
状态的主题示例apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: generation: 124 name: my-topic-1 finalizer: strimzi.io/topic-operator labels: strimzi.io/cluster: my-cluster spec: partitions: 10 replicas: 2 # ... status: observedGeneration: 124 1 topicName: my-topic-1 conditions: - type: Ready status: True lastTransitionTime: 20230301T103000Z
- 1
- 资源成功协调意味着主题不再管理。
metadata.generation
(部署的当前版本)的值必须与 status.observedGeneration (资源的最新协调)匹配
。现在,您可以在不影响管理的 Kafka 主题的情况下更改
KafkaTopic
资源。例如,要更改
metadata.name
,请执行以下操作:删除原始
KafkTopic
资源:oc delete kafkatopic <kafka_topic_name>
-
重新创建具有不同
metadata.name
的KafkTopic
资源,但使用spec.topicName
来引用由原始管理的相同主题
-
如果您没有删除原始
KafkaTopic
资源,并且您希望再次恢复管理 Kafka 主题,请将strimzi.io/managed
注解设置为true
或删除注解。
9.7. (预览)为现有 Kafka 主题启用主题管理
此流程描述了如何为当前没有通过 KafkaTopic
资源管理的主题启用主题管理。您可以通过创建匹配的 KafkaTopic
资源来实现此目的。
如果您使用单向主题管理,您可以执行此任务。
单向主题管理作为技术预览提供。默认情况下,不启用单向主题管理,因此您必须 启用 UnidirectionalTopicOperator
功能门 才能使用它。
流程
使用与 Kafka 主题相同的
metadata.name
创建KafkaTopic
资源。或者,如果 Kafka 中的主题名称不是法律 OpenShift 资源名称,则使用
spec.topicName
。Kafka 主题配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic-1 labels: strimzi.io/cluster: my-cluster spec: partitions: 10 replicas: 2
在本例中,Kafka 主题名为
my-topic-1
。主题 Operator 检查主题是否由另一个
KafkaTopic
资源管理。如果是,旧的资源具有优先权,并在新资源状态中返回资源冲突错误。应用
KafkaTopic
资源:oc apply -f <topic_configuration_file>
等待 Operator 更新 Kafka 中的主题。
Operator 使用具有相同名称的
KafkaTopic
的spec
更新 Kafka 主题。检查
KafkaTopic
资源的状态,以确保请求成功:oc get kafkatopics my-topic-1 -o yaml
具有
Ready
状态的主题示例apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: generation: 1 name: my-topic-1 labels: strimzi.io/cluster: my-cluster spec: partitions: 10 replicas: 2 # ... status: observedGeneration: 1 1 topicName: my-topic-1 conditions: - type: Ready status: True lastTransitionTime: 20230301T103000Z
- 1
- 对资源成功协调意味着主题现已被管理。
metadata.generation
(部署的当前版本)的值必须与 status.observedGeneration (资源的最新协调)匹配
。
9.8. (预览)删除受管主题
单向主题管理支持通过 KafkaTopic
资源删除通过 OpenShift 终结器管理的主题。这由 STRIMZI_USE_FINALIZERS
Topic Operator 环境变量控制。默认情况下,这被设置为 true
,但如果您不想 主题 Operator 来添加终结器,则可以在主题 Operator env
配置中将其设置为 false
。
单向主题管理作为技术预览提供。默认情况下,不启用单向主题管理,因此您必须 启用 UnidirectionalTopicOperator
功能门 才能使用它。
终结器(finalizers)可确保按顺序控制地删除 KafkaTopic
资源。Topic Operator 的终结器添加到 KafkaTopic
资源的元数据中:
控制删除主题的终结器
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: generation: 1 name: my-topic-1 finalizer: strimzi.io/topic-operator labels: strimzi.io/cluster: my-cluster
在本例中,为主题 my-topic-1
添加了终结器。finalizer 会阻止主题被完全删除,直到最终化过程完成为止。如果使用 oc delete kafkatopic my-topic-1
删除主题,则会在元数据中添加时间戳:
删除时的终结器时间戳
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: generation: 1 name: my-topic-1 finalizer: strimzi.io/topic-operator labels: strimzi.io/cluster: my-cluster deletionTimestamp: 20230301T000000.000
资源仍然存在。如果删除失败,则会在资源的状态中显示。
当成功执行最终任务时,终结器会从元数据中删除,并且资源会被完全删除。
终结器还阻止相关资源被删除。如果单向主题 Operator 没有运行,则无法删除 metadata.finalizer
。因此,在 Operator 重启前,尝试删除包含 KafkaTopic
资源的命名空间不会完成,或者删除终结器(例如,使用 oc edit
)。
第 10 章 使用 User Operator 管理 Kafka 用户
当使用 KafkaUser
资源创建、修改或删除用户时,User Operator 可确保这些更改反映在 Kafka 集群中。
有关 KafkaUser
资源的更多信息,请参阅 KafkaUser
模式参考。
10.1. 配置 Kafka 用户
使用 KafkaUser
资源的属性来配置 Kafka 用户。
您可以使用 oc apply
创建或修改用户,oc delete
删除现有用户。
例如:
-
oc apply -f <user_config_file>
-
oc delete KafkaUser <user_name>
用户代表 Kafka 客户端。配置 Kafka 用户时,您可以启用客户端访问 Kafka 所需的用户身份验证和授权机制。使用的机制必须与等同的 Kafka
配置匹配。有关使用 Kafka
和 KafkaUser
资源保护对 Kafka 代理的访问的更多信息,请参阅 保护对 Kafka 代理的访问。
先决条件
- 正在运行的 Kafka 集群使用 mTLS 身份验证和 TLS 加密配置 Kafka 代理监听程序。
- 正在运行的 User Operator (通常使用 Entity Operator 部署)。
流程
配置
KafkaUser
资源。这个示例使用 ACL 指定 mTLS 身份验证和授权。
Kafka 用户配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user-1 labels: strimzi.io/cluster: my-cluster spec: authentication: type: tls authorization: type: simple acls: # Example consumer Acls for topic my-topic using consumer group my-group - resource: type: topic name: my-topic patternType: literal operations: - Describe - Read host: "*" - resource: type: group name: my-group patternType: literal operations: - Read host: "*" # Example Producer Acls for topic my-topic - resource: type: topic name: my-topic patternType: literal operations: - Create - Describe - Write host: "*"
在 OpenShift 中创建
KafkaUser
资源。oc apply -f <user_config_file>
等待用户的就绪状态更改为
True
:oc get kafkausers -o wide -w -n <namespace>
Kafka 用户体验
NAME CLUSTER AUTHENTICATION AUTHORIZATION READY my-user-1 my-cluster tls simple True my-user-2 my-cluster tls simple my-user-3 my-cluster tls simple True
当
READY
输出显示为True
时,用户创建成功。如果
READY
列留空,请从资源 YAML 或 User Operator 日志中获取有关状态的更多详细信息。消息提供有关当前状态的原因的详细信息。
oc get kafkausers my-user-2 -o yaml
具有
NotReady
状态的用户详情# ... status: conditions: - lastTransitionTime: "2022-06-10T10:07:37.238065Z" message: Simple authorization ACL rules are configured but not supported in the Kafka cluster configuration. reason: InvalidResourceException status: "True" type: NotReady
在本例中,用户未就绪的原因是,在
Kafka
配置中没有启用简单的授权。用于简单授权的 Kafka 配置
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... authorization: type: simple
更新 Kafka 配置后,状态会显示用户已就绪。
oc get kafkausers my-user-2 -o wide -w -n <namespace>
用户的状态更新
NAME CLUSTER AUTHENTICATION AUTHORIZATION READY my-user-2 my-cluster tls simple True
获取详情不显示任何消息。
oc get kafkausers my-user-2 -o yaml
具有
READY
状态的用户详情# ... status: conditions: - lastTransitionTime: "2022-06-10T10:33:40.166846Z" status: "True" type: Ready
第 11 章 使用红帽构建的 Apicurio Registry 验证模式
对于 AMQ Streams,也可以使用红帽构建的 Apicurio Registry。
Apicurio Registry 是一个数据存储,用于在 API 和事件驱动的构架中共享标准事件模式和 API 设计。您可以使用 Apicurio Registry 将数据的结构与客户端应用程序分离,并使用 REST 接口在运行时共享和管理您的数据类型和 API 描述。
Apicurio Registry 存储用于序列化和反序列化消息的模式,然后可以从客户端应用程序引用这些消息,以确保它们发送和接收的信息与这些模式兼容。Apicurio Registry 为 Kafka 生成者和消费者应用程序提供 Kafka 客户端序列化器/反序列化器。Kafka 制作者应用程序使用 serializers 对符合特定事件模式的信息进行编码。Kafka 消费者应用程序使用反序列化器,它根据特定的模式 ID 验证信息是否被序列化使用正确的模式。
您可以使应用程序使用 registry 中的模式。这样可确保一致的模式使用,并有助于防止运行时出现数据错误。
其他资源
- Red Hat build of Apicurio Registry 产品文档
- 红帽构建的 Apicurio Registry 基于 GitHub: Apicurio/apicurio-registry上提供的 Apicurio Registry 构建
第 12 章 与红帽构建的 Debezium 集成以更改数据捕获
红帽构建的 Debezium 是一个分布式更改数据捕获平台。它捕获数据库中的行级更改,创建更改事件记录,并将记录流传输到 Kafka 主题。Debezium 基于 Apache Kafka 构建。您可以将红帽构建的 Debezium 与 AMQ Streams 一起部署并集成。部署 AMQ Streams 后,您可以通过 Kafka Connect 将 Debezium 部署为连接器配置。Debezium 将更改事件记录传递到 OpenShift 上的 AMQ Streams。应用程序可以读取 这些更改事件流,并按发生更改事件的顺序访问更改事件。
Debezium 具有多个用途,包括:
- 数据复制
- 更新缓存和搜索索引
- 简化单体式应用程序
- 数据集成
- 启用流查询
要捕获数据库更改,请使用 Debezium 数据库连接器部署 Kafka Connect。您可以配置 KafkaConnector
资源来定义连接器实例。
有关将红帽构建的 Debezium 与 AMQ Streams 一起部署的更多信息,请参阅产品文档。文档包括 Debezium 入门指南,指导您完成设置数据库更新事件记录所需的服务和连接器。
第 13 章 设置 Kafka 集群的客户端访问权限
部署 AMQ Streams 后,您可以设置对 Kafka 集群的客户端访问。要验证部署,您可以部署示例制作者和消费者客户端。否则,创建在 OpenShift 集群内部或外部提供客户端访问的监听程序。
13.1. 部署客户端示例
部署示例制作者和消费者客户端,以发送和接收消息。您可以使用这些客户端来验证 AMQ Streams 的部署。
先决条件
- Kafka 集群可用于客户端。
流程
部署 Kafka producer。
oc run kafka-producer -ti --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 --rm=true --restart=Never -- bin/kafka-console-producer.sh --bootstrap-server cluster-name-kafka-bootstrap:9092 --topic my-topic
- 在运行制作者的控制台中键入一条消息。
- 按 Enter 来发送邮件。
部署 Kafka 使用者。
oc run kafka-consumer -ti --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 --rm=true --restart=Never -- bin/kafka-console-consumer.sh --bootstrap-server cluster-name-kafka-bootstrap:9092 --topic my-topic --from-beginning
- 确认您在使用者控制台中看到传入的信息。
13.2. 配置监听程序以连接到 Kafka 代理
使用监听程序进行与 Kafka 代理的客户端连接。AMQ Streams 提供了一个通用的 GenericKafkaListener
模式,它带有通过 Kafka
资源配置监听程序的属性。GenericKafkaListener
提供了灵活的监听程序配置方法。您可以指定属性来配置 内部监听程序 以在 OpenShift 集群内连接,或 外部监听程序 用于在 OpenShift 集群外部连接。
指定在监听器配置中公开 Kafka 的 连接类型
。选择的类型取决于您的要求,以及您的环境和基础架构。支持以下监听程序类型:
- 内部监听程序
-
在同一 OpenShift 集群内连接的
内部
-
cluster-ip
使用针对每个代理的ClusterIP
服务公开 Kafka
-
在同一 OpenShift 集群内连接的
- 外部监听程序
-
NodePort
使用 OpenShift 节点上的端口 -
LoadBalancer
使用负载均衡器服务 -
ingress
使用 KubernetesIngress
和 Ingress NGINX Controller for Kubernetes (仅限 Kubernetes) -
route
使用 OpenShiftRoute
和默认的 HAProxy 路由器(仅限 OpenShift)
-
不要在 OpenShift 上使用 ingress
,改为使用 route
类型。Ingress NGINX Controller 仅适用于 Kubernetes。路由类型
只在 OpenShift 中被支持。
内部
类型的监听程序配置使用无头服务和提供给代理 pod 的 DNS 名称。您可能需要将 OpenShift 网络加入到外部网络。在这种情况下,您可以配置 内部
类型监听程序(使用 useServiceDnsDomain
属性),以便不使用 OpenShift 服务 DNS 域(通常为 .cluster.local
)。您还可以配置基于每个代理的 ClusterIP
服务的 Kafka 集群的 cluster-ip
类型。当您无法通过无头服务路由或者您希望纳入自定义访问机制时,这个选项是一个实用的选项。例如,您可以在为特定 Ingress 控制器或 OpenShift 网关 API 构建自己的类型的外部监听程序时使用此监听程序。
外部监听程序从需要不同身份验证机制的网络处理对 Kafka 集群的访问。您可以使用指定的连接机制(如 loadbalancer 或 route)为 OpenShift 环境外部访问配置外部监听程序。例如,负载均衡器可能不适用于某些基础架构,如裸机,节点端口提供更好的选项。
每个监听器都定义为 Kafka
资源中的一个数组。
侦听器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... listeners: - name: plain port: 9092 type: internal tls: false configuration: useServiceDnsDomain: true - name: tls port: 9093 type: internal tls: true authentication: type: tls - name: external port: 9094 type: route tls: true configuration: brokerCertChainAndKey: secretName: my-secret certificate: my-certificate.crt key: my-key.key # ...
您可以根据需要配置多个监听程序,只要它们的名称和端口是唯一的。您还可以使用身份验证为安全连接配置监听程序。
如果要了解更多有关每种连接类型的 pros 和 cons,请参阅在 Strimzi 中访问 Apache Kafka。
如果您在使用外部监听程序时需要扩展 Kafka 集群,可能会触发所有 Kafka 代理的滚动更新。这取决于配置。
13.3. 使用监听程序设置对 Kafka 集群的客户端访问
使用 Kafka 集群的地址,您可以提供对同一 OpenShift 集群中的客户端的访问权限;或者,为不同 OpenShift 命名空间或外部 OpenShift 上的客户端提供外部访问。此流程演示了如何配置从 OpenShift 外部或从另一个 OpenShift 集群配置对 Kafka 集群的客户端访问。
Kafka 侦听器提供对 Kafka 集群的访问。客户端访问使用以下配置进行保护:
-
为 Kafka 集群配置了外部监听程序,它启用了 TLS 加密和 mTLS 身份验证,并启用了 Kafka
简单
授权。 -
为客户端创建一个
KafkaUser
,它带有 mTLS 身份验证,以及为简单
授权定义的访问控制列表(ACL)。
您可以将监听程序配置为使用 mutual tls
、scram-sha-512
或 oauth
身份验证。mTLS 始终使用加密,但在使用 SCRAM-SHA-512 和 OAuth 2.0 身份验证时也建议使用加密。
您可以为 Kafka 代理配置简单的
、oauth
、opa
或 自定义授权
。启用后,授权将应用到所有启用的监听程序。
当您配置 KafkaUser
身份验证和授权机制时,请确保它们与等同的 Kafka 配置匹配:
-
KafkaUser.spec.authentication
匹配Kafka.spec.kafka.listeners[*].authentication
-
KafkaUser.spec.authorization
matchesKafka.spec.kafka.authorization
您应该至少有一个监听程序支持您要用于 KafkaUser
的身份验证。
Kafka 用户和 Kafka 代理之间的身份验证取决于每个身份验证设置。例如,如果在 Kafka 配置中也没有启用,则无法使用 mTLS 验证用户。
AMQ Streams operator 自动配置过程并创建身份验证所需的证书:
- Cluster Operator 创建监听程序并设置集群和客户端证书颁发机构(CA)证书,以便使用 Kafka 集群进行身份验证。
- User Operator 根据所选的验证类型,创建代表客户端身份验证的用户和用于客户端身份验证的安全凭证。
您可以将证书添加到客户端配置中。
在此过程中,使用 Cluster Operator 生成的 CA 证书,但 您可以通过安装自己的证书 来替换它们。您还可以将监听程序 配置为使用由外部 CA (证书颁发机构)管理的 Kafka 侦听器证书。
证书以 PEM (.crt) 和 PKCS #12 (.p12) 格式提供。此流程使用 PEM 证书。将 PEM 证书与使用 X.509 格式的证书的客户端一起使用。
对于同一 OpenShift 集群和命名空间中的内部客户端,您可以在 pod 规格中挂载集群 CA 证书。如需更多信息,请参阅配置内部客户端以信任集群 CA。
先决条件
- Kafka 集群可供在 OpenShift 集群外运行的客户端进行连接
- Cluster Operator 和 User Operator 在集群中运行
流程
使用 Kafka 侦听器配置 Kafka 集群。
- 定义通过监听程序访问 Kafka 代理所需的身份验证。
在 Kafka 代理上启用授权。
侦听器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster namespace: myproject spec: kafka: # ... listeners: 1 - name: external 2 port: 9094 3 type: <listener_type> 4 tls: true 5 authentication: type: tls 6 configuration: 7 #... authorization: 8 type: simple superUsers: - super-user-name 9 # ...
- 1
- 在 Generic Kafka listener schema reference 中描述了启用外部监听程序的配置选项。
- 2
- 用于标识监听程序的名称。在 Kafka 集群中必须是唯一的。
- 3
- Kafka 中监听程序使用的端口号。端口号必须在给定的 Kafka 集群中唯一。允许端口号为 9092 及更高版本,但端口 9404 和 9999 除外,它们已用于 Prometheus 和 JMX。根据监听程序类型,端口号可能与连接 Kafka 客户端的端口号不同。
- 4
- 外部监听器类型指定为
route
(只限 OpenShift),loadbalancer
,nodeport
或ingress
(只限 Kubernetes)。内部监听程序指定为internal
或cluster-ip
。 - 5
- 必需。侦听器上的 TLS 加密。对于
route
和ingress
类型监听程序,它必须设置为true
。对于 mTLS 身份验证,也使用authentication
属性。 - 6
- 侦听器上的客户端身份验证机制。对于使用 mTLS 的服务器和客户端身份验证,您可以指定
tls: true
和authentication.type: tls
。 - 7
- (可选)根据监听器类型的要求,您可以指定额外的 监听程序配置。
- 8
- 授权指定为
simple
,它使用AclAuthorizer
Kafka 插件。 - 9
- (可选)无论 ACL 中定义的任何访问限制,Super 用户可以访问所有代理。
警告OpenShift Route 地址由 Kafka 集群的名称、监听程序的名称以及它在其中创建的命名空间的名称组成。例如,
my-cluster-kafka-listener1-bootstrap-myproject
(CLUSTER-NAME-kafka-LISTENER-NAME-bootstrap-NAMESPACE)。如果您使用路由
监听程序类型,请注意地址的整个长度不超过 63 个字符的最大值。
创建或更新
Kafka
资源。oc apply -f <kafka_configuration_file>
Kafka 集群被配置为使用 mTLS 身份验证配置 Kafka 代理监听程序。
为每个 Kafka 代理 pod 创建一个服务。
创建一个服务,以用作连接到 Kafka 集群的 bootstrap 地址。
一个服务也作为外部 bootstrap 地址为到 Kafka 集群的外部连接创建,使用
nodeport
监听器。验证 kafka 代理的身份的集群 CA 证书也会在 secret <
cluster_name> -cluster-ca-cert
中创建。注意如果您在使用外部监听程序时需要扩展 Kafka 集群,可能会触发所有 Kafka 代理的滚动更新。这取决于配置。
从
Kafka
资源的状态中检索可用于访问 Kafka 集群的 bootstrap 地址。oc get kafka <kafka_cluster_name> -o=jsonpath='{.status.listeners[?(@.name=="<listener_name>")].bootstrapServers}{"\n"}'
例如:
oc get kafka my-cluster -o=jsonpath='{.status.listeners[?(@.name=="external")].bootstrapServers}{"\n"}'
使用 Kafka 客户端中的 bootstrap 地址连接到 Kafka 集群。
创建或修改代表需要访问 Kafka 集群的客户端的用户。
-
指定与
Kafka
侦听器相同的身份验证类型。 指定
简单
授权的授权 ACL。用户配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster 1 spec: authentication: type: tls 2 authorization: type: simple acls: 3 - resource: type: topic name: my-topic patternType: literal operations: - Describe - Read - resource: type: group name: my-group patternType: literal operations: - Read
-
指定与
创建或修改
KafkaUser
资源。oc apply -f USER-CONFIG-FILE
创建用户,以及名称与
KafkaUser
资源相同的 secret。secret 包含 mTLS 身份验证的公钥和私钥。secret 示例
apiVersion: v1 kind: Secret metadata: name: my-user labels: strimzi.io/kind: KafkaUser strimzi.io/cluster: my-cluster type: Opaque data: ca.crt: <public_key> # Public key of the clients CA user.crt: <user_certificate> # Public key of the user user.key: <user_private_key> # Private key of the user user.p12: <store> # PKCS #12 store for user certificates and keys user.password: <password_for_store> # Protects the PKCS #12 store
从 Kafka 集群的 <
cluster_name>-cluster-ca-cert
secret 中提取集群 CA 证书。oc get secret <cluster_name>-cluster-ca-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
从 <
user_name>
; secret 中提取用户 CA 证书。oc get secret <user_name> -o jsonpath='{.data.user\.crt}' | base64 -d > user.crt
从 <
user_name>
; secret 中提取用户的私钥。oc get secret <user_name> -o jsonpath='{.data.user\.key}' | base64 -d > user.key
使用 bootstrap 地址主机名和端口配置客户端以连接到 Kafka 集群:
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "<hostname>:<port>");
使用 truststore 凭证配置客户端以验证 Kafka 集群的身份。
指定公共集群 CA 证书。
truststore 配置示例
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL"); props.put(SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG, "PEM"); props.put(SslConfigs.SSL_TRUSTSTORE_CERTIFICATES_CONFIG, "<ca.crt_file_content>");
SSL 是 mTLS 身份验证指定的安全协议。通过 TLS 为 SCRAM-SHA-512 身份验证指定
SASL_SSL
。PEM 是信任存储的文件格式。使用密钥存储凭证配置客户端,以便在连接到 Kafka 集群时验证用户。
指定公钥证书和私钥。
keystore 配置示例
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL"); props.put(SslConfigs.SSL_KEYSTORE_TYPE_CONFIG, "PEM"); props.put(SslConfigs.SSL_KEYSTORE_CERTIFICATE_CHAIN_CONFIG, "<user.crt_file_content>"); props.put(SslConfigs.SSL_KEYSTORE_KEY_CONFIG, "<user.key_file_content>");
将密钥存储证书和私钥直接添加到配置中。以单行格式添加。在
BEGIN CERTIFICATE
和END CERTIFICATE
分隔符之间,以换行符(\n
)开头。也来自原始证书的每行
。keystore 配置示例
props.put(SslConfigs.SSL_KEYSTORE_CERTIFICATE_CHAIN_CONFIG, "-----BEGIN CERTIFICATE----- \n<user_certificate_content_line_1>\n<user_certificate_content_line_n>\n-----END CERTIFICATE---"); props.put(SslConfigs.SSL_KEYSTORE_KEY_CONFIG, "----BEGIN PRIVATE KEY-----\n<user_key_content_line_1>\n<user_key_content_line_n>\n-----END PRIVATE KEY-----");
其他资源
- 第 14.1.1 节 “侦听器身份验证”
- 第 14.1.2 节 “Kafka 授权”
如果使用授权服务器,您可以使用基于令牌的身份验证和授权:
13.4. 使用节点端口访问 Kafka
使用节点端口从 OpenShift 集群外的外部客户端访问 AMQ Streams Kafka 集群。
要连接到代理,您可以为 Kafka bootstrap 地址指定主机名和端口号,以及用于 TLS 加密的证书。
该流程显示基本的 nodeport
侦听器配置。您可以使用监听程序属性启用 TLS 加密(tls
)并指定客户端身份验证机制(身份验证
)。使用 配置属性
添加额外的配置。例如,您可以将以下配置属性用于 nodeport
侦听器:
preferredNodePortAddressType
- 指定作为节点地址检查的第一个地址类型。
externalTrafficPolicy
- 指定服务是否将外部流量路由到节点本地还是集群范围的端点。
nodePort
- 覆盖 bootstrap 和 broker 服务的分配的节点端口号。
有关监听器配置的更多信息,请参阅 GenericKafkaListener
模式参考。
先决条件
- 正在运行的 Cluster Operator
在此过程中,Kafka 集群名称为 my-cluster
。侦听器的名称是 外部
。
流程
配置一个
Kafka
资源,并将外部监听程序设置为nodeport
类型。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: labels: app: my-cluster name: my-cluster namespace: myproject spec: kafka: # ... listeners: - name: external port: 9094 type: nodeport tls: true authentication: type: tls # ... # ... zookeeper: # ...
创建或更新资源。
oc apply -f <kafka_configuration_file>
在 secret
my-cluster-cluster-ca-cert
中创建了用于验证 kafka 代理的身份的集群 CA 证书。为每个 Kafka 代理以及外部 bootstrap 服务创建
NodePort
类型服务。为 bootstrap 和代理创建的节点端口服务
NAME TYPE CLUSTER-IP PORT(S) my-cluster-kafka-external-0 NodePort 172.30.55.13 9094:31789/TCP my-cluster-kafka-external-1 NodePort 172.30.250.248 9094:30028/TCP my-cluster-kafka-external-2 NodePort 172.30.115.81 9094:32650/TCP my-cluster-kafka-external-bootstrap NodePort 172.30.30.23 9094:32650/TCP
用于客户端连接的 bootstrap 地址传播到
Kafka
资源的status
。bootstrap 地址的状态示例
status: clusterId: Y_RJQDGKRXmNF7fEcWldJQ conditions: - lastTransitionTime: '2023-01-31T14:59:37.113630Z' status: 'True' type: Ready listeners: # ... - addresses: - host: ip-10-0-224-199.us-west-2.compute.internal port: 32650 bootstrapServers: 'ip-10-0-224-199.us-west-2.compute.internal:32650' certificates: - | -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- name: external type: external observedGeneration: 2 # ...
从
Kafka
资源的状态中检索可用于访问 Kafka 集群的 bootstrap 地址。oc get kafka my-cluster -o=jsonpath='{.status.listeners[?(@.name=="external")].bootstrapServers}{"\n"}' ip-10-0-224-199.us-west-2.compute.internal:32650
提取集群 CA 证书。
oc get secret my-cluster-cluster-ca-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
将您的客户端配置为连接到代理。
-
指定 Kafka 客户端中的 bootstrap 主机和端口作为连接到 Kafka 集群的 bootstrap 地址。例如,
ip-10-0-224-199.us-west-2.compute.internal:32650
。 将提取的证书添加到 Kafka 客户端的信任存储中,以配置 TLS 连接。
如果启用了客户端身份验证机制,您还需要在客户端上配置它。
-
指定 Kafka 客户端中的 bootstrap 主机和端口作为连接到 Kafka 集群的 bootstrap 地址。例如,
如果您使用自己的监听程序证书,请检查您是否需要将 CA 证书添加到客户端的信任存储配置中。如果是一个公共(外部)CA,您通常不需要添加它。
13.5. 使用 loadbalancers 访问 Kafka
使用 loadbalancers 从 OpenShift 集群外的外部客户端访问 AMQ Streams Kafka 集群。
要连接到代理,您可以为 Kafka bootstrap 地址指定主机名和端口号,以及用于 TLS 加密的证书。
该流程显示基本的 loadbalancer
侦听器配置。您可以使用监听程序属性启用 TLS 加密(tls
)并指定客户端身份验证机制(身份验证
)。使用 配置属性
添加额外的配置。例如,您可以将以下配置属性用于 loadbalancer
侦听程序:
loadBalancerSourceRanges
- 将流量限制为指定的 CIDR 列表(Classless Inter-Domain Routing)范围。
externalTrafficPolicy
- 指定服务是否将外部流量路由到节点本地还是集群范围的端点。
loadBalancerIP
- 在创建 loadbalancer 时请求特定的 IP 地址。
有关监听器配置的更多信息,请参阅 GenericKafkaListener
模式参考。
先决条件
- 正在运行的 Cluster Operator
在此过程中,Kafka 集群名称为 my-cluster
。侦听器的名称是 外部
。
流程
配置一个
Kafka
资源,并将外部监听程序设置为loadbalancer
类型。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: labels: app: my-cluster name: my-cluster namespace: myproject spec: kafka: # ... listeners: - name: external port: 9095 type: loadbalancer tls: true authentication: type: tls # ... # ... zookeeper: # ...
创建或更新资源。
oc apply -f <kafka_configuration_file>
验证 kafka 代理的身份的集群 CA 证书也会在 secret
my-cluster-cluster-ca-cert
中创建。为每个 Kafka 代理创建
loadbalancer
类型服务和负载均衡器,以及外部 bootstrap 服务。为 bootstrap 和代理创建的 LoadBalancer 服务和负载均衡器
NAME TYPE CLUSTER-IP PORT(S) my-cluster-kafka-external-0 LoadBalancer 172.30.204.234 9095:30011/TCP my-cluster-kafka-external-1 LoadBalancer 172.30.164.89 9095:32544/TCP my-cluster-kafka-external-2 LoadBalancer 172.30.73.151 9095:32504/TCP my-cluster-kafka-external-bootstrap LoadBalancer 172.30.30.228 9095:30371/TCP NAME EXTERNAL-IP (loadbalancer) my-cluster-kafka-external-0 a8a519e464b924000b6c0f0a05e19f0d-1132975133.us-west-2.elb.amazonaws.com my-cluster-kafka-external-1 ab6adc22b556343afb0db5ea05d07347-611832211.us-west-2.elb.amazonaws.com my-cluster-kafka-external-2 a9173e8ccb1914778aeb17eca98713c0-777597560.us-west-2.elb.amazonaws.com my-cluster-kafka-external-bootstrap a8d4a6fb363bf447fb6e475fc3040176-36312313.us-west-2.elb.amazonaws.com
用于客户端连接的 bootstrap 地址传播到
Kafka
资源的status
。bootstrap 地址的状态示例
status: clusterId: Y_RJQDGKRXmNF7fEcWldJQ conditions: - lastTransitionTime: '2023-01-31T14:59:37.113630Z' status: 'True' type: Ready listeners: # ... - addresses: - host: >- a8d4a6fb363bf447fb6e475fc3040176-36312313.us-west-2.elb.amazonaws.com port: 9095 bootstrapServers: >- a8d4a6fb363bf447fb6e475fc3040176-36312313.us-west-2.elb.amazonaws.com:9095 certificates: - | -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- name: external type: external observedGeneration: 2 # ...
用于客户端连接的 DNS 地址会传播到每个 loadbalancer
服务的状态
。bootstrap loadbalancer 的状态示例
status: loadBalancer: ingress: - hostname: >- a8d4a6fb363bf447fb6e475fc3040176-36312313.us-west-2.elb.amazonaws.com # ...
从
Kafka
资源的状态中检索可用于访问 Kafka 集群的 bootstrap 地址。oc get kafka my-cluster -o=jsonpath='{.status.listeners[?(@.name=="external")].bootstrapServers}{"\n"}' a8d4a6fb363bf447fb6e475fc3040176-36312313.us-west-2.elb.amazonaws.com:9095
提取集群 CA 证书。
oc get secret my-cluster-cluster-ca-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
将您的客户端配置为连接到代理。
-
指定 Kafka 客户端中的 bootstrap 主机和端口作为连接到 Kafka 集群的 bootstrap 地址。例如,
a8d4a6fb363bf447fb6e475fc3040176-36312313.us-west-2.elb.amazonaws.com:9095
。 将提取的证书添加到 Kafka 客户端的信任存储中,以配置 TLS 连接。
如果启用了客户端身份验证机制,您还需要在客户端上配置它。
-
指定 Kafka 客户端中的 bootstrap 主机和端口作为连接到 Kafka 集群的 bootstrap 地址。例如,
如果您使用自己的监听程序证书,请检查您是否需要将 CA 证书添加到客户端的信任存储配置中。如果是一个公共(外部)CA,您通常不需要添加它。
13.6. 使用 OpenShift 路由访问 Kafka
使用 OpenShift 路由从 OpenShift 集群外的客户端访问 AMQ Streams Kafka 集群。
为了可以使用路由,请在 Kafka
自定义资源中为 route
类型监听程序添加配置。应用时,配置会为外部 bootstrap 和集群中的每个代理创建一个专用路由和服务。客户端连接到 bootstrap 路由,该路由通过 bootstrap 服务路由以连接到代理。然后,使用 DNS 名称建立每个代理连接,该名称通过特定于代理的路由和服务将流量从客户端路由到代理。
要连接到代理,您可以为路由 bootstrap 地址指定主机名,以及用于 TLS 加密的证书。对于使用路由访问,端口始终为 443。
OpenShift 路由地址包含 Kafka 集群的名称、监听程序的名称及其在其中创建的项目的名称。例如,my-cluster-kafka-external-bootstrap-myproject
(<cluster_name>-kafka-<listener_name>-bootstrap-<namespace>)。请注意,地址的整个长度不超过 63 个字符的最大值。
该流程显示基本的监听程序配置。必须启用 TLS 加密(tls
)。您还可以指定客户端身份验证机制(身份验证
)。使用 配置属性
添加额外的配置。例如,您可以使用带有 路由
监听程序 的主机
配置属性来指定 bootstrap 和 per-broker 服务使用的主机名。
有关监听器配置的更多信息,请参阅 GenericKafkaListener
模式参考。
TLS 透传
为 AMQ Streams 创建的路由启用 TLS 透传。Kafka 通过 TCP 使用二进制协议,但路由旨在使用 HTTP 协议。为了能够通过路由路由 TCP 流量,AMQ Streams 使用带有 Server Name Indication (SNI)的 TLS 透传。
SNI 有助于识别并传递到 Kafka 代理的连接。在 passthrough 模式中,始终使用 TLS 加密。由于连接传递到代理,因此监听程序使用由内部集群 CA 签名的 TLS 证书,而不是入口证书。要将监听程序配置为使用您自己的监听程序证书,请使用 brokerCertChainAndKey
属性。
先决条件
- 正在运行的 Cluster Operator
在此过程中,Kafka 集群名称为 my-cluster
。侦听器的名称是 外部
。
流程
配置
Kafka
资源,将外部监听程序设置为route
类型。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: labels: app: my-cluster name: my-cluster namespace: myproject spec: kafka: # ... listeners: - name: external port: 9094 type: route tls: true 1 authentication: type: tls # ... # ... zookeeper: # ...
- 1
- 对于
路由类型
监听程序,必须启用 TLS 加密(为true
)。
创建或更新资源。
oc apply -f <kafka_configuration_file>
在 secret
my-cluster-cluster-ca-cert
中创建了用于验证 kafka 代理的身份的集群 CA 证书。为每个 Kafka 代理以及外部 bootstrap 服务创建
ClusterIP
类型服务。另外,还会为每个服务创建一个
路由
,其中包含一个 DNS 地址 (host/port),以使用默认的 OpenShift HAProxy 路由器公开它们。路由已预先配置有 TLS 透传。
为 bootstrap 和代理创建的路由
NAME HOST/PORT SERVICES PORT TERMINATION my-cluster-kafka-external-0 my-cluster-kafka-external-0-my-project.router.com my-cluster-kafka-external-0 9094 passthrough my-cluster-kafka-external-1 my-cluster-kafka-external-1-my-project.router.com my-cluster-kafka-external-1 9094 passthrough my-cluster-kafka-external-2 my-cluster-kafka-external-2-my-project.router.com my-cluster-kafka-external-2 9094 passthrough my-cluster-kafka-external-bootstrap my-cluster-kafka-external-bootstrap-my-project.router.com my-cluster-kafka-external-bootstrap 9094 passthrough
用于客户端连接的 DNS 地址会传播到每个路由的
状态
。bootstrap 路由的状态示例
status: ingress: - host: >- my-cluster-kafka-external-bootstrap-my-project.router.com # ...
使用目标代理使用 OpenSSL
s_client
检查端口 443 上的 client-server TLS 连接。openssl s_client -connect my-cluster-kafka-external-0-my-project.router.com:443 -servername my-cluster-kafka-external-0-my-project.router.com -showcerts
服务器名称是用于传递到代理连接的 SNI。
如果连接成功,则返回代理的证书。
代理的证书
Certificate chain 0 s:O = io.strimzi, CN = my-cluster-kafka i:O = io.strimzi, CN = cluster-ca v0
从
Kafka
资源的状态检索 bootstrap 服务的地址。oc get kafka my-cluster -o=jsonpath='{.status.listeners[?(@.name=="external")].bootstrapServers}{"\n"}' my-cluster-kafka-external-bootstrap-my-project.router.com:443
地址包含集群名称、监听程序名称、项目名称和路由器的域(本例中为
router.com
)。提取集群 CA 证书。
oc get secret my-cluster-cluster-ca-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
将您的客户端配置为连接到代理。
- 指定 Kafka 客户端中的 bootstrap 服务和端口 443 的地址,作为连接到 Kafka 集群的 bootstrap 地址。
将提取的证书添加到 Kafka 客户端的信任存储中,以配置 TLS 连接。
如果启用了客户端身份验证机制,您还需要在客户端上配置它。
如果您使用自己的监听程序证书,请检查您是否需要将 CA 证书添加到客户端的信任存储配置中。如果是一个公共(外部)CA,您通常不需要添加它。
第 14 章 管理对 Kafka 的安全访问
通过管理客户端对 Kafka 代理的访问来保护 Kafka 集群。指定保护 Kafka 代理和客户端的配置选项
Kafka 代理和客户端之间的安全连接可以包括以下内容:
- 数据交换加密
- 证明身份的身份验证
- 允许或拒绝用户执行操作的授权
为客户端指定的身份验证和授权机制必须与为 Kafka 代理指定的匹配。AMQ Streams Operator 自动配置过程并创建身份验证所需的证书。Cluster Operator 会自动为集群中的数据加密和身份验证设置 TLS 证书。
14.1. Kafka 的安全选项
使用 Kafka
资源来配置用于 Kafka 身份验证和授权的机制。
14.1.1. 侦听器身份验证
在创建监听程序时,为 Kafka 代理配置客户端身份验证。使用 Kafka
资源中的 Kafka.spec.kafka.listeners.authentication
属性指定监听程序身份验证类型。
对于 OpenShift 集群内的客户端,您可以创建 普通
(无需加密)或 tls
内部监听程序。内部监听程序
类型使用无头服务和提供给代理 pod 的 DNS 名称。作为无头服务的替代选择,您还可以创建一个 cluster-ip
类型的内部监听程序,以使用每个代理 ClusterIP
服务公开 Kafka。对于 OpenShift 集群外的客户端,您可以创建 外部监听程序 并指定连接机制,可以是 nodeport
、loadbalancer
、ingress
(仅限 Kubernetes) 或路由
(仅限 OpenShift)。
有关连接外部客户端的配置选项的更多信息,请参阅 第 13 章 设置 Kafka 集群的客户端访问权限。
支持的身份验证选项:
- mTLS 身份验证(仅在启用了 TLS 的监听程序中)
- SCRAM-SHA-512 身份验证
- 基于 OAuth 2.0 令牌的身份验证
- 自定义身份验证
您选择的身份验证选项取决于您如何验证客户端对 Kafka 代理的访问。
在使用自定义身份验证前,尝试探索标准身份验证选项。自定义身份验证允许任何类型的 kafka 支持的验证。它可以提供更大的灵活性,但也增加了复杂性。
图 14.1. Kafka 侦听器身份验证选项

listener authentication
属性用于指定特定于该监听程序的身份验证机制。
如果没有指定 身份验证
属性,则监听器不会验证通过该监听程序连接的客户端。侦听器将接受所有连接,而无需身份验证。
在使用 User Operator 管理 KafkaUsers
时,必须配置身份验证。
以下示例显示了:
-
为 SCRAM-SHA-512 身份验证配置
的普通
监听程序 -
带有 mTLS 身份验证的
tls
侦听程序 -
带有 mTLS 身份验证的
外部监听程序
每个监听器都配置有 Kafka 集群中的唯一名称和端口。
当为客户端配置监听程序对代理的访问时,您可以使用端口 9092 或更高版本(9093、9094 等),但有一些例外。侦听程序无法配置为使用为 interbroker 通信(9090 和 9091)、Prometheus 指标(9404)和 JMX (Java 管理扩展)监控(9999)保留的端口。
侦听器身份验证配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster namespace: myproject spec: kafka: # ... listeners: - name: plain port: 9092 type: internal tls: true authentication: type: scram-sha-512 - name: tls port: 9093 type: internal tls: true authentication: type: tls - name: external port: 9094 type: loadbalancer tls: true authentication: type: tls # ...
14.1.1.1. mTLS 身份验证
mTLS 身份验证总是用于 Kafka 代理和 ZooKeeper pod 之间的通信。
AMQ Streams 可将 Kafka 配置为使用 TLS (传输层安全)来提供 Kafka 代理和客户端之间的加密通信,并不使用 mutual 身份验证。对于 mutual 或双向身份验证,服务器和客户端都存在证书。当您配置 mTLS 身份验证时,代理会验证客户端(客户端身份验证),客户端验证代理(服务器身份验证)。
Kafka
资源中的 mTLS 侦听器配置需要以下内容:
-
tls: true
用于指定 TLS 加密和服务器身份验证 -
authentication.type: tls
指定客户端身份验证
当 Cluster Operator 创建 Kafka 集群时,它会创建一个名为 < cluster_name>-cluster-ca-cert
的新 secret。secret 包含 CA 证书。CA 证书采用 PEM 和 PKCS #12 格式。要验证 Kafka 集群,请将 CA 证书添加到客户端配置中的信任存储中。要验证客户端,请将用户证书和密钥添加到您的客户端配置的密钥存储中。有关为 mTLS 配置客户端的详情,请参考 第 14.2.2 节 “用户身份验证”。
TLS 身份验证更为常见,一方对另一个身份进行身份验证。例如,当在 Web 浏览器和 Web 服务器间使用 HTTPS 时,浏览器获取 Web 服务器的身份的概念验证。
14.1.1.2. SCRAM-SHA-512 身份验证
SCRAM (Salted Challenge Response Authentication Mechanism)是一个身份验证协议,可以使用密码建立 mutual 身份验证。AMQ Streams 可将 Kafka 配置为使用 SASL (Simple Authentication and Security Layer) SCRAM-SHA-512,以便在未加密的和加密的客户端连接中提供身份验证。
当 SCRAM-SHA-512 验证与 TLS 连接一起使用时,TLS 协议会提供加密,但不用于身份验证。
以下 SCRAM 属性使得即使在未加密的连接中也安全地使用 SCRAM-SHA-512:
- 密码不会通过通信频道以明确发送。相反,客户端和服务器都有其他挑战,从而证明他们知道验证用户的密码。
- 服务器和客户端为每个身份验证交换生成一个新的挑战。这意味着交换对重播攻击具有弹性。
当 KafkaUser.spec.authentication.type
配置为 scram-sha-512
时,User Operator 将生成一个由大写和小写 ASCII 字母和数字组成的随机 12 个字符密码。
14.1.1.3. 网络策略
默认情况下,AMQ Streams 会自动为每个在 Kafka 代理上启用的监听程序创建一个 NetworkPolicy
资源。此 NetworkPolicy
允许应用程序连接到所有命名空间中的监听程序。使用网络策略作为监听程序配置的一部分。
如果要将对网络级别的监听程序的访问限制为只选择的应用程序或命名空间,请使用 networkPolicyPeers
属性。每个监听程序都可以有不同的 networkPolicyPeers
配置。如需有关网络策略对等点的更多信息,请参阅 NetworkPolicyPeer API 参考。
如果要使用自定义网络策略,您可以在 Cluster Operator 配置中将 STRIMZI_NETWORK_POLICY_GENERATION
环境变量设置为 false
。如需更多信息,请参阅 第 8.5 节 “配置 Cluster Operator”。
您的 OpenShift 配置必须支持 ingress NetworkPolicies
,以便在 AMQ Streams 中使用网络策略。
14.1.1.4. 提供监听程序证书
您可以为启用了 TLS 加密的 TLS 侦听器或外部监听程序提供自己的服务器证书,称为 Kafka 侦听器证书。如需更多信息,请参阅 第 14.3.4 节 “为 TLS 加密提供自己的 Kafka 侦听器证书”。
14.1.2. Kafka 授权
使用 Kafka 资源中的 Kafka.spec.kafka.authorization
属性为 Kafka
代理配置授权。如果缺少 authorization
属性,则不会启用授权,并且客户端没有限制。启用后,授权将应用到所有启用的监听程序。授权方法在 type
字段中定义。
支持的授权选项:
- 简单授权
- OAuth 2.0 授权 (如果您使用基于 OAuth 2.0 令牌的身份验证)
- 开放策略代理 (OPA) 授权
- 自定义授权
图 14.2. Kafka 集群授权选项

14.1.2.1. 超级用户
无论任何访问限制,且所有授权机制都支持超级用户,用户都可以访问 Kafka 集群中的所有资源。
要为 Kafka 集群指定超级用户,请在 superUsers
属性中添加用户主体列表。如果用户使用 mTLS 身份验证,用户名是 TLS 证书主题中前缀为 CN=
的通用名称。如果您没有使用 User Operator 并使用您自己的证书 mTLS,则用户名是完整证书主题。一个完整的证书主题可以有以下字段: CN=user,OU=my_ou,O=my_org,L=my_location,ST=my_state,C=my_country_code
。省略任何不存在的字段。
带有超级用户的示例配置
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster namespace: myproject spec: kafka: # ... authorization: type: simple superUsers: - CN=client_1 - user_2 - CN=client_3 - CN=client_4,OU=my_ou,O=my_org,L=my_location,ST=my_state,C=US - CN=client_5,OU=my_ou,O=my_org,C=GB - CN=client_6,O=my_org # ...
14.2. Kafka 客户端的安全选项
使用 KafkaUser
资源为 Kafka 客户端配置身份验证机制、授权机制和访问权限。在配置安全性方面,客户端以用户表示。
您可以验证并授权用户访问 Kafka 代理。身份验证允许访问,授权限制对允许的操作的访问权限。
您还可以创建对 Kafka 代理不受限制访问权限的 超级用户。
身份验证和授权机制必须与 用于访问 Kafka 代理的监听程序规格 匹配。
有关配置 KafkaUser
资源以安全访问 Kafka 代理的更多信息,请参阅 第 13.3 节 “使用监听程序设置对 Kafka 集群的客户端访问”。
14.2.1. 识别用于用户处理的 Kafka 集群
KafkaUser
资源包含一个标签,用于定义它所属的 Kafka 集群的名称(从 Kafka
资源的名称中获得)。
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster
用户 Operator 使用该标签来识别 KafkaUser
资源并创建新用户,以及后续处理用户。
如果标签与 Kafka 集群不匹配,则 User Operator 无法识别 KafkaUser
,且不会创建用户。
如果 KafkaUser
资源的状态为空,请检查您的标签。
14.2.2. 用户身份验证
使用 KafkaUser
自定义资源为需要访问 Kafka 集群的用户(客户端)配置身份验证凭证。使用 KafkaUser.spec
中的 authentication
属性配置凭据。通过指定 类型
,您可以控制生成的凭据。
支持的验证类型:
-
TLS
用于 mTLS 身份验证 -
使用外部证书的 mTLS 身份验证的
tls-external
-
SCRAM-sha-512
用于 SCRAM-SHA-512 验证
如果指定了 tls
或 scram-sha-512
,User Operator 会在创建用户时创建身份验证凭据。如果指定了 tls-external
,用户仍然使用 mTLS,但不会创建身份验证凭证。当您提供自己的证书时使用这个选项。如果没有指定身份验证类型,User Operator 不会创建用户或其凭证。
您可以使用 tls-external
来使用 User Operator 外部发布的证书与 mTLS 进行身份验证。User Operator 不会生成 TLS 证书或 secret。您仍然可以通过 User Operator 管理 ACL 规则和配额,方式与使用 tls
机制时相同。这意味着,您在指定 ACL 规则和配额时使用 CN=USER-NAME
格式。USER-NAME 是 TLS 证书中给出的通用名称。
14.2.2.1. mTLS 身份验证
要使用 mTLS 身份验证,请将 KafkaUser
资源中的 type
字段设置为 tls
。
启用 mTLS 身份验证的用户示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: authentication: type: tls # ...
身份验证类型必须与用于访问 Kafka 集群的 Kafka
侦听器的等效配置匹配。
当用户由 User Operator 创建时,它会创建一个新的 secret,其名称与 KafkaUser
资源的名称相同。secret 包含 mTLS 的私钥和公钥。公钥包含在用户证书中,该证书在创建时由客户端 CA (证书授权)签名。所有密钥都是 X.509 格式。
如果您使用 Cluster Operator 生成的客户端 CA,则当 Cluster Operator 更新客户端 CA 时,用户 Operator 生成的用户证书也会续订。
用户 secret 以 PEM 和 PKCS #12 的形式提供密钥和证书。
使用用户凭证的 secret 示例
apiVersion: v1 kind: Secret metadata: name: my-user labels: strimzi.io/kind: KafkaUser strimzi.io/cluster: my-cluster type: Opaque data: ca.crt: <public_key> # Public key of the clients CA user.crt: <user_certificate> # Public key of the user user.key: <user_private_key> # Private key of the user user.p12: <store> # PKCS #12 store for user certificates and keys user.password: <password_for_store> # Protects the PKCS #12 store
配置客户端时,您可以指定以下内容:
- 公共集群 CA 证书的 Truststore 属性用于验证 Kafka 集群的身份
- 用户身份验证凭证的 Keystore 属性用于验证客户端
配置取决于文件格式 (PEM 或 PKCS #12)。这个示例使用 PKCS #12 格式存储,以及访问存储中凭证所需的密码。
以 PKCS #12 格式使用 mTLS 的客户端配置示例
bootstrap.servers=<kafka_cluster_name>-kafka-bootstrap:9093 1 security.protocol=SSL 2 ssl.truststore.location=/tmp/ca.p12 3 ssl.truststore.password=<truststore_password> 4 ssl.keystore.location=/tmp/user.p12 5 ssl.keystore.password=<keystore_password> 6
14.2.2.2. 使用 User Operator 外部发布的证书进行 mTLS 验证
要使用 User Operator 外部发布的证书使用 mTLS 身份验证,您需要将 KafkaUser
资源中的 type
字段设置为 tls-external
。不会为用户创建 secret 和凭证。
具有 mTLS 身份验证的用户示例,它使用 User Operator 外部发布的证书
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: authentication: type: tls-external # ...
14.2.2.3. SCRAM-SHA-512 身份验证
要使用 SCRAM-SHA-512 身份验证机制,您需要将 KafkaUser
资源中的 type
字段设置为 scram-sha-512
。
启用 SCRAM-SHA-512 验证的用户示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: authentication: type: scram-sha-512 # ...
当用户由 User Operator 创建时,它会创建一个新的 secret,其名称与 KafkaUser
资源的名称相同。secret 包含在 password
键中生成的密码,该密钥使用 base64 编码。要使用密码,必须对其进行解码。
使用用户凭证的 secret 示例
apiVersion: v1 kind: Secret metadata: name: my-user labels: strimzi.io/kind: KafkaUser strimzi.io/cluster: my-cluster type: Opaque data: password: Z2VuZXJhdGVkcGFzc3dvcmQ= 1 sasl.jaas.config: b3JnLmFwYWNoZS5rYWZrYS5jb21tb24uc2VjdXJpdHkuc2NyYW0uU2NyYW1Mb2dpbk1vZHVsZSByZXF1aXJlZCB1c2VybmFtZT0ibXktdXNlciIgcGFzc3dvcmQ9ImdlbmVyYXRlZHBhc3N3b3JkIjsK 2
解码生成的密码:
echo "Z2VuZXJhdGVkcGFzc3dvcmQ=" | base64 --decode
14.2.2.3.1. 自定义密码配置
创建用户时,AMQ Streams 会生成一个随机密码。您可以使用自己的密码而不是 AMQ Streams 生成的密码。要做到这一点,使用密码创建一个 secret,并在 KafkaUser
资源中引用它。
为 SCRAM-SHA-512 验证设定密码的用户示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: authentication: type: scram-sha-512 password: valueFrom: secretKeyRef: name: my-secret 1 key: my-password 2 # ...
14.2.3. 用户授权
使用 KafkaUser
自定义资源为用户(客户端)配置需要访问 Kafka 集群的授权规则。使用 KafkaUser.spec
中的 authorization
属性配置规则。通过指定 类型
,您可以控制使用哪些规则。
要使用简单的授权,您可以在 KafkaUser.spec.authorization
中将 type
属性设置为 simple
。简单的授权使用 Kafka Admin API 管理 Kafka 集群中的 ACL 规则。User Operator 中的 ACL 管理是启用的,还是取决于您的 Kafka 集群中的授权配置。
- 对于简单的授权,总是启用 ACL 管理。
- 对于 OPA 授权,始终禁用 ACL 管理。授权规则在 OPA 服务器中配置。
- 对于 Red Hat Single Sign-On 授权,您可以在 Red Hat Single Sign-On 中直接管理 ACL 规则。您还可以将授权委派给简单授权器作为配置中的回退选项。当启用到简单授权器时,用户 Operator 也会启用对 ACL 规则的管理。
-
要使用自定义授权插件进行自定义授权,请使用
Kafka
自定义资源的.spec.kafka.authorization
配置中的supportsAdminApi
属性来启用或禁用支持。
授权是集群范围的。授权类型必须与 Kafka
自定义资源中的等效配置匹配。
如果没有启用 ACL 管理,AMQ Streams 会在包含任何 ACL 规则时拒绝资源。
如果您使用 User Operator 的独立部署,则默认启用 ACL 管理。您可以使用 STRIMZI_ACLS_ADMIN_API_SUPPORTED
环境变量来禁用它。
如果没有指定授权,User Operator 不会为用户置备任何访问权限。此类 KafkaUser
是否仍然可以访问资源,这取决于所使用的授权者。例如,对于 AclAuthorizer
,这由 allow.everyone.if.no.acl.found
配置决定。
14.2.3.1. ACL 规则
AclAuthorizer
使用 ACL 规则来管理对 Kafka 代理的访问。
ACL 规则授予您在 acls
属性中指定的用户访问权限。
有关 AclRule
对象的更多信息,请参阅 AclRule
模式参考。
14.2.3.2. 超级用户对 Kafka 代理的访问
如果用户被添加到 Kafka 代理配置中的超级用户列表中,无论 KafkaUser
中 ACL 中定义的任何授权限制,用户都可以不受限制地访问集群。
有关配置超级用户对代理的访问权限的更多信息,请参阅 Kafka 授权。
14.2.3.3. 用户配额
您可以为 KafkaUser
资源配置 spec
来强制实施配额,以便用户不会超过配置对 Kafka 代理的访问级别。您可以设置基于大小的网络使用量以及基于时间的 CPU 使用率阈值。您还可以添加分区变异配额来控制用户请求接受更改分区的请求的速度。
带有用户配额的 KafkaUser
示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: # ... quotas: producerByteRate: 1048576 1 consumerByteRate: 2097152 2 requestPercentage: 55 3 controllerMutationRate: 10 4
有关这些属性的更多信息,请参阅 KafkaUserQuotas
模式参考。
14.3. 保护对 Kafka 代理的访问
要建立对 Kafka 代理的安全访问,请配置并应用:
Kafka
资源:- 使用指定验证类型创建监听程序
- 为整个 Kafka 集群配置授权
-
通过监听程序安全地访问 Kafka 代理的
KafkaUser
资源
将 Kafka
资源配置为设置:
- 侦听器身份验证
- 限制访问 Kafka 监听器的网络策略
- Kafka 授权
- 超级用户对代理不受限制访问
每个监听器都独立配置身份验证。始终为整个 Kafka 集群配置授权。
Cluster Operator 创建监听程序并设置集群和客户端证书颁发机构(CA)证书,以便在 Kafka 集群中启用身份验证。
您可以通过安装自己的证书来替换 Cluster Operator 生成的证书。
您还可以为启用了 TLS 加密的任何监听器提供自己的服务器证书和私钥。这些用户提供的证书称为 Kafka 侦听器证书。通过提供 Kafka 侦听器证书,您可以利用现有的安全基础架构,如机构的私有 CA 或公共 CA。Kafka 客户端需要信任用于为监听器证书签名的 CA。在需要时,您必须手动续订 Kafka 侦听器证书。证书以 PKCS #12 格式 (.p12) 和 PEM (.crt) 格式提供。
使用 KafkaUser
启用特定客户端用来访问 Kafka 的身份验证和授权机制。
将 KafkaUser
资源配置为设置:
- 与启用的监听程序身份验证匹配的身份验证
- 与启用 Kafka 授权匹配的授权
- 控制客户端资源使用的配额
User Operator 根据所选的验证类型,创建代表客户端身份验证的用户和用于客户端身份验证的安全凭证。
有关访问配置属性的更多信息,请参阅 schema 参考:
14.3.1. 保护 Kafka 代理
此流程演示了如何在运行 AMQ Streams 时保护 Kafka 代理的步骤。
Kafka 代理实现的安全性必须与需要访问的客户端实现的安全性兼容。
-
Kafka.spec.kafka.listeners[*].authentication
matchesKafkaUser.spec.authentication
-
Kafka.spec.kafka.authorization
matchesKafkaUser.spec.authorization
步骤显示使用 mTLS 身份验证的简单授权和监听程序的配置。有关监听器配置的更多信息,请参阅 GenericKafkaListener
模式参考。
或者,您可以使用 SCRAM-SHA 或 OAuth 2.0 进行 监听器身份验证,OAuth 2.0 或 OPA 用于 Kafka 授权。
流程
配置
Kafka
资源。-
为
授权
配置授权属性。 配置
listeners
属性,以使用身份验证创建监听程序。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... authorization: 1 type: simple superUsers: 2 - CN=client_1 - user_2 - CN=client_3 listeners: - name: tls port: 9093 type: internal tls: true authentication: type: tls 3 # ... zookeeper: # ...
- 1
- 2
- 对 Kafka 有无限访问权限的用户主体列表。在使用 mTLS 身份验证时,CN 是客户端证书的通用名称。
- 3
- 可以为每个监听器配置监听器验证机制,并指定为 mTLS、SCRAM-SHA-512 或基于令牌的 OAuth 2.0。
如果要配置外部监听程序,配置取决于所选的连接机制。
-
为
创建或更新
Kafka
资源。oc apply -f <kafka_configuration_file>
Kafka 集群被配置为使用 mTLS 身份验证配置 Kafka 代理监听程序。
为每个 Kafka 代理 pod 创建一个服务。
创建一个服务,以用作连接到 Kafka 集群的 bootstrap 地址。
验证 kafka 代理的身份的集群 CA 证书也会在 secret <
cluster_name> -cluster-ca-cert
中创建。
14.3.2. 保护用户对 Kafka 的访问
创建或修改 KafkaUser
以代表需要对 Kafka 集群安全访问权限的客户端。
当您配置 KafkaUser
身份验证和授权机制时,请确保它们与等同的 Kafka
配置匹配:
-
KafkaUser.spec.authentication
匹配Kafka.spec.kafka.listeners[*].authentication
-
KafkaUser.spec.authorization
matchesKafka.spec.kafka.authorization
此流程演示了如何使用 mTLS 身份验证创建用户。您还可以创建带有 SCRAM-SHA 身份验证的用户。
所需的身份验证取决于 为 Kafka 代理监听程序配置的验证类型。
Kafka 用户和 Kafka 代理之间的身份验证取决于每个身份验证设置。例如,如果在 Kafka 配置中也没有启用,则无法使用 mTLS 验证用户。
先决条件
- 正在运行的 Kafka 集群使用 mTLS 身份验证和 TLS 加密配置 Kafka 代理监听程序。
- 正在运行的 User Operator (通常使用 Entity Operator 部署)。
KafkaUser
中的身份验证类型应与 Kafka
代理中配置的身份验证匹配。
流程
配置
KafkaUser
资源。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: authentication: 1 type: tls authorization: type: simple 2 acls: - resource: type: topic name: my-topic patternType: literal operations: - Describe - Read - resource: type: group name: my-group patternType: literal operations: - Read
创建或更新
KafkaUser
资源。oc apply -f <user_config_file>
创建用户,以及名称与
KafkaUser
资源相同的 Secret。Secret 包含 mTLS 身份验证的私钥和公钥。
有关使用到 Kafka 代理的安全连接配置 Kafka 客户端的详情,请参考 第 13.3 节 “使用监听程序设置对 Kafka 集群的客户端访问”。
14.3.3. 使用网络策略限制 Kafka 侦听程序的访问
您可以使用 networkPolicyPeers
属性将对监听程序的访问限制为所选应用程序。
先决条件
- 支持 Ingress NetworkPolicies 的 OpenShift 集群。
- Cluster Operator 正在运行。
流程
-
打开
Kafka
资源。 在
networkPolicyPeers
属性中,定义允许访问 Kafka 集群的应用程序 pod 或命名空间。例如,要配置
tls
侦听程序,仅允许从标签app
设置为kafka-client
的应用程序 pod 的连接:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: kafka: # ... listeners: - name: tls port: 9093 type: internal tls: true authentication: type: tls networkPolicyPeers: - podSelector: matchLabels: app: kafka-client # ... zookeeper: # ...
创建或更新资源。
使用
oc apply
:oc apply -f your-file
14.3.4. 为 TLS 加密提供自己的 Kafka 侦听器证书
监听器提供对 Kafka 代理的客户端访问。在 Kafka
资源中配置监听程序,包括使用 TLS 进行客户端访问所需的配置。
默认情况下,监听程序使用由 AMQ Streams 生成的内部 CA (证书授权)证书签名的证书。Cluster Operator 在创建 Kafka 集群时生成 CA 证书。当您为 TLS 配置客户端时,您可以将 CA 证书添加到其信任存储配置中以验证 Kafka 集群。您还可以安装和使用自己的 CA 证书。或者,您可以使用 brokerCertChainAndKey
属性配置监听程序,并使用自定义服务器证书。
brokerCertChainAndKey
属性允许您使用监听程序级别自己的自定义证书访问 Kafka 代理。您可以使用自己的私钥和服务器证书创建 secret,然后在监听器的 brokerCertChainAndKey
配置中指定密钥和证书。您可以使用由公共(外部)CA 或私有 CA 签名的证书。如果由公共 CA 签名,您通常不需要将其添加到客户端的信任存储配置中。自定义证书不由 AMQ Streams 管理,因此您需要手动更新它们。
侦听器证书仅用于 TLS 加密和服务器身份验证。它们不用于 TLS 客户端身份验证。如果要使用自己的证书进行 TLS 客户端身份验证,您必须安装和使用您自己的客户端 CA。
先决条件
- Cluster Operator 正在运行。
每个监听器都需要以下内容:
由外部 CA 签名的兼容服务器证书。(提供 PEM 格式的 X.509 证书。)
您可以将一个监听程序证书用于多个监听程序。
- 主题备用名称(SAN)在每个监听器的证书中指定。更多信息请参阅 第 14.3.5 节 “Kafka 监听器的服务器证书中的替代主题”。
如果您不使用自签名证书,您可以提供一个证书中包含整个 CA 链的证书。
如果为监听程序配置了 TLS 加密(tls: true
),只能使用 brokerCertChainAndKey
属性。
AMQ Streams 不支持将加密私钥用于 TLS。secret 中存储的私钥必须未加密的,才能正常工作。
流程
创建包含私钥和服务器证书的
Secret
:oc create secret generic my-secret --from-file=my-listener-key.key --from-file=my-listener-certificate.crt
编辑集群的
Kafka
资源。将监听程序配置为使用
configuration.brokerCertChainAndKey
属性中的Secret
、证书文件和私钥文件。启用 TLS 加密的
loadbalancer
外部监听程序配置示例# ... listeners: - name: plain port: 9092 type: internal tls: false - name: external port: 9094 type: loadbalancer tls: true configuration: brokerCertChainAndKey: secretName: my-secret certificate: my-listener-certificate.crt key: my-listener-key.key # ...
TLS 侦听器配置示例
# ... listeners: - name: plain port: 9092 type: internal tls: false - name: tls port: 9093 type: internal tls: true configuration: brokerCertChainAndKey: secretName: my-secret certificate: my-listener-certificate.crt key: my-listener-key.key # ...
应用新配置以创建或更新资源:
oc apply -f kafka.yaml
Cluster Operator 启动 Kafka 集群的滚动更新,该集群更新监听程序的配置。
注意如果您更新监听程序已使用的
Secret
中的 Kafka 侦听器证书,也会启动滚动更新。
14.3.5. Kafka 监听器的服务器证书中的替代主题
要将 TLS 主机名验证用于您自己的 Kafka 侦听器证书,您必须为每个监听器 使用正确的 Subject Alternative Names (SANs)。证书 SAN 必须为以下内容指定主机名:
- 集群中的所有 Kafka 代理
- Kafka 集群 bootstrap 服务
如果您的 CA 支持,您可以使用通配符证书。
14.3.5.1. 内部监听程序的 SAN 示例
使用以下示例来帮助为内部监听程序在证书中指定 SAN 的主机名。
将 <cluster-name
> 替换为 Kafka 集群的名称,<namespace
> 替换为运行集群的 OpenShift 命名空间。
type: internal
listener 的通配符示例
//Kafka brokers *.<cluster-name>-kafka-brokers *.<cluster-name>-kafka-brokers.<namespace>.svc // Bootstrap service <cluster-name>-kafka-bootstrap <cluster-name>-kafka-bootstrap.<namespace>.svc
type: internal
listener 的非通配符示例
// Kafka brokers <cluster-name>-kafka-0.<cluster-name>-kafka-brokers <cluster-name>-kafka-0.<cluster-name>-kafka-brokers.<namespace>.svc <cluster-name>-kafka-1.<cluster-name>-kafka-brokers <cluster-name>-kafka-1.<cluster-name>-kafka-brokers.<namespace>.svc # ... // Bootstrap service <cluster-name>-kafka-bootstrap <cluster-name>-kafka-bootstrap.<namespace>.svc
type: cluster-ip
listener 的非通配符示例
// Kafka brokers <cluster-name>-kafka-<listener-name>-0 <cluster-name>-kafka-<listener-name>-0.<namespace>.svc <cluster-name>-kafka-<listener-name>-1 <cluster-name>-kafka-<listener-name>-1.<namespace>.svc # ... // Bootstrap service <cluster-name>-kafka-<listener-name>-bootstrap <cluster-name>-kafka-<listener-name>-bootstrap.<namespace>.svc
14.3.5.2. 外部监听程序的 SAN 示例
对于启用了 TLS 加密的外部监听程序,在证书中指定的主机名取决于外部监听程序 类型
。
外部监听程序类型 | 在 SAN 中,指定… |
---|---|
|
所有 Kafka 代理 您可以使用匹配的通配符名称。 |
|
所有 Kafka 代理 您可以使用匹配的通配符名称。 |
|
所有 Kafka 代理 您可以使用匹配的通配符名称。 |
| Kafka 代理 pod 可能调度到的所有 OpenShift worker 节点的地址。 您可以使用匹配的通配符名称。 |
14.4. 使用基于 OAuth 2.0 令牌的身份验证
AMQ Streams 支持使用 OAUTHBEARER 和 PLAIN 机制使用 OAuth 2.0 身份验证。
OAuth 2.0 启用应用程序之间的基于令牌的标准化身份验证和授权,使用中央授权服务器签发对资源有限访问权限的令牌。
您可以配置 OAuth 2.0 身份验证,然后配置 OAuth 2.0 授权。
Kafka 代理和客户端都需要配置为使用 OAuth 2.0。OAuth 2.0 身份验证也可以与 简单
或基于 OPA 的 Kafka 授权 一起使用。
使用基于 OAuth 2.0 令牌的身份验证时,应用程序客户端可以访问应用服务器(称为 资源服务器)上的资源,而无需公开帐户凭证。
应用程序客户端通过访问令牌作为身份验证方法传递,应用服务器也可以用来决定要授予的访问权限级别。授权服务器处理访问权限的授予和关注访问权限的查询。
在 AMQ Streams 上下文中:
- Kafka 代理充当 OAuth 2.0 资源服务器
- Kafka 客户端充当 OAuth 2.0 应用程序客户端
Kafka 客户端在 Kafka 代理验证。代理和客户端根据需要与 OAuth 2.0 授权服务器通信,以获取或验证访问令牌。
对于 AMQ Streams 的部署,OAuth 2.0 集成提供:
- Kafka 代理的服务器端 OAuth 2.0 支持
- 对 Kafka MirrorMaker、Kafka Connect 和 Kafka Bridge 的客户端 OAuth 2.0 支持
14.4.1. OAuth 2.0 身份验证机制
AMQ Streams 支持 OAUTHBEARER 和 PLAIN 机制进行 OAuth 2.0 身份验证。两个机制都允许 Kafka 客户端与 Kafka 代理建立经过身份验证的会话。客户端、授权服务器和 Kafka 代理之间的身份验证流因每种机制而异。
我们建议您将客户端配置为尽可能使用 OAUTHBEARER。OAUTHBEARER 提供比 PLAIN 更高的安全性,因为客户端凭证不会与 Kafka 代理共享。考虑仅在不支持 OAUTHBEARER 的 Kafka 客户端中使用 PLAIN。
您可以将 Kafka 代理监听程序配置为使用 OAuth 2.0 身份验证来连接客户端。如果需要,您可以在同一 oauth
侦听器上使用 OAUTHBEARER 和 PLAIN 机制。必须支持每个机制的属性必须在 oauth
侦听器配置中明确指定。
OAUTHBEARER 概述
OAUTHBEARER 在 oauth
侦听器配置中自动启用用于 Kafka 代理。您可以将 enableOauthBearer
属性设置为 true
,但这不是必需的。
# ... authentication: type: oauth # ... enableOauthBearer: true
许多 Kafka 客户端工具使用在协议级别为 OAUTHBEARER 提供基本支持的库。为了支持应用程序开发,AMQ Streams 为上游 Kafka Client Java 库(但不适用于其他库)提供了一个 OAuth 回调处理器。因此,您不需要编写自己的回调处理程序。应用程序客户端可以使用回调处理程序来提供访问令牌。使用 Go 等其他语言编写的客户端必须使用自定义代码连接到授权服务器并获取访问令牌。
使用 OAUTHBEARER 时,客户端使用 Kafka 代理启动会话,用于凭证交换,其中凭证采用回调处理器提供的 bearer 令牌形式。使用回调,您可以使用三种方式配置令牌置备:
- 客户端 ID 和 Secret (通过使用 OAuth 2.0 客户端凭证 机制)
- 长期访问令牌,在配置时手动获取
- 长期刷新令牌,在配置时手动获取
OAUTHBEARER 身份验证只能由支持协议级别的 OAUTHBEARER 机制的 Kafka 客户端使用。
PLAIN 概述
要使用 PLAIN,您必须在 Kafka 代理的 oauth
侦听器配置中启用它。
在以下示例中,除了 OAUTHBEARER 外,还启用了 PLAIN,这默认是启用的。如果只使用 PLAIN,可以通过将 enableOauthBearer
设置为 false
来禁用 OAUTHBEARER。
# ...
authentication:
type: oauth
# ...
enablePlain: true
tokenEndpointUri: https://OAUTH-SERVER-ADDRESS/auth/realms/external/protocol/openid-connect/token
PLAIN 是所有 Kafka 客户端工具使用的简单身份验证机制。要启用 PLAIN 以用于 OAuth 2.0 身份验证,AMQ Streams 提供了 OAuth 2.0 over PLAIN 服务器端的回调。
对于 PLAIN 的 AMQ Streams 实现,客户端凭证不会存储在 ZooKeeper 中。相反,客户端凭证会在兼容授权服务器后进行集中处理,这与使用 OAUTHBEARER 身份验证类似。
当与 OAuth 2.0 over PLAIN 回调一起使用时,Kafka 客户端使用以下方法之一与 Kafka 代理进行身份验证:
- 客户端 ID 和 secret (通过使用 OAuth 2.0 客户端凭证机制)
- 长期访问令牌,在配置时手动获取
对于这两种方法,客户端必须提供 PLAIN username
和 password
属性,将凭证传递给 Kafka 代理。客户端使用这些属性传递客户端 ID 和机密或用户名和访问令牌。
客户端 ID 和 secret 用于获取访问令牌。
访问令牌作为 password
属性值传递。您可以使用或不使用 $accessToken:
前缀传递访问令牌。
-
如果您在监听器配置中配置了令牌端点(
tokenEndpointUri
),则需要前缀。 -
如果您没有在监听器配置中配置令牌端点(
tokenEndpointUri
),则不需要前缀。Kafka 代理将密码解释为原始访问令牌。
如果将密码
设置为访问令牌,则必须将用户名
设置为 Kafka 代理从访问令牌获取的相同的主体名称。您可以使用 userNameClaim
,fallbackUserNameClaim
,fallbackUsernamePrefix
, 和 userInfoEndpointUri
属性在监听器中指定用户名提取选项。用户名提取过程还取决于您的授权服务器;特别是,它将客户端 ID 映射到帐户名称。
使用 PLAIN 的 OAuth 不支持 密码
授权机制。您只能通过 SASL PLAIN 机制对 客户端凭证
(clientId + secret)或访问令牌进行"proxy"机制,如上所述。
14.4.2. OAuth 2.0 Kafka 代理配置
OAuth 2.0 的 Kafka 代理配置涉及:
- 在授权服务器中创建 OAuth 2.0 客户端
- 在 Kafka 自定义资源中配置 OAuth 2.0 身份验证
与授权服务器相关,Kafka 代理和 Kafka 客户端都被视为 OAuth 2.0 客户端。
14.4.2.1. 授权服务器上的 OAuth 2.0 客户端配置
要配置 Kafka 代理以验证会话启动期间收到的令牌,建议的做法是在授权服务器中创建一个 OAuth 2.0 client 定义(配置为 confidential),并启用了以下客户端凭证:
-
客户端 ID 为
kafka
(例如) - 客户端 ID 和 Secret 作为身份验证机制
在使用授权服务器的非公共内省端点时,您只需要使用客户端 ID 和 secret。使用公共授权服务器端点时通常不需要凭据,就像快速本地 JWT 令牌验证一样。
14.4.2.2. Kafka 集群中的 OAuth 2.0 身份验证配置
要在 Kafka 集群中使用 OAuth 2.0 身份验证,您可以使用身份验证方法 oauth
指定 Kafka 集群自定义资源的 tls
侦听器配置:
评估 OAuth 2.0 的身份验证方法类型
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
spec:
kafka:
# ...
listeners:
- name: tls
port: 9093
type: internal
tls: true
authentication:
type: oauth
#...
您可以在监听程序中配置 OAuth 2.0 身份验证。我们建议将 OAuth 2.0 身份验证与 TLS 加密一起使用(tls: true
)。如果没有加密,连接容易通过令牌偏移而受到网络伪造和未授权访问的影响。
为安全传输层配置带有 type: oauth
的 外部监听程序
,以便与客户端通信。
使用带有外部监听程序的 OAuth 2.0
# ...
listeners:
- name: external
port: 9094
type: loadbalancer
tls: true
authentication:
type: oauth
#...
tls
属性默认为 false,因此必须启用它。
当您将验证类型定义为 OAuth 2.0 时,您可以根据验证类型添加配置,可以是 fast local JWT validation 或 token validation using an introspection endpoint。
为监听器配置 OAuth 2.0 的步骤,带有描述和示例,请参考 为 Kafka 代理配置 OAuth 2.0 支持。
14.4.2.3. 快速本地 JWT 令牌验证配置
快速本地 JWT 令牌验证在本地检查 JWT 令牌签名。
本地检查可确保令牌:
-
通过包含访问令牌的
Bearer
的(typ)声明值来达到类型 - 有效(未过期)
-
具有与
validIssuerURI
匹配的签发者
在配置监听程序时,您可以指定 validIssuerURI
属性,以便授权服务器未签发的任何令牌都会被拒绝。
授权服务器不需要在快速本地 JWT 令牌验证期间联系。您可以通过指定 jwksEndpointUri
属性(OAuth 2.0 授权服务器公开的端点)来激活快速本地 JWT 令牌验证。端点包含验证已签名的 JWT 令牌的公钥,这些令牌由 Kafka 客户端作为凭证发送。
所有与授权服务器的通信都应该使用 TLS 加密来执行。
您可以在 AMQ Streams 项目命名空间中将证书信任存储配置为 OpenShift Secret,并使用 tlsTrustedCertificates
属性指向包含 truststore 文件的 OpenShift Secret。
您可能想要配置 userNameClaim
,以从 JWT 令牌正确提取用户名。如果需要,您可以使用 JsonPath 表达式,如 "['user.info'].['user.id']"
,从令牌中的嵌套 JSON 属性检索用户名。
如果要使用 Kafka ACL 授权,则需要在身份验证过程中通过用户名识别用户。( JWT 令牌中的 子
声明通常是唯一 ID,而不是用户名。)
快速本地 JWT 令牌验证配置示例
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
spec:
kafka:
#...
listeners:
- name: tls
port: 9093
type: internal
tls: true
authentication:
type: oauth
validIssuerUri: <https://<auth_server_address>/auth/realms/tls>
jwksEndpointUri: <https://<auth_server_address>/auth/realms/tls/protocol/openid-connect/certs>
userNameClaim: preferred_username
maxSecondsWithoutReauthentication: 3600
tlsTrustedCertificates:
- secretName: oauth-server-cert
certificate: ca.crt
#...
14.4.2.4. OAuth 2.0 内省端点配置
使用 OAuth 2.0 内省端点验证令牌会将收到的访问令牌视为不透明。Kafka 代理向内省端点发送访问令牌,该端点使用验证所需的令牌信息进行响应。最重要的是,如果特定的访问令牌有效,它会返回最新的信息,以及令牌何时到期的信息。
要配置基于 OAuth 2.0 内省的验证,您可以指定一个 introspectionEndpointUri
属性,而不是为快速本地 JWT 令牌验证指定的 jwksEndpointUri
属性。根据授权服务器,通常必须指定 clientId
和 clientSecret
,因为内省端点通常受到保护。
内省端点配置示例
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
spec:
kafka:
listeners:
- name: tls
port: 9093
type: internal
tls: true
authentication:
type: oauth
clientId: kafka-broker
clientSecret:
secretName: my-cluster-oauth
key: clientSecret
validIssuerUri: <https://<auth_server_-_address>/auth/realms/tls>
introspectionEndpointUri: <https://<auth_server_address>/auth/realms/tls/protocol/openid-connect/token/introspect>
userNameClaim: preferred_username
maxSecondsWithoutReauthentication: 3600
tlsTrustedCertificates:
- secretName: oauth-server-cert
certificate: ca.crt
14.4.3. Kafka 代理的会话重新身份验证
您可以将 oauth
侦听器配置为使用 Kafka 会话重新身份验证 Kafka 客户端和 Kafka 代理之间的 OAuth 2.0 会话。这种机制在定义的时间段内强制实施客户端和代理之间经过身份验证的会话的到期。当会话过期时,客户端会立即使用现有连接而不是丢弃它来启动新的会话。
会话重新身份验证默认被禁用。要启用它,您可以在 oauth
侦听器配置中为 maxSecondsWithoutReauthentication
设置时间值。相同的属性用于为 OAUTHBEARER 和 PLAIN 身份验证配置会话重新身份验证。有关配置示例,请参阅 第 14.4.6.2 节 “为 Kafka 代理配置 OAuth 2.0 支持”。
会话重新身份验证必须由客户端使用的 Kafka 客户端库支持。
会话重新身份验证可用于快速 本地 JWT 或 内省端点 令牌验证。
客户端重新身份验证
当代理的经过身份验证的会话过期时,客户端必须通过向代理发送新的有效的访问令牌来重新验证现有的会话。
如果令牌验证成功,则使用现有连接启动新的客户端会话。如果客户端无法重新验证,代理会在进一步尝试发送或接收消息时关闭连接。如果在代理上启用了重新身份验证机制,使用 Kafka 客户端库 2.2 或更高版本的 Java 客户端会自动重新验证。
如果使用,会话重新身份验证也适用于刷新令牌。当会话过期时,客户端会使用其刷新令牌来刷新访问令牌。然后,客户端使用新的访问令牌重新验证现有会话。
OAUTHBEARER 和 PLAIN 的会话过期
配置会话重新身份验证后,对于 OAUTHBEARER 和 PLAIN 身份验证,会话到期会有所不同。
对于 OAUTHBEARER 和 PLAIN,使用客户端 ID 和 secret 方法:
-
代理的经过身份验证的用户会话将在配置的
maxSeconds withoutReauthentication
下过期。 - 如果访问令牌在配置时间之前过期,则会话将过期。
对于使用长期访问令牌方法的 PLAIN:
-
代理的经过身份验证的用户会话将在配置的
maxSeconds withoutReauthentication
下过期。 - 如果访问令牌在配置时间之前过期,则重新身份验证将失败。虽然尝试会话重新身份验证,但 PLAIN 没有刷新令牌的机制。
如果没有配置 maxSecondsWithoutReauthentication
,OAUTHBEARER 和 PLAIN 客户端可以无限期地连接到代理,而无需重新验证。经过身份验证的会话不会以访问令牌到期结尾。但是,这可以在配置授权时考虑,例如使用 keycloak
授权或安装自定义授权器。
14.4.4. OAuth 2.0 Kafka 客户端配置
Kafka 客户端配置有:
- 从授权服务器获取有效访问令牌(客户端 ID 和 Secret)所需的凭证
- 使用授权服务器提供的工具获取有效的长期访问令牌或刷新令牌
发送到 Kafka 代理的唯一信息是一个访问令牌。用于与授权服务器进行身份验证的凭证从不会发送到代理。
当客户端获取访问令牌时,不需要进一步与授权服务器通信。
最简单的机制是使用客户端 ID 和 Secret 进行身份验证。使用长期的访问令牌或长期的刷新令牌会增加复杂性,因为对授权服务器工具还有额外的依赖。
如果您使用长期访问令牌,您可能需要在授权服务器中配置客户端,以增加令牌的最大生命周期。
如果 Kafka 客户端没有直接配置访问令牌,客户端会在 Kafka 会话发起授权服务器的过程中交换访问令牌的凭证。Kafka 客户端交换:
- 客户端 ID 和 Secret
- 客户端 ID、刷新令牌和(可选)secret
- 用户名和密码,带有客户端 ID 和(可选)secret
14.4.5. OAuth 2.0 客户端身份验证流程
OAuth 2.0 身份验证流程取决于底层 Kafka 客户端和 Kafka 代理配置。该流还必须被使用的授权服务器支持。
Kafka 代理侦听器配置决定了客户端如何使用访问令牌进行身份验证。客户端可以传递客户端 ID 和机密来请求访问令牌。
如果侦听器配置为使用 PLAIN 身份验证,客户端可以通过客户端 ID 和 secret 或用户名和访问令牌进行身份验证。这些值作为 PLAIN 机制 username
和 password
属性传递。
侦听器配置支持以下令牌验证选项:
- 您可以使用基于 JWT 签名检查和本地令牌内省的快速本地令牌验证,而无需联系授权服务器。授权服务器提供带有公共证书的 JWKS 端点,用于验证令牌中的签名。
- 您可以使用对授权服务器提供的令牌内省端点的调用。每次建立新的 Kafka 代理连接时,代理都会将从客户端收到的访问令牌传递给授权服务器。Kafka 代理检查响应以确认令牌是否有效。
授权服务器可能只允许使用不透明访问令牌,这意味着无法进行本地令牌验证。
Kafka 客户端凭证也可以为以下类型的身份验证配置:
- 使用之前生成的长期访问令牌直接进行本地访问
- 与授权服务器联系以获取要发布的新访问令牌(使用客户端 ID 和 secret、刷新令牌或用户名和密码)
14.4.5.1. 使用 SASL OAUTHBEARER 机制的客户端身份验证流示例
您可以使用 SASL OAUTHBEARER 机制将以下通信流用于 Kafka 身份验证。
使用客户端 ID 和 secret 的客户端,并将代理委派给授权服务器
- Kafka 客户端使用客户端 ID 和 secret 从授权服务器请求访问令牌,以及可选的刷新令牌。或者,客户端也可以使用用户名和密码进行身份验证。
- 授权服务器生成新的访问令牌。
- Kafka 客户端使用 SASL OAUTHBEARER 机制通过访问令牌通过 Kafka 代理进行身份验证。
- Kafka 代理通过使用自己的客户端 ID 和 secret,在授权服务器上调用令牌内省端点来验证访问令牌。
- 如果令牌有效,则会建立 Kafka 客户端会话。
使用客户端 ID 和 secret 的客户端以及执行快速本地令牌验证的代理
- Kafka 客户端使用令牌端点、使用客户端 ID 和 secret 以及刷新令牌(可选)从令牌端点验证。或者,客户端也可以使用用户名和密码进行身份验证。
- 授权服务器生成新的访问令牌。
- Kafka 客户端使用 SASL OAUTHBEARER 机制通过访问令牌通过 Kafka 代理进行身份验证。
- Kafka 代理使用 JWT 令牌签名检查和本地令牌内省在本地验证访问令牌。
使用长期访问令牌的客户端,并将代理委派给授权服务器
- Kafka 客户端使用 SASL OAUTHBEARER 机制通过 Kafka 代理进行身份验证,以传递长期访问令牌。
- Kafka 代理通过使用自己的客户端 ID 和 secret,在授权服务器上调用令牌内省端点来验证访问令牌。
- 如果令牌有效,则会建立 Kafka 客户端会话。
使用长期访问令牌的客户端,以及执行快速本地验证的代理
- Kafka 客户端使用 SASL OAUTHBEARER 机制通过 Kafka 代理进行身份验证,以传递长期访问令牌。
- Kafka 代理使用 JWT 令牌签名检查和本地令牌内省在本地验证访问令牌。
快速的本地 JWT 令牌签名验证仅适用于短期的令牌,因为如果已撤销令牌,就不会通过授权服务器检查该授权服务器。令牌到期时间写入到令牌,但可以随时进行撤销,因此不能在不联系授权服务器的情况下被考虑。任何发布的令牌都将被视为有效,直到其过期为止。
14.4.5.2. 使用 SASL PLAIN 机制的客户端身份验证流示例
您可以使用 OAuth PLAIN 机制将以下通信流用于 Kafka 身份验证。
使用客户端 ID 和 secret 的客户端以及代理获取客户端的访问令牌
-
Kafka 客户端或传递一个
clientId
作为用户名,以及一个secret
作为密码。 -
Kafka 代理使用令牌端点将
clientId
和secret
传递给授权服务器。 - 如果客户端凭据无效,授权服务器会返回一个新的访问令牌或错误。
Kafka 代理使用以下方法之一验证令牌:
- 如果指定了令牌内省端点,Kafka 代理通过在授权服务器上调用端点来验证访问令牌。如果令牌验证成功,则会建立会话。
- 如果使用本地令牌内省,则不会向授权服务器发出请求。Kafka 代理使用 JWT 令牌签名检查在本地验证访问令牌。
使用长期访问令牌(无需客户端 ID 和 secret)的客户端
- Kafka 客户端会传递用户名和密码。密码提供在运行客户端前手动和配置的访问令牌的值。
密码通过或不使用
$accessToken:
字符串前缀来传递,具体取决于 Kafka 代理侦听程序是否配置了令牌端点来进行身份验证。-
如果配置了令牌端点,密码应该以
$accessToken:
前缀,以便代理知道 password 参数包含访问令牌,而不是客户端 secret。Kafka 代理将用户名解释为帐户用户名。 -
如果没有在 Kafka 代理监听器上配置令牌端点(强制使用
no-client-credentials 模式
),密码应提供没有前缀的访问令牌。Kafka 代理将用户名解释为帐户用户名。在此模式中,客户端不使用客户端 ID 和 secret,password
参数始终解释为原始访问令牌。
-
如果配置了令牌端点,密码应该以
Kafka 代理使用以下方法之一验证令牌:
- 如果指定了令牌内省端点,Kafka 代理通过在授权服务器上调用端点来验证访问令牌。如果令牌验证成功,则会建立会话。
- 如果使用本地令牌内省,则不会向授权服务器发出请求。Kafka 代理使用 JWT 令牌签名检查在本地验证访问令牌。
14.4.6. 配置 OAuth 2.0 身份验证
OAuth 2.0 用于在 Kafka 客户端和 AMQ Streams 组件间交互。
要将 OAuth 2.0 用于 AMQ Streams,您必须:
14.4.6.1. 配置 OAuth 2.0 授权服务器
此流程描述了配置授权服务器以便与 AMQ Streams 集成所需的一般操作。
这些说明不是特定于产品的。
这些步骤取决于所选的授权服务器。有关如何设置 OAuth 2.0 访问的详情,请参考授权服务器的产品文档。
如果您已经部署了授权服务器,您可以跳过部署步骤并使用您当前的部署。
流程
- 将授权服务器部署到集群中。
访问授权服务器的 CLI 或管理控制台,以便为 AMQ Streams 配置 OAuth 2.0。
现在,准备授权服务器以用于 AMQ Streams。
-
配置
kafka-broker
客户端。 - 为应用程序的每个 Kafka 客户端组件配置客户端。
接下来要做什么
部署和配置授权服务器后,将 Kafka 代理配置为使用 OAuth 2.0。
14.4.6.2. 为 Kafka 代理配置 OAuth 2.0 支持
此流程描述了如何配置 Kafka 代理,以便代理监听程序可以使用授权服务器使用 OAuth 2.0 身份验证。
我们建议通过带有 tls: true
的监听程序通过加密接口使用 OAuth 2.0。不建议使用普通监听程序。
如果授权服务器使用可信 CA 签名的证书并与 OAuth 2.0 服务器主机名匹配,TLS 连接可使用默认设置。否则,您可能需要使用正确的证书配置信任存储,或者禁用证书主机名验证。
在配置 Kafka 代理时,您可以在新连接的 Kafka 客户端的 OAuth 2.0 身份验证过程中验证访问令牌的机制有两个选项:
开始前
有关为 Kafka 代理监听程序配置 OAuth 2.0 身份验证的更多信息,请参阅:
先决条件
- AMQ Streams 和 Kafka 正在运行
- 部署 OAuth 2.0 授权服务器
流程
在编辑器中更新
Kafka
资源的 Kafka 代理配置(Kafka.spec.kafka
)。oc edit kafka my-cluster
配置 Kafka 代理
监听程序
配置。每种类型的监听程序的配置不必相同,因为它们是独立的。
此处的示例显示了为外部监听器配置的配置选项。
示例 1:配置快速本地 JWT 令牌验证
#... - name: external port: 9094 type: loadbalancer tls: true authentication: type: oauth 1 validIssuerUri: https://<auth_server_address>/auth/realms/external 2 jwksEndpointUri: https://<auth_server_address>/auth/realms/external/protocol/openid-connect/certs 3 userNameClaim: preferred_username 4 maxSecondsWithoutReauthentication: 3600 5 tlsTrustedCertificates: 6 - secretName: oauth-server-cert certificate: ca.crt disableTlsHostnameVerification: true 7 jwksExpirySeconds: 360 8 jwksRefreshSeconds: 300 9 jwksMinRefreshPauseSeconds: 1 10
- 1
- 侦听器类型设置为
oauth
。 - 2
- 用于身份验证的令牌签发者的 URI。
- 3
- 用于本地 JWT 验证的 JWKS 证书端点的 URI。
- 4
- 包含用于识别用户的实际用户名的令牌声明(或密钥)。其值取决于授权服务器。如有必要,可以使用类似
"['user.info'].['user.id']"
的 JsonPath 表达式,从令牌内的嵌套 JSON 属性检索用户名。 - 5
- (可选)激活 Kafka 重新身份验证机制,该机制强制会话到期的时间与访问令牌相同。如果指定的值小于访问令牌过期的时间,那么客户端必须在实际令牌到期前重新验证。默认情况下,当访问令牌过期时,会话不会过期,客户端也不会尝试重新身份验证。
- 6
- (可选)与授权服务器的 TLS 连接的可信证书。
- 7
- (可选)禁用 TLS 主机名验证。默认为
false
。 - 8
- JWKS 证书在过期前被视为有效的持续时间。默认为
360
秒。如果您指定较长的时间,请考虑允许访问撤销的证书的风险。 - 9
- JWKS 证书刷新之间的周期。间隔必须至少为 60 秒,超过到期间隔。默认为
300
秒。 - 10
- 连续尝试刷新 JWKS 公钥之间的最小暂停(以秒为单位)。当遇到未知签名密钥时,JWKS 密钥刷新在常规定期调度后调度,且至少在最后一次刷新尝试后出现指定暂停。刷新密钥遵循 exponential backoff 规则,重试失败的刷新,并增加暂停,直到它到达
jwksRefreshSeconds
。默认值为 1。
示例 2:使用内省端点配置令牌验证
- name: external port: 9094 type: loadbalancer tls: true authentication: type: oauth validIssuerUri: https://<auth_server_address>/auth/realms/external introspectionEndpointUri: https://<auth_server_address>/auth/realms/external/protocol/openid-connect/token/introspect 1 clientId: kafka-broker 2 clientSecret: 3 secretName: my-cluster-oauth key: clientSecret userNameClaim: preferred_username 4 maxSecondsWithoutReauthentication: 3600 5
根据您如何应用 OAuth 2.0 身份验证以及授权服务器的类型,您可以使用额外的(可选)配置设置:
# ... authentication: type: oauth # ... checkIssuer: false 1 checkAudience: true 2 fallbackUserNameClaim: client_id 3 fallbackUserNamePrefix: client-account- 4 validTokenType: bearer 5 userInfoEndpointUri: https://<auth_server_address>/auth/realms/external/protocol/openid-connect/userinfo 6 enableOauthBearer: false 7 enablePlain: true 8 tokenEndpointUri: https://<auth_server_address>/auth/realms/external/protocol/openid-connect/token 9 customClaimCheck: "@.custom == 'custom-value'" 10 clientAudience: audience 11 clientScope: scope 12 connectTimeoutSeconds: 60 13 readTimeoutSeconds: 60 14 httpRetries: 2 15 httpRetryPauseMs: 300 16 groupsClaim: "$.groups" 17 groupsClaimDelimiter: "," 18
- 1
- 如果您的授权服务器不提供
iss
声明,则无法执行签发者检查。在这种情况下,将checkIssuer
设置为false
,且不指定有效的IssuerUri
。默认为true
。 - 2
- 如果您的授权服务器提供
aud
(audience)声明,并且您想要强制进行使用者检查,请将checkAudience
设置为true
。Audience 检查标识令牌的预期接收者。因此,Kafka 代理将拒绝在其aud
声明中没有clientId
的令牌。默认为false
。 - 3
- 授权服务器可能不会提供单个属性来标识常规用户和客户端。当客户端在其自己的名称中进行身份验证时,服务器可能会提供 客户端 ID。当用户使用用户名和密码进行身份验证来获取刷新令牌或访问令牌时,除了客户端 ID 外,服务器可能会提供一个 username 属性。使用此回退选项指定在主用户 ID 属性不可用时要使用的用户名声明(attribute)。如有必要,可以使用 JsonPath 表达式(如
"['client.info'].['client.id']"
来检索回退用户名,以从令牌内嵌套的 JSON 属性检索用户名。 - 4
- 当有
fallbackUserNameClaim
时,可能还需要防止用户名声明的值和回退用户名声明之间的名称冲突。考虑存在名为producer
的客户端,但也存在名为producer
的普通用户。为了区分两者,您可以使用此属性向客户端的用户 ID 添加前缀。 - 5
- (仅在使用
introspectionEndpointUri
)取决于您使用的授权服务器,内省端点也可能不会返回 令牌 type 属性,或者可能包含不同的值。您可以指定来自内省端点必须包含的有效令牌类型值。 - 6
- (仅在使用
introspectionEndpointUri
时)授权服务器可以配置或实施,从而无法在内省端点响应中提供任何可识别的信息。要获得用户 ID,您可以将userinfo
端点的 URI 配置为回退。userNameClaim
,fallbackUserNameClaim
, 和fallbackUserNamePrefix
设置应用到userinfo
端点的响应。 - 7
- 把它设置为
false
,以禁用监听器上的 OAUTHBEARER 机制。必须至少启用 PLAIN 或 OAUTHBEARER 之一。默认为true
。 - 8
- 设置为
true
以在监听器上启用 PLAIN 身份验证,在所有平台上的客户端都支持该身份验证。 - 9
- PLAIN 机制的额外配置。如果指定,客户端可以使用
$accessToken:
前缀将访问令牌作为密码
来通过 PLAIN 进行身份验证。对于生产环境,始终使用https://
urls。 - 10
- 通过将其设置为 JsonPath 过滤器查询,可以在验证过程中对 JWT 访问令牌实施额外的自定义规则。如果访问令牌不包含必要的数据,则会被拒绝。使用
introspectionEndpointUri
时,自定义检查将应用到内省端点响应 JSON。 - 11
- 一个
audience
参数传递给令牌端点。在获取用于代理身份验证的访问令牌时,需要使用 audience。它还在使用clientId
和secret
的 PLAIN 客户端验证中用于 OAuth 2.0 的客户端名称。这只会影响获取令牌的能力,以及令牌的内容,具体取决于授权服务器。它不会影响监听程序的令牌验证规则。 - 12
- 传递给令牌端点的
scope
参数。获取访问令牌进行代理身份验证时使用的 scope。它还在使用clientId
和secret
的 PLAIN 客户端验证中用于 OAuth 2.0 的客户端名称。这只会影响获取令牌的能力,以及令牌的内容,具体取决于授权服务器。它不会影响监听程序的令牌验证规则。 - 13
- 连接到授权服务器时的连接超时(以秒为单位)。默认值为 60。
- 14
- 连接到授权服务器时的读取超时(以秒为单位)。默认值为 60。
- 15
- 将失败的 HTTP 请求重试到授权服务器的次数上限。默认值为
0,
表示没有执行重试。要有效地使用这个选项,请考虑减少connectTimeoutSeconds
和readTimeoutSeconds
选项的超时时间。但请注意,重试可能会阻止当前 worker 线程对其他请求使用,如果太多请求停滞,可能会导致 Kafka 代理无响应。 - 16
- 在尝试另一个失败 HTTP 请求重试到授权服务器前等待的时间。默认情况下,这段时间设为零,这意味着不会应用暂停。这是因为,导致失败请求的很多问题都是可快速解决的网络 glitches 或代理问题。但是,如果您的授权服务器处于压力或遇到高流量,您可能希望将此选项设置为 100 ms 或更高值,以减少服务器上的负载并增加成功重试的可能性。
- 17
- JsonPath 查询,用于从 JWT 令牌或内省端点响应中提取组信息。默认情况下不设置这个选项。通过配置此选项,自定义授权程序可以根据用户组做出授权决策。
- 18
- 当以单一分隔字符串返回时,用于解析组的分隔符。默认值为 ','(comma)。
- 保存并退出编辑器,然后等待滚动更新完成。
检查日志中的更新,或者通过观察 pod 状态转换:
oc logs -f ${POD_NAME} -c ${CONTAINER_NAME} oc get pod -w
滚动更新将代理配置为使用 OAuth 2.0 身份验证。
接下来要做什么
14.4.6.3. 配置 Kafka Java 客户端以使用 OAuth 2.0
配置 Kafka producer 和消费者 API,以使用 OAuth 2.0 与 Kafka 代理交互。在您的客户端 pom.xml
文件中添加回调插件,然后为 OAuth 2.0 配置客户端。
在客户端配置中指定以下内容:
SASL (简单身份验证和安全层)安全协议:
-
SASL_SSL
用于通过 TLS 加密连接进行身份验证 SASL_PLAINTEXT
用于通过未加密的连接进行身份验证将
SASL_SSL
用于生产环境,并且SASL_PLAINTEXT
仅用于本地开发。使用SASL_SSL
时,需要额外的ssl.truststore
配置。安全连接(https://
)与 OAuth 2.0 授权服务器需要 truststore 配置。要验证 OAuth 2.0 授权服务器,请将授权服务器的 CA 证书添加到客户端配置的信任存储中。您可以使用 PEM 或 PKCS #12 格式配置信任存储。
-
Kafka SASL 机制:
-
OAUTHBEARER
用于使用 bearer 令牌的凭证交换 -
PLAIN
传递客户端凭证(clientId + secret)或访问令牌
-
实现 SASL 机制的 JAAS (Java 身份验证和授权服务)模块:
-
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule
实现 OAUTHBEARER 机制 -
org.apache.kafka.common.security.plain.PlainLoginModule
实现 PLAIN 机制
-
SASL 验证方法,它支持以下验证方法:
- OAuth 2.0 客户端凭证
- OAuth 2.0 密码授权(已弃用)
- 访问令牌
- 刷新令牌
添加 SASL 身份验证属性作为 JAAS 配置(sasl.jaas.config
)。如何配置身份验证属性取决于您用于访问 OAuth 2.0 授权服务器的身份验证方法。在此过程中,属性在属性文件中指定,然后加载到客户端配置中。
您还可以将身份验证属性指定为环境变量,或作为 Java 系统属性指定。对于 Java 系统属性,您可以使用 setProperty
设置它们,并使用 -D
选项在命令行中传递它们。
先决条件
- AMQ Streams 和 Kafka 正在运行
- 为 OAuth 访问 Kafka 代理部署并配置 OAuth 2.0 授权服务器
- 为 OAuth 2.0 配置 Kafka 代理
流程
将带有 OAuth 2.0 支持的客户端库添加到 Kafka 客户端的
pom.xml
文件中:<dependency> <groupId>io.strimzi</groupId> <artifactId>kafka-oauth-client</artifactId> <version>0.13.0.redhat-00008</version> </dependency>
通过在属性文件中指定以下配置来配置客户端属性:
- 安全协议
- SASL 机制
JAAS 模块和身份验证属性,具体取决于所使用的方法
例如,我们可以将以下内容添加到
client.properties
文件中:客户端凭证机制属性
security.protocol=SASL_SSL 1 sasl.mechanism=OAUTHBEARER 2 ssl.truststore.location=/tmp/truststore.p12 3 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.token.endpoint.uri="<token_endpoint_url>" \ 4 oauth.client.id="<client_id>" \ 5 oauth.client.secret="<client_secret>" \ 6 oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \ 7 oauth.ssl.truststore.password="$STOREPASS" \ 8 oauth.ssl.truststore.type="PKCS12" \ 9 oauth.scope="<scope>" \ 10 oauth.audience="<audience>" ; 11
- 1
- TLS 加密连接的
SASL_SSL
安全协议。仅对本地开发使用SASL_PLAINTEXT
来进行本地开发。 - 2
- SASL 机制指定为
OAUTHBEARER
或PLAIN
。 - 3
- 用于安全访问 Kafka 集群的信任存储配置。
- 4
- 授权服务器令牌端点的 URI。
- 5
- 客户端 ID,这是在授权服务器中创建客户端时使用的名称。
- 6
- 在授权服务器中创建 客户端 时创建的客户端 secret。
- 7
- 位置包含授权服务器的公钥证书(
truststore.p12
)。 - 8
- 用于访问 truststore 的密码。
- 9
- truststore 类型。
- 10
- (可选)从令牌端点请求令牌的
范围
。授权服务器可能需要客户端指定范围。 - 11
- (可选)从令牌端点请求令牌的
听众
。授权服务器可能需要客户端指定使用者。
密码授予机制属性
security.protocol=SASL_SSL sasl.mechanism=OAUTHBEARER ssl.truststore.location=/tmp/truststore.p12 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.token.endpoint.uri="<token_endpoint_url>" \ oauth.client.id="<client_id>" \ 1 oauth.client.secret="<client_secret>" \ 2 oauth.password.grant.username="<username>" \ 3 oauth.password.grant.password="<password>" \ 4 oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \ oauth.ssl.truststore.password="$STOREPASS" \ oauth.ssl.truststore.type="PKCS12" \ oauth.scope="<scope>" \ oauth.audience="<audience>" ;
访问令牌属性
security.protocol=SASL_SSL sasl.mechanism=OAUTHBEARER ssl.truststore.location=/tmp/truststore.p12 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.token.endpoint.uri="<token_endpoint_url>" \ oauth.access.token="<access_token>" ; 1 oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \ oauth.ssl.truststore.password="$STOREPASS" \ oauth.ssl.truststore.type="PKCS12" \
- 1
- Kafka 客户端的长期访问令牌。
刷新令牌属性
security.protocol=SASL_SSL sasl.mechanism=OAUTHBEARER ssl.truststore.location=/tmp/truststore.p12 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.token.endpoint.uri="<token_endpoint_url>" \ oauth.client.id="<client_id>" \ 1 oauth.client.secret="<client_secret>" \ 2 oauth.refresh.token="<refresh_token>" ; 3 oauth.ssl.truststore.location="/tmp/oauth-truststore.p12" \ oauth.ssl.truststore.password="$STOREPASS" \ oauth.ssl.truststore.type="PKCS12" \
在 Java 客户端代码中输入 OAUTH 2.0 身份验证的客户端属性。
显示客户端属性输入示例
Properties props = new Properties(); try (FileReader reader = new FileReader("client.properties", StandardCharsets.UTF_8)) { props.load(reader); }
- 验证 Kafka 客户端能否访问 Kafka 代理。
14.4.6.4. 为 Kafka 组件配置 OAuth 2.0
这个步骤描述了如何使用授权服务器将 Kafka 组件配置为使用 OAuth 2.0 身份验证。
您可以为以下配置身份验证:
- Kafka Connect
- Kafka MirrorMaker
- Kafka Bridge
在这种情况下,Kafka 组件和授权服务器在同一集群中运行。
开始前
有关为 Kafka 组件配置 OAuth 2.0 身份验证的更多信息,请参阅 KafkaClientAuthenticationOAuth
模式参考。schema 引用包括配置选项示例。
先决条件
- AMQ Streams 和 Kafka 正在运行
- 为 OAuth 访问 Kafka 代理部署并配置 OAuth 2.0 授权服务器
- 为 OAuth 2.0 配置 Kafka 代理
流程
创建客户端 secret,并将它作为环境变量挂载到组件。
例如,这里为 Kafka Bridge 创建客户端
Secret
:apiVersion: kafka.strimzi.io/v1beta2 kind: Secret metadata: name: my-bridge-oauth type: Opaque data: clientSecret: MGQ1OTRmMzYtZTllZS00MDY2LWI5OGEtMTM5MzM2NjdlZjQw 1
- 1
clientSecret
密钥必须采用 base64 格式。
创建或编辑 Kafka 组件的资源,以便为身份验证属性配置 OAuth 2.0 身份验证。
对于 OAuth 2.0 身份验证,您可以使用以下选项:
- 客户端 ID 和 secret
- 客户端 ID 和刷新令牌
- 访问令牌
- 用户名和密码
- TLS
例如,这里的 OAuth 2.0 使用客户端 ID 和 secret 和 TLS 分配给 Kafka Bridge 客户端:
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: # ... authentication: type: oauth 1 tokenEndpointUri: https://<auth-server-address>/auth/realms/master/protocol/openid-connect/token 2 clientId: kafka-bridge clientSecret: secretName: my-bridge-oauth key: clientSecret tlsTrustedCertificates: 3 - secretName: oauth-server-cert certificate: tls.crt
根据您如何应用 OAuth 2.0 身份验证以及授权服务器的类型,您可以使用额外的配置选项:
# ... spec: # ... authentication: # ... disableTlsHostnameVerification: true 1 checkAccessTokenType: false 2 accessTokenIsJwt: false 3 scope: any 4 audience: kafka 5 connectTimeoutSeconds: 60 6 readTimeoutSeconds: 60 7 httpRetries: 2 8 httpRetryPauseMs: 300 9
- 1
- (可选)禁用 TLS 主机名验证。默认为
false
。 - 2
- 如果授权服务器没有返回 JWT 令牌中的
typ
(类型)声明,您可以应用checkAccessTokenType: false
来跳过令牌类型检查。默认为true
。 - 3
- 如果使用不透明令牌,您可以应用
accessTokenIsJwt: false
,以便访问令牌不会被视为 JWT 令牌。 - 4
- (可选)从令牌端点请求令牌的
范围
。授权服务器可能需要客户端指定范围。在这种情况下,它都是any
。 - 5
- (可选)从令牌端点请求令牌的
听众
。授权服务器可能需要客户端指定使用者。在本例中,是kafka
。 - 6
- (可选)连接到授权服务器时的连接超时(以秒为单位)。默认值为 60。
- 7
- (可选)连接到授权服务器时的读取超时(以秒为单位)。默认值为 60。
- 8
- (可选)将失败的 HTTP 请求重试到授权服务器的次数上限。默认值为
0,
表示没有执行重试。要有效地使用这个选项,请考虑减少connectTimeoutSeconds
和readTimeoutSeconds
选项的超时时间。但请注意,重试可能会阻止当前 worker 线程对其他请求使用,如果太多请求停滞,可能会导致 Kafka 代理无响应。 - 9
- (可选)尝试对授权服务器进行另一个失败的 HTTP 请求重试前等待的时间。默认情况下,这段时间设为零,这意味着不会应用暂停。这是因为,导致失败请求的很多问题都是可快速解决的网络 glitches 或代理问题。但是,如果您的授权服务器处于压力或遇到高流量,您可能希望将此选项设置为 100 ms 或更高值,以减少服务器上的负载并增加成功重试的可能性。
将更改应用到 Kafka 资源的部署。
oc apply -f your-file
检查日志中的更新,或者通过观察 pod 状态转换:
oc logs -f ${POD_NAME} -c ${CONTAINER_NAME} oc get pod -w
滚动更新配置组件以使用 OAuth 2.0 身份验证与 Kafka 代理交互。
14.5. 使用基于 OAuth 2.0 令牌的授权
AMQ Streams 支持通过 Red Hat Single Sign-On Authorization Services 使用基于 OAuth 2.0 令牌的授权,它允许您集中管理安全策略和权限。
Red Hat Single Sign-On 中定义的安全策略和权限用于授予对 Kafka 代理上资源的访问权限。用户和客户端与允许对 Kafka 代理执行特定操作的策略进行匹配。
Kafka 允许所有用户默认对代理进行完全访问,同时还提供 AclAuthorizer
插件来配置基于 Access Control Lists (ACL)的授权。
ZooKeeper 存储 ACL 规则,该规则根据 用户名 授予或拒绝对资源的访问。但是,红帽单点登录基于 OAuth 2.0 令牌的授权在您希望实现对 Kafka 代理的访问控制方面具有更大的灵活性。另外,您可以将 Kafka 代理配置为使用 OAuth 2.0 授权和 ACL。
14.5.1. OAuth 2.0 授权机制
AMQ Streams 中的 OAuth 2.0 授权使用红帽单点登录服务器授权服务 REST 端点,通过在特定用户上应用定义的安全策略来扩展基于令牌的身份验证,并为该用户提供授予不同资源的权限列表。策略使用角色和组来匹配用户的权限。OAuth 2.0 授权根据从 Red Hat Single Sign-On Authorization Services 用户获得的授予者列表在本地强制实施权限。
14.5.1.1. Kafka 代理自定义授权器
AMQ Streams 提供了一个 Red Hat Single Sign-On authorizer (KeycloakAuthorizer
)。为了对 Red Hat Single Sign-On 提供的授权服务使用 Red Hat Single Sign-On REST 端点,您可以在 Kafka 代理上配置自定义授权程序。
授权程序根据需要从授权服务器获取授予权限的列表,并在 Kafka Broker 上本地强制实施授权,为每个客户端请求做出快速授权决策。
14.5.2. 配置 OAuth 2.0 授权支持
这个步骤描述了如何使用 Red Hat Single Sign-On Authorization Services 将 Kafka 代理配置为使用 OAuth 2.0 授权服务。
开始前
考虑某些用户所需的访问权限或希望限制某些用户。您可以使用 Red Hat Single Sign-On 组、角色、客户端 和用户 的组合在 Red Hat Single Sign-On 中配置访问权限。
通常,组用于根据机构部门或地理位置匹配用户。和 角色用于根据其功能匹配用户。
使用红帽单点登录,您可以在 LDAP 中存储用户和组,而客户端和角色不能以这种方式存储。在选择配置授权策略时,对用户数据的存储和访问可能是如何配置授权策略的因素。
无论在 Kafka 代理上实现的授权是什么,超级用户 始终对 Kafka 代理具有不受限制的访问权限。
先决条件
- AMQ Streams 必须通过 Red Hat Single Sign-On 配置为使用 OAuth 2.0 进行基于令牌的身份验证。设置授权时,您可以使用相同的 Red Hat Single Sign-On 服务器端点。
-
OAuth 2.0 身份验证必须使用
maxSecondsWithoutReauthentication
选项进行配置,才能启用重新身份验证。
流程
- 访问 Red Hat Single Sign-On Admin 控制台,或使用 Red Hat Single Sign-On Admin CLI 为设置 OAuth 2.0 身份验证时创建的 Kafka 代理客户端启用授权服务。
- 使用授权服务为客户端定义资源、授权范围、策略和权限。
- 通过分配角色和组,将权限绑定到用户和客户端。
通过在编辑器中更新
Kafka
资源的 Kafka 代理配置(Kafka.spec.kafka
),将 Kafka 代理配置为使用 Red Hat Single Sign-On 授权。oc edit kafka my-cluster
将 Kafka 代理
kafka
配置配置为使用keycloak
授权,并能够访问授权服务器和授权服务器。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... authorization: type: keycloak 1 tokenEndpointUri: <https://<auth-server-address>/auth/realms/external/protocol/openid-connect/token> 2 clientId: kafka 3 delegateToKafkaAcls: false 4 disableTlsHostnameVerification: false 5 superUsers: 6 - CN=fred - sam - CN=edward tlsTrustedCertificates: 7 - secretName: oauth-server-cert certificate: ca.crt grantsRefreshPeriodSeconds: 60 8 grantsRefreshPoolSize: 5 9 grantsMaxIdleSeconds: 300 10 grantsGcPeriodSeconds: 300 11 grantsAlwaysLatest: false 12 connectTimeoutSeconds: 60 13 readTimeoutSeconds: 60 14 httpRetries: 2 15 enableMetrics: false 16 #...
- 1
- 类型
keycloak
启用 Red Hat Single Sign-On authorization。 - 2
- Red Hat Single Sign-On 令牌端点的 URI。对于生产环境,始终使用
https://
urls。当您配置基于令牌的oauth
身份验证时,您可以指定jwksEndpointUri
作为本地 JWT 验证的 URI。tokenEndpointUri
URI 的主机名必须相同。 - 3
- Red Hat Single Sign-On 中启用了授权服务的 OAuth 2.0 客户端定义的客户端 ID。通常,
kafka
用作 ID。 - 4
- (可选)如果 Red Hat Single Sign-On Authorization Services 策略无法访问,则对 Kafka
AclAuthorizer
的授权授权。默认为false
。 - 5
- (可选)禁用 TLS 主机名验证。默认为
false
。 - 6
- (可选)指定超级用户。
- 7
- (可选)与授权服务器的 TLS 连接的可信证书。
- 8
- (可选)两个连续授予刷新运行之间的时间。这是活动会话的最大时间,用于检测 Red Hat Single Sign-On 上用户的任何权限更改。默认值为 60。
- 9
- (可选)用于刷新活跃会话的授予的线程数量(并行)。默认值为 5。
- 10
- (可选)缓存中闲置授权可以被驱除的时间(以秒为单位)。默认值为 300。
- 11
- (可选) 连续运行从缓存中清除过时的作业之间的时间(以秒为单位)。默认值为 300。
- 12
- (可选)控制是否为新会话获取最新的授权。启用后,从 Red Hat Single Sign-On 检索并缓存该用户。默认值为
false
。 - 13
- (可选)连接到 Red Hat Single Sign-On 令牌端点时的连接超时(以秒为单位)。默认值为 60。
- 14
- (可选)连接到 Red Hat Single Sign-On 令牌端点时的读取超时(以秒为单位)。默认值为 60。
- 15
- (可选)到授权服务器失败的 HTTP 请求的次数(无需暂停)的最大次数。默认值为
0,
表示没有执行重试。要有效地使用这个选项,请考虑减少connectTimeoutSeconds
和readTimeoutSeconds
选项的超时时间。但请注意,重试可能会阻止当前 worker 线程对其他请求使用,如果太多请求停滞,可能会导致 Kafka 代理无响应。 - 16
- (可选)启用或禁用 OAuth 指标。默认值为
false
。
- 保存并退出编辑器,然后等待滚动更新完成。
检查日志中的更新,或者通过观察 pod 状态转换:
oc logs -f ${POD_NAME} -c kafka oc get pod -w
滚动更新将代理配置为使用 OAuth 2.0 授权。
- 通过以客户端或具有特定角色的用户访问 Kafka 代理来验证配置的权限,确保它们具有必要的访问权限,或者没有应该具有访问权限。
14.5.3. 在 Red Hat Single Sign-On 授权服务中管理策略和权限
本节论述了 Red Hat Single Sign-On Authorization 服务和 Kafka 使用的授权模型,并在每个模型中定义重要概念。
要授予访问 Kafka 的权限,您可以通过在 Red Hat Single Sign-On 中创建 OAuth 客户端规格 将 Red Hat Single Sign-On 授权服务对象映射到 Kafka 资源。使用 Red Hat Single Sign-On Authorization Services 规则为用户帐户或服务帐户授予 Kafka 权限。
示例显示了常见 Kafka 操作所需的不同用户权限,如创建和列出主题。
14.5.3.1. Kafka 和 Red Hat Single Sign-On 授权模型概述
Kafka 和 Red Hat Single Sign-On 授权服务使用不同的授权模型。
Kafka 授权模型
Kafka 的授权模型使用 资源类型。当 Kafka 客户端对代理执行操作时,代理使用配置的 KeycloakAuthorizer
来根据操作和资源类型检查客户端的权限。
Kafka 使用五个资源类型来控制访问: 主题
、组
、集群
、TransactionalId
和 DelegationToken
。每个资源类型都有一组可用权限。
Topic
-
创建
-
写
-
读
-
删除
-
Describe
-
DescribeConfigs
-
更改
-
AlterConfigs
组
-
读
-
Describe
-
删除
集群
-
创建
-
Describe
-
更改
-
DescribeConfigs
-
AlterConfigs
-
IdempotentWrite
-
ClusterAction
transactionalId
-
Describe
-
写
DelegationToken
-
Describe
Red Hat Single Sign-On Authorization Services 模型
Red Hat Single Sign-On Authorization Services 模型有四个概念来定义和授予权限:resources(资源), authorization scopes(授权范围), policies(政策), 和 permissions(权限)。
- Resources
- 资源是一组资源定义,用于将资源与允许的操作匹配。资源可以是单独的主题,例如,也可以是名称以相同前缀开头的所有主题。资源定义与一组可用的授权范围关联,它们代表资源上所有可用的操作。通常,实际上只允许这些操作的子集。
- 授权范围
- 授权范围是特定资源定义上所有可用操作的集合。当您定义新资源时,您可以从所有范围集中添加范围。
- 策略(policy)
策略是一个授权规则,它使用与帐户列表匹配的条件。策略可以匹配:
- 基于客户端 ID 或角色 的服务帐户
- 基于用户名、组或角色 的用户帐户。
- 权限
- 权限为一组用户授予特定资源定义上的授权范围子集。
其他资源
14.5.3.2. 将 Red Hat Single Sign-On 授权服务映射到 Kafka 授权模型
Kafka 授权模型用作定义将控制对 Kafka 访问权限的 Red Hat Single Sign-On 角色和资源的基础。
要为用户帐户或服务帐户授予 Kafka 权限,您首先在 Red Hat Single Sign-On 中为 Kafka 代理创建 OAuth 客户端规格。然后,您可以在客户端上指定 Red Hat Single Sign-On Authorization Services 规则。通常,代表代理的 OAuth 客户端的客户端 ID 是 kafka
。由 AMQ Streams 提供 的示例配置文件 使用 kafka
作为 OAuth 客户端 ID。
如果您有多个 Kafka 集群,您可以将单个 OAuth 客户端(kafka
)用于所有这些集群。这可让您定义一个统一空间,在其中定义和管理授权规则。但是,您还可以使用不同的 OAuth 客户端 ID (如 my-cluster-kafka
或 cluster-dev-kafka
),并在每个客户端配置中为每个集群定义授权规则。
kafka
客户端定义必须在 Red Hat Single Sign-On Admin 控制台中启用 Authorization Enabled 选项。
所有权限都存在于 kafka
客户端范围内。如果您使用不同的 OAuth 客户端 ID 配置不同的 Kafka 集群,则每个集群都需要一组单独的权限,即使它们是同一个 Red Hat Single Sign-On 域的一部分。
当 Kafka 客户端使用 OAUTHBEARER 身份验证时,Red Hat Single Sign-On 授权器(KeycloakAuthorizer
)使用当前会话的访问令牌从 Red Hat Single Sign-On 服务器检索授权列表。为了检索授予,授权者评估 Red Hat Single Sign-On Authorization Services 策略和权限。
Kafka 权限的授权范围
初始的红帽单点登录配置通常涉及上传授权范围,以创建可在每个 Kafka 资源类型上执行的所有可能操作的列表。在定义任何权限前,仅执行此步骤一次。您可以手动添加授权范围,而不是上传它们。
授权范围必须包含所有可能的 Kafka 权限,而不考虑资源类型:
-
创建
-
写
-
读
-
删除
-
Describe
-
更改
-
DescribeConfig
-
AlterConfig
-
ClusterAction
-
IdempotentWrite
如果您确定您不需要权限(例如,Idempot entWrite
),您可以从授权范围列表中省略它。但是,那个权限无法用于 Kafka 资源上的目标。
权限检查的资源模式
在执行权限检查时,资源模式用于与目标资源匹配的模式匹配。常规模式格式为 RESOURCE-TYPE:PATTERN-NAME
。
资源类型镜像 Kafka 授权模型。模式允许两个匹配选项:
-
完全匹配(当模式不以
*
结尾) -
前缀匹配(当模式匹配时,其
模式匹配
)
资源模式示例
Topic:my-topic Topic:orders-* Group:orders-* Cluster:*
另外,常规模式格式可以加上 kafka-cluster:CLUSTER-NAME
前缀,后跟一个逗号,其中 CLUSTER-NAME 代表 Kafka 自定义资源中的 metadata.name
。
具有集群前缀的资源模式示例
kafka-cluster:my-cluster,Topic:* kafka-cluster:*,Group:b_*
当缺少 kafka-cluster
前缀时,它被假定为 kafka-cluster:*
。
在定义资源时,您可以将其与资源相关的可能授权范围列表关联。设置目标资源类型有意义的任何操作。
虽然您可以在任何资源中添加任何授权范围,但只有资源类型支持的范围才被视为访问控制。
应用访问权限的策略
策略用于将权限指向一个或多个用户帐户或服务帐户。目标可以引用:
- 特定用户或服务帐户
- 域角色或客户端角色
- 用户组
- 与客户端 IP 地址匹配的 JavaScript 规则
带有一个唯一名称,可以重复使用以多个资源为目标的多个权限。
授予访问权限的权限
使用细粒度权限将策略、资源和授权范围一起拉取给用户授予访问权限的策略、资源和授权范围。
每个权限的名称应明确定义其授予哪些用户的权限。例如,Dev Team B 可以从以 x 开头的主题中读取
。
其他资源
- 有关如何通过红帽单点登录授权服务配置权限的更多信息,请参阅 第 14.5.4 节 “Try Red Hat Single Sign-On Authorization Services”。
14.5.3.3. Kafka 操作所需的权限示例
以下示例演示了在 Kafka 上执行常见操作所需的用户权限。
创建主题
要创建主题,需要特定主题或 Cluster:kafka-cluster
的 Create
权限。
bin/kafka-topics.sh --create --topic my-topic \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
列出主题
如果用户对指定主题具有 Describe
权限,则会列出该主题。
bin/kafka-topics.sh --list \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
显示主题详情
要显示主题的详情,在主题上需要 Describe
和 DescribeConfigs
权限。
bin/kafka-topics.sh --describe --topic my-topic \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
生成消息到主题
要生成消息到主题,在主题上需要 Describe
和 Write
权限。
如果主题尚未创建,并且启用了主题自动创建,则需要创建主题的权限。
bin/kafka-console-producer.sh --topic my-topic \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --producer.config=/tmp/config.properties
使用来自主题的消息
为了消费主题中的消息,需要有主题的 Describe
和 Read
权限。在主题中使用通常依赖于将消费者偏移存储在消费者组中,这需要对消费者组需要额外的 Describe
和 Read
权限。
匹配需要两个 资源
。例如:
Topic:my-topic Group:my-group-*
bin/kafka-console-consumer.sh --topic my-topic --group my-group-1 --from-beginning \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --consumer.config /tmp/config.properties
使用幂等制作者向主题生成消息
除了生成主题的权限外,Cluster:kafka-cluster
资源还需要额外的 IdempotentWrite
权限。
匹配需要两个 资源
。例如:
Topic:my-topic Cluster:kafka-cluster
bin/kafka-console-producer.sh --topic my-topic \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --producer.config=/tmp/config.properties --producer-property enable.idempotence=true --request-required-acks -1
列出消费者组
列出消费者组时,仅返回具有 Describe
权限的组。或者,如果用户对 Cluster:kafka-cluster
具有 Describe
权限,则返回所有消费者组。
bin/kafka-consumer-groups.sh --list \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
显示消费者组详情
要显示消费者组的详细信息,需要 Describe
权限以及与组关联的主题。
bin/kafka-consumer-groups.sh --describe --group my-group-1 \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
更改主题配置
要更改主题的配置,需要主题的 Describe
和 Alter
权限。
bin/kafka-topics.sh --alter --topic my-topic --partitions 2 \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
显示 Kafka 代理配置
要使用 kafka-configs.sh
获取代理的配置,Cluster:kafka-cluster
需要 DescribeConfigs
权限。
bin/kafka-configs.sh --entity-type brokers --entity-name 0 --describe --all \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
更改 Kafka 代理配置
要更改 Kafka 代理的配置,Cluster:kafka-cluster
需要 DescribeConfigs
和 AlterConfigs
权限。
bin/kafka-configs --entity-type brokers --entity-name 0 --alter --add-config log.cleaner.threads=2 \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
删除主题
要删除主题,需要主题上的 Describe
和 Delete
权限。
bin/kafka-topics.sh --delete --topic my-topic \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
选择一个领导分区
要为主题分区运行领导选择,Cluster:kafka-cluster
需要 Alter
权限。
bin/kafka-leader-election.sh --topic my-topic --partition 0 --election-type PREFERRED / --bootstrap-server my-cluster-kafka-bootstrap:9092 --admin.config /tmp/config.properties
重新分配分区
要生成分区重新分配文件,对涉及的主题需要 Describe
权限。
bin/kafka-reassign-partitions.sh --topics-to-move-json-file /tmp/topics-to-move.json --broker-list "0,1" --generate \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties > /tmp/partition-reassignment.json
要执行分区重新分配,需要在 Cluster:kafka-cluster
上需要 Describe
和 Alter
权限。另外,有关涉及的主题还需要 Describe
权限。
bin/kafka-reassign-partitions.sh --reassignment-json-file /tmp/partition-reassignment.json --execute \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties
要在 Cluster:kafka-cluster
,以及涉及的每个主题上需要验证分区重新分配、Describe
和 AlterConfigs
权限。
bin/kafka-reassign-partitions.sh --reassignment-json-file /tmp/partition-reassignment.json --verify \ --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties
14.5.4. Try Red Hat Single Sign-On Authorization Services
本例解释了如何在 keycloak
授权中使用 Red Hat Single Sign-On Authorization Services。使用 Red Hat Single Sign-On Authorization Services 对 Kafka 客户端强制访问限制。Red Hat Single Sign-On Authorization Services 使用授权范围、策略和权限来定义并应用访问控制。
Red Hat Single Sign-On Authorization Services REST 端点提供经过身份验证的用户授予资源的权限列表。授权(权限)列表从 Red Hat Single Sign-On 服务器获取,作为 Kafka 客户端建立身份验证会话的第一个操作。该列表在后台刷新,以便检测到对授权的更改。授予会在 Kafka 代理本地缓存并强制每个用户会话,以提供快速授权决策。
AMQ Streams 提供 示例配置文件。这包括用于设置 Red Hat Single Sign-On 的示例文件:
kafka-ephemeral-oauth-single-keycloak-authz.yaml
-
使用 Red Hat Single Sign-On 为基于 OAuth 2.0 令牌的授权配置的
Kafka
自定义资源示例。您可以使用自定义资源来部署使用keycloak
授权和基于令牌的oauth
身份验证的 Kafka 集群。 kafka-authz-realm.json
- 配置了示例组、用户、角色和客户端的 Red Hat Single Sign-On 域示例。您可以将域导入到 Red Hat Single Sign-On 实例中,以设置精细的权限来访问 Kafka。
如果要使用 Red Hat Single Sign-On 尝试示例,请使用这些文件按照所示的顺序执行本节中所述的任务。
身份验证
当您配置基于令牌的 oauth
身份验证时,您可以指定 jwksEndpointUri
作为本地 JWT 验证的 URI。当您配置 keycloak
授权时,您可以指定 tokenEndpointUri
作为 Red Hat Single Sign-On 令牌端点的 URI。两个 URI 的主机名必须相同。
带有组或角色策略的目标权限
在 Red Hat Single Sign-On 中,启用了服务帐户的机密客户端可以使用客户端 ID 和 secret 向服务器进行身份验证。这对通常以自己的名称而不是特定用户代理(如网站)的微服务方便。服务帐户可以像常规用户一样分配角色。但是,他们无法分配组。因此,如果要使用服务帐户将权限传送到微服务,则无法使用组策略,而应使用角色策略。相反,如果您只想将某些权限限制为需要使用用户名和密码进行身份验证的普通用户帐户,您可以实现作为使用组策略而非角色策略的副作用。本例中使用了以 ClusterManager
开头的权限。执行集群管理通常使用 CLI 工具以互动方式完成。在使用生成的访问令牌向 Kafka 代理进行身份验证前,需要用户登录。在这种情况下,访问令牌代表特定用户,而不是客户端应用程序。
14.5.4.1. 访问 Red Hat Single Sign-On 管理控制台
设置 Red Hat Single Sign-On,然后连接到其管理控制台并添加预配置的域。使用示例 kafka-authz-realm.json
文件导入域。您可以在管理控制台中检查为域定义的授权规则。规则授予对配置为使用 Red Hat Single Sign-On 域示例的 Kafka 集群上的资源的访问权限。
先决条件
- 一个正常运行的 OpenShift 集群。
-
包含预配置的域的 AMQ Streams
examples/security/keycloak-authorization/kafka-authz-realm.json
文件。
流程
- 使用 Red Hat Single Sign-On Operator 安装 Red Hat Single Sign-On 服务器,如 Red Hat Single Sign-On 文档中的 Server Installation and Configuration 所述。
- 等待 Red Hat Single Sign-On 实例正在运行。
获取外部主机名来访问管理控制台。
NS=sso oc get ingress keycloak -n $NS
在本例中,我们假定 Red Hat Single Sign-On 服务器在
sso
命名空间中运行。获取
admin
用户的密码。oc get -n $NS pod keycloak-0 -o yaml | less
密码存储为一个 secret,因此获取 Red Hat Single Sign-On 实例的配置 YAML 文件,以识别 secret 的名称(
secretKeyRef.name
)。使用 secret 的名称来获取明文密码。
SECRET_NAME=credential-keycloak oc get -n $NS secret $SECRET_NAME -o yaml | grep PASSWORD | awk '{print $2}' | base64 -D
在本例中,我们假定 secret 的名称是
credential-keycloak
。使用用户名
admin
和密码您获取的密码登录管理控制台。使用
https://HOSTNAME
访问 KubernetesIngress
。现在,您可以使用管理控制台将示例域上传到 Red Hat Single Sign-On。
- 单击 Add Realm 以导入示例域。
添加
examples/security/keycloak-authorization/kafka-authz-realm.json
文件,然后点 Create。现在,您有
kafka-authz
作为控制台中的当前域。默认视图显示 Master 域。
在 Red Hat Single Sign-On Admin 控制台中,进入 Clients > kafka > Authorization > Settings,检查 Decision Strategy 是否已设置为 Affirmative。
一个关系策略表示,必须至少满足一个策略,以便客户端访问 Kafka 集群。
在 Red Hat Single Sign-On Admin Console 中,进入 Groups, Users, Roles 和 Clients 来查看 realm 配置。
- 组
-
组
用于创建用户组并设置用户权限。组是一组分配了名称的用户。它们用于将用户分为地理、组织或部门单元。组可以链接到 LDAP 身份提供程序。您可以通过自定义 LDAP 服务器 admin 用户界面让用户成为组的成员,例如,授予 Kafka 资源的权限。 - 用户
-
用户
用于创建用户。在本例中,定义了alice
和bob
。alice
是ClusterManager
组的成员,bob
是ClusterManager-my-cluster
组的成员。用户可以存储在 LDAP 身份提供程序中。 - 角色
-
Roles
代表用户或客户端具有特定权限。角色与组类似的概念。它们通常 用于标记 具有机构角色的用户并具有必要的权限。角色不能存储在 LDAP 身份提供程序中。如果 LDAP 是必需的,您可以使用组,并将 Red Hat Single Sign-On 角色添加到组中,以便在为用户分配他们获得对应角色的组时。 - 客户端
客户端可以
具有特定的配置。在本例中,配置了kafka
,kafka-cli
,team-a-client
, 和team-b-client
客户端。-
Kafka 代理使用
kafka
客户端来执行访问令牌验证所需的 OAuth 2.0 通信。此客户端还包含用于在 Kafka 代理上执行授权的授权服务资源定义、策略和授权范围。授权配置在 Authorization 选项卡的kafka
客户端中定义,在从 Settings 标签页上切换 Authorization 时,它就会可见。 -
kafka-cli
客户端是一个公共客户端,在使用用户名和密码进行身份验证时,Kafka 命令行工具使用它来获取访问令牌或刷新令牌。 -
team-a-client
和team-b-client
客户端是代表可以部分访问某些 Kafka 主题的服务的机密客户端。
-
Kafka 代理使用
在 Red Hat Single Sign-On Admin 控制台中,进入 Authorization > Permissions 以查看授予使用为域定义的资源和策略的权限。
例如,
kafka
客户端具有以下权限:Dev Team A can write to topics that start with x_ on any cluster Dev Team B can read from topics that start with x_ on any cluster Dev Team B can update consumer group offsets that start with x_ on any cluster ClusterManager of my-cluster Group has full access to cluster config on my-cluster ClusterManager of my-cluster Group has full access to consumer groups on my-cluster ClusterManager of my-cluster Group has full access to topics on my-cluster
- 开发团队 A
-
Dev Team A realm 角色可写入任何集群上以
x_
开头的主题。这会组合一个名为Topic:x
、Describe
和Write
范围的资源,以及Dev 团队 A
策略。Dev Team A
策略与具有名为Dev Team A
的域角色匹配的所有用户匹配。 - Dev Team B
-
Dev Team B realm 角色可以从任何集群中以
x_
开头的主题中读取。这可组合Topic:xö
、Group:x
the 资源、Describe
和Read
范围,以及Dev 团队 B
策略。Dev Team B
策略与具有名为Dev Team B
的域角色匹配的所有用户。匹配用户和客户端能够读取主题,并为名称以x_
开头的主题和消费者组更新消耗的偏移量。
14.5.4.2. 使用 Red Hat Single Sign-On 授权部署 Kafka 集群
部署配置为连接到 Red Hat Single Sign-On 服务器的 Kafka 集群。使用 kafka-ephemeral-oauth-single-keycloak-authz.yaml
文件示例将 Kafka 集群部署为 Kafka
自定义资源。这个示例使用 keycloak
授权和 oauth
身份验证部署单节点 Kafka 集群。
先决条件
- Red Hat Single Sign-On 授权服务器部署到 OpenShift 集群,并使用 example 域加载。
- Cluster Operator 部署到 OpenShift 集群。
-
AMQ Streams
examples/security/keycloak-authorization/kafka-ephemeral-oauth-single-keycloak-authz.yaml
自定义资源。
流程
使用您部署的 Red Hat Single Sign-On 实例的主机名,为 Kafka 代理准备信任存储证书,以便与 Red Hat Single Sign-On 服务器通信。
SSO_HOST=SSO-HOSTNAME SSO_HOST_PORT=$SSO_HOST:443 STOREPASS=storepass echo "Q" | openssl s_client -showcerts -connect $SSO_HOST_PORT 2>/dev/null | awk ' /BEGIN CERTIFICATE/,/END CERTIFICATE/ { print $0 } ' > /tmp/sso.pem
需要该证书,因为 Kubernetes
Ingress
用于建立安全(HTTPS)连接。通常没有单个证书,但一个证书链。您只需要提供最顶层的签发者 CA,该 CA 在
/tmp/sso.pem
文件中最后列出。您可以手动提取,或者使用以下命令:在证书链中提取顶级 CA 证书的命令示例
split -p "-----BEGIN CERTIFICATE-----" sso.pem sso- for f in $(ls sso-*); do mv $f $f.pem; done cp $(ls sso-* | sort -r | head -n 1) sso-ca.crt
注意可信 CA 证书通常从可信源获取,而不使用
openssl
命令。将证书部署到 OpenShift 作为机密。
oc create secret generic oauth-server-cert --from-file=/tmp/sso-ca.crt -n $NS
将主机名设置为环境变量
SSO_HOST=SSO-HOSTNAME
创建并部署示例 Kafka 集群。
cat examples/security/keycloak-authorization/kafka-ephemeral-oauth-single-keycloak-authz.yaml | sed -E 's#\${SSO_HOST}'"#$SSO_HOST#" | oc create -n $NS -f -
14.5.4.3. 为 CLI Kafka 客户端会话准备 TLS 连接
为交互式 CLI 会话创建一个新 pod。使用 Red Hat Single Sign-On 证书为 TLS 连接设置信任存储。信任存储是连接到 Red Hat Single Sign-On 和 Kafka 代理。
先决条件
Red Hat Single Sign-On 授权服务器部署到 OpenShift 集群,并使用 example 域加载。
在 Red Hat Single Sign-On Admin 控制台中,检查分配给客户端的角色显示在 Clients > Service Account Roles 中。
- 配置为与 Red Hat Single Sign-On 连接的 Kafka 集群被部署到 OpenShift 集群。
流程
使用 AMQ Streams Kafka 镜像运行新的交互式 pod 容器,以连接到正在运行的 Kafka 代理。
NS=sso oc run -ti --restart=Never --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 kafka-cli -n $NS -- /bin/sh
注意如果
oc
time out 等待镜像下载,后续的尝试可能会导致 AlreadyExists 错误。附加到 pod 容器。
oc attach -ti kafka-cli -n $NS
使用 Red Hat Single Sign-On 实例的主机名,使用 TLS 为客户端连接准备证书。
SSO_HOST=SSO-HOSTNAME SSO_HOST_PORT=$SSO_HOST:443 STOREPASS=storepass echo "Q" | openssl s_client -showcerts -connect $SSO_HOST_PORT 2>/dev/null | awk ' /BEGIN CERTIFICATE/,/END CERTIFICATE/ { print $0 } ' > /tmp/sso.pem
通常没有单个证书,但一个证书链。您只需要提供最顶层的签发者 CA,该 CA 在
/tmp/sso.pem
文件中最后列出。您可以手动提取,或者使用以下命令:在证书链中提取顶级 CA 证书的命令示例
split -p "-----BEGIN CERTIFICATE-----" sso.pem sso- for f in $(ls sso-*); do mv $f $f.pem; done cp $(ls sso-* | sort -r | head -n 1) sso-ca.crt
注意可信 CA 证书通常从可信源获取,而不使用
openssl
命令。为到 Kafka 代理的 TLS 连接创建一个信任存储。
keytool -keystore /tmp/truststore.p12 -storetype pkcs12 -alias sso -storepass $STOREPASS -import -file /tmp/sso-ca.crt -noprompt
使用 Kafka bootstrap 地址作为 Kafka 代理的主机名和
tls
侦听端口(9093)来为 Kafka 代理准备证书。KAFKA_HOST_PORT=my-cluster-kafka-bootstrap:9093 STOREPASS=storepass echo "Q" | openssl s_client -showcerts -connect $KAFKA_HOST_PORT 2>/dev/null | awk ' /BEGIN CERTIFICATE/,/END CERTIFICATE/ { print $0 } ' > /tmp/my-cluster-kafka.pem
获取的
.pem
文件通常不是一个证书,而是一个证书链。您只需要提供最顶层的签发者 CA,该 CA 在/tmp/my-cluster-kafka.pem
文件中最后列出。您可以手动提取,或者使用以下命令:在证书链中提取顶级 CA 证书的命令示例
split -p "-----BEGIN CERTIFICATE-----" /tmp/my-cluster-kafka.pem kafka- for f in $(ls kafka-*); do mv $f $f.pem; done cp $(ls kafka-* | sort -r | head -n 1) my-cluster-kafka-ca.crt
注意可信 CA 证书通常从可信源获取,而不使用
openssl
命令。在本例中,我们假定客户端在部署了 Kafka 集群的同一命名空间中的 pod 中运行。如果客户端从 OpenShift 集群外部访问 Kafka 集群,您必须首先确定 bootstrap 地址。在这种情况下,您还可以直接从 OpenShift secret 获取集群证书,且不需要openssl
。如需更多信息,请参阅 第 13 章 设置 Kafka 集群的客户端访问权限。将 Kafka 代理的证书添加到信任存储中。
keytool -keystore /tmp/truststore.p12 -storetype pkcs12 -alias my-cluster-kafka -storepass $STOREPASS -import -file /tmp/my-cluster-kafka-ca.crt -noprompt
使会话保持打开,以检查授权访问。
14.5.4.4. 使用 CLI Kafka 客户端会话检查对 Kafka 的授权访问
使用交互式 CLI 会话,检查通过 Red Hat Single Sign-On 域应用的授权规则。使用 Kafka 示例制作者和消费者客户端应用检查,以使用具有不同访问权限的用户和服务帐户创建主题。
使用 team-a-client
和 team-b-client
客户端检查授权规则。使用 alice
admin 用户在 Kafka 上执行额外的管理任务。
本例中使用的 AMQ Streams Kafka 镜像包含 Kafka producer 和消费者二进制文件。
先决条件
- ZooKeeper 和 Kafka 在 OpenShift 集群中运行,以便能够发送和接收信息。
设置客户端和管理员用户配置
使用
team-a-client
客户端的身份验证属性准备 Kafka 配置文件。SSO_HOST=SSO-HOSTNAME cat > /tmp/team-a-client.properties << EOF security.protocol=SASL_SSL ssl.truststore.location=/tmp/truststore.p12 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.mechanism=OAUTHBEARER sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.client.id="team-a-client" \ oauth.client.secret="team-a-client-secret" \ oauth.ssl.truststore.location="/tmp/truststore.p12" \ oauth.ssl.truststore.password="$STOREPASS" \ oauth.ssl.truststore.type="PKCS12" \ oauth.token.endpoint.uri="https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" ; sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler EOF
使用 SASL OAUTHBEARER 机制。这种机制需要客户端 ID 和客户端 secret,这意味着客户端第一次连接到 Red Hat Single Sign-On 服务器以获取访问令牌。然后,客户端连接到 Kafka 代理,并使用访问令牌进行身份验证。
使用
team-b-client
客户端的身份验证属性准备 Kafka 配置文件。cat > /tmp/team-b-client.properties << EOF security.protocol=SASL_SSL ssl.truststore.location=/tmp/truststore.p12 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.mechanism=OAUTHBEARER sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.client.id="team-b-client" \ oauth.client.secret="team-b-client-secret" \ oauth.ssl.truststore.location="/tmp/truststore.p12" \ oauth.ssl.truststore.password="$STOREPASS" \ oauth.ssl.truststore.type="PKCS12" \ oauth.token.endpoint.uri="https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" ; sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler EOF
使用
curl
并执行密码授权身份验证来获取刷新令牌,来验证 admin 用户alice
。USERNAME=alice PASSWORD=alice-password GRANT_RESPONSE=$(curl -X POST "https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" -H 'Content-Type: application/x-www-form-urlencoded' -d "grant_type=password&username=$USERNAME&password=$PASSWORD&client_id=kafka-cli&scope=offline_access" -s -k) REFRESH_TOKEN=$(echo $GRANT_RESPONSE | awk -F "refresh_token\":\"" '{printf $2}' | awk -F "\"" '{printf $1}')
刷新令牌是一个离线令牌,其长期且不会过期。
使用 admin 用户
alice
的身份验证属性准备 Kafka 配置文件。cat > /tmp/alice.properties << EOF security.protocol=SASL_SSL ssl.truststore.location=/tmp/truststore.p12 ssl.truststore.password=$STOREPASS ssl.truststore.type=PKCS12 sasl.mechanism=OAUTHBEARER sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \ oauth.refresh.token="$REFRESH_TOKEN" \ oauth.client.id="kafka-cli" \ oauth.ssl.truststore.location="/tmp/truststore.p12" \ oauth.ssl.truststore.password="$STOREPASS" \ oauth.ssl.truststore.type="PKCS12" \ oauth.token.endpoint.uri="https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" ; sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler EOF
kafka-cli
公共客户端用于sasl.jaas.config
中的oauth.client.id
。由于它是公共客户端,因此不需要 secret。客户端使用上一步中身份验证的刷新令牌进行身份验证。刷新令牌请求 scenes 后面的访问令牌,然后发送到 Kafka 代理进行身份验证。
生成具有授权访问权限的消息
使用 team-a-client
配置检查您可以生成消息到以 a_
或 x_
开头的主题。
写入主题
my-topic
。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic my-topic \ --producer.config=/tmp/team-a-client.properties First message
此请求返回一个
Not authorized to access topics: [my-topic]
错误。team-a-client
有一个Dev Team A
角色,该角色授予对以a_
开头的主题执行任何受支持的操作的权限,但只能写入以x_
开头的主题。名为my-topic
的主题都匹配这些规则。写入主题
a_messages
。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \ --producer.config /tmp/team-a-client.properties First message Second message
消息成功生成给 Kafka。
- 按 CTRL+C 退出 CLI 应用程序。
检查 Kafka 容器日志,以了解请求的
Authorization GRANTED
的调试日志。oc logs my-cluster-kafka-0 -f -n $NS
使用具有授权访问的消息
使用 team-a-client
配置使用来自主题 a_messages
的消息。
从主题
a_messages
获取消息。bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \ --from-beginning --consumer.config /tmp/team-a-client.properties
请求返回一个错误,因为
team-a-client
的Dev Team A
角色只能访问名称以a_
开头的消费者组。更新
team-a-client
属性,以指定允许使用的自定义消费者组。bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \ --from-beginning --consumer.config /tmp/team-a-client.properties --group a_consumer_group_1
消费者接收来自
a_messages
主题的所有消息。
管理具有授权访问权限的 Kafka
team-a-client
是一个没有集群级别访问权限的帐户,但可用于某些管理操作。
列出主题。
bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties --list
返回
a_messages
主题。列出消费者组。
bin/kafka-consumer-groups.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties --list
返回
a_consumer_group_1
消费者组。获取集群配置的详情。
bin/kafka-configs.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties \ --entity-type brokers --describe --entity-default
请求会返回错误,因为操作需要
team-a-client
没有任何集群级别权限。
使用具有不同权限的客户端
使用 team-b-client
配置为以 b_
开头的主题生成消息。
写入主题
a_messages
。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \ --producer.config /tmp/team-b-client.properties Message 1
此请求返回一个
Not authorized to access topics: [a_messages]
错误。写入主题
b_messages
。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic b_messages \ --producer.config /tmp/team-b-client.properties Message 1 Message 2 Message 3
消息成功生成给 Kafka。
写入主题
x_messages
。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --producer.config /tmp/team-b-client.properties Message 1
无法访问主题的 Not authorized to access: [x_messages]
错误,team-b-client
只能从主题x_messages
中读取。使用
team-a-client
写入主题x_messages
。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --producer.config /tmp/team-a-client.properties Message 1
此请求返回一个
Not authorized to access topics: [x_messages]
错误。team-a-client
可以写入x_messages
主题,但如果尚不存在,则没有创建主题的权限。在team-a-client
可以写入x_messages
主题之前,管理员用户 必须使用正确配置(如分区和副本数)创建它。
使用授权管理员用户管理 Kafka
使用 admin 用户 alice
管理 Kafka。alice
具有管理任何 Kafka 集群上的所有内容的完整访问权限。
以
alice
身份创建x_messages
主题。bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/alice.properties \ --topic x_messages --create --replication-factor 1 --partitions 1
主题已创建成功。
以
alice
身份列出所有主题。bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/alice.properties --list bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties --list bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-b-client.properties --list
管理员用户
alice
可以列出所有主题,而team-a-client
和team-b-client
只能列出他们有权访问的主题。Dev 团队 A
和Dev 团队 B
角色对以x_
开头的主题具有Describe
权限,但它们无法看到其他团队的主题,因为它们对它们没有描述
权限。使用
team-a-client
向x_messages
主题生成信息:bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --producer.config /tmp/team-a-client.properties Message 1 Message 2 Message 3
当
alice
创建x_messages
主题时,消息会被成功生成给 Kafka。使用
team-b-client
向x_messages
主题生成消息。bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --producer.config /tmp/team-b-client.properties Message 4 Message 5
此请求返回一个
Not authorized to access topics: [x_messages]
错误。使用
team-b-client
使用x_messages
主题的消息:bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --from-beginning --consumer.config /tmp/team-b-client.properties --group x_consumer_group_b
消费者接收来自
x_messages
主题的所有消息。使用
team-a-client
使用x_messages
主题的消息。bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --from-beginning --consumer.config /tmp/team-a-client.properties --group x_consumer_group_a
此请求返回一个
Not authorized to access topics: [x_messages]
错误。使用
team-a-client
使用以a_
开头的消费者组中的消息。bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --from-beginning --consumer.config /tmp/team-a-client.properties --group a_consumer_group_a
此请求返回一个
Not authorized to access topics: [x_messages]
错误。Dev Team A
没有以x_
开始的主题的Read
访问权限。使用
alice
生成消息到x_messages
主题。bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \ --from-beginning --consumer.config /tmp/alice.properties
消息成功生成给 Kafka。
alice
可以从任何主题读取或写入。使用
alice
读取集群配置。bin/kafka-configs.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/alice.properties \ --entity-type brokers --describe --entity-default
本例中的集群配置为空。
第 15 章 管理 TLS 证书
AMQ Streams 支持 TLS 用于 Kafka 和 AMQ Streams 组件间的加密通信。
AMQ Streams 建立加密的 TLS 连接,用于以下组件之间的通信:
- Kafka 代理和 ZooKeeper 节点
- Kafka 代理(interbroker 通信)
- ZooKeeper 节点(中间通信)
- AMQ Streams operator 和 Kafka 和 ZooKeeper
- Cruise Control 和 Kafka
- Kafka Exporter 和 Kafka
客户端和代理之间的连接使用监听程序,您必须将它们配置为使用 TLS 加密通信。您可以在 Kafka
自定义资源中配置这些监听程序,每个监听程序名称和端口号必须在集群中唯一。Kafka 代理和 Kafka 客户端之间的通信会根据为监听程序配置 tls
属性的方式进行加密。如需更多信息,请参阅 第 13 章 设置 Kafka 集群的客户端访问权限。
下图显示了安全通信的连接。
图 15.1. Kafka 和 ZooKeeper 通信由 TLS 加密保护

图中显示的端口如下:
- control plane 侦听器(9090)
- Kafka 控制器和代理之间的连接在端口 9090 上使用内部 control plane 监听程序,促进代理间通信。Kafka 客户端无法访问此监听程序。
- 复制监听程序(9091)
- 代理之间的数据复制以及 AMQ Streams operator、Cruise Control 和 Kafka Exporter 的内部连接,使用端口 9091 上的复制监听程序。Kafka 客户端无法访问此监听程序。
- 客户端连接(9092 或更高版本)的监听程序
- 对于 TLS 加密的通信(通过配置监听程序),内部和外部客户端连接到 Kafka 代理。外部客户端(producers 和 consumers)通过公告的监听程序端口连接到 Kafka 代理。
- zookeeper 端口(2181)
- 用于连接 Kafka 的 ZooKeeper 端口。
- ZooKeeper 间的通信端口(2888)
- ZooKeeper 端口,用于在 ZooKeeper 节点之间进行干预。
- ZooKeeper 领导选举端口(3888)
- ZooKeeper 端口,用于 ZooKeeper 集群中的节点间的领导选举机制。
当为客户端配置监听程序对代理的访问时,您可以使用端口 9092 或更高版本(9093、9094 等),但有一些例外。侦听程序无法配置为使用为 interbroker 通信(9090 和 9091)、Prometheus 指标(9404)和 JMX (Java 管理扩展)监控(9999)保留的端口。
15.1. 内部集群 CA 和客户端 CA
要支持加密,每个 AMQ Streams 组件需要自己的私钥和公钥证书。所有组件证书都由名为 集群 CA 的内部 CA (证书颁发机构)签名。
CA (证书授权机构)证书由 Cluster Operator 生成,以验证组件和客户端的身份。
同样,使用 mTLS 连接到 AMQ Streams 的每个 Kafka 客户端应用程序都需要使用私钥和证书。第二个内部 CA (名为 客户端 CA )用于为 Kafka 客户端签名证书。
集群 CA 和客户端 CA 均有自签名公钥证书。
Kafka 代理配置为信任由集群 CA 或客户端 CA 签名的证书。客户端不需要连接到的组件,如 ZooKeeper,只信任由集群 CA 签名的证书。除非禁用外部监听程序的 TLS 加密,否则客户端应用程序必须信任由集群 CA 签名的证书。对于执行 mTLS 身份验证的客户端应用程序也是如此。
默认情况下,AMQ Streams 会自动生成和更新集群 CA 或客户端 CA 发布的 CA 证书。您可以使用 Kafka.spec.clusterCa
和 Kafka.spec.clientsCa
属性来配置这些 CA 证书的管理。
如果您不想使用 Cluster Operator 生成的 CA,您可以安装自己的集群和客户端 CA 证书。您提供的任何证书都不会由 Cluster Operator 更新。
15.2. Operator 生成的 secret
Cluster Operator 会自动设置和更新 TLS 证书,以便在集群中启用加密和身份验证。如果要在 Kafka 代理和客户端之间启用加密或 mTLS 身份验证,它还设置其他 TLS 证书。
在部署自定义资源时会创建 secret,如 Kafka
和 KafkaUser
。AMQ Streams 使用这些 secret 为 Kafka 集群、客户端和用户存储私钥和公钥证书。secret 用于在 Kafka 代理和代理和客户端之间建立 TLS 加密连接。它们也用于 mTLS 身份验证。
集群和客户端 secret 始终是对的:一个包含公钥,另一个包含私钥。
- 集群 secret
- 集群 secret 包含用于为 Kafka 代理证书签名的 集群 CA。连接客户端使用证书与 Kafka 集群建立 TLS 加密连接。证书验证代理身份。
- 客户端 secret
- 客户端 secret 包含用户为自己的客户端 证书签名的客户端 CA。这允许对 Kafka 集群进行 mutual 身份验证。代理通过证书验证客户端的身份。
- 用户 secret
- 用户 secret 包含私钥和证书。创建新用户时,secret 由客户端 CA 创建并签名。密钥和证书用于在访问集群时验证和授权用户。
您可以为 TLS 侦听程序或启用了 TLS 加密的外部监听程序提供 Kafka 侦听器证书。使用 Kafka 侦听器证书合并您已就位的安全基础架构。
15.2.1. 使用 PEM 或 PKCS #12 格式的密钥和证书进行 TLS 身份验证
由 AMQ Streams 创建的 secret 以 PEM (Privacy Enhanced 邮件) 和 PKCS #12 (Public-Key Cryptography Standards) 格式提供私钥和证书。PEM 和 PKCS #12 是用于使用 SSL 协议的 TLS 通信的 OpenSSL 生成的密钥格式。
您可以配置 mutual TLS (mTLS)身份验证,它使用为 Kafka 集群和用户生成的 secret 中包含的凭证。
要设置 mTLS,您必须首先执行以下操作:
部署 Kafka 集群时,会使用公钥创建一个 <cluster_name>-cluster-ca-cert
secret 来验证集群。您可以使用公钥为客户端配置信任存储。
当您创建 KafkaUser
时,会使用 密钥和证书创建一个 <kafka_user_name
> secret 来验证用户(客户端)。使用这些凭证为客户端配置密钥存储。
当 Kafka 集群和客户端设置为使用 mTLS 时,您可以从 secret 中提取凭证并将其添加到客户端配置中。
- PEM 密钥和证书
对于 PEM,您可以在客户端配置中添加以下内容:
- truststore
-
CA
.crt
来自 <cluster_name>-cluster-ca-cert
secret,这是集群的 CA 证书。
-
CA
- keystore
-
来自 <
kafka_user_name>
; secret 的user.crt
,这是用户的公共证书。 -
来自 <
kafka_user_name>
; secret 的user.key
,这是用户的私钥。
-
来自 <
- PKCS #12 密钥和证书
对于 PKCS #12,您可以在客户端配置中添加以下内容:
- truststore
-
来自 <
cluster_name>-cluster-ca-cert
secret 的 CA.p12
,这是集群的 CA 证书。 -
CA
.password
来自 <cluster_name>-cluster-ca-cert
secret,这是用于访问公共集群 CA 证书的密码。
-
来自 <
- keystore
-
来自 <
kafka_user_name
> secret 的user.p12
,这是用户的公钥证书。 -
来自 <
kafka_user_name>
; secret 的user.password
,这是用于访问 Kafka 用户的公钥证书的密码。
-
来自 <
Java 支持 PKCS #12,以便您可以将证书的值直接添加到 Java 客户端配置中。您还可以从安全存储位置引用证书。使用 PEM 文件,您必须直接将证书添加到客户端配置中,格式为单行格式。选择适合在 Kafka 集群和客户端之间建立 TLS 连接的格式。如果您对 PEM 不熟悉,可以使用 PKCS #12。
所有密钥的大小为 2048 位,默认情况下,从初始生成起的 365 天内有效。您可以更改有效期。
15.2.2. Cluster Operator 生成的 secret
Cluster Operator 会生成以下证书,这些证书保存为 OpenShift 集群中的 secret。AMQ Streams 默认使用这些 secret。
集群 CA 和客户端 CA 为私钥和公钥有单独的 secret。
<cluster_name>-cluster-ca
- 包含集群 CA 的私钥。AMQ Streams 和 Kafka 组件使用私钥为服务器证书签名。
<cluster_name>-cluster-ca-cert
- 包含集群 CA 的公钥。Kafka 客户端使用公钥验证它们通过 TLS 服务器身份验证连接的 Kafka 代理的身份。
<cluster_name>-clients-ca
- 包含客户端 CA 的私钥。Kafka 客户端在连接到 Kafka 代理时,使用私钥为 mTLS 身份验证签名新的用户证书。
<cluster_name>-clients-ca-cert
- 包含客户端 CA 的公钥。在使用 mTLS 身份验证时,Kafka 代理使用公钥来验证客户端访问 Kafka 代理的客户端的身份。
用于 AMQ Streams 组件间通信的 secret 包含由集群 CA 签名的私钥和公钥证书。
<cluster_name>-kafka-brokers
- 包含 Kafka 代理的私钥和公钥。
<cluster_name>-zookeeper-nodes
- 包含 ZooKeeper 节点的私钥和公钥。
<cluster_name>-cluster-operator-certs
- 包含用于加密 Cluster Operator 和 Kafka 或 ZooKeeper 之间的通信的私钥和公钥。
<cluster_name>-entity-topic-operator-certs
- 包含用于加密主题 Operator 和 Kafka 或 ZooKeeper 之间的通信的私钥和公钥。
<cluster_name>-entity-user-operator-certs
- 包含用于加密 User Operator 和 Kafka 或 ZooKeeper 之间的通信的私钥和公钥。
<cluster_name>-cruise-control-certs
- 包含用于加密 Cruise Control 和 Kafka 或 ZooKeeper 之间的通信的私钥和公钥。
<cluster_name>-kafka-exporter-certs
- 包含用于加密 Kafka Exporter 和 Kafka 或 ZooKeeper 之间的通信的私钥和公钥。
您可以提供自己的服务器证书和私钥,以使用 Kafka 侦听器证书 而不是集群 CA 签名的证书连接到 Kafka 代理。
15.2.3. 集群 CA secret
集群 CA secret 由 Kafka 集群中的 Cluster Operator 管理。
客户端只需要 <cluster_name> -cluster-ca-cert
secret。所有其他集群 secret 都可通过 AMQ Streams 组件访问。如果需要,您可以使用 OpenShift 基于角色的访问控制来执行此操作。
< cluster_name> -cluster-ca-cert
中的 CA 证书必须被 Kafka 客户端应用程序信任,以便在通过 TLS 连接到 Kafka 代理时验证 Kafka 代理证书。
字段 | Description |
---|---|
| 集群 CA 的当前私钥。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
| 集群 CA 的当前证书。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
Kafka 代理 pod < num> 的证书。由 <cluster |
|
Kafka 代理 pod < |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
ZooKeeper 节点 <num> 的证书。由 <cluster |
|
ZooKeeper pod < |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
Cluster Operator 和 Kafka 或 ZooKeeper 之间 mTLS 通信的证书。由 <cluster |
| Cluster Operator 和 Kafka 或 ZooKeeper 之间 mTLS 通信的私钥。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
主题 Operator 和 Kafka 或 ZooKeeper 之间 mTLS 通信的证书。由 <cluster |
| 主题 Operator 和 Kafka 或 ZooKeeper 之间 mTLS 通信的私钥。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
用于 User Operator 和 Kafka 或 ZooKeeper 之间的 mTLS 通信的证书。由 <cluster |
| User Operator 和 Kafka 或 ZooKeeper 间的 mTLS 通信的私钥。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
用于 Cruise Control 和 Kafka 或 ZooKeeper 之间的 mTLS 通信的证书。由 <cluster |
| Cruise Control 和 Kafka 或 ZooKeeper 间的 mTLS 通信的私钥。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
|
用于 Kafka Exporter 和 Kafka 或 ZooKeeper 之间的 mTLS 通信的证书。由 <cluster |
| Kafka Exporter 和 Kafka 或 ZooKeeper 间的 mTLS 通信的私钥。 |
15.2.4. 客户端 CA secret
客户端 CA secret 由 Kafka 集群中的 Cluster Operator 管理。
<cluster_name>-clients-ca-cert
中的正式是 Kafka 代理信任的证书。
& lt;cluster_name> -clients-ca
secret 用于为客户端应用程序的证书签名。如果您打算在没有使用 User Operator 的情况下发布应用程序证书,则 AMQ Streams 组件和管理访问此 secret 必须可以被 AMQ Streams 组件访问。如果需要,您可以使用 OpenShift 基于角色的访问控制来执行此操作。
字段 | Description |
---|---|
| 客户端 CA 的当前私钥。 |
字段 | Description |
---|---|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 |
| 客户端 CA 的当前证书。 |
15.2.5. User Operator 生成的用户 secret
用户 secret 由 User Operator 管理。
当使用 User Operator 创建用户时,会使用用户名生成一个 secret。
Secret 名称 | secret 中的字段 | Description |
---|---|---|
|
| 用于存储证书和密钥的 PKCS #12 存储。 |
| 用于保护 PKCS #12 存储的密码。 | |
| 用户的证书,由客户端 CA 签名 | |
| 用户的私钥 |
15.2.6. 在集群 CA secret 中添加标签和注解
通过在 Kafka
自定义资源中配置 clusterCaCert
模板属性,您可以将自定义标签和注解添加到 Cluster Operator 创建的 Cluster CA secret 中。标签和注解可用于识别对象并添加上下文信息。您可以在 AMQ Streams 自定义资源中配置模板属性。
为 secret 添加标签和注解的模板自定义示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... template: clusterCaCert: metadata: labels: label1: value1 label2: value2 annotations: annotation1: value1 annotation2: value2 # ...
15.2.7. 在 CA secret 中禁用 ownerReference
默认情况下,集群和客户端 CA secret 使用设置为 Kafka
自定义资源的 ownerReference
属性创建。这意味着,当 Kafka
自定义资源被删除时,OpenShift 也会删除 CA secret (收集垃圾收集)。
如果要为新集群重复使用 CA,您可以通过在 Kafka
配置中将集群和客户端 CA secret 的 generateSecretOwnerReference
属性设置为 false
来禁用 ownerReference
。当禁用 ownerReference
时,当删除对应的 Kafka
自定义资源时,OpenShift 不会删除 CA secret。
集群和客户端 CA 禁用 ownerReference
的 Kafka 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka # ... spec: # ... clusterCa: generateSecretOwnerReference: false clientsCa: generateSecretOwnerReference: false # ...
15.3. 证书续订和有效期
集群 CA 和客户端 CA 证书只在有限的时间段内有效,称为有效期。这通常定义自生成证书以来的天数。
对于 Cluster Operator 自动创建的 CA 证书,您可以配置以下的有效性周期:
-
Kafka.spec.clusterCa.validityDays
中的集群 CA 证书 -
Clients CA certificates in
Kafka.spec.clientsCa.validityDays
两个证书的默认有效期为 365 天。手动安装的 CA 证书应定义自己的有效期。
当 CA 证书过期时,仍信任该证书的组件和客户端不接受来自其证书由 CA 私钥签名的对等点的连接。组件和客户端需要信任新的 CA 证书。
要允许在不丢失服务的情况下续订 CA 证书,Cluster Operator 会在旧的 CA 证书过期前启动证书续订。
您可以配置 Cluster Operator 创建的证书的续订周期:
-
Kafka.spec.clusterCa.renewalDays
中的集群 CA 证书 -
Clients CA certificates in
Kafka.spec.clientsCa.renewalDays
两个证书的默认续订周期为 30 天。
续订周期从当前证书的到期日期后测量。
根据续订周期的有效期
Not Before Not After | | |<--------------- validityDays --------------->| <--- renewalDays --->|
要在创建 Kafka 集群后更改有效期和续订周期,您可以配置并应用 Kafka
自定义资源,并 手动更新 CA 证书。如果您不手动更新证书,则在下次自动更新证书时将使用新的周期。
证书有效期和续订周期的 Kafka 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka # ... spec: # ... clusterCa: renewalDays: 30 validityDays: 365 generateCertificateAuthority: true clientsCa: renewalDays: 30 validityDays: 365 generateCertificateAuthority: true # ...
在续订期间,Cluster Operator 的行为取决于集群 CA 和客户端 CA 的 generateCertificateAuthority
证书生成属性的设置。
true
-
如果属性设为
true
,Cluster Operator 会自动生成 CA 证书,并在续订周期内自动更新。 false
-
如果属性设为
false
,Cluster Operator 不会生成 CA 证书。如果要安装自己的证书,则使用此选项。
15.3.1. 使用自动生成的 CA 证书的续订过程
Cluster Operator 在续订 CA 证书时按照以下顺序执行以下进程:
生成一个新的 CA 证书,但保留现有的密钥。
新证书将旧证书替换为对应
Secret
中的名称ca.crt
。生成新的客户端证书(用于 ZooKeeper 节点、Kafka 代理和实体 Operator)。
这并不严格是必需的,因为签名密钥没有改变,但它保留客户端证书的有效性周期与 CA 证书同步。
- 重启 ZooKeeper 节点,以便它们信任新的 CA 证书并使用新的客户端证书。
- 重启 Kafka 代理,以便它们信任新的 CA 证书并使用新的客户端证书。
重启主题和用户 Operator,以便它们信任新的 CA 证书并使用新的客户端证书。
用户证书由客户端 CA 签名。用户 Operator 生成的用户证书会在客户端 CA 续订时续订。
15.3.2. 客户端证书续订
Cluster Operator 不知道使用 Kafka 集群的客户端应用程序。
当连接到集群时,并确保它们正确运行,客户端应用程序必须:
- 信任 <cluster> - cluster-ca-cert Secret 中发布的集群 CA 证书。
使用 < user-name> Secret 中发布的凭证连接到集群。
User Secret 以 PEM 和 PKCS #12 格式提供凭证,或者在使用 SCRAM-SHA 身份验证时提供密码。User Operator 在创建用户时会创建用户凭证。
您必须确保客户端在证书续订后继续工作。续订过程取决于客户端的配置方式。
如果要手动置备客户端证书和密钥,您必须生成新的客户端证书,并确保客户端在续订周期内使用新证书。在续订周期结束时无法执行此操作可能会导致客户端应用程序无法连接到集群。
对于在同一 OpenShift 集群和命名空间中运行的工作负载,Secret 可以挂载为卷,因此客户端 Pod 可以从 Secret 的当前状态构建其密钥存储和信任存储。有关此过程的详情,请参阅配置内部客户端以信任集群 CA。
15.3.3. 手动续订 Cluster Operator 管理的 CA 证书
Cluster Operator 会自动续订其相应证书续订周期开始时,集群和客户端 CA 证书会自动续订。但是,您可以使用 strimzi.io/force-renew
注解在证书续订周期开始前手动续订其中一个或两个证书。出于安全原因,您可能执行此操作,或者更改了证书的续订或有效期。
更新的证书使用与旧证书相同的私钥。
如果您使用自己的 CA 证书,则无法使用 force-renew
注解。相反,请按照流程 续订您自己的 CA 证书。
先决条件
- 必须部署 Cluster Operator。
- 安装 CA 证书和私钥的 Kafka 集群。
- OpenSSL TLS 管理工具,用于检查 CA 证书的有效性周期。
在此过程中,我们在 my-project
命名空间中使用名为 my-cluster
的 Kafka 集群。
流程
将
strimzi.io/force-renew
注解应用到包含您要续订的 CA 证书的 secret。续订集群 CA secret
oc annotate secret my-cluster-cluster-ca-cert -n my-project strimzi.io/force-renew=true
续订客户端 CA secret
oc annotate secret my-cluster-clients-ca-cert -n my-project strimzi.io/force-renew=true
在下一个协调时,Cluster Operator 会生成新证书。
如果配置了维护时间窗,Cluster Operator 会在下一次维护时间窗内第一次协调时生成新的 CA 证书。
检查新 CA 证书的有效性周期。
检查新集群 CA 证书的有效性周期
oc get secret my-cluster-cluster-ca-cert -n my-project -o=jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -dates
检查新客户端 CA 证书的有效性周期
oc get secret my-cluster-clients-ca-cert -n my-project -o=jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -dates
该命令返回一个
notBefore
和notAfter
date,这是 CA 证书的有效开始和结束日期。更新客户端配置以信任新的集群 CA 证书。
请参阅:
15.3.4. 手动从已过期的 Cluster Operator 管理的 CA 证书中恢复
Cluster Operator 会在续订周期开始时自动更新集群和客户端 CA 证书。然而,意外的操作问题或中断可能会阻止续订过程,如 Cluster Operator 的停机时间或 Kafka 集群不可用。如果 CA 证书过期,Kafka 集群组件无法相互通信,Cluster Operator 在无需人工干预的情况下无法续订 CA 证书。
要立即执行恢复,请按照给出的顺序操作此流程中所述的步骤。您可以从过期的集群和客户端 CA 证书中恢复。此过程涉及删除包含过期证书的 secret,以便 Cluster Operator 生成新证书的 secret。有关 AMQ Streams 中管理的 secret 的更多信息,请参阅 第 15.2.2 节 “Cluster Operator 生成的 secret”。
如果您使用自己的 CA 证书并使其过期,则该过程类似,但您需要 续订 CA 证书,而不是使用 Cluster Operator 生成的证书。
先决条件
- 必须部署 Cluster Operator。
- 安装 CA 证书和私钥的 Kafka 集群。
- OpenSSL TLS 管理工具,用于检查 CA 证书的有效性周期。
在此过程中,我们在 my-project
命名空间中使用名为 my-cluster
的 Kafka 集群。
流程
删除包含过期 CA 证书的 secret。
删除 Cluster CA secret
oc delete secret my-cluster-cluster-ca-cert -n my-project
删除 Clients CA secret
oc delete secret my-cluster-clients-ca-cert -n my-project
等待 Cluster Operator 生成新证书。
-
新的 CA 集群证书以验证 Kafka 代理的身份在相同名称的 secret 中创建了(
my-cluster-cluster-ca-cert
)。 -
在相同名称的 secret 中创建了用于验证 Kafka 用户身份的新 CA 客户端证书(
my-cluster-clients-ca-cert
)。
-
新的 CA 集群证书以验证 Kafka 代理的身份在相同名称的 secret 中创建了(
检查新 CA 证书的有效性周期。
检查新集群 CA 证书的有效性周期
oc get secret my-cluster-cluster-ca-cert -n my-project -o=jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -dates
检查新客户端 CA 证书的有效性周期
oc get secret my-cluster-clients-ca-cert -n my-project -o=jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -dates
该命令返回一个
notBefore
和notAfter
date,这是 CA 证书的有效开始和结束日期。删除使用 CA 证书的组件 pod 和 secret。
- 删除 ZooKeeper secret。
- 等待 Cluster Operator 检测缺少的 ZooKeeper secret 并重新创建它。
- 删除所有 ZooKeeper pod。
- 删除 Kafka secret。
- 等待 Cluster Operator 检测缺少的 Kafka secret 并重新创建它。
- 删除所有 Kafka pod。
如果您只恢复客户端 CA 证书,则只需要删除 Kafka secret 和 pod。
您可以使用以下
oc
命令查找资源,并验证它是否已被删除。oc get <resource_type> --all-namespaces | grep <kafka_cluster_name>
将
<resource_type
> 替换为资源的类型,如Pod
或Secret
。等待 Cluster Operator 检测缺少的 Kafka 和 ZooKeeper pod,并使用更新的 CA 证书重新创建它们。
在协调时,Cluster Operator 会自动更新其他组件以信任新的 CA 证书。
- 验证 Cluster Operator 日志中没有与证书验证相关的问题。
更新客户端配置以信任新的集群 CA 证书。
请参阅:
15.3.5. 替换 Cluster Operator 管理的 CA 证书使用的私钥
您可以替换由 Cluster Operator 生成的集群 CA 和客户端 CA 证书使用的私钥。当替换私钥时,Cluster Operator 会为新私钥生成一个新的 CA 证书。
如果您使用自己的 CA 证书,则无法使用 force-replace
注解。相反,请按照流程 续订您自己的 CA 证书。
先决条件
- Cluster Operator 正在运行。
- 安装 CA 证书和私钥的 Kafka 集群。
流程
将
strimzi.io/force-replace
注解应用到包含您要更新的私钥的Secret
。表 15.13. 替换私钥的命令 的私钥 Secret 注解命令 集群 CA
cluster-name-cluster-ca
oc annotate secret CLUSTER-NAME-cluster-ca strimzi.io/force-replace=true
客户端 CA
cluster-name-clients-ca
oc annotate secret CLUSTER-NAME-clients-ca strimzi.io/force-replace=true
在下一次协调时,Cluster Operator 将:
-
为您注解的
Secret
生成新私钥 - 生成新的 CA 证书
如果配置了维护时间窗,Cluster Operator 将在下次维护时间窗口中第一次协调时生成新的私钥和 CA 证书。
客户端应用程序必须重新加载 Cluster Operator 更新的集群和客户端 CA 证书。
15.4. 配置内部客户端以信任集群 CA
此流程描述了如何配置位于 OpenShift 集群中的 Kafka 客户端 - 连接到 TLS 侦听器 - 以信任集群 CA 证书。
为内部客户端实现此操作的最简单方法是使用卷挂载来访问 包含所需
证书和密钥的 Secret。
按照以下步骤配置由基于 Java 的 Kafka Producer、Consumer 和 Streams API 的集群 CA 签名的信任证书。
根据集群 CA 的证书格式,选择遵循的步骤:PKCS #12 (.p12
) 或 PEM (.crt
)。
这些步骤描述了如何挂载 Cluster Secret,该 Secret 验证 Kafka 集群的身份到客户端 pod。
先决条件
- Cluster Operator 必须正在运行。
-
OpenShift 集群中需要有一个
Kafka
资源。 - 您需要使用 TLS 连接的 OpenShift 集群内的 Kafka 客户端应用程序,并需要信任集群 CA 证书。
-
客户端应用程序必须与
Kafka
资源在同一命名空间中运行。
使用 PKCS #12 格式 (.p12)
在定义客户端 pod 时,将集群 Secret 挂载为卷。
例如:
kind: Pod apiVersion: v1 metadata: name: client-pod spec: containers: - name: client-name image: client-name volumeMounts: - name: secret-volume mountPath: /data/p12 env: - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: my-secret key: my-password volumes: - name: secret-volume secret: secretName: my-cluster-cluster-ca-cert
在这里挂载以下内容:
- PKCS #12 会进入一个准确的路径中,这可以进行配置
- 密码到环境变量中,可用于 Java 配置
使用以下属性配置 Kafka 客户端:
安全协议选项:
-
security.protocol:使用 TLS 加密时 SSL
(使用 mTLS 身份验证)。 -
security.protocol :在通过 TLS 使用 SCRAM-SHA 身份验证时 SASL_SSL
。
-
-
ssl.truststore.location
,使用导入证书的 truststore 位置。 -
ssl.truststore.password
,使用用于访问信任存储的密码。 -
ssl.truststore.type=PKCS12
来识别信任存储类型。
使用 PEM 格式(.crt)
在定义客户端 pod 时,将集群 Secret 挂载为卷。
例如:
kind: Pod apiVersion: v1 metadata: name: client-pod spec: containers: - name: client-name image: client-name volumeMounts: - name: secret-volume mountPath: /data/crt volumes: - name: secret-volume secret: secretName: my-cluster-cluster-ca-cert
- 使用提取的证书在使用 X.509 格式的证书的客户端中配置 TLS 连接。
15.5. 配置外部客户端以信任集群 CA
此流程描述了如何配置位于 OpenShift 集群外的 Kafka 客户端 - 连接到 外部监听程序
- 以信任集群 CA 证书。当替换旧客户端 CA 证书时,请按照设置客户端和续订周期时按照以下步骤操作。
按照以下步骤配置由基于 Java 的 Kafka Producer、Consumer 和 Streams API 的集群 CA 签名的信任证书。
根据集群 CA 的证书格式,选择遵循的步骤:PKCS #12 (.p12
) 或 PEM (.crt
)。
这些步骤描述了如何从验证 Kafka 集群身份的集群 Secret 获取证书。
& lt;cluster_name> -cluster-ca-cert
secret 在 CA 证书续订期间包含多个 CA 证书。客户端必须将它们全部添加到其信任存储中。
先决条件
- Cluster Operator 必须正在运行。
-
OpenShift 集群中需要有一个
Kafka
资源。 - 您需要 OpenShift 集群外的 Kafka 客户端应用程序需要使用 TLS 连接,并需要信任集群 CA 证书。
使用 PKCS #12 格式 (.p12)
从 Kafka 集群的 <
cluster_name> -cluster-ca-cert
Secret 中提取集群 CA 证书和密钥。oc get secret <cluster_name>-cluster-ca-cert -o jsonpath='{.data.ca\.p12}' | base64 -d > ca.p12
oc get secret <cluster_name>-cluster-ca-cert -o jsonpath='{.data.ca\.password}' | base64 -d > ca.password
将 <cluster_name > 替换为 Kafka 集群的名称。
使用以下属性配置 Kafka 客户端:
安全协议选项:
-
security.protocol :在使用 TLS 时 SSL
。 -
security.protocol :在通过 TLS 使用 SCRAM-SHA 身份验证时 SASL_SSL
。
-
-
ssl.truststore.location
,使用导入证书的 truststore 位置。 -
ssl.truststore.password
,使用用于访问信任存储的密码。如果 truststore 不需要此属性,则可以省略此属性。 -
ssl.truststore.type=PKCS12
来识别信任存储类型。
使用 PEM 格式(.crt)
从 Kafka 集群的 <
cluster_name>-cluster-ca-cert
secret 中提取集群 CA 证书。oc get secret <cluster_name>-cluster-ca-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
- 使用提取的证书在使用 X.509 格式的证书的客户端中配置 TLS 连接。
15.6. 使用您自己的 CA 证书和私钥
安装和使用您自己的 CA 证书和私钥,而不使用 Cluster Operator 生成的默认值。您可以替换集群和客户端 CA 证书和私钥。
您可以使用以下方法切换到使用自己的 CA 证书和私钥:
- 在部署 Kafka 集群前安装自己的 CA 证书和私钥
- 在部署 Kafka 集群后,将默认 CA 证书和私钥替换为您自己的
在部署 Kafka 集群后替换默认 CA 证书和私钥的步骤与用来更新您自己的 CA 证书和私钥的步骤相同。
如果您使用自己的证书,则不会自动更新它们。您需要在过期前续订 CA 证书和私钥。
续订选项:
- 仅续订 CA 证书
- 续订 CA 证书和私钥(或替换默认值)
15.6.1. 安装您自己的 CA 证书和私钥
安装您自己的 CA 证书和私钥,而不使用 Cluster Operator 生成的集群和客户端 CA 证书和私钥。
默认情况下,AMQ Streams 使用以下 集群 CA 和客户端 CA secret,这些 secret 会自动续订。
集群 CA secret
-
<cluster_name>-cluster-ca
-
<cluster_name>-cluster-ca-cert
-
客户端 CA secret
-
<cluster_name>-clients-ca
-
<cluster_name>-clients-ca-cert
-
要安装自己的证书,请使用相同的名称。
先决条件
- Cluster Operator 正在运行。
Kafka 集群尚未部署。
如果您已经部署了 Kafka 集群,您可以将 默认 CA 证书替换为您自己的。
集群 CA 或客户端 CA 的 PEM 格式的您自己的 X.509 证书和密钥。
如果要使用不是 Root CA 的集群或客户端 CA,则必须在证书文件中包含整个链。链应该按以下顺序排列:
- 集群或客户端 CA
- 一个或多个中间 CA
- root CA
- 链中的所有 CA 都应该使用 X509v3 基本约束扩展进行配置。基本限制限制证书链的路径长度。
- 用于转换证书的 OpenSSL TLS 管理工具。
开始前
Cluster Operator 以 PEM (Privacy Enhanced Mail) 和 PKCS #12 (Public-Key Cryptography Standards) 格式生成密钥和证书。您可以使用任一格式添加自己的证书。
有些应用程序无法使用 PEM 证书,且只支持 PKCS #12 证书。如果您没有 PKCS #12 格式的集群证书,请使用 OpenSSL TLS 管理工具从 ca.crt
文件中生成一个。
证书生成命令示例
openssl pkcs12 -export -in ca.crt -nokeys -out ca.p12 -password pass:<P12_password> -caname ca.crt
将 <P12_password > 替换为您自己的密码。
流程
创建一个包含 CA 证书的新 secret。
仅使用 PEM 格式的证书创建客户端 secret
oc create secret generic <cluster_name>-clients-ca-cert --from-file=ca.crt=ca.crt
使用 PEM 和 PKCS #12 格式的证书创建集群 secret
oc create secret generic <cluster_name>-cluster-ca-cert \ --from-file=ca.crt=ca.crt \ --from-file=ca.p12=ca.p12 \ --from-literal=ca.password=P12-PASSWORD
将 <cluster_name > 替换为 Kafka 集群的名称。
创建一个包含私钥的新 secret。
oc create secret generic CA-KEY-SECRET --from-file=ca.key=ca.key
标记 secret。
oc label secret CA-CERTIFICATE-SECRET strimzi.io/kind=Kafka strimzi.io/cluster=<cluster_name>
oc label secret CA-KEY-SECRET strimzi.io/kind=Kafka strimzi.io/cluster=<cluster_name>
-
Label
strimzi.io/kind=Kafka
标识 Kafka 自定义资源。 -
标签
strimzi.io/cluster= <cluster_name&
gt; 标识 Kafka 集群。
-
Label
注解 secret
oc annotate secret CA-CERTIFICATE-SECRET strimzi.io/ca-cert-generation=CA-CERTIFICATE-GENERATION
oc annotate secret CA-KEY-SECRET strimzi.io/ca-key-generation=CA-KEY-GENERATION
-
注解
strimzi.io/ca-cert-generation=CA-CERTIFICATE-GENERATION
定义新 CA 证书的生成。 注解
strimzi.io/ca-key-generation=CA-KEY-GENERATION
定义新 CA 密钥的生成。从 0 (零)作为您自己的 CA 证书的增量值(
strimzi.io/ca-cert-generation=0
)开始。在续订证书时设置更高的增量值。
-
注解
为集群创建
Kafka
资源,将Kafka.spec.clusterCa
或Kafka.spec.clientsCa
对象配置为不使用生成的 CA。将集群 CA 配置为使用您自己提供的证书片段
Kafka
资源示例kind: Kafka version: kafka.strimzi.io/v1beta2 spec: # ... clusterCa: generateCertificateAuthority: false
15.6.2. 续订您自己的 CA 证书
如果您使用自己的 CA 证书,则需要手动续订它们。Cluster Operator 不会自动更新它们。在续订周期到期前续订 CA 证书。
当您续订 CA 证书并使用相同的私钥时,请执行以下步骤中的步骤。如果您要更新自己的 CA 证书和私钥,请参阅 第 15.6.3 节 “自行续订或替换 CA 证书和私钥”。
该流程描述了以 PEM 格式续订 CA 证书。
先决条件
- Cluster Operator 正在运行。
- 您有 PEM 格式的新集群或客户端 X.509 证书。
流程
更新 CA 证书的
Secret
。编辑现有 secret 以添加新 CA 证书并更新证书生成注解值。
oc edit secret <ca_certificate_secret_name>
<ca_certificate_secret_name > 是
Secret
的名称,即 <kafka_cluster_name> -cluster-ca-cert
用于集群 CA 证书,<kafka_cluster_name> -clients-ca-cert
用于客户端 CA 证书。以下示例显示了与集群 CA 证书的 secret,它与名为
my-cluster
的 Kafka 集群相关联。集群 CA 证书的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0F... 1 metadata: annotations: strimzi.io/ca-cert-generation: "0" 2 labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca-cert #... type: Opaque
将新 CA 证书编码为 base64。
cat <path_to_new_certificate> | base64
更新 CA 证书。
复制上一步中的 base64 编码的 CA 证书,作为
data
下的ca.crt
属性的值。增加 CA 证书生成注解的值。
使用更高的增量值更新
strimzi.io/ca-cert-generation
注解。例如,将strimzi.io/ca-cert-generation=0
更改为strimzi.io/ca-cert-generation=1
。如果Secret
缺少注解,则该值被视为0,
因此添加值为1
的注解。当 AMQ Streams 生成证书时,Cluster Operator 会自动递增证书生成注解。对于您自己的 CA 证书,请使用更高的增量值设置注解。该注解需要的值高于当前 secret 中的值,以便 Cluster Operator 可以滚动 pod 并更新证书。
strimzi.io/ca-cert-generation
必须针对每个 CA 证书续订递增。使用新的 CA 证书和密钥生成注解值保存 secret。
使用新 CA 证书更新的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.crt: GCa6LS3RTHeKFiFDGBOUDYFAZ0F... 1 metadata: annotations: strimzi.io/ca-cert-generation: "1" 2 labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca-cert #... type: Opaque
在下一个协调中,Cluster Operator 对 ZooKeeper、Kafka 和其他组件执行滚动更新,以信任新的 CA 证书。
如果配置了维护时间窗,Cluster Operator 将在下次维护时间窗内第一次协调 pod。
15.6.3. 自行续订或替换 CA 证书和私钥
如果您使用自己的 CA 证书和私钥,则需要手动续订它们。Cluster Operator 不会自动更新它们。在续订周期到期前续订 CA 证书。您还可以使用相同的步骤将 AMQ Streams Operator 生成的 CA 证书和私钥替换为您自己的。
在续订或替换 CA 证书和私钥时,请执行以下步骤中的步骤。如果您只更新自己的 CA 证书,请参阅 第 15.6.2 节 “续订您自己的 CA 证书”。
该流程描述了以 PEM 格式续订 CA 证书和私钥。
在执行以下步骤前,请确保新 CA 证书的 CN (Common Name)与当前 CA 证书不同。例如,当 Cluster Operator 续订证书时自动添加 v<version_number> 后缀来标识版本时。通过在每个续订中添加不同的后缀,对您自己的 CA 证书执行同样的操作。通过使用其他密钥生成新 CA 证书,您可以保留存储在 Secret
中的当前 CA 证书。
先决条件
- Cluster Operator 正在运行。
- 您有 PEM 格式的新集群或客户端 X.509 证书和密钥。
流程
暂停
Kafka
自定义资源的协调。在 OpenShift 中注解自定义资源,将
pause-reconciliation
注解设置为true
:oc annotate Kafka <name_of_custom_resource> strimzi.io/pause-reconciliation="true"
例如,对于名为
my-cluster
的Kafka
自定义资源:oc annotate Kafka my-cluster strimzi.io/pause-reconciliation="true"
检查自定义资源的状态条件是否显示
ReconciliationPaused
的更改:oc describe Kafka <name_of_custom_resource>
在
lastTransitionTime
中type
条件会变为ReconciliationPaused
。
更新 CA 证书的
Secret
。编辑现有 secret 以添加新 CA 证书并更新证书生成注解值。
oc edit secret <ca_certificate_secret_name>
<ca_certificate_secret_name > 是
Secret
的名称,即KAFKA-CLUSTER-NAME-cluster-ca-cert
用于集群 CA 证书,KAFKA-CLUSTER-NAME-clients-ca-cert
用于客户端 CA 证书。以下示例显示了与集群 CA 证书的 secret,它与名为
my-cluster
的 Kafka 集群相关联。集群 CA 证书的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0F... 1 metadata: annotations: strimzi.io/ca-cert-generation: "0" 2 labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca-cert #... type: Opaque
重命名当前的 CA 证书以保留它。
将数据
下的当前ca.crt
属性重命名为ca- <date& gt; .crt
,其中 & lt;date> 是 YEAR-MONTH-DAYTHOUR-MINUTE-SECONDZ 格式的证书过期日期。例如ca-2023-01-26T17-32-00Z.crt:
保留属性的值,因为它保留当前的 CA 证书。将新 CA 证书编码为 base64。
cat <path_to_new_certificate> | base64
更新 CA 证书。
在
data
下创建一个新的ca.crt
属性,并将上一步中的 base64 编码的 CA 证书复制为ca.crt
属性的值。增加 CA 证书生成注解的值。
使用更高的增量值更新
strimzi.io/ca-cert-generation
注解。例如,将strimzi.io/ca-cert-generation=0
更改为strimzi.io/ca-cert-generation=1
。如果Secret
缺少注解,则该值被视为0,
因此添加值为1
的注解。当 AMQ Streams 生成证书时,Cluster Operator 会自动递增证书生成注解。对于您自己的 CA 证书,请使用更高的增量值设置注解。该注解需要的值高于当前 secret 中的值,以便 Cluster Operator 可以滚动 pod 并更新证书。
strimzi.io/ca-cert-generation
必须针对每个 CA 证书续订递增。使用新的 CA 证书和密钥生成注解值保存 secret。
使用新 CA 证书更新的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.crt: GCa6LS3RTHeKFiFDGBOUDYFAZ0F... 1 ca-2023-01-26T17-32-00Z.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0F... 2 metadata: annotations: strimzi.io/ca-cert-generation: "1" 3 labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca-cert #... type: Opaque
更新用于为您的新 CA 证书签名的 CA 密钥的
Secret
。编辑现有 secret 以添加新的 CA 密钥并更新密钥生成注解值。
oc edit secret <ca_key_name>
<ca_key_name > 是 CA 密钥的名称,即 <
;kafka_cluster_name> -cluster-ca
用于集群 CA 密钥,<kafka_cluster_name> -clients-ca
用于客户端 CA 密钥。以下示例显示了与集群 CA 密钥的 secret,它与名为
my-cluster
的 Kafka 集群相关联。集群 CA 密钥的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.key: SA1cKF1GFDzOIiPOIUQBHDNFGDFS... 1 metadata: annotations: strimzi.io/ca-key-generation: "0" 2 labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca #... type: Opaque
将 CA 密钥编码为 base64。
cat <path_to_new_key> | base64
更新 CA 密钥。
复制上一步中的 base64 编码的 CA 密钥,作为
data
下的ca.key
属性的值。增加 CA 密钥生成注解的值。
使用更高的增量值更新
strimzi.io/ca-key-generation
注解。例如,将strimzi.io/ca-key-generation=0
更改为strimzi.io/ca-key-generation=1
。如果Secret
缺少注解,它将被视为0,
因此添加值为1
的注解。当 AMQ Streams 生成证书时,Cluster Operator 会自动递增密钥生成注解。对于您自己的 CA 证书以及新的 CA 密钥,请使用更高的增量值设置注解。该注解需要的值高于当前 secret 中的值,以便 Cluster Operator 可以滚动 pod 并更新证书和密钥。
strimzi.io/ca-key-generation
必须针对每个 CA 证书续订递增。
使用新的 CA 密钥和密钥生成注解值保存 secret。
使用新 CA 密钥更新的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.key: AB0cKF1GFDzOIiPOIUQWERZJQ0F... 1 metadata: annotations: strimzi.io/ca-key-generation: "1" 2 labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca #... type: Opaque
从暂停中恢复。
要恢复
Kafka
自定义资源协调,请将pause-reconciliation
注解设置为false
。oc annotate --overwrite Kafka <name_of_custom_resource> strimzi.io/pause-reconciliation="false"
您还可以删除
pause-reconciliation
注解来达到同样的操作。oc annotate Kafka <name_of_custom_resource> strimzi.io/pause-reconciliation-
在下一个协调中,Cluster Operator 对 ZooKeeper、Kafka 和其他组件执行滚动更新,以信任新的 CA 证书。滚动更新完成后,Cluster Operator 将启动一个新的服务器证书来生成由新 CA 密钥签名的新的服务器证书。
如果配置了维护时间窗,Cluster Operator 将在下次维护时间窗内第一次协调 pod。
- 等待滚动更新移至新的 CA 证书。
从 secret 配置中删除任何过时的证书,以确保集群不再信任它们。
oc edit secret <ca_certificate_secret_name>
删除旧证书的 secret 配置示例
apiVersion: v1 kind: Secret data: ca.crt: GCa6LS3RTHeKFiFDGBOUDYFAZ0F... metadata: annotations: strimzi.io/ca-cert-generation: "1" labels: strimzi.io/cluster: my-cluster strimzi.io/kind: Kafka name: my-cluster-cluster-ca-cert #... type: Opaque
启动集群的手动滚动更新,以获取对 secret 配置所做的更改。
第 16 章 将安全上下文应用到 AMQ Streams pod 和容器
安全性上下文约束定义 pod 和容器的限制。通过指定安全上下文,pod 和容器仅具有所需的权限。例如,权限可以控制运行时操作或访问资源。
16.1. 通过 OpenShift 平台处理安全上下文
处理安全上下文取决于您使用的 OpenShift 平台的工具。
例如,OpenShift 使用内置安全性上下文约束(SCC)来控制权限。SCC 是控制 Pod 能够访问的安全功能的设置和策略。
默认情况下,OpenShift 会自动注入安全上下文配置。在大多数情况下,这意味着您不需要为 Cluster Operator 创建的 pod 和容器配置安全上下文。虽然您仍然可以创建和管理自己的 SCC。
如需更多信息,请参阅 OpenShift 文档。
第 17 章 通过添加或删除代理来扩展集群
通过添加代理扩展 Kafka 集群可以提高集群的性能和可靠性。添加更多代理会增加可用资源,允许集群处理较大的工作负载并处理更多信息。它还可以通过提供更多副本和备份来提高容错。相反,删除使用率不足的代理可以降低资源消耗并提高效率。必须仔细进行缩放以避免中断或数据丢失。通过在集群中的所有代理间重新分发分区,每个代理的资源利用率会减少,这可以提高集群的整体吞吐量。
要增加 Kafka 主题的吞吐量,您可以增加该主题的分区数量。这允许加载集群中的不同代理之间共享该主题。但是,如果每个代理都受特定资源(如 I/O)的限制,添加更多分区不会增加吞吐量。在这种情况下,您需要在集群中添加更多代理。
调整 Kafka.spec.kafka.replicas
配置会影响作为副本的集群中的代理数量。主题的实际复制因素由 default.replication.factor
和 min.insync.replicas
的设置以及可用代理的数量决定。例如,复制因素 3 表示主题的每个分区在三个代理之间复制,确保在代理失败时进行容错。
副本配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: replicas: 3 # ... config: # ... default.replication.factor: 3 min.insync.replicas: 2 # ...
当通过 Kafka
配置添加代理时,节点 ID 以 0 (零)开始,Cluster Operator 会为新节点分配下一个最低 ID。代理删除过程从集群中 ID 的最高代理 pod 开始。
如果您要使用节点池功能的预览来管理集群中的节点,您可以调整 KafkaNodePool.spec.replicas
配置以更改节点池中的节点数。另外,在使用节点池扩展现有集群时,您可以为 扩展操作分配节点 ID。
当您添加或删除代理时,Kafka 不会自动重新分配分区。执行此操作的最佳方法是使用 Cruise Control。您可以在扩展集群或缩减时使用 Cruise Control 的 add-brokers
和 remove-brokers
模式。
-
在扩展 Kafka 集群后,使用
add-brokers
模式,将分区副本从现有代理移到新添加的代理中。 -
在缩减 Kafka 集群前,使用
remove-brokers
模式,将分区副本从要删除的代理移出。
第 18 章 使用 Cruise Control 重新平衡集群
Cruise Control 是一个开源系统,支持以下 Kafka 操作:
- 监控集群工作负载
- 根据预定义的约束重新平衡集群
此操作可帮助运行更有效地使用代理 pod 的 Kafka 集群。
典型的集群可能会随着时间不均匀地加载。处理大量消息流量的分区可能无法在可用的代理中平均分布。要重新平衡集群,管理员必须监控代理上的负载,并将忙碌的分区手动分配给具有备用容量的代理。
Cruise Control 自动执行集群重新平衡过程。它基于 CPU、磁盘和网络负载(您可以批准或拒绝)为集群构建资源利用率 的工作负载模型。一组可配置的优化目标用于计算这些提议。
您可以在特定模式中生成优化方案。默认 full
模式在所有代理间重新平衡分区。您还可以使用 add-brokers
和 remove-brokers
模式来适应扩展集群或缩减时的更改。
当您批准一个优化建议时,Cruise Control 会将它应用到您的 Kafka 集群。您可以使用 KafkaRebalance
资源配置和生成优化建议。您可以使用注解配置资源,以便自动或手动批准优化提议。
AMQ Streams 为 Cruise Control 提供示例配置文件。
18.1. Cruise Control 组件和功能
Cruise Control 包括四个主要组件 - Load Monitor、Anomaly Detector 和 Executor- 以及用于客户端交互的 REST API。AMQ Streams 使用 REST API 来支持以下 Cruise Control 功能:
- 从优化目标生成优化建议。
- 根据优化提议,重新平衡 Kafka 集群。
- 优化目标
优化目标描述了从重新平衡实现的特定目标。例如,目标是更加均匀地在代理间分发主题副本。您可以更改要通过配置包含哪些目标。目标定义为一个硬目标或软目标。您可以通过 Cruise Control 部署配置添加硬目标。您还有特定于这些类别的主要、默认和用户提供的目标。
- 硬 目标是预先设置的,必须满足优化建议才能成功。
- 不需要满足软 目标 才能成功进行优化建议。如果达到所有硬目标,则可以设置它们。
- 主要目标从 Cruise Control 中继承。有些是预先设置为硬目标。默认情况下,主目标用于优化提议。
- 默认目标 与主要目标相同。您可以指定您自己的一组默认目标。
- 用户提供的目标是 配置用于生成特定优化建议的默认目标子集。
- 优化提议
优化建议由您要从重新平衡实现的目标组成。您可以生成一个优化建议,以创建提议的更改概述以及重新平衡的结果。目标按照特定优先级顺序进行评估。然后您可以选择批准或拒绝提议。您可以拒绝使用调整的目标集合再次运行它。
您可以使用三种模式之一生成优化提议。
-
full
是默认模式,运行完全重新平衡。 -
add-brokers
是扩展 Kafka 集群时添加代理时使用的模式。 -
remove-brokers
是您在缩减 Kafka 集群时删除代理前使用的模式。
-
目前还不支持其他 Cruise Control 功能,包括自我修复、通知、编写目标以及更改主题复制因素。
其他资源
18.2. 优化目标概述
优化目标对 Kafka 集群的工作负载重新分配和资源利用率的限制。要重新平衡 Kafka 集群,Cruise Control 使用 优化目标来生成优化提议,您可以批准或拒绝。
18.2.1. 优先级的目标顺序
AMQ Streams 支持在 Cruise Control 项目中开发的大多数优化目标。支持的目标(以默认降序排列)如下:
- rack-awareness
- 一组主题的每个代理的最小领导副本数
- 副本容量
容量目标
- 磁盘容量
- 网络入站容量
- 网络出站容量
- CPU 容量
- 副本分发
- 潜在的网络输出
资源分配目标
- 磁盘使用率分布
- 网络入站使用分布
- 网络出站使用分布
- CPU 使用率分布
- 领导字节速率分布
- 主题副本分发
- 领导副本分发
- 首选领导选举机制
- intra-broker 磁盘容量
- intra-broker 磁盘用量分布
有关每个优化目标的更多信息,请参阅 Cruise Control Wiki 中的目标。
尚不支持"写您自己的目标"目标和 Kafka 分配目标。
18.2.2. AMQ Streams 自定义资源中的目标配置
您可以在 Kafka
和 KafkaRebalance
自定义资源中配置优化目标。Cruise Control 具有必须满足的硬优化目标的配置,以及主要、默认和用户提供的优化目标。
您可以在以下配置中指定优化目标:
-
Main goals —
Kafka.spec.cruiseControl.config.goals
-
Hard goals —
Kafka.spec.cruiseControl.config.hard.goals
-
Default goals —
Kafka.spec.cruiseControl.config.default.goals
-
用户提供的目标 IANA -
KafkaRebalance.spec.goals
资源分布目标取决于代理资源的 容量限制。
18.2.3. 硬和软优化目标
硬目标是在优化建议时 必须满足 的目标。没有作为硬目标配置的目标被成为软目标。您可以将软目标视为 最佳工作 目标: 它们不需要 在优化建议方面满足,但包含在优化计算中。违反一个或多个软目标但满足所有硬目标的优化建议有效。
Cruise Control 将计算满足所有硬目标以及尽可能多的软目标(按优先级顺序)的优化建议。无法满足所有硬目标的优化建议将由 Cruise 控制而拒绝,而不会发送给用户进行批准。
例如,您可能有一个软目标来在集群间平均分配主题的副本(主题分布目标)。如果这样做可让所有配置的硬目标满足,则 Cruise Control 将忽略这个目标。
在 Cruise Control 中,以下 主要优化目标 被预先设置为硬目标:
RackAwareGoal; MinTopicLeadersPerBrokerGoal; ReplicaCapacityGoal; DiskCapacityGoal; NetworkInboundCapacityGoal; NetworkOutboundCapacityGoal; CpuCapacityGoal
您可以通过编辑 Kafka.spec.cruiseControl.config
中的 hard.goals
属性,在 Cruise Control 部署配置中配置硬目标。
-
要从 Cruise Control 中继承预设置的硬目标,请不要在
Kafka.spec.cruiseControl.config
中指定hard.goals
属性 -
要更改预设置的硬目标,请使用其完全限定域名在
hard.goals
属性中指定所需的目标。
硬优化目标的 Kafka
配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... zookeeper: # ... entityOperator: topicOperator: {} userOperator: {} cruiseControl: brokerCapacity: inboundNetwork: 10000KB/s outboundNetwork: 10000KB/s config: # Note that `default.goals` (superset) must also include all `hard.goals` (subset) default.goals: > com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal, com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal hard.goals: > com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal, com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal # ...
增加配置的硬目标数量可减少 Cruise 控制生成有效优化建议的可能性。
如果在 KafkaRebalance
自定义资源中指定 skipHardGoalCheck: true
,Cruise Control 不会检查 用户提供的优化目标(在 KafkaRebalance.spec.goals
)是否包含 所有配置的 硬目标(hard.goals
)。因此,如果用户提供的优化目标在 hard.goals
列表中,Cruise Control 仍会将它们视为硬目标,即使指定了 skipHardGoalCheck: true
。
18.2.4. 主要优化目标
所有用户都提供了主要的优化目标。没有在主优化目标中列出的目标不适用于 Cruise Control 操作。
除非更改 Cruise Control 部署配置,AMQ Streams 将以降序从 Cruise Control 中继承以下主要优化目标:
RackAwareGoal; ReplicaCapacityGoal; DiskCapacityGoal; NetworkInboundCapacityGoal; NetworkOutboundCapacityGoal; CpuCapacityGoal; ReplicaDistributionGoal; PotentialNwOutGoal; DiskUsageDistributionGoal; NetworkInboundUsageDistributionGoal; NetworkOutboundUsageDistributionGoal; CpuUsageDistributionGoal; TopicReplicaDistributionGoal; LeaderReplicaDistributionGoal; LeaderBytesInDistributionGoal; PreferredLeaderElectionGoal
其中一些目标被预先设置为硬目标。
为降低复杂性,建议您使用继承的主要优化目标,除非您需要 完全 排除一个或多个目标在 KafkaRebalance
资源中使用。如果需要,可以在配置中为默认优化目标修改主要优化目标的优先级顺序(如果需要)。
如果需要,您可以在 Cruise Control 部署配置中配置主要优化目标: Kafka.spec.cruiseControl.config.goals
-
要接受继承的主要优化目标,请不要在
Kafka.spec.cruiseControl.config
中指定goals
属性。 -
如果您需要修改继承的主要优化目标,请在
goals
配置选项中指定目标列表(按优先级降序排列)。
为了避免生成优化建议时出现错误,请确保对 Kafka.spec.cruiseControl.config
中的 goals
或 default.goals
所做的任何更改都包含 hard.goals
属性指定的所有硬目标。要说明,还必须为主要优化目标和默认目标指定硬目标(作为子集)。
18.2.5. 默认优化目标
Cruise Control 使用默认优化目标来生成缓存的优化建议。有关缓存的优化建议的更多信息,请参阅 第 18.3 节 “优化提议概述”。
您可以通过在 KafkaRebalance
自定义资源中设置 用户提供的优化目标 来覆盖默认的优化目标。
除非在 Cruise Control 部署配置中 指定 default.goals
,否则主要优化目标将用作默认的优化目标。在这种情况下,缓存的优化建议是使用主要优化目标生成的。
-
要使用主要优化目标作为默认目标,请不要在
Kafka.spec.cruiseControl.config
中指定default.goals
属性。 -
要修改默认优化目标,请编辑
Kafka.spec.cruiseControl.config
中的default.goals
属性。您必须使用主要优化目标的子集。
默认优化目标的 Kafka
配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... zookeeper: # ... entityOperator: topicOperator: {} userOperator: {} cruiseControl: brokerCapacity: inboundNetwork: 10000KB/s outboundNetwork: 10000KB/s config: # Note that `default.goals` (superset) must also include all `hard.goals` (subset) default.goals: > com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal, com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal, com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal hard.goals: > com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal # ...
如果没有指定默认优化目标,则使用主优化目标生成缓存的提议。
18.2.6. 用户提供的优化目标
用户提供的优化目标 缩小为特定优化提议配置的默认目标。您可以根据需要在 KafkaRebalance
自定义资源中的 spec.goals
中设置它们:
KafkaRebalance.spec.goals
用户提供的优化目标可以为不同的场景生成优化提议。例如,您可能希望在 Kafka 集群间优化领导副本分布,而无需考虑磁盘容量或磁盘利用率。因此,您可以创建一个 KafkaRebalance
自定义资源,其中包含用于领导副本分发的单个用户提供的目标。
用户提供的优化目标必须:
- 包括所有配置的硬目标,或发生错误
- 是主要优化目标的子集
要在生成优化建议时忽略配置的硬目标,请在 KafkaRebalance
自定义资源中添加 skipHardGoalCheck: true
属性。请参阅 第 18.6 节 “生成优化建议”。
其他资源
- 使用 Kafka 配置和部署 Cruise 控制
- Cruise Control Wiki 中的配置。
18.3. 优化提议概述
配置 KafkaRebalance
资源来生成优化建议并应用推荐的更改。optimization proposal 是要生成一个更加均衡的 Kafka 集群、在代理中平均分配分区工作负载的建议概述。
每个优化建议都基于一组用于生成它的 优化目标,受代理资源 配置的任何容量限制。
所有优化的提议都是对提议重新平衡的影响的估算。您可以批准或拒绝提议。您无法在不先生成优化建议的情况下批准集群重新平衡。
您可以在以下重新平衡模式下运行优化建议:
-
full
-
add-brokers
-
remove-brokers
18.3.1. 重新平衡模式
您可以使用 KafkaRebalance
自定义资源的 spec.mode
属性指定重新平衡模式。
full
-
full
模式通过在集群中的所有代理间移动副本来运行完全重新平衡。如果在KafkaRebalance
自定义资源中没有定义spec.mode
属性,则这是默认模式。 add-brokers
-
add-brokers
模式在扩展 Kafka 集群后通过添加一个或多个代理来使用。通常,在扩展 Kafka 集群后,新的代理仅用于托管新创建的主题的分区。如果没有创建新主题,则不会使用新添加的代理,现有代理仍保留在同一负载中。通过在向集群添加代理后立即使用add-brokers
模式,重新平衡操作会将副本从现有代理移到新添加的代理中。您可以使用KafkaRebalance
自定义资源的spec.brokers
属性将新代理指定为列表。 remove-brokers
-
在通过删除一个或多个代理来缩减 Kafka 集群前使用
remove-brokers
模式。如果缩减 Kafka 集群,代理也会关闭,即使它们托管副本。这可能导致复制分区不足,并可能导致某些分区处于最小 ISR 下(同步副本)。为了避免这个问题,delete-brokers
模式会将副本从要删除的代理移出。当这些代理不再托管副本时,可以安全地运行缩减操作。您可以在KafkaRebalance
自定义资源的spec.brokers
属性中将您要删除的代理指定为列表。
通常,通过将负载分散到代理中,使用完整
重新平衡模式重新平衡 Kafka 集群。只有在您要扩展集群或缩减时,才使用 add-brokers
和 remove-brokers
模式,并相应地重新平衡副本。
在三种不同的模式下,运行重新平衡的过程实际上相同。唯一的区别是通过 spec.mode
属性指定模式,如果需要,列出已添加或将通过 spec.brokers
属性删除的代理。
18.3.2. 优化提议的结果
生成优化建议时,会返回概述和代理负载。
- 概述
-
Summary 包含在
KafkaRebalance
资源中。概述概述了建议的集群重新平衡,并指示涉及的更改规模。KafkaRebalance
资源的Status.OptimizationResult
属性中包含成功生成的优化建议概述。提供的信息是完整优化提议的总结。 - 代理加载
- 代理负载存储在 ConfigMap 中,其中包含为 JSON 字符串的数据。代理负载显示在提议重新平衡的之前和之后,以便您可以看到对集群中的每个代理的影响。
18.3.3. 手动批准或拒绝优化建议
优化建议概述显示了推荐的更改范围。
您可以使用 KafkaRebalance
资源的名称从命令行返回摘要。
返回优化建议概述
oc describe kafkarebalance <kafka_rebalance_resource_name> -n <namespace>
您还可以使用 jq
命令行 JSON 解析器工具。
使用 jq 返回优化建议概述
oc get kafkarebalance -o json | jq <jq_query>
.
使用摘要来决定是否批准或拒绝优化提议。
- 批准优化建议
-
您可以通过将
KafkaRebalance
资源的strimzi.io/rebalance
注解设置为批准来批准
优化建议。Cruise Control 将提议应用到 Kafka 集群,并启动集群重新平衡操作。 - 拒绝优化建议
-
如果您选择不批准优化方案,您可以更改优化目标或更新任何重新平衡性能调优选项,然后生成另一个提议。您可以通过将
strimzi.io/rebalance
注解设置为refresh
来为KafkaRebalance
资源生成新的优化建议。
使用优化建议来评估重新平衡所需的移动。例如,概述描述了 inter-broker 和 intra-broker 移动。在独立代理间重新平衡数据。当您使用 JBOD 存储配置时,在同一代理的磁盘间移动数据重新平衡。即使您没有提前并批准提议,此类信息也很有用。
因为在重新平衡时在 Kafka 集群中出现额外的负载,您可能会拒绝优化过程或延迟其批准。
在以下示例中,建议在单独的代理间重新平衡数据。重新平衡涉及在代理间移动 55 分区副本(数据总量为 12MB)。虽然分区副本间的移动对性能有高影响,但数据总数不大。如果总数据更大,您可以拒绝提议,或者在批准重新平衡时限制对 Kafka 集群性能的影响。
重新平衡性能调优选项有助于降低数据移动的影响。如果可扩展重新平衡周期,您可以将重新平衡分成较小的批处理。一次的数据移动较少可减少集群的负载。
优化提议概述示例
Name: my-rebalance Namespace: myproject Labels: strimzi.io/cluster=my-cluster Annotations: API Version: kafka.strimzi.io/v1alpha1 Kind: KafkaRebalance Metadata: # ... Status: Conditions: Last Transition Time: 2022-04-05T14:36:11.900Z Status: ProposalReady Type: State Observed Generation: 1 Optimization Result: Data To Move MB: 0 Excluded Brokers For Leadership: Excluded Brokers For Replica Move: Excluded Topics: Intra Broker Data To Move MB: 12 Monitored Partitions Percentage: 100 Num Intra Broker Replica Movements: 0 Num Leader Movements: 24 Num Replica Movements: 55 On Demand Balancedness Score After: 82.91290759174306 On Demand Balancedness Score Before: 78.01176356230222 Recent Windows: 5 Session Id: a4f833bd-2055-4213-bfdd-ad21f95bf184
该提议还将 24 个分区领导移到不同的代理。这需要对 ZooKeeper 配置的更改,这会影响性能。
平衡分数是批准优化提议前和之后 Kafka 集群的整体平衡度量。平衡分数基于优化目标。如果满足所有目标,则分数为 100。当一个目标不满足时,分数会降低。比较均衡分数,以查看 Kafka 集群是否比重新平衡要小。
18.3.4. 自动批准优化建议
要节省时间,您可以自动执行批准优化方案的过程。通过自动化,当您生成优化建议时,它会进入集群重新平衡。
要启用优化提议 auto-approval 机制,请创建 KafkaRebalance
资源,并将 strimzi.io/rebalance-auto-approval
注解设置为 true
。如果未设置注解或设置为 false
,则优化提议需要手动批准。
启用 auto-approval 机制的重新平衡请求示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster annotations: strimzi.io/rebalance-auto-approval: "true" spec: mode: # any mode # ...
在自动批准优化提议时,您仍然可以检查状态。在重新平衡完成后,KafkaRebalance
资源的状态将变为 Ready
。
18.3.5. 优化建议概述属性
下表解释了优化提议概述部分中包含的属性。
JSON 属性 | Description |
---|---|
| 在集群代理磁盘之间传输的分区副本数量。
重新平衡操作期间的性能影响 :高,但低于 |
| 尚不受支持。返回空列表。 |
| 在独立代理之间移动的分区副本数量。 重新平衡操作期间的性能影响 :非常高。 |
| 在生成优化提议前和之后,测量 Kafka 集群的整体 平衡性。
分数通过将每个违反的软目标从 100 中减去
|
|
在同一代理的磁盘间移动的每个分区副本的大小总和(请参阅
重新平衡操作期间的性能影响 :变量.集群重新平衡所需的时间越大,完成集群重新平衡所需的时间。在同一代理的磁盘之间移动大量数据比不同的代理之间的影响要小(请参阅 |
| 优化提议的指标窗口数量。 |
|
移到独立代理的每个分区副本的大小总和(请参阅 重新平衡操作期间的性能影响 :变量.集群重新平衡所需的时间越大,完成集群重新平衡所需的时间。 |
|
优化提议涵盖的 Kafka 集群中的分区百分比。受 |
|
如果您在 |
| 领导程序切换到不同副本的分区数量。这包括对 ZooKeeper 配置的更改。 重新平衡操作期间的性能影响 :非常低。 |
| 尚不受支持。返回空列表。 |
18.3.6. 代理加载属性
代理负载存储在 ConfigMap 中(与 KafkaRebalance 自定义资源的名称相同),与 JSON 格式的字符串相同。此 JSON 字符串由一个 JSON 对象组成,每个代理 ID 的键链接到每个代理的多个指标。每个指标由三个值组成:第一个是应用优化提议前的指标值,第二个是应用提议后指标的预期值,第三个是前两个值之间的差别(在前减前)。
当 KafkaRebalance 资源处于 ProposalReady
状态时,ConfigMap 会出现,并在重新平衡完成后保留。
您可以使用 ConfigMap 的名称从命令行查看其数据。
返回 ConfigMap 数据
oc describe configmaps <my_rebalance_configmap_name> -n <namespace>
您还可以使用 jq
命令行 JSON 解析器工具从 ConfigMap 中提取 JSON 字符串。
使用 jq 从 ConfigMap 提取 JSON 字符串
oc get configmaps <my_rebalance_configmap_name> -o json | jq '.["data"]["brokerLoad.json"]|fromjson|.'
下表解释了优化提议的代理加载 ConfigMap 中包含的属性:
JSON 属性 | Description |
---|---|
| 此代理中分区领导的副本数。 |
| 此代理的副本数。 |
| CPU 使用率作为定义的容量的百分比。 |
| 磁盘利用率作为定义的容量的百分比。 |
| 以 MB 为单位的绝对磁盘用量。 |
| 代理的网络输出率总数。 |
| 此代理上所有分区领导副本的网络输入率。 |
| 此代理上所有后续副本的网络输入率。 |
| 如果此代理成为当前主机的所有副本的领导,则预测最大网络输出率将获得。 |
18.3.7. 缓存优化建议
Cruise Control 根据配置的默认优化目标维护缓存的优化建议。从工作负载模型生成,缓存的优化方案每 15 分钟更新一次,以反映 Kafka 集群的当前状态。如果您使用默认优化目标生成优化建议,Cruise Control 会返回最新的缓存提议。
要更改缓存的优化建议刷新间隔,请编辑 Cruise Control 部署配置中的 proposal.expiration.ms
设置。对于快速更改的集群,考虑一个较短的间隔,但这会增加 Cruise Control 服务器的负载。
18.4. 重新平衡性能调优概述
您可以为集群重新平衡调整几个性能调优选项。这些选项控制如何执行重新平衡中的分区副本和领导移动,以及分配给重新平衡操作的带宽。
18.4.1. 分区重新分配命令
优化建议 由单独的分区重新分配命令组成。当您 批准 一个提议时,Cruise Control 服务器会将这些命令应用到 Kafka 集群。
分区重新分配命令由以下一种操作组成:
分区移动:将分区副本及其数据传输到新位置。分区移动可以采用两种形式之一:
- Inter-broker move: 分区副本被移到不同代理上的日志目录中。
- intra-broker move: 分区副本被移到同一代理的不同日志目录中。
- 领导移动:这涉及切换分区副本的领导。
Cruise Control issues 分区重新分配命令到批处理中的 Kafka 集群。在重新平衡过程中集群的性能会受到每个批处理中包含的每种移动数量的影响。
18.4.2. 副本移动策略
集群重新平衡性能也会受到 副本移动策略的影响,该策略应用到分区重新分配命令的批处理。默认情况下,Cruise Control 使用 BaseReplicaMovementStrategy
,它只是按照生成的顺序应用命令。但是,如果提议的早期有一些非常大的分区重新分配,则此策略可能会减慢其他重新分配的应用程序。
Cruise Control 提供四个替代的副本移动策略,可用于优化提议:
-
priorityitizeSmallReplicaMovementStrategy
: Order reassignments 按顺序排列。 -
prioritizeitizeLargeReplicaMovementStrategy
: Order reassignments 顺序降序。 -
PostponeUrpReplicaMovementStrategy
: 优先考虑为没有处于不同步状态的分区的服务的重新分配。 -
prioritizeitizeMinIsrWithOfflineReplicasStrategy
: 优先考虑重新分配(At/Under) MinISR 分区,并带有离线副本。只有在Kafka
自定义资源的 spec 中将cruiseControl.config.concurrency.adjuster.min.isr.check.enabled
设置为true
时,此策略才会正常工作。
这些策略可以配置为序列。第一个策略尝试使用其内部逻辑比较两个分区重新分配。如果重新分配等同于,那么它将按顺序传递给下一个策略,以确定顺序等。
18.4.3. intra-broker 磁盘平衡
在同一代理的磁盘间移动大量数据比单独的代理的影响要小得多。如果您运行一个 Kafka 部署,它将 JBOD 存储与同一代理中的多个磁盘搭配使用,Cruise Control 可以在磁盘之间平衡分区。
如果您将 JBOD 存储与单一磁盘配合使用,在代理磁盘平衡中,则会导致一个有 0 分区移动的成成,因为没有磁盘之间的平衡。
要执行内部磁盘平衡,请在 KafkaRebalance.spec
下将 rebalanceDisk
设置为 true
。当将 rebalanceDisk
设置为 true
时,不要在 KafkaRebalance.spec
中设置 goals
字段,因为 Cruise Control 会自动设置 intra-broker 目标并忽略 inter-broker 目标。Cruise Control 不会同时执行 inter-broker 和 intra-broker 平衡。
18.4.4. 重新平衡调整选项
Cruise Control 提供了几个配置选项,用于调整上述讨论的重新平衡参数。您可以在 使用 Kafka 配置和部署 Cruise Control 或 优化建议 级别时设置这些调整选项:
-
Cruise Control 服务器设置可以在 Kafka.
spec.cruiseControl.config 下的 Kafka
自定义资源中设置。 -
单个重新平衡性能配置可以在
KafkaRebalance.spec
下设置。
下表中总结了相关的配置。
Cruise Control 属性 | KafkaRebalance 属性 | 默认 | 描述 |
---|---|---|---|
|
| 5 | 每个分区重新分配批处理中的最大代理分区移动数 |
|
| 2 | 每个分区重新分配批处理中的最大 intra-broker 分区移动数 |
|
| 1000 | 每个分区重新分配批处理中的最大分区领导更改数 |
|
| null (无限制) | 分配给分区重新分配的带宽(以字节为单位) |
|
|
|
用于决定为生成的提议执行分区重新分配命令的顺序(优先级顺序)的列表。对于 server 设置,使用逗号分隔的字符串以及策略类的完全限定域名(将 |
- |
| false | 启用内部磁盘平衡,在同一代理的磁盘之间平衡磁盘空间利用率。只适用于使用多个磁盘的 JBOD 存储的 Kafka 部署。 |
更改默认设置会影响重新平衡完成所需的时间,以及重新平衡期间 Kafka 集群上的负载。使用较低值可减少负载,但会增加花费的时间,反之亦然。
18.5. 使用 Kafka 配置和部署 Cruise 控制
配置 Kafka
资源,以使用 Kafka 集群部署 Cruise Control。您可以使用 Kafka
资源的 cruiseControl
属性来配置部署。为每个 Kafka 集群部署一个 Cruise Control 实例。
在 Cruise Control config
中使用 goals
配置来指定优化目标,以生成优化建议。您可以使用 brokerCapacity
更改与资源分发相关的目标的默认容量限制。如果代理在带有异构网络资源的节点上运行,您可以使用 覆盖
为每个代理设置网络容量限制。
如果将空对象({}
)用于 cruiseControl
配置,则所有属性都使用它们的默认值。
有关 Cruise Control 配置选项的更多信息,请参阅 AMQ Streams 自定义资源 API 参考。
先决条件
- 一个 OpenShift 集群
- 正在运行的 Cluster Operator
流程
编辑
Kafka
资源的cruiseControl
属性。您可以配置的属性显示在本示例配置中:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: # ... cruiseControl: brokerCapacity: 1 inboundNetwork: 10000KB/s outboundNetwork: 10000KB/s overrides: 2 - brokers: [0] inboundNetwork: 20000KiB/s outboundNetwork: 20000KiB/s - brokers: [1, 2] inboundNetwork: 30000KiB/s outboundNetwork: 30000KiB/s # ... config: 3 # Note that `default.goals` (superset) must also include all `hard.goals` (subset) default.goals: > 4 com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal, com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal, com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal # ... hard.goals: > com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal # ... cpu.balance.threshold: 1.1 metadata.max.age.ms: 300000 send.buffer.bytes: 131072 webserver.http.cors.enabled: true 5 webserver.http.cors.origin: "*" webserver.http.cors.exposeheaders: "User-Task-ID,Content-Type" # ... resources: 6 requests: cpu: 1 memory: 512Mi limits: cpu: 2 memory: 2Gi logging: 7 type: inline loggers: rootLogger.level: INFO template: 8 pod: metadata: labels: label1: value1 securityContext: runAsUser: 1000001 fsGroup: 0 terminationGracePeriodSeconds: 120 readinessProbe: 9 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: initialDelaySeconds: 15 timeoutSeconds: 5 metricsConfig: 10 type: jmxPrometheusExporter valueFrom: configMapKeyRef: name: cruise-control-metrics key: metrics-config.yml # ...
- 1
- 代理资源的容量限制。
- 2
- 当使用异构网络资源的节点运行时,覆盖为特定代理设置网络容量限制。
- 3
- Cruise Control 配置。可以提供标准的 Cruise Control 配置,仅限于不直接由 AMQ Streams 管理的这些属性。
- 4
- 优化目标配置,其中包括用于默认优化目标(
default.goals
)、主要优化目标(目标)和硬目标
(硬.
goals)的配置。 - 5
- 为对 Cruise Control API 的只读访问启用并配置 CORS。
- 6
- 用于保留支持的资源、当前
cpu
和内存
以及限制的请求,以指定可消耗的最大资源。 - 7
- 通过 ConfigMap 直接添加 Cruise Control logger 和 loglevel (
内联
)或间接(外部
)。自定义 Log4j 配置必须放在 ConfigMap 中的log4j.properties
键下。Cruise Control 有一个名为rootLogger.level
的单个日志记录器。您可以将日志级别设置为 INFO, ERROR, WARN, TRACE, DEBUG, FATAL 或 OFF。 - 8
- 模板自定义。这里的 pod 使用额外的安全属性调度。
- 9
- 健康检查以了解何时重启容器(持续)以及容器可以接受流量(就绪状态)。
- 10
- 启用 Prometheus 指标。在本例中,为 Prometheus JMX Exporter (默认指标导出器)配置了指标。
创建或更新资源:
oc apply -f <kafka_configuration_file>
检查部署的状态:
oc get deployments -n <my_cluster_operator_namespace>
输出显示部署名称和就绪度
NAME READY UP-TO-DATE AVAILABLE my-cluster-cruise-control 1/1 1 1
my-cluster
是 Kafka 集群的名称。READY
显示就绪/预期的副本数。当AVAILABLE
输出显示为1
时,部署成功。
自动创建的主题
下表显示了部署 Cruise Control 时自动创建的三个主题。Cruise Control 正常工作且不得删除或更改这些主题。您可以使用指定的配置选项更改主题的名称。
自动创建的主题配置 | 默认主题名称 | 创建方 | 功能 |
---|---|---|---|
|
| AMQ Streams Metrics Reporter | 将 Metrics Reporter 中的原始指标存储在每个 Kafka 代理中。 |
|
| Sything Control | 存储每个分区派生的指标。它们由指标示例聚合器创建。 |
|
| Sything Control | 存储用于创建 Cluster Workload Model 的指标示例。 |
要防止删除 Cruise Control 所需的记录,在自动创建的主题中禁用日志压缩。
如果在启用了 Cruise Control 的 Kafka 集群中更改自动创建主题的名称,旧的主题不会被删除,应手动删除旧的主题。
接下来要做什么
配置和部署 Cruise Control 后,您可以生成优化提议。
其他资源
18.6. 生成优化建议
当您创建或更新 KafkaRebalance
资源时,Cruise Control 会根据配置的 优化目标 为 Kafka 集群生成优化建议。分析优化建议中的信息,并决定是否批准它。您可以使用优化提议的结果来重新平衡 Kafka 集群。
您可以在以下模式之一运行优化提议:
-
full
(默认) -
add-brokers
-
remove-brokers
您使用的模式取决于您是否在 Kafka 集群中已在运行的所有代理重新平衡 ; 或者要在扩展后或缩减 Kafka 集群前重新平衡。如需更多信息,请参阅使用代理扩展重新平衡模式。
先决条件
- 您已将 Cruise Control 部署到 AMQ Streams 集群。
- 您已配置了优化目标,并选择性地对代理资源的容量限制。
有关配置 Cruise Control 的详情,请参考 第 18.5 节 “使用 Kafka 配置和部署 Cruise 控制”。
流程
创建
KafkaRebalance
资源并指定适当的模式。完整
模式(默认)要使用
Kafka
资源中定义的 默认优化目标,请将spec
属性留空。默认情况下,Cruise Control 以完整
模式重新平衡 Kafka 集群。默认具有完全重新平衡的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster spec: {}
您还可以通过
spec.mode
属性指定完整
模式来运行完整的重新平衡。指定
完整
模式的配置示例apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster spec: mode: full
add-brokers
模式如果要在扩展后重新平衡 Kafka 集群,请指定
add-brokers
模式。在这个模式中,现有副本被移到新添加的代理中。您需要将代理指定为列表。
指定
add-brokers
模式的配置示例apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster spec: mode: add-brokers brokers: [3, 4] 1
- 1
- 扩展操作添加新添加的代理列表。此属性是必需的。
remove-brokers
模式如果要在缩减前重新平衡 Kafka 集群,请指定
remove-brokers
模式。在这个模式中,副本将从要删除的代理移出。您需要指定作为列表删除的代理。
指定
remove-brokers
模式的配置示例apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster spec: mode: remove-brokers brokers: [3, 4] 1
- 1
- 缩减操作要删除的代理列表。此属性是必需的。
注意无论您使用的重新平衡模式是什么,以下步骤以及批准或停止重新平衡的步骤相同。
要配置 用户提供的优化目标 而不使用默认目标,请添加
goals
属性并输入一个或多个目标。在以下示例中,机架感知和副本容量配置为用户提供的优化目标:
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster spec: goals: - RackAwareGoal - ReplicaCapacityGoal
要忽略配置的硬目标,请添加
skipHardGoalCheck: true
属性:apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster spec: goals: - RackAwareGoal - ReplicaCapacityGoal skipHardGoalCheck: true
(可选)要自动批准优化提议,请将
strimzi.io/rebalance-auto-approval
注解设置为true
:apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaRebalance metadata: name: my-rebalance labels: strimzi.io/cluster: my-cluster annotations: strimzi.io/rebalance-auto-approval: "true" spec: goals: - RackAwareGoal - ReplicaCapacityGoal skipHardGoalCheck: true
创建或更新资源:
oc apply -f <kafka_rebalance_configuration_file>
Cluster Operator 从 Cruise Control 请求优化提议。这可能需要几分钟时间,具体取决于 Kafka 集群的大小。
如果您使用自动批准机制,请等待优化提议的状态更改为
Ready
。如果您没有启用自动批准机制,请等待优化提议的状态更改为ProposalReady
:oc get kafkarebalance -o wide -w -n <namespace>
PendingProposal
-
PendingProposal
状态意味着重新平衡 Operator 正在轮询 Cruise Control API 来检查优化提议是否就绪。 ProposalReady
-
ProposalReady
状态表示优化提议已准备好审核和批准。
当状态变为
ProposalReady
时,优化提议可以批准。查看优化提议。
优化建议包含在
KafkaRebalance
资源的Status.Optimization Result
属性中。oc describe kafkarebalance <kafka_rebalance_resource_name>
优化提议示例
Status: Conditions: Last Transition Time: 2020-05-19T13:50:12.533Z Status: ProposalReady Type: State Observed Generation: 1 Optimization Result: Data To Move MB: 0 Excluded Brokers For Leadership: Excluded Brokers For Replica Move: Excluded Topics: Intra Broker Data To Move MB: 0 Monitored Partitions Percentage: 100 Num Intra Broker Replica Movements: 0 Num Leader Movements: 0 Num Replica Movements: 26 On Demand Balancedness Score After: 81.8666802863978 On Demand Balancedness Score Before: 78.01176356230222 Recent Windows: 1 Session Id: 05539377-ca7b-45ef-b359-e13564f1458c
Optimization Result
部分中的属性描述了待处理的集群重新平衡操作。有关每个属性的描述,请参阅优化提议的内容。
CPU 容量不足
如果 Kafka 集群被 CPU 使用率过载,您可能会在 KafkaRebalance
状态中看到 CPU 容量错误不足。值得注意的是,这个使用值不受 excludedTopics
配置的影响。虽然优化建议不会重新分配排除主题的副本,但它们的负载仍然考虑在利用率计算中。
CPU 使用率错误示例
com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException: [CpuCapacityGoal] Insufficient capacity for cpu (Utilization 615.21, Allowed Capacity 420.00, Threshold: 0.70). Add at least 3 brokers with the same cpu capacity (100.00) as broker-0. Add at least 3 brokers with the same cpu capacity (100.00) as broker-0.
错误以百分比而不是 CPU 内核数的形式显示 CPU 容量。因此,它不会直接映射到 Kafka 自定义资源中配置的 CPU 数量。它像每个代理都有一个 虚拟 CPU,它在 Kafka.spec.kafka.resources.limits.cpu
中配置 CPU 的周期。这不会影响重新平衡行为,因为 CPU 使用率和容量之间的比率保持不变。
接下来要做什么
其他资源
18.7. 批准优化建议
如果其状态是 ProposalReady
,则可以批准 Cruise Control 生成的 优化提议。然后,Cruise Control 会将优化建议应用到 Kafka 集群,将分区重新分配给代理并更改分区领导。
这不是一个空运行。在批准优化前,您必须:
- 刷新提议(如果其过期)。
- 仔细检查 提议的内容。
先决条件
- 您已从 Cruise 控制中生成了优化的提议。
-
KafkaRebalance
自定义资源状态为ProposalReady
。
流程
对您要批准的优化提议执行这些步骤。
除非新生成了优化建议,否则请检查它是否基于有关 Kafka 集群状态的当前信息。要做到这一点,刷新优化建议以确保它使用最新的集群指标:
使用
strimzi.io/rebalance=refresh
注解 OpenShift 中的KafkaRebalance
资源:oc annotate kafkarebalance <kafka_rebalance_resource_name> strimzi.io/rebalance=refresh
等待优化提议的状态更改为
ProposalReady
:oc get kafkarebalance -o wide -w -n <namespace>
PendingProposal
-
PendingProposal
状态意味着重新平衡 Operator 正在轮询 Cruise Control API 来检查优化提议是否就绪。 ProposalReady
-
ProposalReady
状态表示优化提议已准备好审核和批准。
当状态变为
ProposalReady
时,优化提议可以批准。批准您希望 Cruise Control 适用的优化方案。
使用
strimzi.io/rebalance=approve
注解 OpenShift 中的KafkaRebalance
资源:oc annotate kafkarebalance <kafka_rebalance_resource_name> strimzi.io/rebalance=approve
- Cluster Operator 会检测注解的资源,并指示 Cruise Control 来重新平衡 Kafka 集群。
等待优化提议的状态更改为
Ready
:oc get kafkarebalance -o wide -w -n <namespace>
重新平衡
-
Rebalancing
状态代表重新平衡正在进行。 Ready
-
Ready
状态表示重新平衡已完成。 NotReady
-
NotReady
状态意味着会出现错误,请参阅 修复KafkaRebalance
资源的问题。
当状态变为
Ready
时,重新平衡已完成。要使用同一
KafkaRebalance
自定义资源生成另一个优化建议,请将refresh
注解应用到自定义资源。这会将自定义资源移到PendingProposal
或ProposalReady
状态。然后,您可以检查优化提议并批准它(如果需要)。
18.8. 停止集群重新平衡
启动后,集群重新平衡操作可能需要一些时间才能完成并影响 Kafka 集群的整体性能。
如果要停止正在进行的集群重新平衡操作,请将 stop
注解应用到 KafkaRebalance
自定义资源。这指示 Cruise Control 完成当前的分区重新分配批处理,然后停止重新平衡。当重新平衡停止后,已完成的分区重新分配已被应用;因此,在重新平衡操作开始前 Kafka 集群的状态会有所不同。如果需要进一步重新平衡,您应该生成新的优化建议。
在 intermediate(停止)状态中的 Kafka 集群的性能可能比初始状态更糟。
先决条件
-
您已通过使用
approve
注解了KafkaRebalance
自定义资源来批准优化的提议。 -
KafkaRebalance
自定义资源的状态是Rebalancing
。
流程
在 OpenShift 中注解
KafkaRebalance
资源:oc annotate kafkarebalance rebalance-cr-name strimzi.io/rebalance=stop
检查
KafkaRebalance
资源的状态:oc describe kafkarebalance rebalance-cr-name
-
等待状态变为
Stopped
。
其他资源
18.9. 修复 KafkaRebalance
资源的问题
如果在创建 KafkaRebalance
资源或与 Cruise Control 交互时出现问题,则会在资源状态中报告错误,以及如何修复它的详情。资源也会进入 NotReady
状态。
要继续进行集群重新平衡操作,您必须修复 KafkaRebalance
资源本身或整个 Cruise Control 部署中的问题。问题可能包括以下内容:
-
KafkaRebalance
资源中的错误参数。 -
在
KafkaRebalance
资源中指定 Kafka 集群的strimzi.io/cluster
标签缺失。 -
Cruise Control 服务器没有部署为
Kafka
资源中的cruiseControl
属性。 - 无法访问 Cruise Control 服务器。
修复这个问题后,您需要在 KafkaRebalance
资源中添加刷新
注解。在 "refresh" 期间,通过 Cruise Control 服务器请求一个新的优化提议。
先决条件
- 您已 批准了优化建议。
-
重新平衡操作的
KafkaRebalance
自定义资源的状态为NotReady
。
流程
从
KafkaRebalance
状态获取有关错误的信息:oc describe kafkarebalance rebalance-cr-name
-
尝试解决
KafkaRebalance
资源中的问题。 在 OpenShift 中注解
KafkaRebalance
资源:oc annotate kafkarebalance rebalance-cr-name strimzi.io/rebalance=refresh
检查
KafkaRebalance
资源的状态:oc describe kafkarebalance rebalance-cr-name
-
等待状态变为
PendingProposal
,或直接更改为ProposalReady
。
其他资源
第 19 章 使用分区重新分配工具
在扩展 Kafka 集群时,您可能需要添加或删除代理并更新分区分布或主题复制因素。要更新分区和主题,您可以使用 kafka-reassign-partitions.sh
工具。
AMQ Streams Cruise Control 集成或主题 Operator 支持更改主题的复制因素。但是,您可以使用 kafka-reassign-partitions.sh
工具更改主题的复制因素。
该工具也可用于重新分配分区并在代理间平衡分区分布,以提高性能。但是,建议使用 Cruise Control 自动分区重新分配和集群重新平衡。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。
建议将 kafka-reassign-partitions.sh
工具作为单独的交互式 pod 运行,而不是在代理容器中运行。在代理容器中运行 Kafka bin/
脚本可能会导致 JVM 从与 Kafka 代理相同的设置开始,这可能会导致中断。在单独的 pod 中运行 kafka-reassign-partitions.sh
工具,您可以避免出现这个问题。使用 -ti
选项运行 pod,创建一个交互式 pod,并在 pod 中运行 shell 命令。
使用终端运行交互式 pod
oc run helper-pod -ti --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 --rm=true --restart=Never -- bash
19.1. 分区重新分配工具概述
分区重新分配工具提供以下功能来管理 Kafka 分区和代理:
- 重新分发分区副本
- 通过添加或删除代理来扩展集群,并将 Kafka 分区从大量加载的代理移到使用不足的代理。要做到这一点,您必须创建一个分区重新分配计划,以标识要移动的主题和分区以及移动它们的位置。对于这种类型的操作,建议使用 Cruise Control,因为它 自动执行集群重新平衡过程。
- 扩展主题复制因素和缩减
- 增加或减少 Kafka 主题的复制因素。要做到这一点,您必须创建一个分区重新分配计划,以标识分区之间的现有复制分配,以及使用复制因素更改的更新分配。
- 更改首选领导
- 更改 Kafka 分区的首选领导。如果当前首选领导不可用或者您要在集群中在代理间重新分发负载,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,该计划通过更改副本顺序来指定每个分区的新首选领导。
- 将日志目录更改为使用特定的 JBOD 卷
- 将 Kafka 代理的日志目录更改为使用特定的 JBOD 卷。如果要将 Kafka 数据移动到不同的磁盘或存储设备中,这非常有用。要做到这一点,您必须创建一个分区重新分配计划,用于指定每个主题的新日志目录。
19.1.1. 生成分区重新分配计划
分区重新分配工具(kafka-reassign-partitions.sh
)的工作原理,方法是生成一个分区分配计划,指定哪些分区应从其当前代理移到新代理中。
如果您对计划满意,您可以执行它。然后该工具执行以下操作:
- 将分区数据迁移到新代理
- 更新 Kafka 代理的元数据以反映新分区分配
- 触发 Kafka 代理滚动重启,以确保新分配生效
分区重新分配工具有三种不同的模式:
--generate
- 采用一组主题和代理并生成 重新分配 JSON 文件,该文件将导致将这些主题的分区分配给这些代理。由于这在整个主题上运行,因此当您只想重新分配某些主题分区时无法使用它。
--execute
- 采用 重新分配 JSON 文件,并将其应用到集群中的分区和代理。由于因为分区领导者成为分区领导者而获得分区的代理。对于给定分区,新代理发现并加入 ISR (同步副本)后,旧代理将停止后续代理,并删除其副本。
--verify
-
使用与
--execute
步骤相同的 重新分配 JSON 文件,--verify
会检查文件中所有分区是否已移至其预期的代理中。如果重新分配完成,--verify
也会删除所有生效的流量节流(-throttle
)。除非被删除,即使重新分配完成,节流将继续对集群的影响。
在任意给定时间,集群中只能有一个重新分配,且无法取消正在运行的重新分配。如果需要取消重新分配,请等待它完成,然后执行另一个重新分配来恢复第一个重新分配的影响。kafka-reassign-partitions.sh
将打印这个 reversion 的重新分配 JSON 作为其输出的一部分。非常大的重新分配应该被分解为多个较小的重新分配,以防需要停止 in-progress 重新分配。
19.1.2. 在分区重新分配 JSON 文件中指定主题
kafka-reassign-partitions.sh
工具使用一个重新分配 JSON 文件来指定要重新分配的主题。如果要移动特定的分区,您可以生成重新分配 JSON 文件或手动创建文件。
基本重新分配 JSON 文件在以下示例中显示的结构,它描述了属于两个 Kafka 主题的三个分区。每个分区被重新分配给一组新的副本,这些副本由代理 ID 标识。需要 版本
、主题
、分区
和 副本
属性。
分区重新分配 JSON 文件结构示例
{ "version": 1, 1 "partitions": [ 2 { "topic": "example-topic-1", 3 "partition": 0, 4 "replicas": [1, 2, 3] 5 }, { "topic": "example-topic-1", "partition": 1, "replicas": [2, 3, 4] }, { "topic": "example-topic-2", "partition": 0, "replicas": [3, 4, 5] } ] }
未包含在 JSON 中的分区不会改变。
如果您只使用主题数组指定 主题
,则分区重新分配工具会重新分配属于指定主题的所有分区。
重新分配 JSON 文件结构示例,用于重新分配主题的所有分区
{ "version": 1, "topics": [ { "topic": "my-topic"} ] }
19.1.3. 在 JBOD 卷间重新分配分区
在 Kafka 集群中使用 JBOD 存储时,您可以在特定卷及其日志目录间重新分配分区(每个卷都有一个日志目录)。
要将分区重新分配给特定卷,请在重新分配 JSON 文件中为每个分区添加 log_dirs
值。每个 log_dirs
数组包含与 replicas
数组相同的条目数量,因为每个副本都应该分配给特定的日志目录。log_dirs
数组包含到日志目录的绝对路径或 特殊值
。任何
值表示 Kafka 可以为该副本选择任何可用的日志目录,这在 JBOD 卷间重新分配分区时非常有用。
使用日志目录重新分配 JSON 文件结构示例
{ "version": 1, "partitions": [ { "topic": "example-topic-1", "partition": 0, "replicas": [1, 2, 3] "log_dirs": ["/var/lib/kafka/data-0/kafka-log1", "any", "/var/lib/kafka/data-1/kafka-log2"] }, { "topic": "example-topic-1", "partition": 1, "replicas": [2, 3, 4] "log_dirs": ["any", "/var/lib/kafka/data-2/kafka-log3", "/var/lib/kafka/data-3/kafka-log4"] }, { "topic": "example-topic-2", "partition": 0, "replicas": [3, 4, 5] "log_dirs": ["/var/lib/kafka/data-4/kafka-log5", "any", "/var/lib/kafka/data-5/kafka-log6"] } ] }
19.1.4. 分区重新分配节流
分区重新分配可能会是一个较慢的过程,因为它涉及在代理间传输大量数据。为了避免对客户端造成负面影响,您可以节流重新分配过程。使用带有 kafka-reassign-partitions.sh
工具的 --throttle
参数来节流重新分配。您可以为代理之间的分区移动指定每秒的最大阈值(以字节为单位)。例如,-- throttle 5000000
为移动 50 MBps 的分区设置最大阈值。
节流可能会导致重新分配更长的时间完成。
- 如果节流太低,则新分配的代理将无法与发布的记录保持同步,且重新分配永远不会完成。
- 如果节流过高,客户端将会受到影响。
例如,对于生成者,这可能会清单高于等待确认的正常延迟。对于消费者,这可能会导致在轮询之间延迟更高的延迟导致的吞吐量下降。
19.2. 生成重新分配 JSON 文件来重新分配分区
使用 kafka-reassign-partitions.sh
工具生成重新分配 JSON 文件,以便在扩展 Kafka 集群后重新分配分区。添加或删除代理不会自动重新分发现有分区。要平衡分区分发并充分利用新代理,您可以使用 kafka-reassign-partitions.sh
工具重新分配分区。
您可以从连接到 Kafka 集群的交互式 pod 容器运行该工具。
以下流程描述了使用 mTLS 的安全重新分配过程。您需要一个使用 TLS 加密和 mTLS 身份验证的 Kafka 集群。
您需要以下内容来建立连接:
- 当 Kafka 集群时,Cluster Operator 生成的集群 CA 证书和密钥
- 当用户为客户端访问 Kafka 集群的用户创建时,User Operator 生成的用户 CA 证书和密钥
在此过程中,CA 证书和对应的密码会从集群和包含它们的用户 secret 中提取,这些 secret 以 PKCS #12 (.p12
和 .password
) 的格式提取。密码允许访问包含证书的 .p12
存储。您可以使用 .p12
存储来指定信任存储和密钥存储来验证与 Kafka 集群的连接。
先决条件
- 您有一个正在运行的 Cluster Operator。
您有一个基于配置了内部 TLS 加密和 mTLS 身份验证的
Kafka
资源运行 Kafka 集群。使用 TLS 加密和 mTLS 身份验证配置 Kafka
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... listeners: # ... - name: tls port: 9093 type: internal tls: true 1 authentication: type: tls 2 # ...
正在运行的 Kafka 集群包含一组要重新分配的主题和分区。
my-topic
的主题配置示例apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic labels: strimzi.io/cluster: my-cluster spec: partitions: 10 replicas: 3 config: retention.ms: 7200000 segment.bytes: 1073741824 # ...
有一个配置了 ACL 规则的
KafkaUser
,它用于指定从 Kafka 代理生成和使用主题的权限。带有 ACL 规则的 Kafka 用户配置示例,允许对
my-topic
和my-cluster
执行操作apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: name: my-user labels: strimzi.io/cluster: my-cluster spec: authentication: 1 type: tls authorization: type: simple 2 acls: # access to the topic - resource: type: topic name: my-topic operations: - Create - Describe - Read - AlterConfigs host: "*" # access to the cluster - resource: type: cluster operations: - Alter - AlterConfigs host: "*" # ... # ...
流程
从 Kafka 集群的 <
cluster_name> -cluster-ca-cert
secret 中提取集群 CA 证书和密钥。oc get secret <cluster_name>-cluster-ca-cert -o jsonpath='{.data.ca\.p12}' | base64 -d > ca.p12
oc get secret <cluster_name>-cluster-ca-cert -o jsonpath='{.data.ca\.password}' | base64 -d > ca.password
将 <cluster_name > 替换为 Kafka 集群的名称。当使用 Kafka 资源部署 Kafka 时,会使用
Kafka
集群名称(<cluster_name> -cluster-ca-cert)创建带有集群
CA 证书的 secret。例如,my-cluster-cluster-ca-cert
。使用 AMQ Streams Kafka 镜像运行新的交互式 pod 容器,以连接到正在运行的 Kafka 代理。
oc run --restart=Never --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 <interactive_pod_name> -- /bin/sh -c "sleep 3600"
将 <interactive_pod_name > 替换为 pod 的名称。
将集群 CA 证书复制到交互式 pod 容器。
oc cp ca.p12 <interactive_pod_name>:/tmp
从具有访问 Kafka 代理权限的 Kafka 用户的 secret 中提取用户 CA 用户和密码。
oc get secret <kafka_user> -o jsonpath='{.data.user\.p12}' | base64 -d > user.p12
oc get secret <kafka_user> -o jsonpath='{.data.user\.password}' | base64 -d > user.password
将 <kafka_user > 替换为 Kafka 用户的名称。当使用
KafkaUser
资源创建 Kafka 用户时,会使用 Kafka 用户名创建带有用户 CA 证书的 secret。例如,my-user
。将用户 CA 证书复制到交互式 pod 容器。
oc cp user.p12 <interactive_pod_name>:/tmp
CA 证书允许交互式 pod 容器使用 TLS 连接到 Kafka 代理。
创建
config.properties
文件,以指定用于验证与 Kafka 集群的连接的信任存储和密钥存储。使用您在上一步中提取的证书和密码。
bootstrap.servers=<kafka_cluster_name>-kafka-bootstrap:9093 1 security.protocol=SSL 2 ssl.truststore.location=/tmp/ca.p12 3 ssl.truststore.password=<truststore_password> 4 ssl.keystore.location=/tmp/user.p12 5 ssl.keystore.password=<keystore_password> 6
将
config.properties
文件复制到交互式 pod 容器。oc cp config.properties <interactive_pod_name>:/tmp/config.properties
准备名为
topics.json
的 JSON 文件,以指定要移动的主题。将主题名称指定为用逗号分开的列表。
重新分配
my-topic
的所有分区的 JSON 文件示例{ "version": 1, "topics": [ { "topic": "my-topic"} ] }
您还可以使用此文件 更改主题的复制因素。
将
topics.json
文件复制到交互式 pod 容器。oc cp topics.json <interactive_pod_name>:/tmp/topics.json
在交互式 pod 容器中启动 shell 进程。
oc exec -n <namespace> -ti <interactive_pod_name> /bin/bash
将 <namespace > 替换为运行 pod 的 OpenShift 命名空间。
使用
kafka-reassign-partitions.sh
命令生成重新分配 JSON。将
my-topic
分区移到指定的代理的命令示例bin/kafka-reassign-partitions.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --topics-to-move-json-file /tmp/topics.json \ --broker-list 0,1,2,3,4 \ --generate
19.3. 添加代理后重新分配分区
在增加 Kafka 集群中的代理数量后,使用 kafka-reassign-partitions.sh
工具生成的重新分配文件来重新分配分区。重新分配文件应描述如何将分区重新分配给 enlarged Kafka 集群中的代理。您可以将文件中指定的重新分配应用到代理,然后验证新分区分配。
此流程描述了使用 TLS 的安全扩展流程。您需要一个使用 TLS 加密和 mTLS 身份验证的 Kafka 集群。
kafka-reassign-partitions.sh
工具可用于重新分配 Kafka 集群中的分区,无论您是否通过集群管理所有节点,还是使用节点池预览来管理集群中的节点组。
虽然您可以使用 kafka-reassign-partitions.sh
工具,但推荐对自动 分区重新分配和集群重新平衡进行 Cruise Control。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。
先决条件
-
您有一个基于配置了内部 TLS 加密和 mTLS 身份验证的
Kafka
资源运行 Kafka 集群。 -
您已生成了一个重新分配 JSON 文件,名为
reassignment.json
。 - 您正在运行连接到正在运行的 Kafka 代理的交互式 pod 容器。
-
您作为
KafkaUser
配置有 ACL 规则,该规则指定管理 Kafka 集群及其主题的权限。
流程
-
通过增加
Kafka.spec.kafka.replicas
配置选项,根据需要添加任意数量的新代理。 - 验证新代理 pod 是否已启动。
-
如果没有这样做,请运行交互式 pod 容器来生成一个重新分配 JSON 文件,名为
reassignment.json
。 将
reassignment.json
文件复制到交互式 pod 容器。oc cp reassignment.json <interactive_pod_name>:/tmp/reassignment.json
将 <interactive_pod_name > 替换为 pod 的名称。
在交互式 pod 容器中启动 shell 进程。
oc exec -n <namespace> -ti <interactive_pod_name> /bin/bash
将 <namespace > 替换为运行 pod 的 OpenShift 命名空间。
使用交互式 pod 容器中的
kafka-reassign-partitions.sh
脚本运行分区重新分配。bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --execute
将 <cluster_name > 替换为 Kafka 集群的名称。例如,
my-cluster-kafka-bootstrap:9093
如果您要节流复制,也可以使用每秒的 throttle 节流率传递
--throttle
选项。例如:bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --throttle 5000000 \ --execute
此命令将输出两个重新分配 JSON 对象。第一个记录了正在移动的分区的当前分配。如果您需要稍后恢复重新分配,您应该将它保存到本地文件(而不是 pod 中的文件)。第二个 JSON 对象是您在重新分配 JSON 文件中传递的目标重新分配。
如果您需要在重新分配过程中更改节流,您可以使用具有不同节流率相同的命令。例如:
bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --throttle 10000000 \ --execute
使用任何代理 pod 的
kafka-reassign-partitions.sh
命令行工具验证重新分配是否已完成。这与上一步的命令相同,但使用--verify
选项而不是--execute
选项。bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --verify
当
--verify
命令报告正在移动的每个分区都成功完成时,重新分配已完成。最后--verify
也会导致删除任何重新分配节流的影响。- 现在,如果您保存了 JSON 以将分配恢复到其原始代理,您可以删除恢复文件。
19.4. 在删除代理前重新分配分区
在减少 Kafka 集群中的代理数量前,使用 kafka-reassign-partitions.sh
工具生成的重新分配文件来重新分配分区。重新分配文件必须描述如何将分区重新分配给 Kafka 集群中的其余代理。您可以将文件中指定的重新分配应用到代理,然后验证新分区分配。最高数字 pod 中的代理会首先被删除。
此流程描述了使用 TLS 的安全扩展流程。您需要一个使用 TLS 加密和 mTLS 身份验证的 Kafka 集群。
kafka-reassign-partitions.sh
工具可用于重新分配 Kafka 集群中的分区,无论您是否通过集群管理所有节点,还是使用节点池预览来管理集群中的节点组。
虽然您可以使用 kafka-reassign-partitions.sh
工具,但推荐对自动 分区重新分配和集群重新平衡进行 Cruise Control。Cruise Control 可以在没有任何停机时间的情况下将主题从一个代理移到另一个代理,它是重新分配分区的最有效方法。
先决条件
-
您有一个基于配置了内部 TLS 加密和 mTLS 身份验证的
Kafka
资源运行 Kafka 集群。 -
您已生成了一个重新分配 JSON 文件,名为
reassignment.json
。 - 您正在运行连接到正在运行的 Kafka 代理的交互式 pod 容器。
-
您作为
KafkaUser
配置有 ACL 规则,该规则指定管理 Kafka 集群及其主题的权限。
流程
-
如果没有这样做,请运行交互式 pod 容器来生成一个重新分配 JSON 文件,名为
reassignment.json
。 将
reassignment.json
文件复制到交互式 pod 容器。oc cp reassignment.json <interactive_pod_name>:/tmp/reassignment.json
将 <interactive_pod_name > 替换为 pod 的名称。
在交互式 pod 容器中启动 shell 进程。
oc exec -n <namespace> -ti <interactive_pod_name> /bin/bash
将 <namespace > 替换为运行 pod 的 OpenShift 命名空间。
使用交互式 pod 容器中的
kafka-reassign-partitions.sh
脚本运行分区重新分配。bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --execute
将 <cluster_name > 替换为 Kafka 集群的名称。例如,
my-cluster-kafka-bootstrap:9093
如果您要节流复制,也可以使用每秒的 throttle 节流率传递
--throttle
选项。例如:bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --throttle 5000000 \ --execute
此命令将输出两个重新分配 JSON 对象。第一个记录了正在移动的分区的当前分配。如果您需要稍后恢复重新分配,您应该将它保存到本地文件(而不是 pod 中的文件)。第二个 JSON 对象是您在重新分配 JSON 文件中传递的目标重新分配。
如果您需要在重新分配过程中更改节流,您可以使用具有不同节流率相同的命令。例如:
bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --throttle 10000000 \ --execute
使用任何代理 pod 的
kafka-reassign-partitions.sh
命令行工具验证重新分配是否已完成。这与上一步的命令相同,但使用--verify
选项而不是--execute
选项。bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --verify
当
--verify
命令报告正在移动的每个分区都成功完成时,重新分配已完成。最后--verify
也会导致删除任何重新分配节流的影响。- 现在,如果您保存了 JSON 以将分配恢复到其原始代理,您可以删除恢复文件。
当所有分区重新分配完成后,正在删除的代理不应负责集群中的任何分区。您可以通过检查代理的数据日志目录不包含任何实时分区日志来验证这一点。如果代理上的日志目录包含一个与扩展的正则表达式
\.[a-z0-9]-delete$
不匹配的目录,则代理仍然具有实时分区,且不应停止。您可以通过执行以下命令来检查它:
oc exec my-cluster-kafka-0 -c kafka -it -- \ /bin/bash -c \ "ls -l /var/lib/kafka/kafka-log_<n>_ | grep -E '^d' | grep -vE '[a-zA-Z0-9.-]+\.[a-z0-9]+-delete$'"
其中 n 是要删除的 pod 的数量。
如果上述命令打印任何输出,则代理仍然有实时分区。在这种情况下,重新分配还没有完成,或者重新分配 JSON 文件不正确。
-
当您确认代理没有实时分区时,您可以编辑
Kafka
资源的Kafka.spec.kafka.replicas
属性来减少代理数量。
19.5. 更改主题的复制因素
要更改 Kafka 集群中主题的复制因素,请使用 kafka-reassign-partitions.sh
工具。这可以通过从连接到 Kafka 集群的交互式 pod 容器运行工具,并使用重新分配文件来描述主题副本是如何更改的。
此流程描述了使用 TLS 的安全进程。您需要一个使用 TLS 加密和 mTLS 身份验证的 Kafka 集群。
先决条件
-
您有一个基于配置了内部 TLS 加密和 mTLS 身份验证的
Kafka
资源运行 Kafka 集群。 - 您正在运行连接到正在运行的 Kafka 代理的交互式 pod 容器。
-
您已生成了一个名为
reassignment.json
的重新分配 JSON 文件。 -
您作为
KafkaUser
配置有 ACL 规则,该规则指定管理 Kafka 集群及其主题的权限。
请参阅 生成重新分配 JSON 文件。
在此过程中,名为 my-topic
的主题有 4 个副本,我们希望将其减少到 3。名为 topics.json
的 JSON 文件指定主题,用于生成 reassignment.json
文件。
JSON 文件示例指定 my-topic
{ "version": 1, "topics": [ { "topic": "my-topic"} ] }
流程
如果没有这样做,请运行交互式 pod 容器来生成一个重新分配 JSON 文件,名为
reassignment.json
。显示当前和建议的副本分配的重新分配 JSON 文件示例
Current partition replica assignment {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[3,4,2,0],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[0,2,3,1],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[1,3,0,4],"log_dirs":["any","any","any","any"]}]} Proposed partition reassignment configuration {"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2,3],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3,4],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,4,0],"log_dirs":["any","any","any","any"]}]}
如果需要稍后恢复更改,在本地保存此文件的副本。
编辑
reassignment.json
,以从每个分区中删除副本。例如,使用
jq
删除主题的每个分区列表中的最后一个副本:删除每个分区的最后一个主题副本
jq '.partitions[].replicas |= del(.[-1])' reassignment.json > reassignment.json
显示更新的副本的重新分配文件示例
{"version":1,"partitions":[{"topic":"my-topic","partition":0,"replicas":[0,1,2],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":1,"replicas":[1,2,3],"log_dirs":["any","any","any","any"]},{"topic":"my-topic","partition":2,"replicas":[2,3,4],"log_dirs":["any","any","any","any"]}]}
将
reassignment.json
文件复制到交互式 pod 容器。oc cp reassignment.json <interactive_pod_name>:/tmp/reassignment.json
将 <interactive_pod_name > 替换为 pod 的名称。
在交互式 pod 容器中启动 shell 进程。
oc exec -n <namespace> -ti <interactive_pod_name> /bin/bash
将 <namespace > 替换为运行 pod 的 OpenShift 命名空间。
使用交互式 pod 容器中的
kafka-reassign-partitions.sh
脚本进行主题副本更改。bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --execute
注意从代理中删除副本不需要任何代理数据移动,因此无需节流复制。如果要添加副本,您可能需要更改节流率。
验证对主题副本的更改是否已从任何代理 pod 使用
kafka-reassign-partitions.sh
命令行工具完成。这与上一步的命令相同,但使用--verify
选项而不是--execute
选项。bin/kafka-reassign-partitions.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --reassignment-json-file /tmp/reassignment.json \ --verify
当
--verify
命令报告正在移动的每个分区都成功完成时,重新分配已完成。最后--verify
也会导致删除任何重新分配节流的影响。使用
--describe
选项运行bin/kafka-topics.sh
命令,以查看对主题的更改的结果。bin/kafka-topics.sh --bootstrap-server <cluster_name>-kafka-bootstrap:9093 \ --command-config /tmp/config.properties \ --describe
减少主题副本数的结果
my-topic Partition: 0 Leader: 0 Replicas: 0,1,2 Isr: 0,1,2 my-topic Partition: 1 Leader: 2 Replicas: 1,2,3 Isr: 1,2,3 my-topic Partition: 2 Leader: 3 Replicas: 2,3,4 Isr: 2,3,4
第 20 章 为 AMQ Streams 设置指标和仪表板
收集指标对于了解 Kafka 部署的健康状况和性能至关重要。通过监控指标,您可以在问题变为关键前主动发现问题,并对资源分配和容量规划做出建议决策。如果没有指标数据,您可能会对 Kafka 部署的行为具有有限的可见性,这使得故障排除更困难和耗时。设置指标可节省长时间运行时和资源,并帮助确保 Kafka 部署的可靠性。
AMQ Streams 中的每个组件都提供了指标数据,从而深入了解其独立性能。虽然其他组件需要配置来公开指标暴露,但 AMQ Streams operator 默认自动公开 Prometheus 指标。这些指标包括:
- 协调计数
- 正在处理自定义资源数
- 协调持续时间
- JVM 指标
您还可以通过在 Kafka
资源的监听程序或授权配置中启用 enableMetrics
属性来收集特定于 oauth
身份验证和 opa
或 keycloak
授权的指标。同样,您可以在自定义资源中启用 oauth
身份验证的指标,如 KafkaBridge
、KafkaConnect
、KafkaMirrorMaker
和 KafkaMirrorMaker2
。
您可以使用 Prometheus 和 Grafana 监控 AMQ Streams。当使用 Prometheus 规则配置时,Prometheus 会消耗集群中正在运行的 pod 的指标。Grafana 在仪表板中视觉化这些指标,为监控提供了一个直观的界面。
为便于指标集成,AMQ Streams 为 AMQ Streams 组件提供 Prometheus 规则和 Grafana 仪表板示例。您可以自定义 Grafana 仪表板示例以满足您的特定部署要求。您可以使用规则来定义根据特定指标触发警报的条件。
根据您的监控要求,您可以执行以下操作:
另外,您可以通过设置 分布式追踪,或使用 诊断工具 (report.sh
)来检索故障排除数据,配置部署以跟踪消息端到端。
AMQ Streams 为 Prometheus 和 Grafana 提供示例安装文件,它可以充当监控 AMQ Streams 部署的起点。为获得进一步的支持,请尝试与 Prometheus 和 Grafana 开发人员社区合作。
支持指标和监控工具的文档
如需有关指标和监控工具的更多信息,请参阅支持文档:
- Prometheus
- Prometheus 配置
- Kafka Exporter
- Grafana Labs
- Apache Kafka Monitoring 描述了 Apache Kafka 公开的 JMX 指标
- ZooKeeper JMX 描述了 Apache ZooKeeper 公开的 JMX 指标
20.1. 使用 Kafka Exporter 监控消费者滞后
Kafka Exporter 是一个开源项目,用于增强对 Apache Kafka 代理和客户端的监控。您可以配置 Kafka
资源,以使用 Kafka 集群部署 Kafka 导出器。Kafka Exporter 从与偏移、消费者组、消费者滞后和主题相关的 Kafka 代理中提取额外的指标数据。例如,指标数据用于帮助识别较慢的用户。滞后数据作为 Prometheus 指标公开,然后可在 Grafana 中显示以进行分析。
Kafka Exporter 从 __consumer_offsets
主题读取,该主题存储消费者组的提交偏移信息。要使 Kafka Exporter 能够正常工作,消费者组需要正在使用。
Kafka Exporter 的 Grafana 仪表板是 AMQ Streams 提供的多个 Grafana 仪表板 之一。
Kafka Exporter 仅提供与消费者滞后和消费者偏移相关的额外指标。对于常规 Kafka 指标,您必须在 Kafka 代理 中配置 Prometheus 指标。
消费者滞后表示消息的速度与消息的消耗的差别。具体来说,给定消费者组的消费者滞后指示分区中最后一个消息之间的延迟,以及当前由该消费者获取的消息之间的延迟。
lag 反映了与分区日志结束相关的消费者偏移的位置。
消费者在生成者和消费者偏移之间滞后
这种差异有时被称为制作者偏移和消费者偏移之间的 delta : Kafka 代理主题分区中的读取和写入位置。
假设主题流 100 个消息。在制作者偏移(主题分区头)和最后一个偏移之间发生 1000 个消息,使用者读取的最后偏移时间为 10 秒的延迟。
监控消费者的重要性
对于依赖于实时数据的处理的应用程序,监控消费者来判断其是否不会变得太大。整个过程越好,流程从实时处理目标中得到的增长。
例如,消费者滞后可能是消耗太多的旧数据(这些数据尚未被清除)或出现计划外的关闭。
减少消费者滞后
使用 Grafana chart 分析滞后,检查操作是否减少对受影响的消费者组的影响。例如,如果对 Kafka 代理进行了调整以减少滞后,仪表板将显示 Lag by consumer group 图表下降,Messages consumed per minute 图表增加。
减少滞后的典型操作包括:
- 通过添加新消费者来扩展消费者组
- 增加保留时间以便消息保留在主题中
- 添加更多磁盘容量以增加消息缓冲
减少消费者滞后的操作取决于底层基础架构和 AMQ Streams 的用例。例如,分发的消费者不太可能从其磁盘缓存中获取请求的服务从代理服务。在某些情况下,在消费者发现前,可以接受自动丢弃消息。
20.2. 监控 Cruise Control 操作
Cruise Control 监控 Kafka 代理,以跟踪代理、主题和分区的利用率。Cruise Control 还提供一组指标来监控其自身的性能。
Cruise Control 指标报告程序从 Kafka 代理收集原始指标数据。数据生成给由 Cruise Control 自动创建的主题。指标 用于为 Kafka 集群生成优化建议。
Cruise Control 指标可用于对 Cruise Control 操作进行实时监控。例如,您可以使用 Cruise Control 指标来监控运行重新平衡操作的状态,或针对操作性能中检测到的任何异常情况提供警报。
您可以通过在 Cruise Control 配置中启用 Prometheus JMX Exporter 来公开 Cruise Control 指标。
有关可用 Cruise Control 指标的完整列表,称为 sensors,请参阅 Cruise Control 文档
20.2.1. 监控均衡分数
Cruise Control 指标包括平衡分数。Balancedness 是在 Kafka 集群中平均分配工作负载的方法。
用于均衡分数的 Cruise Control 指标(balancedness-score
)可能与 KafkaRebalance
资源中的均衡分数不同。Cruise Control 使用 aoma ly.detection.goals
计算每个分数,它可能与 KafkaRebalance
资源中使用的 default.goals
不同。a omaly.detection.goals
在 Kafka
自定义资源的 spec.cruiseControl.config
中指定。
刷新 KafkaRebalance
资源获取优化提议。如果满足以下条件之一,则会获取最新的缓存的优化建议:
-
KafkaRebalance
目标
与Kafka
资源的default.goals
部分中配置的目标匹配 -
未指定 KafkaRebalance
目标
否则,Cruise Control 会根据 KafkaRebalance 目标
生成一个新的优化建议。如果每次刷新中都会生成新的提议,这可能会影响性能监控。
20.2.2. 为异常检测设置警报
Cruise Control 的 omaly detector 提供了阻止生成优化目标(如代理故障)的条件的指标数据。如果要提高可见性,您可以使用 anomaly detector 提供的指标来设置警报并发送通知。您可以设置 Cruise Control 的 anomaly notifier,以根据这些指标通过指定的通知频道路由警报。另外,您可以设置 Prometheus 来提取 aomaly detector 提供的指标数据并生成警报。然后,Prometheus Alertmanager 可以路由 Prometheus 生成的警报。
Cruise Control 文档 提供有关 AnomalyDetector
指标和 aomaly notifier 的信息。
20.3. 指标文件示例
您可以在 AMQ Streams 提供 的示例配置文件 中找到 Grafana 仪表板和其他指标配置文件示例。
AMQ Streams 提供的指标文件示例
metrics ├── grafana-dashboards 1 │ ├── strimzi-cruise-control.json │ ├── strimzi-kafka-bridge.json │ ├── strimzi-kafka-connect.json │ ├── strimzi-kafka-exporter.json │ ├── strimzi-kafka-mirror-maker-2.json │ ├── strimzi-kafka.json │ ├── strimzi-operators.json │ └── strimzi-zookeeper.json ├── grafana-install │ └── grafana.yaml 2 ├── prometheus-additional-properties │ └── prometheus-additional.yaml 3 ├── prometheus-alertmanager-config │ └── alert-manager-config.yaml 4 ├── prometheus-install │ ├── alert-manager.yaml 5 │ ├── prometheus-rules.yaml 6 │ ├── prometheus.yaml 7 │ └── strimzi-pod-monitor.yaml 8 ├── kafka-bridge-metrics.yaml 9 ├── kafka-connect-metrics.yaml 10 ├── kafka-cruise-control-metrics.yaml 11 ├── kafka-metrics.yaml 12 └── kafka-mirror-maker-2-metrics.yaml 13
- 1
- 不同 AMQ Streams 组件的 Grafana 仪表板示例。
- 2
- Grafana 镜像的安装文件。
- 3
- 其他配置用于提取 CPU、内存和磁盘使用的指标,这些指标直接从节点上的 OpenShift cAdvisor 代理和 kubelet 提供。
- 4
- 通过 Alertmanager 发送通知的 hook 定义。
- 5
- 用于部署和配置 Alertmanager 的资源。
- 6
- 用于 Prometheus Alertmanager 的警报规则示例(与 Prometheus 部署)。
- 7
- Prometheus 镜像的安装资源文件。
- 8
- PodMonitor 定义由 Prometheus Operator 转换为作业,以便 Prometheus 服务器直接从 pod 提取指标数据。
- 9
- 启用指标的 Kafka Bridge 资源。
- 10
- 为 Kafka Connect 定义 Prometheus JMX Exporter 重新标记规则的指标配置。
- 11
- 为 Cruise 控制定义 Prometheus JMX Exporter 重新标记规则的指标配置。
- 12
- 为 Kafka 和 ZooKeeper 定义 Prometheus JMX Exporter 重新标记规则的指标配置。
- 13
- 为 Kafka Mirror Maker 2.0 定义 Prometheus JMX Exporter 重新标记规则的指标配置。
20.3.1. Prometheus 指标配置示例
AMQ Streams 使用 Prometheus JMX Exporter 通过 HTTP 端点公开指标,该端点可由 Prometheus 服务器提取。
Grafana 仪表板依赖于 Prometheus JMX Exporter 重新标记规则,这些规则是为自定义资源配置中 AMQ Streams 组件定义的。
标签是一个名称值对。重新标记是动态写入标签的过程。例如,标签值可以从 Kafka 服务器和客户端 ID 的名称中派生。
AMQ Streams 提供了带有重新标记规则的自定义资源配置 YAML 文件示例。在部署 Prometheus 指标配置时,您可以部署示例自定义资源,或将指标配置复制到您自己的自定义资源定义中。
组件 | 自定义资源 | YAML 文件示例 |
---|---|---|
Kafka 和 ZooKeeper |
|
|
Kafka Connect |
|
|
Kafka MirrorMaker 2 |
|
|
Kafka Bridge |
|
|
Sything Control |
|
|
20.3.2. 警报通知的 Prometheus 规则示例
由 AMQ Streams 提供的 指标配置文件 提供了警报通知的 Prometheus 规则示例。规则在示例 prometheus-rules.yaml
文件中指定,用于在 Prometheus 部署中使用。
prometheus-rules.yaml
文件包含以下组件的示例规则:
- Kafka
- ZooKeeper
- Entity Operator
- Kafka Connect
- Kafka Bridge
- MirrorMaker
- Kafka Exporter
文件中提供了每个示例规则的描述。
警报规则提供有关指标中观察到的特定条件的通知。规则在 Prometheus 服务器上声明,但 Prometheus Alertmanager 负责警报通知。
Prometheus 警报规则使用 PromQL 表达式来持续评估的条件。
当警报表达式变为 true 时,会满足条件,Prometheus 服务器会将警报数据发送到 Alertmanager。然后,Alertmanager 使用为部署配置的通信方法发送通知。
有关警报规则定义的一般点:
-
for
属性与规则一起使用,以确定在触发警报前必须保留条件的时间周期。 -
tick 是一个基本的 ZooKeeper 时间单元,以毫秒为单位,并使用
Kafka.spec.zookeeper.config
的tickTime
参数进行配置。例如,如果 ZooKeepertickTime=3000
,3 个 ticks (3 x 3000)等于 9000 毫秒。 -
ZookeeperRunningOutOfSpace
指标和警报的可用性取决于使用的 OpenShift 配置和存储实施。某些平台的存储实现可能无法提供指标提供警报所需的可用空间的信息。
Alertmanager 可以配置为使用电子邮件、天天消息或其他通知方法。根据您的具体需要,调整示例规则的默认配置。
20.3.3. Grafana 仪表板示例
如果部署 Prometheus 以提供指标,您可以使用 AMQ Streams 提供的 Grafana 仪表板示例来监控 AMQ Streams 组件。
示例仪表板在 example /metrics/grafana-dashboards
目录中作为 JSON 文件提供。
所有仪表板都提供 JVM 指标,以及特定于组件的指标。例如,AMQ Streams operator 的 Grafana 仪表板提供了它们正在处理的协调或自定义资源的数量信息。
示例仪表板没有显示 Kafka 支持的所有指标。仪表板填充了用于监控的指标集合。
组件 | JSON 文件示例 |
---|---|
AMQ Streams operator |
|
Kafka |
|
ZooKeeper |
|
Kafka Connect |
|
Kafka MirrorMaker 2 |
|
Kafka Bridge |
|
Sything Control |
|
Kafka Exporter |
|
当 Kafka Exporter 没有指标时,因为集群中还没有流量,Kafka Exporter Grafana 仪表板将显示 N/A
用于数字字段,且没有要 显示图形的数据
。
20.4. 通过配置启用 Prometheus 指标
要在 AMQ Streams for Prometheus 中启用和公开指标,请使用指标配置属性。
以下组件需要 metricsConfig
配置来公开指标:
- Kafka
- KafkaConnect
- MirrorMaker
- Sything Control
- ZooKeeper
此配置可让 Prometheus JMX Exporter 通过 HTTP 端点公开指标。JMX 导出器 HTTP 端点的端口是 9404。Prometheus 提取此端点来收集 Kafka 指标。
您可以将 enableMetrics
属性设置为 true
,以便为这些组件公开指标:
- Kafka Bridge
- OAuth 2.0 身份验证和授权框架
- 用于授权的开放策略代理(OPA)
要在 AMQ Streams 中部署 Prometheus 指标配置,您可以使用自己的配置或 AMQ Streams 提供的示例自定义资源 配置文件 :
-
kafka-metrics.yaml
-
kafka-connect-metrics.yaml
-
kafka-mirror-maker-2-metrics.yaml
-
kafka-bridge-metrics.yaml
-
kafka-cruise-control-metrics.yaml
-
oauth-metrics.yaml
这些文件包含启用 Prometheus 指标所需的重新标记规则和配置。在使用 AMQ Streams 尝试 Prometheus 时,它们是很好的起点。
此流程演示了如何在 Kafka
资源中部署 Prometheus 指标配置示例。为其他资源部署示例文件时,此过程相同。
如果要包含 Kafka Exporter 指标,请在 Kafka
资源中添加 kafkaExporter
配置。
Kafka Exporter 仅提供额外的与消费者滞后相关的指标。对于常规 Kafka 指标,您必须在 Kafka 代理 中配置 Prometheus 指标。
流程
使用 Prometheus 配置部署示例自定义资源。
例如,对于每个
Kafka
资源,您可以应用kafka-metrics.yaml
文件。部署示例配置
oc apply -f kafka-metrics.yaml
另外,您可以将
kafka-metrics.yaml
中的示例配置复制到您自己的Kafka
资源中。复制示例配置
oc edit kafka <kafka_configuration_file>
复制
metricsConfig
属性及其引用您的Kafka
资源的ConfigMap
。Kafka 的指标配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... metricsConfig: 1 type: jmxPrometheusExporter valueFrom: configMapKeyRef: name: kafka-metrics key: kafka-metrics-config.yml --- kind: ConfigMap 2 apiVersion: v1 metadata: name: kafka-metrics labels: app: strimzi data: kafka-metrics-config.yml: | # metrics configuration...
要部署 Kafka Exporter,请添加
kafkaExporter
配置。kafkaExporter
配置只在Kafka
资源中指定。部署 Kafka Exporter 的配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: # ... kafkaExporter: image: my-registry.io/my-org/my-exporter-cluster:latest 1 groupRegex: ".*" 2 topicRegex: ".*" 3 groupExcludeRegex: "^excluded-.*" 4 topicExcludeRegex: "^excluded-.*" 5 resources: 6 requests: cpu: 200m memory: 64Mi limits: cpu: 500m memory: 128Mi logging: debug 7 enableSaramaLogging: true 8 template: 9 pod: metadata: labels: label1: value1 imagePullSecrets: - name: my-docker-credentials securityContext: runAsUser: 1000001 fsGroup: 0 terminationGracePeriodSeconds: 120 readinessProbe: 10 initialDelaySeconds: 15 timeoutSeconds: 5 livenessProbe: 11 initialDelaySeconds: 15 timeoutSeconds: 5 # ...
要使 Kafka Exporter 能够正常工作,消费者组需要使用。
为 Kafka Bridge 启用指标
要为 Kafka Bridge 公开指标,请在 KafkaBridge
资源中将 enableMetrics
属性设置为 true
。
Kafka Bridge 的指标配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: # ... bootstrapServers: my-cluster-kafka:9092 http: # ... enableMetrics: true # ...
为 OAuth 2.0 和 OPA 启用指标
要公开 OAuth 2.0 或 OPA 的指标,请在适当的自定义资源中将 enableMetrics
属性设置为 true
。
- OAuth 2.0 指标
在
Kafka
资源中为 Kafka 集群授权和 Kafka 侦听器身份验证启用指标。您还可以在其他 受支持组件 的自定义资源中启用 OAuth 2.0 身份验证的指标。
- opa 指标
-
为
Kafka
集群授权启用指标与 OAuth 2.0 相同。
在以下示例中,为 OAuth 2.0 侦听器身份验证和 OAuth 2.0 (keycloak
)集群授权启用指标。
为 OAuth 2.0 启用指标的集群配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster namespace: myproject spec: kafka: # ... listeners: - name: external port: 9094 type: loadbalancer tls: true authentication: type: oauth enableMetrics: true configuration: #... authorization: type: keycloak enableMetrics: true # ...
要将 OAuth 2.0 指标与 Prometheus 搭配使用,您可以使用 oauth-metrics.yaml
文件来部署示例 Prometheus 指标配置。将 ConfigMap
配置复制 oauth-metrics.yaml
文件包含到为 OAuth 2.0 启用指标的同一 Kafka
资源配置文件。
20.5. 查看 OpenShift 中的 Kafka 指标和仪表板
当 AMQ Streams 部署到 OpenShift Container Platform 时,通过 监控用户定义的项目提供指标。此 OpenShift 功能可让开发人员访问一个单独的 Prometheus 实例来监控自己的项目(如 Kafka
项目)。
如果启用了对用户定义的项目的监控,openshift-user-workload-monitoring
项目包含以下组件:
- Prometheus operator
- Prometheus 实例(由 Prometheus Operator 自动部署)
- Thanos Ruler 实例
AMQ Streams 使用这些组件来消耗指标。
集群管理员必须为用户定义的项目启用监控,然后授予开发人员和其他用户权限来监控其自己的项目中的应用程序。
Grafana 部署
您可以将 Grafana 实例部署到包含 Kafka 集群的项目中。然后,Grafana 仪表板示例可用于在 Grafana 用户界面中视觉化 AMQ Streams 的 Prometheus 指标。
openshift-monitoring
项目为核心平台组件提供监控。不要使用 此项目中的 Prometheus 和 Grafana 组件在 OpenShift Container Platform 4.x 上为 AMQ Streams 配置监控。
流程概述
要在 OpenShift Container Platform 中设置 AMQ Streams 监控,请按照以下步骤执行:
20.5.1. 先决条件
- 已使用示例 YAML 文件 部署了 Prometheus 指标配置。
-
启用对用户定义的项目的监控。集群管理员已在 OpenShift 集群中创建了一个
cluster-monitoring-config
配置映射。 -
集群管理员已分配了
monitoring-rules-edit
或monitoring-edit
角色。
有关创建 cluster-monitoring-config
配置映射并授予用户权限来监控用户定义的项目的的更多信息,请参阅 OpenShift 文档。
20.5.2. 部署 Prometheus 资源
使用 Prometheus 获取 Kafka 集群中的监控数据。
您可以使用您自己的 Prometheus 部署,或使用 AMQ Streams 提供的示例指标配置文件 部署 Prometheus。要使用示例文件,请配置和部署 PodMonitor
资源。PodMonitors
直接从 Apache Kafka、Zook、Operator、Kafka Bridge 和 Cruise Control 的 pod 中提取数据。
然后,您要为 Alertmanager 部署示例警报规则。
先决条件
- 正在运行的 Kafka 集群。
- 检查 AMQ Streams 提供的示例警报规则。
流程
检查是否启用了对用户定义的项目的监控:
oc get pods -n openshift-user-workload-monitoring
如果启用,则返回监控组件的 pod。例如:
NAME READY STATUS RESTARTS AGE prometheus-operator-5cc59f9bc6-kgcq8 1/1 Running 0 25s prometheus-user-workload-0 5/5 Running 1 14s prometheus-user-workload-1 5/5 Running 1 14s thanos-ruler-user-workload-0 3/3 Running 0 14s thanos-ruler-user-workload-1 3/3 Running 0 14s
如果没有返回 pod,则禁用对用户定义的项目的监控。请参阅 第 20.5 节 “查看 OpenShift 中的 Kafka 指标和仪表板” 中的先决条件。
示例/指标/prometheus-install/strimzi-pod-monitor.yaml
中定义了多个PodMonitor
资源。对于每个
PodMonitor
资源,编辑spec.namespaceSelector.matchNames
属性:apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: cluster-operator-metrics labels: app: strimzi spec: selector: matchLabels: strimzi.io/kind: cluster-operator namespaceSelector: matchNames: - <project-name> 1 podMetricsEndpoints: - path: /metrics port: http # ...
- 1
- 从其中提取指标的 Pod 项目,如
Kafka
。
将
strimzi-pod-monitor.yaml
文件部署到运行 Kafka 集群的项目中:oc apply -f strimzi-pod-monitor.yaml -n MY-PROJECT
将示例 Prometheus 规则部署到同一项目中:
oc apply -f prometheus-rules.yaml -n MY-PROJECT
20.5.3. 为 Grafana 创建服务帐户
AMQ Streams 的 Grafana 实例需要使用分配了 cluster-monitoring-view
角色的服务帐户运行。
如果使用 Grafana 呈现用于监控的指标,请创建一个服务帐户。
先决条件
流程
在包含 Kafka 集群的项目中为 Grafana 创建
ServiceAccount
:oc create sa grafana-service-account -n my-project
在本例中,在
my-project
命名空间中创建一个名为grafana-service-account
的服务帐户。创建一个
ClusterRoleBinding
资源,将cluster-monitoring-view
角色分配给 GrafanaServiceAccount
。此处的资源名为grafana-cluster-monitoring-binding
。apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: grafana-cluster-monitoring-binding labels: app: strimzi subjects: - kind: ServiceAccount name: grafana-service-account namespace: my-project roleRef: kind: ClusterRole name: cluster-monitoring-view apiGroup: rbac.authorization.k8s.io
将
ClusterRoleBinding
部署到同一项目中:oc apply -f grafana-cluster-monitoring-binding.yaml -n my-project
为服务帐户创建令牌 secret:
apiVersion: v1 kind: Secret metadata: name: secret-sa annotations: kubernetes.io/service-account.name: "grafana-service-account" 1 type: kubernetes.io/service-account-token 2
创建
Secret
对象和访问令牌:oc create -f <secret_configuration>.yaml
部署 Grafana 时需要访问令牌。
20.5.4. 使用 Prometheus 数据源部署 Grafana
部署 Grafana 以提供 Prometheus 指标。Grafana 应用程序需要配置 OpenShift Container Platform 监控堆栈。
OpenShift Container Platform 在 openshift-monitoring
项目中包括 Thanos Querier 实例。Thanos Querier 用于聚合平台指标。
要使用所需的平台指标,Grafana 实例需要一个可以连接到 Thanos Querier 的 Prometheus 数据源。要配置此连接,您需要创建一个配置映射来验证(使用令牌)到与 Thanos Querier 一起运行的 oauth-proxy
sidecar。数据源.yaml
文件用作配置映射的来源。
最后,您可以使用作为卷挂载到包含 Kafka 集群的项目中的配置映射来部署 Grafana 应用程序。
流程
获取 Grafana
ServiceAccount
的访问令牌:oc describe sa/grafana-service-account | grep Tokens: oc describe secret grafana-service-account-token-mmlp9 | grep token:
在本例中,服务帐户名为
grafana-service-account
。复制要在下一步中使用的访问令牌。创建包含 Grafana 的 Thanos Querier 配置的
datasource.yaml
文件。将访问令牌粘贴到
httpHeaderValue1
属性中,如下所示。apiVersion: 1 datasources: - name: Prometheus type: prometheus url: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 access: proxy basicAuth: false withCredentials: false isDefault: true jsonData: timeInterval: 5s tlsSkipVerify: true httpHeaderName1: "Authorization" secureJsonData: httpHeaderValue1: "Bearer ${GRAFANA-ACCESS-TOKEN}" 1 editable: true
- 1
GRAFANA-ACCESS-TOKEN
:GrafrasServiceAccount
的访问令牌值。
从
datasource.yaml
文件中创建一个名为grafana-config
的配置映射:oc create configmap grafana-config --from-file=datasource.yaml -n MY-PROJECT
创建由
Deployment
和Service
组成的 Grafana 应用程序。grafana-config
配置映射作为数据源配置的卷挂载。apiVersion: apps/v1 kind: Deployment metadata: name: grafana labels: app: strimzi spec: replicas: 1 selector: matchLabels: name: grafana template: metadata: labels: name: grafana spec: serviceAccountName: grafana-service-account containers: - name: grafana image: grafana/grafana:10.0.3 ports: - name: grafana containerPort: 3000 protocol: TCP volumeMounts: - name: grafana-data mountPath: /var/lib/grafana - name: grafana-logs mountPath: /var/log/grafana - name: grafana-config mountPath: /etc/grafana/provisioning/datasources/datasource.yaml readOnly: true subPath: datasource.yaml readinessProbe: httpGet: path: /api/health port: 3000 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: /api/health port: 3000 initialDelaySeconds: 15 periodSeconds: 20 volumes: - name: grafana-data emptyDir: {} - name: grafana-logs emptyDir: {} - name: grafana-config configMap: name: grafana-config --- apiVersion: v1 kind: Service metadata: name: grafana labels: app: strimzi spec: ports: - name: grafana port: 3000 targetPort: 3000 protocol: TCP selector: name: grafana type: ClusterIP
将 Grafana 应用程序部署到包含 Kafka 集群的项目中:
oc apply -f <grafana-application> -n <my-project>
20.5.5. 创建到 Grafana 服务的路由
您可以通过公开 Grafana 服务的路由来访问 Grafana 用户界面。
流程
创建到
grafana
服务的边缘路由:oc create route edge <my-grafana-route> --service=grafana --namespace=KAFKA-NAMESPACE
20.5.6. 导入 Grafana 仪表板示例
使用 Grafana 在可自定义仪表板上提供 Prometheus 指标的视觉化。
AMQ Streams 以 JSON 格式为 Grafana 提供示例仪表板配置文件。
-
examples/metrics/grafana-dashboards
此流程使用 Grafana 仪表板示例。
示例仪表板是监控关键指标的一个良好起点,但它们不显示 Kafka 支持的所有指标。您可以根据基础架构修改示例仪表板或添加其他指标。
流程
获取到 Grafana 服务的路由详情。例如:
oc get routes NAME HOST/PORT PATH SERVICES MY-GRAFANA-ROUTE MY-GRAFANA-ROUTE-amq-streams.net grafana
- 在 Web 浏览器中,使用 Route 主机和端口的 URL 访问 Grafana 登录屏幕。
输入您的用户名和密码,然后单击 Log In。
默认的 Grafana 用户名和密码都是
admin
。第一次登录后,您可以更改密码。- 在 Configuration > Data Sources 中,检查 Prometheus 数据源是否已创建。数据源在 第 20.5.4 节 “使用 Prometheus 数据源部署 Grafana” 中创建。
- 点 + 图标,然后点 Import。
-
在
examples/metrics/grafana-dashboards
中,复制要导入的仪表板的 JSON。 - 将 JSON 粘贴到文本框中,然后点 Load。
- 为其他 Grafana 仪表板重复步骤 5-7。
从 Dashboards 主页中查看导入的 Grafana 仪表板。
第 21 章 分布式追踪简介
分布式追踪跟踪分布式系统中应用程序之间的事务进度。在微服务架构中,追踪跟踪服务间的事务进度。跟踪数据可用于监控应用程序性能和调查目标系统和最终用户应用的问题。
在 AMQ Streams 中,追踪有助于对消息的端到端跟踪:从源系统到 Kafka,然后从 Kafka 到目标系统和应用程序。分布式追踪补充了 Grafana 仪表板中的指标的监控,以及组件日志记录器。
以下 Kafka 组件内置了对追踪的支持:
- MirrorMaker 将来自源集群的信息追踪到目标集群
- Kafka 连接到由 Kafka Connect 使用和生成的 trace 信息
- Kafka Bridge 用来跟踪 Kafka 和 HTTP 客户端应用程序之间的信息
Kafka 代理不支持追踪。
您可以通过其自定义资源为这些组件启用和配置追踪。您可以使用 spec.template
属性添加追踪配置。
您可以使用 spec.tracing.type
属性指定追踪类型来启用追踪:
OpenTelemetry
-
指定
type: opentelemetry
以使用 OpenTelemetry。默认情况下,OpenTelemetry 使用 OTLP (OpenTelemetry 协议)导出器和端点来获取追踪数据。您可以指定 OpenTelemetry 支持的其他追踪系统,包括 Jaeger 追踪。要做到这一点,您可以在追踪配置中更改 OpenTelemetry exporter 和端点。 jaeger
-
指定
type:jaeger
来使用 OpenTracing 和 Jaeger 客户端来获取 trace 数据。
对 type: jaeger
tracing 的支持已被弃用。Jaeger 客户端现已停用,OpenTracing 项目存档。因此,我们不能保证其对将来的 Kafka 版本的支持。如果可能,我们将保持对 type: jaeger
tracing 的支持,直到 2023 年 6 月为止。请尽快迁移到 OpenTelemetry。
21.1. 追踪选项
在 Jaeger 追踪系统中使用 OpenTelemetry 或 OpenTracing (已弃用)。
OpenTelemetry 和 OpenTracing 提供独立于追踪或监控系统的 API 规格。
您可以使用 API 检测应用程序代码以进行追踪。
- 检测的应用程序会为跨分布式系统的单个请求生成 trace。
- trace 由定义特定工作单元的 span 组成。
Jaeger 是基于微服务的分布式系统的追踪系统。
- Jaeger 实现追踪 API,并为工具提供客户端库。
- Jaeger 用户界面允许您查询、过滤和分析 trace 数据。
Jaeger 用户界面显示一个简单的查询
21.2. 用于追踪的环境变量
当您为 Kafka 组件启用追踪或为 Kafka 客户端初始化 tracer 时,请使用环境变量。
追踪环境变量可能会改变。有关最新信息,请参阅 OpenTelemetry 文档 和 OpenTracing 文档。
下表描述了设置 tracer 的关键环境变量。
属性 | 必需 | Description |
---|---|---|
| 是 | OpenTelemetry 的 Jaeger tracing 服务的名称。 |
| 是 | 用于追踪的导出器。 |
| 是 |
用于追踪的导出器。默认设置为 |
属性 | 必需 | Description |
---|---|---|
| 是 | Jaeger tracer 服务的名称。 |
| 否 |
通过用户数据报协议(UDP)与 |
| 否 |
用于通过 UDP 与 |
21.3. 设置分布式追踪
通过在自定义资源中指定追踪类型,在 Kafka 组件中启用分布式追踪。在 Kafka 客户端中检测追踪程序,以便端到端跟踪消息。
要设置分布式追踪,请按照以下步骤执行:
- 为 MirrorMaker、Kafka Connect 和 Kafka Bridge 启用追踪
为客户端设置追踪:
使用 tracers 检测客户端:
21.3.1. 先决条件
在设置分布式追踪前,请确保将 Jaeger 后端组件部署到 OpenShift 集群中。我们建议使用 Jaeger operator 在 OpenShift 集群上部署 Jaeger。
有关部署说明,请参阅 Jaeger 文档。
为 AMQ Streams 以外的应用程序和系统设置追踪不在此内容范围内。
21.3.2. 在 MirrorMaker、Kafka Connect 和 Kafka Bridge 资源中启用追踪
MirrorMaker、M MirrorMaker 2、Kafka Connect 和 AMQ Streams Kafka Bridge 支持分布式追踪。配置组件的自定义资源,以指定并启用 tracer 服务。
在资源中启用追踪会触发以下事件:
- 拦截器类在组件的集成消费者和制作者中更新。
- 对于 MirrorMaker、M MirrorMaker 2 和 Kafka Connect,追踪代理根据资源中定义的追踪配置初始化 tracer。
- 对于 Kafka Bridge,基于资源中定义的追踪配置的 tracer 由 Kafka Bridge 本身初始化。
您可以启用使用 OpenTelemetry 或 OpenTracing 的追踪。
MirrorMaker 和 MirrorMaker 2 中的追踪
对于 MirrorMaker 和 MirrorMaker 2,消息从源集群追踪到目标集群。跟踪数据记录消息输入和离开 MirrorMaker 或 MirrorMaker 2 组件。
Kafka Connect 中的追踪
对于 Kafka Connect,只有 Kafka Connect 生成和使用的消息才会被跟踪。要跟踪 Kafka Connect 和外部系统之间发送的消息,您必须在连接器中为这些系统配置追踪。
Kafka Bridge 中的追踪
对于 Kafka Bridge,由 Kafka Bridge 生成和使用的消息会被跟踪。也可以跟踪来自客户端应用程序的传入 HTTP 请求,以通过 Kafka Bridge 发送和接收信息。要获得端到端追踪,您必须在 HTTP 客户端中配置追踪。
流程
为每个 KafkaMirrorMaker
、KafkaMirrorMaker2、
KafkaConnect
和 KafkaBridge
资源执行这些步骤。
在
spec.template
属性中,配置 tracer 服务。- 使用追踪环境变量作为模板配置属性。
-
对于 OpenTelemetry,将
spec.tracing.type
属性设置为opentelemetry
。 -
对于 OpenTracing,将
spec.tracing.type
属性设置为jaeger
。
使用 OpenTelemetry 的 Kafka Connect 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster spec: #... template: connectContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry #...
使用 OpenTelemetry 的 MirrorMaker 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker metadata: name: my-mirror-maker spec: #... template: mirrorMakerContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry #...
使用 OpenTelemetry 的 MirrorMaker 2 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mm2-cluster spec: #... template: connectContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry #...
使用 OpenTelemetry 的 Kafka Bridge 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: #... template: bridgeContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otlp-host:4317" tracing: type: opentelemetry #...
使用 OpenTracing 的 Kafka Connect 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster spec: #... template: connectContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...
使用 OpenTracing 的 MirrorMaker 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker metadata: name: my-mirror-maker spec: #... template: mirrorMakerContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...
使用 OpenTracing 的 MirrorMaker 2 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mm2-cluster spec: #... template: connectContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...
使用 OpenTracing 的 Kafka Bridge 的追踪配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: #... template: bridgeContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...
创建或更新资源:
oc apply -f <resource_configuration_file>
21.3.3. 为 Kafka 客户端初始化追踪
初始化 tracer,然后检测您的客户端应用程序以进行分布式追踪。您可以检测 Kafka producer 和使用者客户端,以及 Kafka Streams API 应用程序。您可以为 OpenTracing 或 OpenTelemetry 初始化 tracer。
使用一组 追踪环境变量 配置和初始化 tracer。
流程
在每个客户端应用程序中,为 tracer 添加依赖项:
将 Maven 依赖项添加到客户端应用程序的
pom.xml
文件中:OpenTelemetry 的依赖项
<dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId> <version>1.19.0.redhat-00002</version> </dependency> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-kafka-clients-{OpenTelemetryKafkaClient}</artifactId> <version>1.19.0.redhat-00002</version> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-otlp</artifactId> <version>1.19.0.redhat-00002</version> </dependency>
OpenTracing 的依赖项
<dependency> <groupId>io.jaegertracing</groupId> <artifactId>jaeger-client</artifactId> <version>1.8.1.redhat-00002</version> </dependency> <dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-kafka-client</artifactId> <version>0.1.15.redhat-00006</version> </dependency>
- 使用追踪环境变量定义 tracer 的配置。
创建一个 tracer,它使用环境变量初始化:
为 OpenTelemetry 创建 tracer
OpenTelemetry ot = GlobalOpenTelemetry.get();
为 OpenTracing 创建 tracer
Tracer tracer = Configuration.fromEnv().getTracer();
将 tracer 注册为全局 tracer:
GlobalTracer.register(tracer);
检测您的客户端:
21.3.4. 检测用于追踪的生产者和消费者
检测应用程序代码,以在 Kafka 生成者和消费者中启用追踪。使用 decorator 模式或拦截器检测您的 Java 生成者和消费者应用程序代码以进行追踪。然后,您可以在生成或从主题检索信息时记录 trace。
OpenTelemetry 和 OpenTracing 检测项目提供支持生产者和消费者的类。
- decorator 检测
- 对于 decorator 检测,请创建一个修改后的制作者或消费者实例以进行追踪。decorator 检测在 OpenTelemetry 和 OpenTracing 中有所不同。
- 拦截器检测
- 对于拦截器工具,请在消费者或制作者配置中添加追踪功能。OpenTelemetry 和 OpenTracing 的拦截器工具是相同的。
先决条件
您已为 客户端初始化了追踪。
您可以通过在项目中添加追踪 JAR 作为依赖项来启用生成者和消费者应用中的检测。
流程
在每个制作者和消费者应用的应用程序代码中执行这些步骤。使用 decorator 模式或拦截器(拦截器)检测您的客户端应用程序代码。
要使用 decorator 模式,请创建一个修改后的制作者或消费者实例来发送或接收消息。
您传递了原始
KafkaProducer
或KafkaConsumer
类。OpenTelemetry 的 decorator 检测示例
// Producer instance Producer < String, String > op = new KafkaProducer < > ( configs, new StringSerializer(), new StringSerializer() ); Producer < String, String > producer = tracing.wrap(op); KafkaTracing tracing = KafkaTracing.create(GlobalOpenTelemetry.get()); producer.send(...); //consumer instance Consumer<String, String> oc = new KafkaConsumer<>( configs, new StringDeserializer(), new StringDeserializer() ); Consumer<String, String> consumer = tracing.wrap(oc); consumer.subscribe(Collections.singleton("mytopic")); ConsumerRecords<Integer, String> records = consumer.poll(1000); ConsumerRecord<Integer, String> record = ... SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);
OpenTracing 的 decorator 检测示例
//producer instance KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps); TracingKafkaProducer<Integer, String> tracingProducer = new TracingKafkaProducer<>(producer, tracer); TracingKafkaProducer.send(...) //consumer instance KafkaConsumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps); TracingKafkaConsumer<Integer, String> tracingConsumer = new TracingKafkaConsumer<>(consumer, tracer); tracingConsumer.subscribe(Collections.singletonList("mytopic")); ConsumerRecords<Integer, String> records = tracingConsumer.poll(1000); ConsumerRecord<Integer, String> record = ... SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);
要使用拦截器,请在制作者或消费者配置中设置拦截器类。
您以通常的方式使用
KafkaProducer
和KafkaConsumer
类。TracingProducerInterceptor
和TracingConsumerInterceptor
interceptor 类负责追踪功能。使用拦截器的制作者配置示例
senderProps.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName()); KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps); producer.send(...);
使用拦截器的消费者配置示例
consumerProps.put(ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName()); KafkaConsumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps); consumer.subscribe(Collections.singletonList("messages")); ConsumerRecords<Integer, String> records = consumer.poll(1000); ConsumerRecord<Integer, String> record = ... SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);
21.3.5. 检测用于追踪的 Kafka Streams 应用程序
检测应用程序代码,以在 Kafka Streams API 应用程序中启用追踪。使用 decorator 模式或拦截器检测 Kafka Streams API 应用程序以进行追踪。然后,您可以在生成或从主题检索信息时记录 trace。
- decorator 检测
-
对于 decorator 检测,请创建一个修改后的 Kafka Streams 实例以进行追踪。OpenTracing 检测项目提供了一个
TracingKafkaClientSupplier
类,它支持 Kafka Streams 的检测。您可以创建一个TracingKafkaClientSupplier
供应商接口的嵌套实例,它为 Kafka Streams 提供追踪工具。对于 OpenTelemetry,该过程相同,但您需要创建自定义TracingKafkaClientSupplier
类来提供支持。 - 拦截器检测
- 对于拦截器工具,在 Kafka Streams producer 和 consumer 配置中添加追踪功能。
先决条件
您已为 客户端初始化了追踪。
您可以通过在项目中添加追踪 JAR 作为依赖项来启用 Kafka Streams 应用程序中的检测。
-
要使用 OpenTelemetry 检测 Kafka Streams,您需要编写自定义
TracingKafkaClientSupplier
。 自定义
TracingKafkaClientSupplier
可以扩展 Kafka 的DefaultKafkaClientSupplier
,覆盖生成者和消费者创建方法,将实例嵌套与遥测相关的代码。自定义
TracingKafkaClientSupplier
示例private class TracingKafkaClientSupplier extends DefaultKafkaClientSupplier { @Override public Producer<byte[], byte[]> getProducer(Map<String, Object> config) { KafkaTelemetry telemetry = KafkaTelemetry.create(GlobalOpenTelemetry.get()); return telemetry.wrap(super.getProducer(config)); } @Override public Consumer<byte[], byte[]> getConsumer(Map<String, Object> config) { KafkaTelemetry telemetry = KafkaTelemetry.create(GlobalOpenTelemetry.get()); return telemetry.wrap(super.getConsumer(config)); } @Override public Consumer<byte[], byte[]> getRestoreConsumer(Map<String, Object> config) { return this.getConsumer(config); } @Override public Consumer<byte[], byte[]> getGlobalConsumer(Map<String, Object> config) { return this.getConsumer(config); } }
流程
为每个 Kafka Streams API 应用程序执行这些步骤。
要使用 decorator 模式,请创建一个
TracingKafkaClientSupplier
供应商接口的实例,然后向KafkaStreams
提供供应商接口。decorator 检测示例
KafkaClientSupplier supplier = new TracingKafkaClientSupplier(tracer); KafkaStreams streams = new KafkaStreams(builder.build(), new StreamsConfig(config), supplier); streams.start();
要使用拦截器,请在 Kafka Streams producer 和消费者配置中设置拦截器类。
TracingProducerInterceptor
和TracingConsumerInterceptor
interceptor 类负责追踪功能。使用拦截器的制作者和消费者配置示例
props.put(StreamsConfig.PRODUCER_PREFIX + ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName()); props.put(StreamsConfig.CONSUMER_PREFIX + ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName());
21.3.6. 引入了不同的 OpenTelemetry 追踪系统
您可以指定 OpenTelemetry 支持的其他追踪系统,而不是默认的 OTLP 系统。您可以通过在 AMQ Streams 提供的 Kafka 镜像中添加所需的工件来实现此目的。还必须设置任何所需的实现特定环境变量。然后,您可以使用 OTEL_TRACES_EXPORTER
环境变量启用新的追踪实施。
此流程演示了如何实施 Zipkin tracing。
流程
将追踪工件添加到 AMQ Streams Kafka 镜像的
/opt/kafka/libs/
目录中。您可以使用 Red Hat Ecosystem Catalog 上的 Kafka 容器镜像作为基础镜像来创建新的自定义镜像。
Zipkin 的 OpenTelemetry 工件
io.opentelemetry:opentelemetry-exporter-zipkin
为新的追踪实施设置追踪导出器和端点。
Zikpin tracer 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mm2-cluster spec: #... template: connectContainer: env: - name: OTEL_SERVICE_NAME value: my-zipkin-service - name: OTEL_EXPORTER_ZIPKIN_ENDPOINT value: http://zipkin-exporter-host-name:9411/api/v2/spans 1 - name: OTEL_TRACES_EXPORTER value: zipkin 2 tracing: type: opentelemetry #...
21.3.7. 自定义范围名称
追踪 span 是 Jaeger 中的逻辑工作单元,包括操作名称、开始时间和持续时间。span 具有内置名称,但您可以在使用的 Kafka 客户端检测中指定自定义范围名称。
指定自定义范围名称是可选的,只有在生成者和消费者客户端检测或 Kafka Streams 检测中使用 decorator 模式时才适用。
21.3.7.1. 为 OpenTelemetry 指定范围名称
无法使用 OpenTelemetry 直接指定自定义范围名称。相反,您可以通过向客户端应用程序添加代码来提取额外的标签和属性来检索范围名称。
提取属性的代码示例
//Defines attribute extraction for a producer private static class ProducerAttribExtractor implements AttributesExtractor < ProducerRecord < ? , ? > , Void > { @Override public void onStart(AttributesBuilder attributes, ProducerRecord < ? , ? > producerRecord) { set(attributes, AttributeKey.stringKey("prod_start"), "prod1"); } @Override public void onEnd(AttributesBuilder attributes, ProducerRecord < ? , ? > producerRecord, @Nullable Void unused, @Nullable Throwable error) { set(attributes, AttributeKey.stringKey("prod_end"), "prod2"); } } //Defines attribute extraction for a consumer private static class ConsumerAttribExtractor implements AttributesExtractor < ConsumerRecord < ? , ? > , Void > { @Override public void onStart(AttributesBuilder attributes, ConsumerRecord < ? , ? > producerRecord) { set(attributes, AttributeKey.stringKey("con_start"), "con1"); } @Override public void onEnd(AttributesBuilder attributes, ConsumerRecord < ? , ? > producerRecord, @Nullable Void unused, @Nullable Throwable error) { set(attributes, AttributeKey.stringKey("con_end"), "con2"); } } //Extracts the attributes public static void main(String[] args) throws Exception { Map < String, Object > configs = new HashMap < > (Collections.singletonMap(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092")); System.setProperty("otel.traces.exporter", "jaeger"); System.setProperty("otel.service.name", "myapp1"); KafkaTracing tracing = KafkaTracing.newBuilder(GlobalOpenTelemetry.get()) .addProducerAttributesExtractors(new ProducerAttribExtractor()) .addConsumerAttributesExtractors(new ConsumerAttribExtractor()) .build();
21.3.7.2. 为 OpenTracing 指定范围名称
要为 OpenTracing 指定自定义范围名称,请在检测生产者和消费者时将 BiFunction
对象作为参数传递。
有关内置名称和指定自定义范围名称以检测客户端应用代码的更多信息,请参阅 OpenTracing Apache Kafka 客户端检测。
第 22 章 检索诊断和故障排除数据
report.sh
诊断工具是由红帽提供的脚本,用于收集 OpenShift 上 AMQ Streams 部署故障排除的基本数据。它收集相关的日志、配置文件和其他诊断数据,以帮助识别和解决问题。运行脚本时,您可以指定额外的参数来检索特定数据。
先决条件
- Bash 4 或更新版本
-
OpenShift
oc
命令行工具已安装并配置为连接到正在运行的集群。
这会为 oc
命令行工具建立必要的身份验证,以与集群交互并检索所需的诊断数据。
流程
下载并提取工具。
诊断工具可从 AMQ Streams 软件下载页面 获得。
在提取工具的目录中打开一个终端并运行报告工具:
./report.sh --namespace=<cluster_namespace> --cluster=<cluster_name> --out-dir=<local_output_directory>
将
<cluster_namespace
> 替换为 AMQ Streams 部署的实际 OpenShift 命名空间,<cluster_name
> 替换为 Kafka 集群的名称,<local_output_directory
> 替换为您要保存生成的报告的本地目录的路径。如果您没有指定目录,则会创建一个临时目录。根据需要包括其他可选报告选项:
- --bridge=<string>
- 指定 Kafka Bridge 集群的名称,以获取其 pod 和日志上的数据。
- --connect=<string>
- 指定 Kafka Connect 集群的名称,以获取其 pod 和日志上的数据。
- --mm2=<string>
- 指定 Mirror Maker 2 集群名称,以获取其 pod 和日志的数据。
- --secrets=(off|hidden|all)
指定 secret 详细程度。默认为
hidden
。可用的选项如下:-
所有
: 报告 Secret 密钥和数据值。 -
hidden
:仅报告带有密钥的 Secret。数据值(如密码)会被删除。 -
off
:不会报告 Secret。
-
使用数据收集选项的请求示例
./report.sh --namespace=my-amq-streams-namespace --cluster=my-kafka-cluster --bridge=my-bridge-component --secrets=all --out-dir=~/reports
注意如果需要,使用
chmod
命令将脚本的执行权限分配给您的用户。例如:chmod +x report.sh
.
执行完脚本后,输出目录包含为 AMQ Streams 部署的每个组件收集的日志、配置和其他诊断数据的文件和目录。
报告诊断工具收集的数据
如果存在,则返回以下组件中的数据:
Cluster Operator
- 部署 YAML 和日志
- 所有相关 pod 及其日志
- 与集群操作器相关的资源的 YAML 文件(ClusterRoles、ClusterRoleBindings)
drain Cleaner (如果存在)
- 部署 YAML 和日志
- Pod 日志
自定义资源
- 自定义资源定义(CRD) YAML
- 所有相关自定义资源(CR)的 YAML 文件
事件
- 与指定命名空间相关的事件
配置
-
Kafka pod 日志和配置文件(
strimzi.properties
) -
ZooKeeper pod 日志和配置文件(
zookeeper.properties
) - Entity Operator (Topic Operator, User Operator) pod 日志
- Cruise Control pod 日志
- Kafka Exporter pod 日志
- 如果在选项中指定,网桥 pod 日志
- 如果在选项中指定,请连接 pod 日志
- 如果在选项中指定,MirrorMaker 2 pod 日志
secret (如果在选项中请求)
- 与指定 Kafka 集群相关的所有 secret 的 YAML 文件
第 23 章 升级 AMQ Streams
将 AMQ Streams 安装升级到 2.5 版本,并从新功能、性能改进和增强的安全选项中受益。在升级过程中,Kafka 也更新至最新支持的版本,为 AMQ Streams 部署引入了额外的功能和程序错误修复。
如果您在新版本时遇到问题,AMQ Streams 可以 降级到 之前的版本。
发布的 AMQ Streams 版本可在 AMQ Streams 软件下载页面 中找到。
在不停机的情况下升级
对于配置了高可用性(至少 3 个和平均分布式分区)的主题,升级过程不应给消费者和生产者造成任何停机时间。
升级会触发滚动更新,其中代理会在进程的不同阶段重启一个。在这个时间内,整个集群可用性会临时减少,这可能会在代理失败时增加消息丢失的风险。
23.1. AMQ Streams 升级路径
AMQ Streams 提供了两个升级路径。
- 增量升级
- 增量升级涉及将 AMQ Streams 从以前的次版本升级到 2.5 版本。
- 多版本升级
- 多版本升级涉及将旧版本的 AMQ Streams 升级到单个升级中的 2.5 版本,跳过一个或多个中间版本。例如,可以直接从 AMQ Streams 2.3 升级到 AMQ Streams 2.5。
23.1.1. 升级时支持 Kafka 版本
升级 AMQ Streams 时,务必要确保与所使用的 Kafka 版本兼容非常重要。
即使支持的 Kafka 版本在旧版本和新版本之间有所不同,也可以进行多版本升级。但是,如果您试图升级到不支持当前 Kafka 版本的新 AMQ Streams 版本,则会出现 没有支持 Kafka 版本的错误。在这种情况下,您必须把 Kafka 自定义资源中的 spec.kafka.version
更改为新的 AMQ Streams 版本,将 Kafka
Streams 升级的一部分升级为 AMQ Streams 升级的一部分。
- Kafka 3.5.0 支持在生产环境中使用。
- Kafka 3.4.0 仅支持升级到 AMQ Streams 2.5。
23.1.2. 从 1.7 更早的 AMQ Streams 版本升级
如果您要从 1.7 版本之前的版本升级到 AMQ Streams 的最新版本,请执行以下操作:
- 按照标准序列 将 AMQ Streams 升级到 1.7 版本。
-
使用 AMQ Streams 提供的 API 转换工具 将 AMQ Streams 自定义资源转换为
v1beta2
。 执行以下操作之一:
-
升级到 AMQ Streams 1.8 (默认禁用
ControlPlaneListener
功能门)。 -
升级到 AMQ Streams 2.0 或 2.2 (其中默认启用
ControlPlaneListener
功能门),并禁用了ControlPlaneListener
功能门。
-
升级到 AMQ Streams 1.8 (默认禁用
-
启用
ControlPlaneListener
功能门。 - 根据 标准序列 升级到 AMQ Streams 2.5。
AMQ Streams 自定义资源使用 1.7 版中的 v1beta2
API 版本启动。在升级到 AMQ Streams 1.8 或更高版本 前,必须转换 CRD 和自定义资源。有关使用 API 转换工具的详情,请参考 AMQ Streams 1.7 升级文档。
作为首次升级到 1.7 版本的替代选择,您可以从 1.7 安装自定义资源,然后转换资源。
现在,AMQ Streams 中永久启用了 ControlPlaneListener
功能。您必须升级到禁用的 AMQ Streams 版本,然后使用 Cluster Operator 配置中的 STRIMZI_FEATURE_GATES
环境变量启用它。
禁用 ControlPlaneListener
功能门
env: - name: STRIMZI_FEATURE_GATES value: -ControlPlaneListener
启用 ControlPlaneListener
功能门
env: - name: STRIMZI_FEATURE_GATES value: +ControlPlaneListener
23.2. 所需的升级序列
要在没有停机的情况下升级代理和客户端,您必须 按照以下顺序完成 AMQ Streams 升级步骤:
确保您的 OpenShift 集群版本被支持。
OpenShift 4.10 支持 AMQ Streams 2.5 到 4.14。
您可以以最少的停机时间来升级 OpenShift。
- 升级 Cluster Operator。
- 将所有 Kafka 代理和客户端应用程序 升级到最新的支持的 Kafka 版本。
23.3. 在短短停机时间的情况下升级 OpenShift
如果要升级 OpenShift,请参阅 OpenShift 升级路径文档,以检查升级路径以及正确升级节点的步骤。在升级 OpenShift 前 ,请检查您的 AMQ Streams 版本支持的版本。
在进行升级时,您要保持 Kafka 集群可用。
您可以使用以下策略之一:
- 配置 pod 中断预算
使用以下方法之一滚动 pod:
- 使用 AMQ Streams Drain Cleaner
- 通过将注解应用到 pod 手动
当使用任一方法滚动 pod 时,您必须使用 maxUnavailable
属性设置 pod 中断预算为零。
StrimziPodSet
自定义资源使用无法使用 maxUnavailable
值的自定义控制器来管理 Kafka 和 ZooKeeper pod。相反,maxUnavailable
值转换为 minAvailable
值。如果有三个代理 pod,并且 maxUnavailable
属性设置为 0 (
零),min
Available 设置为 3
,则需要所有三个代理 pod 都可用,并允许零个 pod 不可用。
要使 Kafka 保持正常运行,还必须复制主题才能进行高可用性。这要求主题配置指定至少 3 个复制因素,最小同步副本的数量为复制因素的数量减 1。
为高可用性复制 Kafka 主题
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic labels: strimzi.io/cluster: my-cluster spec: partitions: 1 replicas: 3 config: # ... min.insync.replicas: 2 # ...
在高可用性环境中,Cluster Operator 在升级过程中为主题维护最少的同步副本,从而无需停机。
23.3.1. 使用 AMQ Streams Drain Cleaner 的滚动 pod
您可以使用 AMQ Streams Drain Cleaner 来在升级过程中驱除节点。AMQ Streams Drain Cleaner 使用滚动更新 pod 注解来注解 pod。这会通知 Cluster Operator 执行被驱除的 pod 的滚动更新。
pod 中断预算只允许指定数量的 pod 在给定时间不可用。在计划维护 Kafka 代理 pod 期间,pod 中断预算可确保 Kafka 继续在高可用性环境中运行。
您可以使用 Kafka 组件 的模板
自定义来指定 pod 中断预算。默认情况下,pod 中断预算只允许一个 pod 在给定时间不可用。
要使用 Drain Cleaner 来滚动 pod,您需要将 maxUnavailable
设置为 0 (
零)。将 pod 中断预算减少为零可防止意外中断,因此必须手动驱除 pod。
指定 pod 中断预算
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster namespace: myproject spec: kafka: # ... template: podDisruptionBudget: maxUnavailable: 0 # ...
23.3.2. 手动滚动 pod,同时保持可用的主题
在升级过程中,您可以通过 Cluster Operator 触发 pod 的手动更新。使用 Pod
资源,滚动更新会使用新 pod 重启资源的 pod。与使用 AMQ Streams Drain Cleaner 一样,您需要为 pod 中断预算将 maxUnavailable
值设置为零。
您需要观察需要排空的 pod。然后,您添加一个 pod 注解来进行更新。
在这里,注解会更新 Kafka 代理。
在 Kafka 代理 pod 上执行手动滚动更新
oc annotate pod <cluster_name>-kafka-<index> strimzi.io/manual-rolling-update=true
将 & lt;cluster_name > 替换为集群的名称。Kafka 代理 pod 被命名为 & lt;cluster-name> -kafka-< index>,其中 <index> 以零开始,结束于副本总数。例如,my-cluster-kafka-0
。
23.4. 升级 Cluster Operator
使用同样的方法升级 Cluster Operator,与初始部署方法相同。
- 使用安装文件
- 如果使用安装 YAML 文件部署 Cluster Operator,请通过修改 Operator 安装文件来执行升级,如 使用安装文件升级 Cluster Operator 所述。
- 使用 OperatorHub
如果您从 OperatorHub 部署 AMQ Streams,请使用 Operator Lifecycle Manager (OLM)将 AMQ Streams Operator 的更新频道改为新的 AMQ Streams 版本。
根据您选择的升级策略,更新频道将启动以下类型的升级:
- 启动自动升级
- 安装开始前需要批准的手动升级
注意如果您订阅了 stable 频道,可以在不更改频道的情况下获得自动更新。但是,不建议启用自动更新,因为可能缺少任何预安装升级步骤。仅在特定于版本的频道中使用自动升级。
有关使用 OperatorHub 升级 Operator 的更多信息,请参阅 升级已安装的 Operator (OpenShift 文档)。
23.4.1. 升级 Cluster Operator 会返回 Kafka 版本错误
如果您将 Cluster Operator 升级到不支持当前使用的 Kafka 版本的版本,您会收到 不受支持的 Kafka 版本 错误。这个错误适用于所有安装方法,意味着您必须将 Kafka 升级到受支持的 Kafka 版本。将 Kafka
资源中的 spec.kafka.version
更改为支持的版本。
您可以使用 oc
检查错误信息,如包括在 Kafka
资源的 status
中的信息。
检查 Kafka 状态中的错误
oc get kafka <kafka_cluster_name> -n <namespace> -o jsonpath='{.status.conditions}'
将 <kafka_cluster_name> 替换为 Kafka 集群的名称,将 <namespace> 替换为运行 pod 的 OpenShift 命名空间。
23.4.2. 使用 OperatorHub 从 AMQ Streams 1.7 或更早版本升级
使用 OperatorHub 从 AMQ Streams 1.7 或更早版本升级时需要的操作
在将 AMQ Streams Operator 升级到 2.5 之前,您需要进行以下更改:
-
将自定义资源和 CRD 转换为
v1beta2
-
升级到禁用
ControlPlaneListener
功能门的 AMQ Streams 版本
这些要求在 第 23.1.2 节 “从 1.7 更早的 AMQ Streams 版本升级” 中进行了描述。
如果您要从 AMQ Streams 1.7 或更早版本升级,请执行以下操作:
- 升级到 AMQ Streams 1.7。
- 从 AMQ Streams 软件下载页下载 AMQ Streams 1.8 提供的 Red Hat AMQ Streams API Conversion Tool。
将自定义资源和 CRD 转换为
v1beta2
。如需更多信息,请参阅 AMQ Streams 1.7 升级文档。
- 在 OperatorHub 中,删除 AMQ Streams Operator 的版本 1.7。
如果也存在,删除 AMQ Streams Operator 的版本 2.5。
如果不存在,请进入下一步。
如果 AMQ Streams Operator 的批准策略被设置为 Automatic,则集群中可能已存在 operator 版本 2.5。如果您在发行版本 前没有 将自定义资源和 CRD 转换为
v1beta2
API 版本,Operator 管理的自定义资源和 CRD 将使用旧的 API 版本。因此,2.5 Operator 处于 Pending 状态。在这种情况下,您需要删除 AMQ Streams Operator 版本 2.5 和版本 1.7。如果删除这两个 Operator,则协调将暂停,直到安装了新的 Operator 版本。立即按照以下步骤操作,以便对自定义资源的任何更改都不会延迟。
在 OperatorHub 中,执行以下操作之一:
-
升级到 AMQ Streams Operator 的 1.8 版本(默认禁用
ControlPlaneListener
功能门)。 -
升级至 AMQ Streams Operator 的 2.0 或 2.2 版本(其中禁用了
ControlPlaneListener
功能门),并禁用了ControlPlaneListener
功能门。
-
升级到 AMQ Streams Operator 的 1.8 版本(默认禁用
立即升级到 AMQ Streams Operator 版本 2.5。
安装的 2.5 operator 开始监视集群并执行滚动更新。您可能会注意到在此过程中,集群性能可能会临时降低。
23.4.3. 使用安装文件升级 Cluster Operator
此流程描述了如何升级 Cluster Operator 部署以使用 AMQ Streams 2.5。
如果您使用安装 YAML 文件部署 Cluster Operator,请按照以下步骤操作。
由 Cluster Operator 管理的 Kafka 集群的可用性不受升级操作的影响。
有关如何升级到该版本的信息,请参阅支持 AMQ Streams 特定版本的文档。
先决条件
- 提供了现有 Cluster Operator 部署。
- 您已下载了 AMQ Streams 2.5 的发行工件。
流程
-
记录在现有 Cluster Operator 资源(
/install/cluster-operator
目录中)所做的任何配置更改。任何更改都会被 Cluster Operator 的新版本 覆盖。 - 更新自定义资源,以反映 AMQ Streams 版本 2.5 支持的配置选项。
更新 Cluster Operator。
根据运行 Cluster Operator 的命名空间修改新 Cluster Operator 版本的安装文件。
在 Linux 中,使用:
sed -i 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
在 MacOS 中,使用:
sed -i '' 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
-
如果您修改了现有 Cluster Operator
Deployment
中的一个或多个环境变量,请编辑install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
文件以使用这些环境变量。
当您有更新的配置时,将其与安装资源的其余部分一起部署:
oc replace -f install/cluster-operator
等待滚动更新完成。
如果新的 Operator 版本不再支持您要从升级 Kafka 版本,Cluster Operator 会返回错误消息来声明版本不被支持。否则,不会返回任何错误消息。
如果返回错误消息,升级到新 Cluster Operator 版本支持的 Kafka 版本:
-
编辑
Kafka
自定义资源。 -
将
spec.kafka.version
属性改为受支持的 Kafka 版本。
-
编辑
- 如果没有 返回错误消息,请进入下一步。您将稍后升级 Kafka 版本。
获取 Kafka pod 的镜像以确保升级成功:
oc get pods my-cluster-kafka-0 -o jsonpath='{.spec.containers[0].image}'
镜像标签显示新的 Operator 版本。例如:
registry.redhat.io/amq-streams/strimzi-kafka-35-rhel8:2.5.1
Cluster Operator 升级到 2.5 版本,但其管理集群中运行的 Kafka 版本不会改变。
在 Cluster Operator 升级后,您必须执行 Kafka 升级。
23.5. 升级 Kafka
将 Cluster Operator 升级到 2.5 后,下一步是将所有 Kafka 代理升级到最新支持的 Kafka 版本。
Kafka 升级由 Cluster Operator 通过 Kafka 代理的滚动更新来执行。
Cluster Operator 根据 Kafka 集群配置启动滚动更新。
如果 Kafka.spec.kafka.config 包含… | Cluster Operator 启动… |
---|---|
|
单个滚动更新。更新后,必须手动更新 |
| 两个滚动更新。 |
没有配置 | 两个滚动更新。 |
从 Kafka 3.0.0 开始,当将 inter.broker.protocol.version
设置为 3.0
或更高版本时,log.message.format.version
选项将被忽略,不需要设置。代理的 log.message.format.version
属性和用于主题的 message.format.version
属性已弃用,并将在以后的 Kafka 发行版本中删除。
作为 Kafka 升级的一部分,Cluster Operator 为 ZooKeeper 启动滚动更新。
- 即使 ZooKeeper 版本没有改变,也会进行单个滚动更新。
- 如果新版本的 Kafka 需要新的 ZooKeeper 版本,则会进行额外的滚动更新。
23.5.1. Kafka 版本
Kafka 的日志消息格式版本和 inter-broker 协议版本分别指定日志格式版本,日志格式版本附加到消息以及集群中使用的 Kafka 协议的版本。为确保使用了正确的版本,升级过程涉及对现有 Kafka 代理和客户端应用程序(使用者和生产者)进行配置更改。
下表显示了 Kafka 版本之间的区别:
AMQ Streams 版本 | Kafka 版本 | 间的代理协议版本 | 日志消息格式版本 | zookeeper 版本 |
---|---|---|---|---|
2.5 | 3.5.0 | 3.5 | 3.5 | 3.6.4 |
2.4 | 3.4.0 | 3.4 | 3.4 | 3.6.3 |
AMQ Streams 2.5 使用 Kafka 3.5.0,但 Kafka 3.4.0 也支持进行升级。
间的代理协议版本
在 Kafka 中,用于内部代理通信的网络协议称为 inter-broker 协议。Kafka 的每个版本都有了一个内部代理协议的兼容版本。协议的次要版本通常会增加以匹配 Kafka 的次版本,如上表所示。
在 Kafka
资源中设置集群范围的协议版本。要更改它,您可以编辑 Kafka.spec.kafka.config
中的 inter.broker.protocol.version
属性。
日志消息格式版本
当制作者向 Kafka 代理发送消息时,消息使用特定格式进行编码。格式可以在 Kafka 发行版本间有所变化,因此消息指定了它们编码的消息格式版本。
用于设置特定消息格式版本的属性如下:
-
主题的
message.format.version
属性 -
Kafka 代理的
log.message.format.version
属性
从 Kafka 3.0.0,消息格式版本值被假定为与 inter.broker.protocol.version
匹配,且不需要设置。这些值反映了使用的 Kafka 版本。
当升级到 Kafka 3.0.0 或更高版本时,您可以在更新 inter.broker.protocol.version
时删除这些设置。否则,请基于您要升级到的 Kafka 版本设置消息格式版本。
由在 Kafka 代理中设置的 log.message.format.version
定义的 message.format.version
的默认值。您可以通过修改其主题配置来手动设置主题的 message.format.version
。
23.5.2. 升级客户端的策略
升级 Kafka 客户端可确保它们从新版本的 Kafka 中引入的功能、修复和改进中受益。升级的客户端维护与其他升级的 Kafka 组件的兼容性。客户端的性能和稳定性也可能得到改进。
考虑升级 Kafka 客户端和服务器的最佳方法,以确保平稳过渡。所选升级策略取决于您是否先升级代理或客户端。从 Kafka 3.0 开始,您可以独立和顺序升级代理和客户端。决定升级客户端或代理首先取决于几个因素,如需要升级的应用程序数量以及可容忍的停机时间。
如果您在代理前升级客户端,一些新功能可能无法工作,因为代理尚不支持它们。但是,代理可以处理使用不同版本运行的制作者和消费者,并支持不同的日志消息版本。
当使用 Kafka 3.0 旧的 Kafka 版本时升级客户端
在 Kafka 3.0 之前,您可以使用 log.message.format.version
属性(或主题级别的 message.format.version
属性)为代理配置特定的消息格式。这允许代理支持使用过时消息格式的旧的 Kafka 客户端。否则,代理需要从旧的客户端转换信息,这会显著提高性能成本。
自 0.11 版以来,Apache Kafka Java 客户端支持最新的消息格式版本。如果所有客户端都使用最新的消息版本,您可以在升级代理时删除 log.message.format.version
或 message.format.version
覆盖。
但是,如果您仍然有使用较旧的消息格式版本的客户端,我们建议首先升级您的客户端。从消费者开始,在升级代理时,在删除 log.message.format.version
或 message.format.version
前升级制作者。这将确保所有客户端都可以支持最新的消息格式版本,并且升级过程可以平稳进行。
您可以使用此指标跟踪 Kafka 客户端名称和版本:
-
kafka.server:type=socket-server-metrics,clientSoftwareName=<name>,clientSoftwareVersion=<version>,listener=<listener>,networkProcessor=<processor>
以下 Kafka 代理指标帮助监控消息 down-conversion 的性能:
-
kafka.network:type=RequestMetrics,name=MessageConversionsTimeMs,request={Produce|Fetch}
提供执行消息转换所需时间的指标。 -
kafka.server:type=BrokerTopicMetrics,name={Produce|Fetch}MessageConversionsPerSec,topic=([-.\w]+)
提供一段时间内转换的消息数量的指标。
23.5.3. Kafka 版本和镜像映射
升级 Kafka 时,请考虑 STRIMZI_KAFKA_IMAGES
环境变量和 Kafka.spec.kafka.version
属性的设置。
-
每个
Kafka
资源都可以使用Kafka.spec.kafka.version
配置。 Cluster Operator 的
STRIMZI_KAFKA_IMAGES
环境变量提供在给定 Kafka 资源中请求该版本时使用的Kafka
版本和镜像之间的映射。-
如果没有配置
Kafka.spec.kafka.image
,则使用给定版本的默认镜像。 -
如果配置了
Kafka.spec.kafka.image
,则默认镜像会被覆盖。
-
如果没有配置
Cluster Operator 无法验证镜像是否实际包含预期版本的 Kafka 代理。请小心,确保给定镜像对应于给定的 Kafka 版本。
23.5.4. 升级 Kafka 代理和客户端应用程序
将 AMQ Streams Kafka 集群升级到最新的支持的 Kafka 版本,以及 代理间的协议版本。
您还应选择升级客户端的策略。在此流程的第 6 步中升级 Kafka 客户端。
先决条件
- Cluster Operator 已启动并在运行。
-
在升级 AMQ Streams Kafka 集群前,请检查
Kafka
资源的Kafka.spec.kafka.config
属性不包含新的 Kafka 版本不支持的配置选项。
流程
更新 Kafka 集群配置:
oc edit kafka <my_cluster>
如果配置,请检查
inter.broker.protocol.version
和log.message.format.version
属性是否已设置为 当前版本。例如,如果从 Kafka 版本 3.4.0 升级到 3.5.0,则当前版本为 3.4 :
kind: Kafka spec: # ... kafka: version: 3.4.0 config: log.message.format.version: "3.4" inter.broker.protocol.version: "3.4" # ...
如果没有配置
log.message.format.version
和inter.broker.protocol.version
,AMQ Streams 会在升级到下一个 Kafka 版本后将这些版本更新至当前的默认值。注意log.message.format.version
和inter.broker.protocol.version
的值必须是字符串,以防止它们被解释为浮点号。更改
Kafka.spec.kafka.version
以指定新的 Kafka 版本;保留log.message.format.version
和inter.broker.protocol.version
,作为 当前 Kafka 版本的默认值。注意更改
kafka.version
可确保集群中的所有代理都会被升级,以使用新的代理二进制文件开始。在此过程中,一些代理会使用旧的二进制文件,而其他代理已升级到新二进制文件。在当前设置中保持不变inter.broker.protocol.version
,可确保代理可以在整个升级过程中继续相互通信。例如,如果从 Kafka 3.4.0 升级到 3.5.0 :
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: # ... kafka: version: 3.5.0 1 config: log.message.format.version: "3.4" 2 inter.broker.protocol.version: "3.4" 3 # ...
警告如果新 Kafka 版本的
inter.broker.protocol.version
发生变化,则无法降级 Kafka。inter-broker 协议版本决定用于代理存储的持久元数据的模式,包括写入__consumer_offsets
的消息。降级的集群不知道消息。如果在 Kafka 自定义资源中定义了 Kafka 集群的镜像,在
Kafka.spec.kafka.image
中,更新image
以指向新的 Kafka 版本的容器镜像。请参阅 Kafka 版本和镜像映射
保存并退出编辑器,然后等待滚动更新完成。
通过观察 pod 状态转换来检查滚动更新的进度:
oc get pods my-cluster-kafka-0 -o jsonpath='{.spec.containers[0].image}'
滚动更新可确保每个 pod 都对新版本的 Kafka 使用代理二进制文件。
根据您选择 升级客户端的策略,升级所有客户端应用程序以使用客户端二进制文件的新版本。
如果需要,将 Kafka Connect 和 MirrorMaker 的
version
属性设置为 Kafka 的新版本:-
对于 Kafka Connect,更新
KafkaConnect.spec.version
。 -
对于 MirrorMaker,更新
KafkaMirrorMaker.spec.version
。 -
对于 MirrorMaker 2,更新
KafkaMirrorMaker2.spec.version
。
-
对于 Kafka Connect,更新
如果配置,将 Kafka 资源更新为使用新的
inter.broker.protocol.version
版本。否则,请转到第 9 步。例如,如果升级到 Kafka 3.5.0 :
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: # ... kafka: version: 3.5.0 config: log.message.format.version: "3.4" inter.broker.protocol.version: "3.5" # ...
- 等待 Cluster Operator 更新集群。
如果配置,将 Kafka 资源更新为使用新的
log.message.format.version
版本。否则,请转到第 10 步。例如,如果升级到 Kafka 3.5.0 :
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: # ... kafka: version: 3.5.0 config: log.message.format.version: "3.5" inter.broker.protocol.version: "3.5" # ...
重要从 Kafka 3.0.0 开始,当将
inter.broker.protocol.version
设置为3.0
或更高版本时,log.message.format.version
选项将被忽略,不需要设置。等待 Cluster Operator 更新集群。
- Kafka 集群和客户端现在使用新的 Kafka 版本。
- 代理被配置为使用 Kafka 的新版本间的代理和消息格式版本发送信息。
23.6. 在升级 AMQ Streams 时切换到 FIPS 模式
将 AMQ Streams 升级到在启用了 FIPS 的 OpenShift 集群中以 FIPS 模式运行。在 AMQ Streams 2.4 之前,只能使用 FIPS_MODE
环境变量禁用 FIPS 模式在启用了 FIPS 的 OpenShift 集群上运行。在版本 2.4 中,AMQ Streams 支持 FIPS 模式。如果您在启用了 FIPS 的 OpenShift 集群上运行 AMQ Streams,FIPS_MODE
被设置为 disabled
,您可以按照以下流程启用它。
先决条件
- 启用 FIPS 的 OpenShift 集群
-
将
FIPS_MODE
环境变量设置为disabled
的现有 Cluster Operator 部署
流程
-
将 Cluster Operator 升级到 2.4 或更高版本,但将
FIPS_MODE
环境变量设置为disabled
。 如果您最初部署了一个早于 2.3 的 AMQ Streams 版本,则可能会在其 PKCS #12 存储中使用旧的加密和摘要算法,该算法在启用了 FIPS 的情况下不被支持。要使用更新的算法重新创建证书,请更新集群和客户端 CA 证书。
-
要续订 Cluster Operator 生成的 CA,请在 CA secret 中添加
force-renew
注解来触发续订。 -
要续订您自己的 CA,请将新证书添加到 CA 机密,并使用更高的增量值更新
ca-cert-generation
注解,以捕获更新。
-
要续订 Cluster Operator 生成的 CA,请在 CA secret 中添加
如果您使用 SCRAM-SHA-512 验证,请检查用户的密码长度。如果它们长度少于 32 个字符,请使用以下方法之一生成新密码:
- 删除用户 secret,以便 User Operator 生成一个新密码有足够长度的新密码。
-
如果您使用
KafkaUser
自定义资源的.spec.authentication.password
属性提供密码,请更新同一密码配置中引用的 OpenShift secret 中的密码。不要忘记更新您的客户端以使用新密码。
- 确保 CA 证书使用正确的算法,并且 SCRAM-SHA-512 密码足够长度。然后您可以启用 FIPS 模式。
-
从 Cluster Operator 部署中删除
FIPS_MODE
环境变量。这会重启 Cluster Operator,并滚动所有操作对象来启用 FIPS 模式。重启完成后,所有 Kafka 集群现在都启用了 FIPS 模式运行。
第 24 章 降级 AMQ Streams
如果您遇到您升级到的 AMQ Streams 版本的问题,您可以将安装恢复到之前的版本。
如果使用 YAML 安装文件安装 AMQ Streams,您可以使用上一版本中的 YAML 安装文件执行以下降级步骤:
如果以前的 AMQ Streams 版本不支持您使用的 Kafka 版本,只要日志消息格式版本附加到消息匹配,您也可以降级 Kafka。
只有在使用安装文件安装 AMQ Streams 时,以下降级说明才适合。如果您使用其他方法(如 OperatorHub)安装 AMQ Streams,则该方法可能不支持降级,除非在文档中指定。为确保成功降级过程,需要使用受支持的方法。
24.1. 将 Cluster Operator 降级到以前的版本
如果您在 AMQ Streams 时遇到问题,可以恢复安装。
此流程描述了如何将 Cluster Operator 部署降级到以前的版本。
先决条件
- 提供了现有 Cluster Operator 部署。
- 您已下载了上一版本的安装文件。
开始前
检查 AMQ Streams 功能门的降级要求。如果永久启用功能门,您可能需要降级到可让您在降级到目标版本前禁用它的版本。
流程
-
记录在现有 Cluster Operator 资源(
/install/cluster-operator
目录中)所做的任何配置更改。任何更改都会被 Cluster Operator 的早期版本 覆盖。 - 恢复自定义资源,以反映您要降级的 AMQ Streams 版本支持的配置选项。
更新 Cluster Operator。
根据 Cluster Operator 运行的命名空间修改之前版本的安装文件。
在 Linux 中,使用:
sed -i 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
在 MacOS 中,使用:
sed -i '' 's/namespace: .*/namespace: my-cluster-operator-namespace/' install/cluster-operator/*RoleBinding*.yaml
-
如果您修改了现有 Cluster Operator
Deployment
中的一个或多个环境变量,请编辑install/cluster-operator/060-Deployment-strimzi-cluster-operator.yaml
文件以使用这些环境变量。
当您有更新的配置时,将其与安装资源的其余部分一起部署:
oc replace -f install/cluster-operator
等待滚动更新完成。
获取 Kafka pod 的镜像,以确保降级成功:
oc get pod my-cluster-kafka-0 -o jsonpath='{.spec.containers[0].image}'
镜像标签显示新的 AMQ Streams 版本,后跟 Kafka 版本。例如,
NEW-STRIMZI-VERSION-kafka-CURRENT-KAFKA-VERSION
。
Cluster Operator 已降级为之前的版本。
24.2. 降级 Kafka
Kafka 版本降级由 Cluster Operator 执行。
24.2.1. 降级的 Kafka 版本兼容性
Kafka 降级取决于兼容的当前和目标 Kafka 版本,以及记录信息的状态。
如果以前的一个版本不支持在集群中已使用过的任何 inter.broker.protocol.version
设置,或者消息已被添加到使用较新的 log.message.format.version
的消息日志中时,则无法恢复到这个以前的 Kafka 版本。
inter.broker.protocol.version
决定用于代理存储的持久元数据的模式,如写入 __consumer_offsets
的消息的 schema。如果您降级到 Kafka 版本,它不知道之前在代理遇到数据的集群中使用的 inter.broker.protocol.version
。
如果目标降级版本 Kafka 具有:
-
与当前版本 相同的
log.message.format.version
,Cluster Operator 通过执行代理的单一滚动重启来降级。 一个不同的
log.message.format.version
,只有运行的集群始终有log.message.format.version
设置为降级版本使用的版本时,才可以下载。这通常只有在更改log.message.format.version
前中止升级过程时才会出现这种情况。在这种情况下,降级需要:- 如果两个版本的 interbroker 协议不同,则两个代理的滚动重启
- 单个滚动重启(如果相同)
如果新版本使用了之前版本不支持的 log.message.format.version
,则无法 降级,包括在使用 log.message.format.version
的默认值时。例如,此资源可以降级到 Kafka 版本 3.4.0,因为 log.message.format.version
没有改变:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: # ... kafka: version: 3.5.0 config: log.message.format.version: "3.4" # ...
如果 log.message.format.version
设置为 "3.5"
或没有值,则无法降级,因此该参数会为 3.5 的 3.5.0 代理使用默认值。
从 Kafka 3.0.0 开始,当将 inter.broker.protocol.version
设置为 3.0
或更高版本时,log.message.format.version
选项将被忽略,不需要设置。
24.2.2. 降级 Kafka 代理和客户端应用程序
将 AMQ Streams Kafka 集群降级到 Kafka 的较低版本,如从 3.5.0 降级到 3.4.0。
先决条件
- Cluster Operator 已启动并在运行。
在降级 AMQ Streams Kafka 集群前,检查
Kafka
资源中的以下内容:- 重要信息: Kafka 版本的兼容性。
-
Kafka.spec.kafka.config
不包含被降级到的 Kafka 版本不支持的选项。 Kafka.spec.kafka.config
有一个log.message.format.version
和inter.broker.protocol.version
,由被降级到的 Kafka 版本支持。从 Kafka 3.0.0 开始,当将
inter.broker.protocol.version
设置为3.0
或更高版本时,log.message.format.version
选项将被忽略,不需要设置。
流程
更新 Kafka 集群配置。
oc edit kafka KAFKA-CONFIGURATION-FILE
更改
Kafka.spec.kafka.version
以指定之前的版本。例如,如果从 Kafka 3.5.0 降级为 3.4.0 :
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka spec: # ... kafka: version: 3.4.0 1 config: log.message.format.version: "3.4" 2 inter.broker.protocol.version: "3.4" 3 # ...
注意log.message.format.version
和inter.broker.protocol.version
的值必须是字符串,以防止它们被解释为浮点号。如果 Kafka 版本的镜像与 Cluster Operator 的
STRIMZI_KAFKA_IMAGES
中定义的镜像不同,请更新Kafka.spec.kafka.image
。保存并退出编辑器,然后等待滚动更新完成。
检查日志中的更新,或者通过观察 pod 状态转换:
oc logs -f CLUSTER-OPERATOR-POD-NAME | grep -E "Kafka version downgrade from [0-9.]+ to [0-9.]+, phase ([0-9]+) of \1 completed"
oc get pod -w
检查 Cluster Operator 日志中的
INFO
级别信息:Reconciliation #NUM(watch) Kafka(NAMESPACE/NAME): Kafka version downgrade from FROM-VERSION to TO-VERSION, phase 1 of 1 completed
降级所有客户端应用程序(消费者),以使用客户端二进制文件的早期版本。
Kafka 集群和客户端现在使用以前的 Kafka 版本。
如果您要恢复到早于 1.7 的 AMQ Streams 版本,它使用 ZooKeeper 来存储主题元数据,请从 Kafka 集群中删除内部主题存储主题。
oc run kafka-admin -ti --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 --rm=true --restart=Never -- ./bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic __strimzi-topic-operator-kstreams-topic-store-changelog --delete && ./bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic __strimzi_store_topic --delete
第 25 章 处理大量信息
如果您的 AMQ Streams 部署需要处理大量信息,您可以使用配置选项来优化吞吐量和延迟。
生成者和消费者配置有助于控制对 Kafka 代理的请求大小和频率。有关配置选项的更多信息,请参阅以下内容:
您还可以将相同的配置选项与 Kafka Connect 运行时源连接器(包括 MirrorMaker 2)和接收器连接器使用的制作者和消费者一起使用。
- 源连接器
- Kafka Connect 运行时的制作者会向 Kafka 集群发送信息。
- 对于 MirrorMaker 2,因为源系统是 Kafka,消费者从源 Kafka 集群检索信息。
- sink 连接器
- Kafka Connect 运行时的用户从 Kafka 集群检索信息。
对于消费者,您可以增加在单个获取请求中获取的数据量,以减少延迟。您可以使用 fetch.max.bytes
和 max.partition.fetch.bytes
属性增加 fetch 请求大小。您还可以使用 max.poll.records
属性设置从消费者缓冲区返回的消息数的最大限制。
对于 MirrorMaker 2,在源连接器级别(consumer.*
)配置 fetch.max.bytes
, max.partition.fetch.bytes
, 和 max.poll.records
值,因为它们与从源获取消息的特定消费者相关。
对于生成者,您可以增加在单个生成请求中发送的消息批处理的大小。您可以使用 batch.size
属性增加批处理大小。更大的批处理大小可减少准备好发送的未完成消息的数量以及消息队列中的 backlog 的大小。发送到同一分区的消息会并行批处理。当达到批处理大小时,将生成请求发送到目标集群。通过增加批处理大小,生成请求会延迟,并将更多消息添加到批处理中,并同时发送到代理。当您只有处理大量消息的几个主题分区时,这可以提高吞吐量。
考虑制作者为合适的生产批处理大小处理的记录的数量和大小。
使用 linger.ms
添加等待时间(毫秒)以在生成者负载减少时延迟生成请求。延迟意味着,如果记录在最大批处理大小下,可以添加更多记录到批处理中。
在连接器级别 (producer.override.*
) 配置 batch.size
和 linger.ms
值,因为它们与向目标 Kafka 集群发送信息的特定制作者相关。
对于 Kafka Connect 源连接器,到目标 Kafka 集群的数据流管道如下:
Kafka Connect 源连接器的数据流管道
External data source →(Kafka Connect tasks) source message queue → producer buffer → target Kafka topic
对于 Kafka Connect sink 连接器,到目标外部数据源的数据流管道如下:
Kafka Connect sink 连接器的数据流管道
source Kafka topic → (Kafka Connect tasks) sink message queue → consumer buffer → external data source
对于 MirrorMaker 2,目标 Kafka 集群的数据镜像管道如下:
MirrorMaker 2 的数据镜像管道
source Kafka topic → (Kafka Connect tasks) source message queue → producer buffer → target Kafka topic
制作者在其缓冲区中向目标 Kafka 集群中的主题发送信息。当发生这种情况时,Kafka Connect 任务将继续轮询数据源,以将信息添加到源消息队列中。
源连接器的制作者缓冲区的大小使用 producer.override.buffer.memory
属性进行设置。在缓冲区被清除前,任务会等待指定的超时周期(offset.flush.timeout.ms
)。这应该有足够的时间,以便代理和偏移数据提交的信息可以确认发送消息。除关闭期间,源任务不会等待制作者为空消息队列,然后再提交偏移。
如果生成者无法满足源消息队列中消息的吞吐量,则缓冲区会被阻断,直到缓冲区内由 max.block.ms
绑定的时间周期内可用。在此期间,缓冲区中仍然发送任何未确认的信息。在确认和清除这些消息之前,新消息不会添加到缓冲区中。
您可以尝试以下配置更改,将未完成的消息的底层源消息队列保持在 manageable 大小下:
-
以
offset.flush.timeout.ms
为单位增加默认值 - 确保有足够的 CPU 和内存资源
通过执行以下操作增加并行运行的任务数量:
-
使用
tasksMax
属性增加并行运行的任务数量 -
使用
replicas
属性增加运行任务的 worker 节点数量
-
使用
根据可用的 CPU 和内存资源和 worker 节点数量,请考虑可以并行运行的任务数量。您可能需要继续调整配置值,直到它们具有所需的效果。
25.1. 为高容量信息配置 Kafka 连接
Kafka Connect 从源外部数据系统获取数据,并将其传递给 Kafka Connect 运行时制作者,使其复制到目标集群。
以下示例显示了使用 KafkaConnect 自定义资源的 Kafka Connect
配置。
处理大量消息的 Kafka 连接配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster annotations: strimzi.io/use-connector-resources: "true" spec: replicas: 3 config: offset.flush.timeout.ms: 10000 # ... resources: requests: cpu: "1" memory: 2Gi limits: cpu: "2" memory: 2Gi # ...
为源连接器添加生成者配置,该连接器通过 KafkaConnector
自定义资源进行管理。
处理大量信息的源连接器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-source-connector labels: strimzi.io/cluster: my-connect-cluster spec: class: org.apache.kafka.connect.file.FileStreamSourceConnector tasksMax: 2 config: producer.override.batch.size: 327680 producer.override.linger.ms: 100 # ...
FileStreamSourceConnector
和 FileStreamSinkConnector
作为示例连接器提供。有关将它们部署为 KafkaConnector
资源的详情,请参考 第 6.4.3.3 节 “部署 KafkaConnector 资源”。
为接收器连接器添加消费者配置。
处理大量消息的接收器连接器配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnector metadata: name: my-sink-connector labels: strimzi.io/cluster: my-connect-cluster spec: class: org.apache.kafka.connect.file.FileStreamSinkConnector tasksMax: 2 config: consumer.fetch.max.bytes: 52428800 consumer.max.partition.fetch.bytes: 1048576 consumer.max.poll.records: 500 # ...
如果您使用 Kafka Connect API 而不是 KafkaConnector
自定义资源来管理连接器,您可以将连接器配置添加为 JSON 对象。
添加用于处理大量消息的源连接器配置的 curl 请求示例
curl -X POST \ http://my-connect-cluster-connect-api:8083/connectors \ -H 'Content-Type: application/json' \ -d '{ "name": "my-source-connector", "config": { "connector.class":"org.apache.kafka.connect.file.FileStreamSourceConnector", "file": "/opt/kafka/LICENSE", "topic":"my-topic", "tasksMax": "4", "type": "source" "producer.override.batch.size": 327680 "producer.override.linger.ms": 100 } }'
25.2. 为高卷消息配置 MirrorMaker 2
MirrorMaker 2 从源集群获取数据,并将其传递给 Kafka Connect 运行时制作者,以便将其复制到目标集群。
以下示例显示了使用 KafkaMirrorMaker2
自定义资源的 MirrorMaker 2 的配置。
用于处理大量消息的 MirrorMaker 2 配置示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mirror-maker2 spec: version: 3.5.0 replicas: 1 connectCluster: "my-cluster-target" clusters: - alias: "my-cluster-source" bootstrapServers: my-cluster-source-kafka-bootstrap:9092 - alias: "my-cluster-target" config: offset.flush.timeout.ms: 10000 bootstrapServers: my-cluster-target-kafka-bootstrap:9092 mirrors: - sourceCluster: "my-cluster-source" targetCluster: "my-cluster-target" sourceConnector: tasksMax: 2 config: producer.override.batch.size: 327680 producer.override.linger.ms: 100 consumer.fetch.max.bytes: 52428800 consumer.max.partition.fetch.bytes: 1048576 consumer.max.poll.records: 500 # ... resources: requests: cpu: "1" memory: Gi limits: cpu: "2" memory: 4Gi
25.3. 检查 MirrorMaker 2 消息流
如果使用 Prometheus 和 Grafana 监控部署,您可以检查 MirrorMaker 2 消息流。
AMQ Streams 提供的 MirrorMaker 2 Grafana 仪表板示例显示了与 flush 管道相关的以下指标。
- Kafka Connect 的未完成消息队列中的消息数
- producer 缓冲区的可用字节
- 偏移提交超时时间(毫秒)
您可以使用这些指标来量化是否需要根据消息卷调整配置。
第 26 章 查找 Kafka 重启信息
当 Cluster Operator 重启了 OpenShift 集群中的一个 Kafka pod 后,它会将 OpenShift 事件发送到 pod 的命名空间中,解释 pod 重启的原因。有关了解集群行为的帮助,您可以从命令行检查重启事件。
您可以使用 Prometheus 等指标集合工具导出和监控重启事件。将 metrics 工具与 事件导出器 一起使用,以适当的格式导出输出。
26.1. 重启事件的原因
Cluster Operator 会因为特定原因启动重启事件。您可以通过获取重启事件的信息来检查原因。
事件 | 描述 |
---|---|
CaCertHasOldGeneration | pod 仍然使用通过旧 CA 签名的服务器证书,因此需要在证书更新过程中重启。 |
CaCertRemoved | 过期的 CA 证书已被删除,pod 会重启以使用当前证书运行。 |
CaCertRenewed | CA 证书已更新,pod 重启以使用更新的证书运行。 |
ClientCaCertKeyReplaced | 用于为客户端 CA 证书签名的密钥已被替换,pod 作为 CA 续订服务器过程的一部分重启。 |
ClusterCaCertKeyReplaced | 用于为集群的 CA 证书签名的密钥已被替换,pod 作为 CA 续订服务器过程的一部分重启。 |
ConfigChangeRequiresRestart | 有些 Kafka 配置属性会动态更改,但其他 Kafka 配置属性需要重启代理。 |
FileSystemResizeNeeded | 文件系统大小已增加,需要重启来应用它。 |
KafkaCertificatesChanged | Kafka 代理使用的一个或多个 TLS 证书已更新,需要使用重启。 |
ManualRollingUpdate |
注解了 pod 或 |
PodForceRestartOnError | 发生错误,需要 pod 重启来重新处理。 |
PodHasOldRevision |
在 Kafka 卷中添加或删除磁盘,需要重启来应用更改。使用 |
PodHasOldRevision |
pod 的 |
PodStuck | pod 仍然处于待处理状态,且没有调度或无法调度,因此 Operator 已在最终尝试运行它时重启 pod。 |
PodUnresponsive | AMQ Streams 无法连接到 pod,这可能表示代理没有正确启动,因此 Operator 会在尝试解决这个问题时重启它。 |
26.2. 重启事件过滤器
从命令行检查重启事件时,您可以指定一个 field-selector
来过滤 OpenShift 事件字段。
在使用 field-selector
过滤事件时,可以使用以下字段。
regardingObject.kind
-
重启的对象以及重启事件的对象始终是
Pod
。 regarding.namespace
- pod 所属的命名空间。
regardingObject.name
-
pod 的名称,如
strimzi-cluster-kafka-0
。 regardingObject.uid
- pod 的唯一 ID。
reason
-
pod 重启的原因,如
JbodVolumesChanged
。 reportingController
-
报告组件始终是 AMQ Streams 重启事件的
strimzi.io/cluster-operator
。 source
-
Source
是reportingController
的旧版本。报告组件始终是 AMQ Streams 重启事件的strimzi.io/cluster-operator
。 type
-
事件类型,可以是
Warning
或Normal
。对于 AMQ Streams 重启事件,类型为Normal
。
在旧版本的 OpenShift 中,使用 相关前缀的字段
可能会改为使用 involvedObject
前缀。reportingController
之前被称为 reportingComponent
。
26.3. 检查 Kafka 重启
使用 oc
命令列出 Cluster Operator 启动的重启事件。通过使用 reportingController
或 源
事件字段将 Cluster Operator 设置为报告组件来过滤 Cluster Operator 发送的重启事件。
先决条件
- Cluster Operator 在 OpenShift 集群中运行。
流程
获取 Cluster Operator 发送的所有重启事件:
oc -n kafka get events --field-selector reportingController=strimzi.io/cluster-operator
显示返回的事件示例
LAST SEEN TYPE REASON OBJECT MESSAGE 2m Normal CaCertRenewed pod/strimzi-cluster-kafka-0 CA certificate renewed 58m Normal PodForceRestartOnError pod/strimzi-cluster-kafka-1 Pod needs to be forcibly restarted due to an error 5m47s Normal ManualRollingUpdate pod/strimzi-cluster-kafka-2 Pod was manually annotated to be rolled
您还可以指定
reason
或其他field-selector
选项来限制返回的事件。在这里添加了一个特定原因:
oc -n kafka get events --field-selector reportingController=strimzi.io/cluster-operator,reason=PodForceRestartOnError
使用输出格式(如 YAML)返回一个或多个事件的详细信息。
oc -n kafka get events --field-selector reportingController=strimzi.io/cluster-operator,reason=PodForceRestartOnError -o yaml
显示详细事件输出的示例
apiVersion: v1 items: - action: StrimziInitiatedPodRestart apiVersion: v1 eventTime: "2022-05-13T00:22:34.168086Z" firstTimestamp: null involvedObject: kind: Pod name: strimzi-cluster-kafka-1 namespace: kafka kind: Event lastTimestamp: null message: Pod needs to be forcibly restarted due to an error metadata: creationTimestamp: "2022-05-13T00:22:34Z" generateName: strimzi-event name: strimzi-eventwppk6 namespace: kafka resourceVersion: "432961" uid: 29fcdb9e-f2cf-4c95-a165-a5efcd48edfc reason: PodForceRestartOnError reportingController: strimzi.io/cluster-operator reportingInstance: strimzi-cluster-operator-6458cfb4c6-6bpdp source: {} type: Normal kind: List metadata: resourceVersion: "" selfLink: ""
以下字段已弃用,因此不会为这些事件填充它们:
-
firstTimestamp
-
lastTimestamp
-
source
第 27 章 管理 AMQ Streams
管理 AMQ Streams 需要执行各种任务来保持 Kafka 集群和相关资源平稳运行。使用 oc
命令检查资源的状态,配置维护窗口以进行滚动更新,并使用 AMQ Streams Drain Cleaner 和 Kafka Static Quota 插件等工具来有效地管理您的部署。
27.1. 使用自定义资源
您可以使用 oc
命令检索信息,并对 AMQ Streams 自定义资源执行其他操作。
将 oc
与自定义资源的 status
子资源一起使用,您可以获取有关资源的信息。
27.1.1. 对自定义资源执行 oc
操作
使用 oc
命令,如 get
, describe
, edit
, 或 delete
, 对资源类型执行操作。例如,oc get kafkatopics
检索所有 Kafka 主题和 oc get kafkas
列表,检索所有部署的 Kafka 集群。
在引用资源类型时,您可以使用单数和复数名称: oc get kafkas
获取与 oc get kafka
相同的结果。
您还可以使用资源 的短名称。学习短名称可在管理 AMQ Streams 时节省时间。Kafka
的短名称为 k
,因此您也可以运行 oc get k
来列出所有 Kafka 集群。
oc get k NAME DESIRED KAFKA REPLICAS DESIRED ZK REPLICAS my-cluster 3 3
AMQ Streams 资源 | 长名称 | 短名称 |
---|---|---|
Kafka | kafka | k |
Kafka 主题 | kafkatopic | kt |
Kafka 用户 | kafkauser | ku |
Kafka Connect | kafkaconnect | kc |
Kafka Connector | kafkaconnector | kctr |
Kafka Mirror Maker | kafkamirrormaker | kmm |
Kafka Mirror Maker 2 | kafkamirrormaker2 | kmm2 |
Kafka Bridge | kafkabridge | kb |
Kafka Rebalance | kafkarebalance | kr |
27.1.1.1. 资源类别
自定义资源的类别也可以在 oc
命令中使用。
所有 AMQ Streams 自定义资源都属于类别 strimzi
,因此您可以使用 strimzi
通过一个命令获取所有 AMQ Streams 资源。
例如,运行 oc get strimzi
列出了给定命名空间中的所有 AMQ Streams 自定义资源。
oc get strimzi NAME DESIRED KAFKA REPLICAS DESIRED ZK REPLICAS kafka.kafka.strimzi.io/my-cluster 3 3 NAME PARTITIONS REPLICATION FACTOR kafkatopic.kafka.strimzi.io/kafka-apps 3 3 NAME AUTHENTICATION AUTHORIZATION kafkauser.kafka.strimzi.io/my-user tls simple
oc get strimzi -o name
命令返回所有资源类型和资源名称。-o name
选项以 type/name 格式获取输出
oc get strimzi -o name kafka.kafka.strimzi.io/my-cluster kafkatopic.kafka.strimzi.io/kafka-apps kafkauser.kafka.strimzi.io/my-user
您可以将这个 strimzi
命令与其他命令合并。例如,您可以将其传递给 oc delete
命令,以删除单个命令中的所有资源。
oc delete $(oc get strimzi -o name) kafka.kafka.strimzi.io "my-cluster" deleted kafkatopic.kafka.strimzi.io "kafka-apps" deleted kafkauser.kafka.strimzi.io "my-user" deleted
删除单个操作中的所有资源可能很有用,例如,当您测试新的 AMQ Streams 功能时。
27.1.1.2. 查询子资源的状态
您可以使用其他值传递给 -o
选项。例如,通过使用 -o yaml
,您可以以 YAML 格式获取输出。使用 -o json
会将它返回为 JSON。
您可以查看 oc get --help
中的所有选项。
最有用的选项是 JSONPath 支持,它允许您传递 JSONPath 表达式来查询 Kubernetes API。JSONPath 表达式可以提取或导航任何资源的特定部分。
例如,您可以使用 JSONPath 表达式 {.status.listeners[? (@.name=="tls")].bootstrapServers}
从 Kafka 自定义资源的状态中获取 bootstrap 地址,并在 Kafka 客户端中使用它。
在这里,命令找到名为 tls
的监听程序的 bootstrapServers
值:
oc get kafka my-cluster -o=jsonpath='{.status.listeners[?(@.name=="tls")].bootstrapServers}{"\n"}' my-cluster-kafka-bootstrap.myproject.svc:9093
通过更改名称条件,您还可以获取其他 Kafka 侦听程序的地址。
您可以使用 jsonpath
从任何自定义资源中提取任何其他属性或属性组。
27.1.2. AMQ Streams 自定义资源状态信息
status 属性为特定自定义资源提供状态信息。
下表列出了提供状态信息(部署时)和定义 status 属性的 schema 的自定义资源。
如需有关 schema 的更多信息,请参阅 AMQ Streams 自定义资源 API 参考。
AMQ Streams 资源 | 模式参考 | 在… 中发布状态信息 |
---|---|---|
|
| Kafka 集群 |
|
| Kafka 集群中的 Kafka 主题 |
|
| Kafka 集群中的 Kafka 用户 |
|
| Kafka Connect 集群 |
|
|
|
|
| Kafka MirrorMaker 2 集群 |
|
| Kafka MirrorMaker 集群 |
|
| AMQ Streams Kafka Bridge |
|
| 重新平衡的状态和结果 |
资源的 status
属性提供有关资源状态的信息。status.conditions
和 status.observedGeneration
属性都是所有资源通用的。
status.conditions
-
状态条件描述了资源的当前状态。状态条件属性可用于跟踪与资源相关的进度,达到其 所需状态,这由
spec
中指定的配置定义。状态条件属性提供资源更改的时间和原因,以及阻止或延迟 Operator 实际状态的事件详情。 status.observedGeneration
-
最后观察到的生成表示 Cluster Operator 资源的最新协调。如果
观察到的Generation
的值与metadata.generation
的值(部署当前版本)不同,Operator 尚未处理对资源的最新更新。如果这些值相同,状态信息反映了资源的最新更改。
status
属性还提供特定于资源的信息。例如,KafkaStatus
提供有关监听器地址的信息,以及 Kafka 集群的 ID。
AMQ Streams 创建和维护自定义资源的状态,定期评估自定义资源的当前状态并相应地更新其状态。当使用 oc edit
在自定义资源上执行更新时,则其状态
不可编辑。另外,更改 状态
不会影响 Kafka 集群的配置。
在这里,我们看到 Kafka
自定义资源的状态
属性。
Kafka 自定义资源状态
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: spec: # ... status: clusterId: XP9FP2P-RByvEy0W4cOEUA 1 conditions: 2 - lastTransitionTime: '2023-01-20T17:56:29.396588Z' status: 'True' type: Ready 3 listeners: 4 - addresses: - host: my-cluster-kafka-bootstrap.prm-project.svc port: 9092 bootstrapServers: 'my-cluster-kafka-bootstrap.prm-project.svc:9092' name: plain type: plain - addresses: - host: my-cluster-kafka-bootstrap.prm-project.svc port: 9093 bootstrapServers: 'my-cluster-kafka-bootstrap.prm-project.svc:9093' certificates: - | -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- name: tls type: tls - addresses: - host: >- 2054284155.us-east-2.elb.amazonaws.com port: 9095 bootstrapServers: >- 2054284155.us-east-2.elb.amazonaws.com:9095 certificates: - | -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- name: external2 type: external2 - addresses: - host: ip-10-0-172-202.us-east-2.compute.internal port: 31644 bootstrapServers: 'ip-10-0-172-202.us-east-2.compute.internal:31644' certificates: - | -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- name: external1 type: external1 observedGeneration: 3 5
状态中列出的 Kafka bootstrap 地址并不表示这些端点或 Kafka 集群处于 Ready
状态。
访问状态信息
您可以从命令行访问资源的状态信息。更多信息请参阅 第 27.1.3 节 “查找自定义资源的状态”。
27.1.3. 查找自定义资源的状态
这个步骤描述了如何查找自定义资源的状态。
先决条件
- 一个 OpenShift 集群。
- Cluster Operator 正在运行。
流程
指定自定义资源,并使用
-o jsonpath
选项应用标准 JSONPath 表达式来选择status
属性:oc get kafka <kafka_resource_name> -o jsonpath='{.status}'
此表达式返回指定自定义资源的所有状态信息。您可以使用点表示法(如
status.listeners
或status.observedGeneration
)来微调您想要查看的状态信息。
其他资源
- 第 27.1.2 节 “AMQ Streams 自定义资源状态信息”
- 有关使用 JSONPath 的更多信息,请参阅 JSONPath 支持。
27.2. 使用标签和注解发现服务
通过服务发现,可以更轻松地在与 AMQ Streams 相同的 OpenShift 集群中运行客户端应用程序,以便与 Kafka 集群交互。
为用于访问 Kafka 集群的服务生成 服务发现 标签和注解:
- 内部 Kafka bootstrap 服务
- HTTP Bridge 服务
该标签有助于使服务发现,注解提供了客户端应用程序可用于进行连接的连接详情。
Service
资源的服务发现标签 strimzi.io/discovery
被设为 true
。服务发现注解具有相同的键,为每个服务提供 JSON 格式的连接详情。
内部 Kafka bootstrap 服务示例
apiVersion: v1 kind: Service metadata: annotations: strimzi.io/discovery: |- [ { "port" : 9092, "tls" : false, "protocol" : "kafka", "auth" : "scram-sha-512" }, { "port" : 9093, "tls" : true, "protocol" : "kafka", "auth" : "tls" } ] labels: strimzi.io/cluster: my-cluster strimzi.io/discovery: "true" strimzi.io/kind: Kafka strimzi.io/name: my-cluster-kafka-bootstrap name: my-cluster-kafka-bootstrap spec: #...
HTTP Bridge 服务示例
apiVersion: v1 kind: Service metadata: annotations: strimzi.io/discovery: |- [ { "port" : 8080, "tls" : false, "auth" : "none", "protocol" : "http" } ] labels: strimzi.io/cluster: my-bridge strimzi.io/discovery: "true" strimzi.io/kind: KafkaBridge strimzi.io/name: my-bridge-bridge-service
27.2.1. 返回服务的连接详情
您可以在从命令行或对应的 API 调用时指定发现标签来查找服务。
oc get service -l strimzi.io/discovery=true
检索服务发现标签时会返回连接详情。
27.3. 从一个终端连接到 ZooKeeper
ZooKeeper 服务使用加密和身份验证进行保护,并不适用于不属于 AMQ Streams 的外部应用程序。
但是,如果要使用需要连接到 ZooKeeper 的 CLI 工具,您可以使用 ZooKeeper pod 中的终端,并连接到 localhost:12181
作为 ZooKeeper 地址。
先决条件
- OpenShift 集群可用。
- Kafka 集群正在运行。
- Cluster Operator 正在运行。
流程
使用 OpenShift 控制台打开一个终端,或者从 CLI 运行
exec
命令。例如:
oc exec -ti my-cluster-zookeeper-0 -- bin/zookeeper-shell.sh localhost:12181 ls /
务必使用
localhost:12181
。
27.4. 暂停自定义资源的协调
有时,暂停由 AMQ Streams Operator 管理的自定义资源协调很有用,以便您可以执行修复或更新。如果暂停协调,Operator 会忽略对自定义资源所做的任何更改,直到暂停结束为止。
如果要暂停自定义资源的协调,请在其配置中将 strimzi.io/pause-reconciliation
注解设置为 true
。这指示适当的 Operator 暂停自定义资源的协调。例如,您可以将注解应用到 KafkaConnect
资源,以便 Cluster Operator 的协调已暂停。
您还可以创建启用 pause 注解的自定义资源。自定义资源已创建,但它将被忽略。
先决条件
- 管理自定义资源的 AMQ Streams Operator 正在运行。
流程
在 OpenShift 中注解自定义资源,将
pause-reconciliation
设置为true
:oc annotate <kind_of_custom_resource> <name_of_custom_resource> strimzi.io/pause-reconciliation="true"
例如,对于
KafkaConnect
自定义资源:oc annotate KafkaConnect my-connect strimzi.io/pause-reconciliation="true"
检查自定义资源的状态条件是否显示
ReconciliationPaused
的更改:oc describe <kind_of_custom_resource> <name_of_custom_resource>
在
lastTransitionTime
中type
条件会变为ReconciliationPaused
。带有暂停协调条件类型的自定义资源示例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: annotations: strimzi.io/pause-reconciliation: "true" strimzi.io/use-connector-resources: "true" creationTimestamp: 2021-03-12T10:47:11Z #... spec: # ... status: conditions: - lastTransitionTime: 2021-03-12T10:47:41.689249Z status: "True" type: ReconciliationPaused
从 pause 恢复
-
要恢复协调,您可以将注解设置为
false
,或删除注解。
其他资源
27.5. 滚动更新的维护时间窗
通过维护时间窗口,您可以调度 Kafka 和 ZooKeeper 集群的某些滚动更新,以便在方便的时间启动。
27.5.1. 维护时间窗概述
在大多数情况下,Cluster Operator 只更新您的 Kafka 或 ZooKeeper 集群,以响应对应的 Kafka
资源。这可让您计划何时对 Kafka
资源应用更改,以最大程度降低对 Kafka 客户端应用程序的影响。
但是,对 Kafka 和 ZooKeeper 集群的一些更新可能会出现任何与 Kafka
资源对应的更改。例如,如果其管理的 CA (证书颁发机构)证书接近到期,Cluster Operator 需要执行滚动重启。
虽然 pod 的滚动重启应该不会影响服务的可用性 (假设正确的代理和主题配置),但它可能会影响 Kafka 客户端应用程序的性能。维护时间窗允许您调度 Kafka 和 ZooKeeper 集群的此类 spontaneous 滚动更新,以便在方便的时间启动。如果没有为集群配置维护时间窗,则此类更新可能会在不方便的时间进行,比如在可预测的高负载期间。
27.5.2. 维护时间窗定义
您可以通过在 Kafka.spec.maintenanceTimeWindows
属性中输入字符串数组来配置维护时间窗。每个字符串都有一个 cron 表达式 解释为 UTC (协调通用时间),用于实际目的与 Greenwich Mean Time 相同。
以下示例配置了一个维护时间窗,其从午夜开始,并以 01:59am (UTC)结束,在 Sundays、Mondays、Mondays、rednesdays 和 Thursdays 上结束:
# ... maintenanceTimeWindows: - "* * 0-1 ? * SUN,MON,TUE,WED,THU *" # ...
在实践中,维护窗口应当与 Kafka
资源的 Kafka.spec.clusterCa.renewalDays
和 Kafka.spec.clientsCa.renewalDays
属性一起设置,以确保在配置的维护时间窗口中完成必要的 CA 证书续订。
AMQ Streams 不根据给定的窗口完全调度维护操作。相反,对于每个协调,它会检查维护窗口当前是否是"打开"。这意味着,在一个给定时间窗内开始维护操作会延迟到 Cluster Operator 协调间隔。因此,维护时间窗必须至少是这个时间。
27.5.3. 配置维护时间窗
您可以为支持的进程触发的滚动更新配置维护时间窗。
先决条件
- 一个 OpenShift 集群。
- Cluster Operator 正在运行。
流程
在
Kafka
资源中添加或编辑maintenanceTimeWindows
属性。例如,允许 0800 到 1059 到 1400 到 1559 之间的维护,您可以设置maintenanceTimeWindows
,如下所示:apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: kafka: # ... zookeeper: # ... maintenanceTimeWindows: - "* * 8-10 * * ?" - "* * 14-15 * * ?"
创建或更新资源:
oc apply -f <kafka_configuration_file>
27.6. 使用 AMQ Streams Drain Cleaner 驱除 pod
Kafka 和 ZooKeeper pod 可在 OpenShift 升级、维护或 pod 重新调度过程中被驱除。如果您的 Kafka 代理和 ZooKeeper pod 由 AMQ Streams 部署,您可以使用 AMQ Streams Drain Cleaner 工具来处理 pod 驱除。AMQ Streams Drain Cleaner 处理驱除而不是 OpenShift。您必须将 Kafka 部署的 podDisruptionBudget
设置为 0 (
零)。然后,OpenShift 将不再允许自动驱除 pod。
通过部署 AMQ Streams Drain Cleaner,您可以使用 Cluster Operator 移动 Kafka pod 而不是 OpenShift。Cluster Operator 确保主题永远不会被复制。Kafka 可在驱除过程中保持操作。Cluster Operator 等待主题同步,因为 OpenShift worker 节点会连续排空。
准入 Webhook 通知对 Kubernetes API 的 pod 驱除请求的 AMQ Streams Drain Cleaner。然后,AMQ Streams Drain Cleaner 为 pod 添加一个滚动更新注解来排空。这会通知 Cluster Operator 执行被驱除的 pod 的滚动更新。
如果您不使用 AMQ Streams Drain Cleaner,您可以添加 pod 注解来手动执行滚动更新。
Webhook 配置
AMQ Streams Drain Cleaner 部署文件包含一个 ValidatingWebhookConfiguration
资源文件。资源提供了将 webhook 注册到 Kubernetes API 的配置。
配置定义了在 pod 驱除请求时要遵守的 Kubernetes API 的规则
。规则指定仅与 pod/eviction 子资源
相关的 CREATE
操作会被截获。如果满足这些规则,API 会转发通知。
clientConfig
指向 AMQ Streams Drain Cleaner 服务和公开 webhook 的 /drainer
端点。Webhook 使用需要身份验证的安全 TLS 连接。caBundle
属性指定验证 HTTPS 通信的证书链。证书以 Base64 编码。
pod 驱除通知的 Webhook 配置
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration # ... webhooks: - name: strimzi-drain-cleaner.strimzi.io rules: - apiGroups: [""] apiVersions: ["v1"] operations: ["CREATE"] resources: ["pods/eviction"] scope: "Namespaced" clientConfig: service: namespace: "strimzi-drain-cleaner" name: "strimzi-drain-cleaner" path: /drainer port: 443 caBundle: Cg== # ...
27.6.1. 下载 AMQ Streams Drain Cleaner 部署文件
要部署并使用 AMQ Streams Drain Cleaner,您需要下载部署文件。
AMQ Streams Drain Cleaner 部署文件可从 AMQ Streams 软件下载页面 获得。
27.6.2. 使用安装文件部署 AMQ Streams Drain Cleaner
将 AMQ Streams Drain Cleaner 部署到运行 Cluster Operator 和 Kafka 集群的 OpenShift 集群。
AMQ Streams 设置默认 PodDisruptionBudget
(PDB),在任何给定时间只允许一个 Kafka 或 ZooKeeper pod 不可用。要使用 Drain Cleaner 进行计划维护或升级,您必须设置 PDB 为零。这是为了防止 pod 的大量驱除,并确保 Kafka 或 ZooKeeper 集群仍然可用。您可以通过在 Kafka
或 ZooKeeper
模板中将 maxUnavailable
值设置为零。StrimziPodSet
自定义资源使用无法使用 maxUnavailable
值的自定义控制器来管理 Kafka 和 ZooKeeper pod。相反,maxUnavailable
值转换为 minAvailable
值。例如,如果有三个代理 pod,并且 maxUnavailable
属性设置为 0 (
零),min
Available 设置为 3
,则需要所有三个代理 pod 可用,并允许零个 pod 不可用。
先决条件
- 您已下载了 AMQ Streams Drain Cleaner 部署文件。
- 您有一个高度可用的 Kafka 集群部署,它运行了您要更新的 OpenShift worker 节点。
复制主题以实现高可用性。
主题配置指定至少 3 个复制因素,最小同步副本的数量为复制因素的数量减 1。
为高可用性复制 Kafka 主题
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic labels: strimzi.io/cluster: my-cluster spec: partitions: 1 replicas: 3 config: # ... min.insync.replicas: 2 # ...
排除 Kafka 或 ZooKeeper
如果您不想在 Drain Cleaner 操作中包含 Kafka 或 ZooKeeper pod,请更改 Drain Cleaner Deployment
配置文件中的默认环境变量。
-
将
STRIMZI_DRAIN_KAFKA
设置为false
以排除 Kafka pod -
将
STRIMZI_DRAIN_ZOOKEEPER
设置为false
以排除 ZooKeeper pod
排除 ZooKeeper pod 的配置示例
apiVersion: apps/v1 kind: Deployment spec: # ... template: spec: serviceAccountName: strimzi-drain-cleaner containers: - name: strimzi-drain-cleaner # ... env: - name: STRIMZI_DRAIN_KAFKA value: "true" - name: STRIMZI_DRAIN_ZOOKEEPER value: "false" # ...
流程
使用
template
设置,在Kafka
资源的 Kafka 和 ZooKeeper 部分中将maxUnavailable
设置为0
(零)。指定 pod 中断预算
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster namespace: myproject spec: kafka: template: podDisruptionBudget: maxUnavailable: 0 # ... zookeeper: template: podDisruptionBudget: maxUnavailable: 0 # ...
此设置可防止在计划中断时自动驱除 pod,导致 AMQ Streams Drain Cleaner 和 Cluster Operator 在不同的 worker 节点上滚动 pod。
如果要使用 AMQ Streams Drain Cleaner 来排空 ZooKeeper 节点,为 ZooKeeper 添加相同的配置。
更新
Kafka
资源:oc apply -f <kafka_configuration_file>
部署 AMQ Streams Drain Cleaner。
要在 OpenShift 上运行 Drain Cleaner,请应用
/install/drain-cleaner/openshift
目录中的资源。oc apply -f ./install/drain-cleaner/openshift
27.6.3. 使用 AMQ Streams Drain Cleaner
与 Cluster Operator 结合使用 AMQ Streams Drain Cleaner,从正在排空的节点移动 Kafka 代理或 ZooKeeper pod。运行 AMQ Streams Drain Cleaner 时,它会使用滚动更新 pod 注解来注解 pod。Cluster Operator 根据注解执行滚动更新。
流程
排空托管 Kafka 代理或 ZooKeeper pod 的指定 OpenShift 节点。
oc get nodes oc drain <name-of-node> --delete-emptydir-data --ignore-daemonsets --timeout=6000s --force
检查 AMQ Streams Drain Cleaner 日志中的驱除事件,以验证 pod 是否已注解以重启。
AMQ Streams Drain Cleaner 日志显示 pod 的注解
INFO ... Received eviction webhook for Pod my-cluster-zookeeper-2 in namespace my-project INFO ... Pod my-cluster-zookeeper-2 in namespace my-project will be annotated for restart INFO ... Pod my-cluster-zookeeper-2 in namespace my-project found and annotated for restart INFO ... Received eviction webhook for Pod my-cluster-kafka-0 in namespace my-project INFO ... Pod my-cluster-kafka-0 in namespace my-project will be annotated for restart INFO ... Pod my-cluster-kafka-0 in namespace my-project found and annotated for restart
检查 Cluster Operator 日志中的协调事件以验证滚动更新。
Cluster Operator 日志显示滚动更新
INFO PodOperator:68 - Reconciliation #13(timer) Kafka(my-project/my-cluster): Rolling Pod my-cluster-zookeeper-2 INFO PodOperator:68 - Reconciliation #13(timer) Kafka(my-project/my-cluster): Rolling Pod my-cluster-kafka-0 INFO AbstractOperator:500 - Reconciliation #13(timer) Kafka(my-project/my-cluster): reconciled
27.6.4. 观察 AMQ Streams Drain Cleaner 使用的 TLS 证书
默认情况下,Drain Cleaner 部署会监视包含其用于身份验证的 TLS 证书的 secret。Drain Cleaner 监视是否有变化,如证书续订。如果检测到更改,它会重启以重新加载 TLS 证书。Drain Cleaner 安装文件默认启用此行为。但是,您可以通过在 Drain Cleaner 安装文件的部署
配置 (060-Deployment.yaml
) 中将 STRIMZI_CERTIFICATE_WATCH_ENABLED
环境变量设置为 false
来禁用对证书的监控。
启用 STRIMZI_CERTIFICATE_WATCH_ENABLED
后,您还可以使用以下环境变量来监视 TLS 证书。
环境变量 | 描述 | 默认 |
---|---|---|
| 启用或禁用证书监视 |
|
| 部署 Drain Cleaner 的命名空间以及证书 secret 存在的位置 |
|
| Drain Cleaner pod 名称 | - |
| 包含 TLS 证书的 secret 名称 |
|
| 包含 TLS 证书的 secret 中的字段列表 |
|
控制监视操作的环境变量配置示例
apiVersion: apps/v1 kind: Deployment metadata: name: strimzi-drain-cleaner labels: app: strimzi-drain-cleaner namespace: strimzi-drain-cleaner spec: # ... spec: serviceAccountName: strimzi-drain-cleaner containers: - name: strimzi-drain-cleaner # ... env: - name: STRIMZI_DRAIN_KAFKA value: "true" - name: STRIMZI_DRAIN_ZOOKEEPER value: "true" - name: STRIMZI_CERTIFICATE_WATCH_ENABLED value: "true" - name: STRIMZI_CERTIFICATE_WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: STRIMZI_CERTIFICATE_WATCH_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name # ...
使用 Downward API 机制配置 STRIMZI_CERTIFICATE_WATCH_NAMESPACE
和 STRIMZI_CERTIFICATE_WATCH_POD_NAME
。
27.7. 使用注解删除 Kafka 节点
此流程描述了如何使用 OpenShift 注解删除现有 Kafka 节点。删除 Kafka 节点包括删除运行 Kafka 代理的 Pod
和相关的 PersistentVolumeClaim
(如果集群使用持久性存储部署)。删除后,Pod
及其相关的 PersistentVolumeClaim
会自动重新创建。
删除 PersistentVolumeClaim
可能会导致持久性数据丢失,且不能保证集群可用。只有在遇到存储问题时才应执行以下步骤。
先决条件
- 正在运行的 Cluster Operator
流程
查找您要删除的
Pod
的名称。Kafka 代理 pod 的名称为 <cluster-name>-kafka-<index>,其中 <index> 从 0 开始,最高为副本数量减一。例如,
my-cluster-kafka-0
。在 OpenShift 中注解
Pod
资源。使用
oc annotate
:oc annotate pod cluster-name-kafka-index strimzi.io/delete-pod-and-pvc=true
- 等待下一个协调,当注解的 pod 带有底层持久性卷声明的 pod 将被删除,然后重新创建。
27.8. 使用注解删除 ZooKeeper 节点
此流程描述了如何使用 OpenShift 注解删除现有 ZooKeeper 节点。删除 ZooKeeper 节点包括删除运行 ZooKeeper 的 Pod
和相关的 PersistentVolumeClaim
(如果集群使用持久性存储部署)。删除后,Pod
及其相关的 PersistentVolumeClaim
会自动重新创建。
删除 PersistentVolumeClaim
可能会导致持久性数据丢失,且不能保证集群可用。只有在遇到存储问题时才应执行以下步骤。
先决条件
- 正在运行的 Cluster Operator
流程
查找您要删除的
Pod
的名称。ZooKeeper pod 名为 < ;cluster-name> -zookeeper-<index > ;,其中 <index > 以零开始,结束于副本减一个总数。例如,
my-cluster-zookeeper-0
。在 OpenShift 中注解
Pod
资源。使用
oc annotate
:oc annotate pod cluster-name-zookeeper-index strimzi.io/delete-pod-and-pvc=true
- 等待下一个协调,当注解的 pod 带有底层持久性卷声明的 pod 将被删除,然后重新创建。
27.9. 使用注解启动 Kafka 和 ZooKeeper 集群的滚动更新
AMQ Streams 支持使用资源上的注解来通过 Cluster Operator 手动触发 Kafka 和 ZooKeeper 集群的滚动更新。滚动更新使用新的资源重启 pod。
在特殊 pod 或一组 pod 上手动执行滚动更新,通常只需要在特殊情况下进行滚动更新。但是,如果您通过 Cluster Operator 执行滚动更新,而不是直接删除 pod,请确保以下内容:
- 手动删除 pod 不会与 Cluster Operator 操作冲突,如同时删除其他 pod。
- Cluster Operator 逻辑处理 Kafka 配置规格,如同步副本数。
27.9.1. 使用 pod 管理注解执行滚动更新
此流程描述了如何触发 Kafka 集群或 ZooKeeper 集群的滚动更新。要触发更新,您可以在 StrimziPodSet
中添加注解,用于管理集群中运行的 pod。
先决条件
要执行手动滚动更新,您需要运行一个正在运行的 Cluster Operator 和 Kafka 集群。
流程
查找控制您要手动更新的 Kafka 或 ZooKeeper pod 的资源名称。
例如,如果您的 Kafka 集群命名为 my-cluster,则对应的名称为 my-cluster-kafka 和 my-cluster-zookeeper。
使用
oc annotate
在 OpenShift 中注解适当的资源。Annotating a StrimziPodSet
oc annotate strimzipodset <cluster_name>-kafka strimzi.io/manual-rolling-update=true oc annotate strimzipodset <cluster_name>-zookeeper strimzi.io/manual-rolling-update=true
- 等待下一个协调发生(默认为两分钟)。触发注解资源中的所有 pod 的滚动更新,只要协调过程检测到注解。当所有 pod 的滚动更新完成后,注解会从资源中删除。
27.9.2. 使用 pod 注解执行滚动更新
此流程描述了如何使用 OpenShift Pod
注解手动触发现有 Kafka 集群或 ZooKeeper 集群的滚动更新。当注解多个 pod 时,连续滚动更新会在同一协调运行中执行。
先决条件
要执行手动滚动更新,您需要运行一个正在运行的 Cluster Operator 和 Kafka 集群。
无论使用了什么主题复制因素,您可以在 Kafka 集群上执行滚动更新。但是,对于 Kafka 在更新过程中保持操作,您需要执行以下操作:
- 使用您要更新的节点运行的高可用性 Kafka 集群部署。
复制的主题以实现高可用性。
主题配置指定至少 3 个复制因素,最小同步副本的数量为复制因素的数量减 1。
为高可用性复制 Kafka 主题
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaTopic metadata: name: my-topic labels: strimzi.io/cluster: my-cluster spec: partitions: 1 replicas: 3 config: # ... min.insync.replicas: 2 # ...
流程
找到您要手动更新的 Kafka 或 ZooKeeper
Pod
的名称。例如,如果您的 Kafka 集群命名为 my-cluster,则对应的
Pod
名称为 my-cluster-kafka-index 和 my-cluster-zookeeper-index。索引 从零开始,结束于副本总数。在 OpenShift 中注解
Pod
资源。使用
oc annotate
:oc annotate pod cluster-name-kafka-index strimzi.io/manual-rolling-update=true oc annotate pod cluster-name-zookeeper-index strimzi.io/manual-rolling-update=true
-
等待下一个协调发生(默认为两分钟)。当在协调过程检测到注解时,就会触发被注解的
Pod
的滚动更新。完成 Pod 的滚动更新后,注解将从Pod
中删除。
27.10. 使用注解执行 MirrorMaker 2 连接器重启
此流程描述了如何使用 OpenShift 注解手动触发 Kafka MirrorMaker 2 连接器重启。
先决条件
- Cluster Operator 正在运行。
流程
查找控制您要重启的 Kafka MirrorMaker 2 连接器的
KafkaMirrorMaker2
自定义资源的名称:oc get KafkaMirrorMaker2
查找要从
KafkaMirrorMaker2
自定义资源重启的 Kafka MirrorMaker 2 连接器的名称。oc describe KafkaMirrorMaker2 KAFKAMIRRORMAKER-2-NAME
要重启连接器,请在 OpenShift 中注解
KafkaMirrorMaker2
资源。在本例中,oc annotate
会重启名为my-source->my-target.MirrorSourceConnector
的连接器:oc annotate KafkaMirrorMaker2 KAFKAMIRRORMAKER-2-NAME "strimzi.io/restart-connector=my-source->my-target.MirrorSourceConnector"
等待下一个协调发生(默认为两分钟)。
只要协调过程检测到注解,Kafka MirrorMaker 2 连接器就会重启。当接受重启请求时,注解会从
KafkaMirrorMaker2
自定义资源中删除。
其他资源
27.11. 使用注解执行 MirrorMaker 2 连接器任务重启
此流程描述了如何使用 OpenShift 注解手动触发 Kafka MirrorMaker 2 连接器任务的重启。
先决条件
- Cluster Operator 正在运行。
流程
查找控制您要重启的 Kafka MirrorMaker 2 连接器的
KafkaMirrorMaker2
自定义资源的名称:oc get KafkaMirrorMaker2
查找 Kafka MirrorMaker 2 连接器的名称以及要从
KafkaMirrorMaker2
自定义资源重启的任务 ID。任务 ID 是非负整数,从 0 开始。oc describe KafkaMirrorMaker2 KAFKAMIRRORMAKER-2-NAME
要重启连接器任务,请在 OpenShift 中注解
KafkaMirrorMaker2
资源。在本例中,oc annotate
restart task 0 of a connector namedmy-source->my-target.MirrorSourceConnector
:oc annotate KafkaMirrorMaker2 KAFKAMIRRORMAKER-2-NAME "strimzi.io/restart-connector-task=my-source->my-target.MirrorSourceConnector:0"
等待下一个协调发生(默认为两分钟)。
Kafka MirrorMaker 2 连接器任务被重启,只要协调过程检测到注解。当接受重启任务请求时,注解会从
KafkaMirrorMaker2
自定义资源中删除。
其他资源
27.12. 从持久性卷恢复集群
如果 Kafka 集群仍然存在,则可以从持久性卷(PV)恢复 Kafka 集群。
例如,您可能需要进行此操作:
- 命名空间被意外删除
- 整个 OpenShift 集群会丢失,但 PV 会保留在基础架构中
27.12.1. 从命名空间删除中恢复
由于持久性卷和命名空间之间的关系,可以从命名空间删除中恢复。PersistentVolume
(PV) 是位于命名空间外的存储资源。PV 使用 PersistentVolumeClaim
(PVC)挂载到 Kafka pod 中,该 PVC 位于命名空间内。
PV 的重新声明策略告知集群如何在删除命名空间时执行的操作。如果重新声明策略被设置为:
- 删除 (默认)、当在命名空间中删除 PVC 时 PV 会被删除
- Retain,当删除命名空间时 PV 不会删除。
如果确保在命名空间被意外删除时可以从 PV 中进行恢复,需要使用 persistentVolumeReclaimPolicy
属性在 PV 规格中将策略从 Delete 重置为 Retain:
apiVersion: v1
kind: PersistentVolume
# ...
spec:
# ...
persistentVolumeReclaimPolicy: Retain
另外,PV 可以继承关联的存储类的重新声明策略。存储类用于动态卷分配。
通过为存储类配置 reclaimPolicy
属性,使用存储类的 PV 会使用适当的重新声明策略创建。存储类使用 storageClassName
属性为 PV 配置。
apiVersion: v1 kind: StorageClass metadata: name: gp2-retain parameters: # ... # ... reclaimPolicy: Retain
apiVersion: v1
kind: PersistentVolume
# ...
spec:
# ...
storageClassName: gp2-retain
如果您使用 Retain 作为重新声明策略,但您想要删除整个集群,则需要手动删除 PV。否则,它们不会被删除,并可能导致不必要的资源。
27.12.2. 恢复丢失 OpenShift 集群
当集群丢失时,如果基础架构内保留,您可以使用磁盘/卷中的数据来恢复集群。恢复过程与删除命名空间相同,假设可以恢复 PV 并手动创建它们。
27.12.3. 从持久性卷中恢复已删除的集群
这个步骤描述了如何从持久性卷(PV)恢复已删除的集群。
在这种情况下,主题 Operator 会标识 Kafka 中存在的主题,但 KafkaTopic
资源不存在。
当进入重新创建集群的步骤时,有两个选项:
当您可以恢复所有
KafkaTopic
资源时,请使用 选项 1。因此,必须在集群启动前恢复
KafkaTopic
资源,以便主题 Operator 不会删除对应的主题。当您无法恢复所有
KafkaTopic
资源时,请使用选项 2。在这种情况下,您可以在没有主题 Operator 的情况下部署集群,删除主题 Operator 主题存储元数据,然后使用 Topic Operator 重新部署 Kafka 集群,以便它可以从对应的主题重新创建
KafkaTopic
资源。
如果没有部署 Topic Operator,则只需要恢复 PersistentVolumeClaim
(PVC)资源。
开始前
在此过程中,PV 被挂载到正确的 PVC 以避免数据崩溃。为 PVC 指定一个 volumeName
,这必须与 PV 的名称匹配。
如需更多信息,请参阅 持久性存储。
该流程不包括对 KafkaUser
资源的恢复,这些资源必须手动重新创建。如果需要保留密码和证书,则必须重新创建 secret,然后才能创建 KafkaUser
资源。
流程
检查集群中 PV 的信息:
oc get pv
显示带有数据的 PV 的信息。
显示对此过程很重要的列示例:
NAME RECLAIMPOLICY CLAIM pvc-5e9c5c7f-3317-11ea-a650-06e1eadd9a4c ... Retain ... myproject/data-my-cluster-zookeeper-1 pvc-5e9cc72d-3317-11ea-97b0-0aef8816c7ea ... Retain ... myproject/data-my-cluster-zookeeper-0 pvc-5ead43d1-3317-11ea-97b0-0aef8816c7ea ... Retain ... myproject/data-my-cluster-zookeeper-2 pvc-7e1f67f9-3317-11ea-a650-06e1eadd9a4c ... Retain ... myproject/data-0-my-cluster-kafka-0 pvc-7e21042e-3317-11ea-9786-02deaf9aa87e ... Retain ... myproject/data-0-my-cluster-kafka-1 pvc-7e226978-3317-11ea-97b0-0aef8816c7ea ... Retain ... myproject/data-0-my-cluster-kafka-2
- NAME 显示每个 PV 的名称。
- RECLAIM POLICY 显示 PV 被保留。
- CLAIM 显示到原始 PVC 的链接。
重新创建原始命名空间:
oc create namespace myproject
重新创建原始 PVC 资源规格,将 PVC 链接到适当的 PV:
例如:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: data-0-my-cluster-kafka-0 spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Gi storageClassName: gp2-retain volumeMode: Filesystem volumeName: pvc-7e1f67f9-3317-11ea-a650-06e1eadd9a4c
编辑 PV 规格,以删除绑定原始 PVC 的
claimRef
属性。例如:
apiVersion: v1 kind: PersistentVolume metadata: annotations: kubernetes.io/createdby: aws-ebs-dynamic-provisioner pv.kubernetes.io/bound-by-controller: "yes" pv.kubernetes.io/provisioned-by: kubernetes.io/aws-ebs creationTimestamp: "<date>" finalizers: - kubernetes.io/pv-protection labels: failure-domain.beta.kubernetes.io/region: eu-west-1 failure-domain.beta.kubernetes.io/zone: eu-west-1c name: pvc-7e226978-3317-11ea-97b0-0aef8816c7ea resourceVersion: "39431" selfLink: /api/v1/persistentvolumes/pvc-7e226978-3317-11ea-97b0-0aef8816c7ea uid: 7efe6b0d-3317-11ea-a650-06e1eadd9a4c spec: accessModes: - ReadWriteOnce awsElasticBlockStore: fsType: xfs volumeID: aws://eu-west-1c/vol-09db3141656d1c258 capacity: storage: 100Gi claimRef: apiVersion: v1 kind: PersistentVolumeClaim name: data-0-my-cluster-kafka-2 namespace: myproject resourceVersion: "39113" uid: 54be1c60-3319-11ea-97b0-0aef8816c7ea nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: failure-domain.beta.kubernetes.io/zone operator: In values: - eu-west-1c - key: failure-domain.beta.kubernetes.io/region operator: In values: - eu-west-1 persistentVolumeReclaimPolicy: Retain storageClassName: gp2-retain volumeMode: Filesystem
在示例中,删除了以下属性:
claimRef: apiVersion: v1 kind: PersistentVolumeClaim name: data-0-my-cluster-kafka-2 namespace: myproject resourceVersion: "39113" uid: 54be1c60-3319-11ea-97b0-0aef8816c7ea
部署 Cluster Operator。
oc create -f install/cluster-operator -n my-project
重新创建集群。
根据是否具有重新创建集群所需的所有
KafkaTopic
资源,请按照以下步骤操作。选项 1: 如果您拥有在丢失集群前存在 的所有
KafkaTopic
资源,包括__consumer_offsets
中的提交偏移等内部主题:重新创建所有
KafkaTopic
资源。在部署集群前,您必须重新创建资源,或者主题 Operator 将删除主题。
部署 Kafka 集群。
例如:
oc apply -f kafka.yaml
选项 2: 如果您没有在丢失集群前存在的所有
KafkaTopic
资源:部署 Kafka 集群,与第一个选项一样,但在部署前,通过从 Kafka 资源中删除
topicOperator
属性来没有 Topic Operator。如果在部署中包含 Topic Operator,则主题 Operator 将删除所有主题。
从 Kafka 集群中删除内部主题存储主题:
oc run kafka-admin -ti --image=registry.redhat.io/amq-streams/kafka-35-rhel8:2.5.1 --rm=true --restart=Never -- ./bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic __strimzi-topic-operator-kstreams-topic-store-changelog --delete && ./bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic __strimzi_store_topic --delete
该命令必须与用于访问 Kafka 集群的监听程序和身份验证类型对应。
通过使用
topicOperator
属性重新部署 Kafka 集群来启用 Topic Operator,以重新创建KafkaTopic
资源。例如:
apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: name: my-cluster spec: #... entityOperator: topicOperator: {} 1 #...
- 1
- 在这里,我们显示没有额外属性的默认配置。您可以使用
EntityTopicOperatorSpec
schema reference 中所述的属性指定所需的配置。
列出
KafkaTopic
资源来验证恢复:oc get KafkaTopic
27.13. 卸载 AMQ Streams
您可以使用 OpenShift Container Platform Web 控制台或 CLI 从 OperatorHub 卸载 AMQ Streams on OpenShift 4.10 到 4.14。
使用您用于安装 AMQ Streams 的相同方法。
卸载 AMQ Streams 时,您需要识别专门为部署创建的资源,并从 AMQ Streams 资源引用。
这些资源包括:
- Secret (自定义 CA 和证书、Kafka Connect secret 和其他 Kafka secret)
-
日志记录
ConfigMap
(类型为external
)
这些是由 Kafka
,KafkaConnect
,KafkaMirrorMaker
, 或 KafkaBridge
配置引用的资源。
删除 CustomResourceDefinitions
会导致相应自定义资源的垃圾回收(Kafka
、KafkaConnect
、KafkaMirrorMaker
或 KafkaBridge
)以及依赖于这些资源的资源(Deployments、StatefulSet 和其他依赖资源)。
27.13.1. 使用 Web 控制台从 OperatorHub 卸载 AMQ Streams
此流程描述了如何从 OperatorHub 卸载 AMQ Streams 并删除与部署相关的资源。
您可以从控制台执行这些步骤或使用替代 CLI 命令。
先决条件
-
使用具有
cluster-admin
或strimzi-admin
权限的账户访问 OpenShift Container Platform Web 控制台。 您已确定要删除的资源。
您可以使用以下
oc
CLI 命令查找资源,并在卸载 AMQ Streams 时验证它们是否已被删除。查找与 AMQ Streams 部署相关的资源的命令
oc get <resource_type> --all-namespaces | grep <kafka_cluster_name>
将 <resource_type > 替换为您要检查的资源类型,如
secret
或configmap
。
流程
- 在 OpenShift Web 控制台中进入到 Operators > Installed Operators。
对于已安装的 AMQ Streams operator,选择选项图标(三个垂直点),然后点 Uninstall Operator。
Operator 已从 Installed Operators 中删除。
- 导航到 Home > Projects,再选择安装 AMQ Streams 和 Kafka 组件的项目。
点 Inventory 下的选项删除相关资源。
资源包括:
- 部署
- StatefulSets
- Pods
- 服务
- ConfigMaps
- Secrets
提示使用搜索来查找以 Kafka 集群名称开头的相关资源。您还可以在 Workloads 下找到资源。
备选CLI命令
您可以使用 CLI 命令从 OperatorHub 卸载 AMQ Streams。
删除 AMQ Streams 订阅。
oc delete subscription amq-streams -n openshift-operators
删除集群服务版本(CSV)。
oc delete csv amqstreams.<version> -n openshift-operators
删除相关的 CRD。
oc get crd -l app=strimzi -o name | xargs oc delete
27.13.2. 使用 CLI 卸载 AMQ Streams
此流程描述了如何使用 oc
命令行工具卸载 AMQ Streams 并删除与部署相关的资源。
先决条件
-
使用具有
cluster-admin
或strimzi-admin
权限的账户访问 OpenShift 集群。 您已确定要删除的资源。
您可以使用以下
oc
CLI 命令查找资源,并在卸载 AMQ Streams 时验证它们是否已被删除。查找与 AMQ Streams 部署相关的资源的命令
oc get <resource_type> --all-namespaces | grep <kafka_cluster_name>
将 <resource_type > 替换为您要检查的资源类型,如
secret
或configmap
。
流程
删除 Cluster Operator
Deployment
、相关的CustomResourceDefinitions
和RBAC
资源。指定用于部署 Cluster Operator 的安装文件。
oc delete -f install/cluster-operator
删除您在先决条件中标识的资源。
oc delete <resource_type> <resource_name> -n <namespace>
将 <resource_type > 替换为您要删除的资源类型,& lt;resource_name > 替换为资源名称。
删除 secret 的示例
oc delete secret my-cluster-clients-ca-cert -n my-project
27.14. 常见问题解答
第 28 章 在 AMQ Streams 上使用 Metering
您可以使用 OpenShift 上可用的 Metering 工具从不同的数据源生成 metering 报告。作为集群管理员,您可使用 Metering 来分析集群中的情况。您可以自行编写报告,也可以使用预定义的 SQL 查询来定义如何处理来自现有不同数据源的数据。使用 Prometheus 作为默认数据源,您可以针对 pod、命名空间和大多数其他 OpenShift 资源生成报告。
您还可以使用 OpenShift Metering operator 分析已安装的 AMQ Streams 组件,以确定您是否符合红帽订阅。
要将 metering 与 AMQ Streams 搭配使用,您必须首先在 OpenShift Container Platform 上安装和配置 Metering Operator。
28.1. Metering 资源
Metering 具有很多资源,可用于管理 Metering 的部署与安装以及 Metering 提供的报告功能。Metering 使用以下 CRD 管理:
名称 | Description |
---|---|
| 为部署配置 metering 堆栈。包含用于控制 metering 堆栈各个组件的自定义和配置选项。 |
| 控制要使用的查询、查询运行时间、运行频率以及查询结果的存储位置。 |
|
包含用于对 |
| 控制 ReportQueries 和 Reports 可用数据。支持配置 metering 中使用的不同数据库的访问权限。 |
28.2. AMQ Streams 的 metering 标签
下表列出了 AMQ Streams 基础架构组件和集成的 metering 标签。
标签 | 可能的值 |
---|---|
|
|
|
|
|
|
|
|
|
|
| 基础架构
|
Application(应用程序)
| |
|
|
例子
基础架构示例(基础架构组件是 entity-operator)
com.company=Red_Hat rht.prod_name=Red_Hat_Application_Foundations rht.prod_ver=2023.Q3 rht.comp=AMQ_Streams rht.comp_ver=2.5 rht.subcomp=entity-operator rht.subcomp_t=infrastructure
应用程序示例(集成部署名称为 kafka-bridge)
com.company=Red_Hat rht.prod_name=Red_Hat_Application_Foundations rht.prod_ver=2023.Q3 rht.comp=AMQ_Streams rht.comp_ver=2.5 rht.subcomp=kafka-bridge rht.subcomp_t=application
附录 A. 使用您的订阅
AMQ Streams 通过软件订阅提供。要管理您的订阅,请访问红帽客户门户中的帐户。
访问您的帐户
- 转至 access.redhat.com。
- 如果您还没有帐户,请创建一个帐户。
- 登录到您的帐户。
激活订阅
- 转至 access.redhat.com。
- 导航到 My Subscriptions。
- 导航到 激活订阅 并输入您的 16 位激活号。
下载 Zip 和 Tar 文件
要访问 zip 或 tar 文件,请使用客户门户网站查找下载的相关文件。如果您使用 RPM 软件包,则不需要这一步。
- 打开浏览器并登录红帽客户门户网站 产品下载页面,网址为 access.redhat.com/downloads。
- 在 INTEGRATION AND AUTOMATION 目录中找到 AMQ Streams for Apache Kafka 项。
- 选择所需的 AMQ Streams 产品。此时会打开 Software Downloads 页面。
- 单击组件的 Download 链接。
使用 DNF 安装软件包
要安装软件包以及所有软件包的依赖软件包,请使用:
dnf install <package_name>
要从本地目录中安装之前下载的软件包,请使用:
dnf install <path_to_download_package>
更新于 2023-11-22