在 Debezium 2.3 中,我们推出了一个全新的 Debezium Operator 的预览版,旨在为 Kubernetes (k8s) 集群提供无缝的 Debezium Server 部署。Debezium 2.4.0.Final 版本带来了向该组件全面支持迈出的下一步。在此版本中,我们很高兴地宣布 Debezium Operator 现在已包含在 Kubernetes 的 OperatorHub 目录以及 OpenShift 和 OKD 分发版中嵌入的社区 Operator 目录中。该 Operator 仍处于孵化阶段;然而,对该组件的全面支持正在快速到来。
目标
在本文中,我们将演示如何使用部署在 Kubernetes 集群中的 Debezium Server,将更改从 PostgreSQL 数据库流式传输到 Apache Kafka。我们还将展示我们新的 k8s 集成的一些功能。为了方便起见,教程中使用的所有代码片段和 Kubernetes 清单也可在我们的 GitHub 示例仓库 中找到。
准备环境
在部署 Operator 并因此部署 Debezium Server 之前,我们需要一个部署的环境。在本节中,我们将展示如何配置一个运行 PostgreSQL 数据库和 Apache Kafka Broker 的本地 Kubernetes 集群。请注意,数据库和/或 Kafka Broker 不需要运行在 Kubernetes 中,我们只是选择这样做是为了本次演示的目的。
运行本地 Kubernetes 集群
如果您已经有一个正在运行的 Kubernetes 集群,则可以跳过此部分;但是,请确保您拥有 cluster-admin 权限,因为这些权限对于 Operator 的安装是必需的。如果没有,请继续阅读。
有多种工具可用于运行本地 k8s 集群,例如 Minikube、Kind 或 Docker Desktop。在本文中,我们将使用 Kind 来创建单个节点的本地集群。
先决条件
安装好 kubectl 和 kind 后,请执行以下命令创建一个本地 Kubernetes 集群。
kind create cluster --name debezium 现在我们可以配置 kubectl 的集群上下文,并通过运行以下命令来检查我们新 k8s 环境的状态。
$ kubectl cluster-info --context kind-debezium
Kubernetes control plane is running at https://127.0.0.1:64815
CoreDNS is running at https://127.0.0.1:64815/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy 作为集群部署的最后一步,我们将为所需的 infrastructure 创建一个新的命名空间。
kubectl create namespace debezium 部署基础设施
在本节中,我们将准备所需的基础设施——PostgreSQL 数据库以及 Kafka Broker 实例。
PostgreSQL 数据库
让我们通过执行以下命令来开始部署 PostgreSQL 数据库。
| 为了简单起见,我们使用了临时的卷挂载,这意味着对数据库实例所做的任何修改在 pod 被重新创建时都不会持久化。 |
kubectl create -f https://raw.githubusercontent.com/debezium/debezium-examples/main/operator/tutorial-postgresql-kafka/infra/001_postgresql.yml -n debezium 提供给 kubectl 的 yaml 文件包含多个 Kubernetes 清单。
apiVersion: v1 (1)
kind: Secret
metadata:
name: postgresql-credentials
type: opaque
data:
POSTGRES_DB: ZGViZXppdW0=
POSTGRES_USER: ZGViZXppdW0=
POSTGRES_PASSWORD: ZGViZXppdW0=
---
kind: Deployment (2)
apiVersion: apps/v1
metadata:
name: postgresql
labels:
app: postgresql
spec:
replicas: 1
selector:
matchLabels:
app: postgresql
deployment: postgresql
template:
metadata:
labels:
app: postgresql
deployment: postgresql
spec:
containers:
- resources: {}
name: postgresql
envFrom:
- secretRef:
name: postgresql-credentials
ports:
- containerPort: 5432
protocol: TCP
imagePullPolicy: IfNotPresent
livenessProbe:
initialDelaySeconds: 30
tcpSocket:
port: 5432
timeoutSeconds: 1
readinessProbe:
exec:
command:
- "/bin/sh"
- "-i"
- "-c"
- "PGPASSWORD=${POSTGRES_PASSWORD} /usr/bin/psql -w -U ${POSTGRES_USER} -d ${POSTGRES_DB} -c 'SELECT 1'"
initialDelaySeconds: 5
timeoutSeconds: 1
terminationMessagePolicy: File
terminationMessagePath: /dev/termination-log
image: quay.io/debezium/example-postgres:latest
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
strategy:
type: Recreate
---
apiVersion: v1 (3)
kind: Service
metadata:
name: postgresql
spec:
selector:
app: postgresql
deployment: postgresql
ports:
- name: db
port: 5432
targetPort: 5432 | 1 | 提供数据库凭证的 Secret。 |
| 2 | 数据库部署。 |
| 3 | 数据库服务。 |
Secret 不仅作为环境变量附加到数据库 pod,而且稍后还将用于在连接器配置中引用这些凭据。
您可以通过运行以下命令来检查您的 PostgreSQL 数据库是否已正确部署。
$ kubectl get deployments -n debezium
NAME READY UP-TO-DATE AVAILABLE
postgresql 1/1 1 1 Kafka Broker
为了部署 Kafka Broker 实例,我们将利用 Strimzi Operator。
首先,我们将部署 Strimzi Operator 本身,运行以下命令。请注意 URL 中的 namespace 参数——它很重要,因为它确保 Strimzi 所需的 Kubernetes 对象在正确的命名空间中创建。
kubectl create -f https://strimzi.io/install/latest?namespace=debezium 一段时间后,您可以通过运行以下命令来检查您的 Strimzi Operator 是否正在运行。
$ kubectl get deployments -n debezium
NAME READY UP-TO-DATE AVAILABLE
strimzi-cluster-operator 1/1 1 1 安装好 Strimzi Operator 后,我们就可以部署 Kafka Broker 的实例了。
kubectl create -f https://raw.githubusercontent.com/debezium/debezium-examples/main/operator/tutorial-postgresql-kafka/infra/002_kafka-ephemeral.yml -n debezium 此命令按照所使用的 yaml 文件部署了 Kafka Broker 的最小工作配置。
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: dbz-kafka
spec:
kafka:
version: 3.4.0
replicas: 1
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
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.4"
storage:
type: ephemeral
zookeeper:
replicas: 1
storage:
type: ephemeral
entityOperator:
topicOperator: {}
userOperator: {} | 同样,此配置使用临时存储和单个 Kafka Broker 副本——这不适合生产环境的配置。 |
要检查您的 Kafka 部署,请执行以下操作。
$ kubectl get pods -n debezium
NAME READY STATUS RESTARTS
dbz-kafka-entity-operator-844ffdcd54-cdq92 3/3 Running 0
dbz-kafka-kafka-0 1/1 Running 0
dbz-kafka-zookeeper-0 1/1 Running 0 部署 Debezium Operator
拥有 Kubernetes 环境和所需的基础设施后,我们现在可以着手本教程的主要明星——全新的 Debezium Operator。目前有两种方法可以将 Operator 部署到您的 Kubernetes 集群。您可以将一组 Kubernetes 清单应用到您的集群(类似于我们对数据库和 Strimzi Operator 所做的),或者直接从 OperatorHub 算子目录中部署。
从 Operator Catalog 部署 Debezium Operator
在本节中,我们将使用 Operator Lifecycle Manager 来创建对 OperatorHub catalog 中可用 Operator 的订阅。正如我们之前提到的,Debezium 是 可用的 Operator 之一。
除其他外,使用 OLM 还允许您将 Operator 监视的命名空间范围从单个命名空间配置为整个集群。但是,此配置超出了本教程的范围。下面的过程会将 Operator 安装到 operators 命名空间——默认情况下,该命名空间用于集群范围的 Operator。
首先,我们需要安装 OLM 本身,运行以下 shell 命令——如果 OLM 已在您的集群中安装,请跳过此步骤。
| 这是一个一次性过程,任何提供对算子目录访问权限的生产 k8s 集群都将已安装 OLM。 |
curl -L https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.25.0/install.sh -o install.sh
chmod +x install.sh
./install.sh v0.25.0 一旦 OLM 在您的集群中启动并运行,您就可以订阅 Debezium Operator 了。
kubectl create -f https://raw.githubusercontent.com/debezium/debezium-examples/main/operator/tutorial-postgresql-kafka/infra/010_debezium-subscription.yml 同样,我们将检查 subscription.yml 文件的内容,以便更好地理解我们刚刚所做的事情。
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription (1)
metadata:
name: debezium-operator-subscription
namespace: operators (2)
spec:
installPlanApproval: Automatic
name: debezium-operator (3)
source: operatorhubio-catalog (4)
sourceNamespace: olm (5)
startingCSV: debezium-operator.v2.4.0 | 1 | Subscription 对象指示 OLM 从 Operator Catalog 安装一个 Operator。 |
| 2 | Operator 安装的目标命名空间。 |
| 3 | 已安装 Operator 的名称。 |
| 4 | Operator Catalog 的名称。 |
| 5 | 包含 Operator Catalog 的命名空间。 |
您可以在 OLM 文档 中了解有关通过 OLM 订阅安装 Operator 的更多信息。
现在,Debezium Operator 应该已准备好跨您的整个 Kubernetes 集群管理 Debezium Server 部署。您可以通过运行以下命令来检查 Operator 是否确实已启动并正在运行。
$ kubectl get deployments -n operators
NAME READY UP-TO-DATE AVAILABLE
debezium-operator 1/1 1 1 | 在上一个部分中,我们选择通过直接将一组 k8s 清单应用到我们的集群来部署 Strimzi Operator。但是,Strimzi 也是 OperatorHub catalog 中可用的 Operator 之一,因此也可以通过 OLM 安装。 |
使用原始 Kubernetes 清单部署 Debezium Operator
此选项允许将 Debezium Operator 部署到任何 Kubernetes 集群,而无需 OLM。
| 以这种方式部署的 Debezium Operator 将仅限于管理 **Operator 相同命名空间内的** Debezium Server 实例。 |
要部署 Debezium Operator,我们需要执行以下命令。
kubectl create -f https://raw.githubusercontent.com/debezium/debezium-operator/2.4/k8/debeziumservers.debezium.io-v1.yml
kubectl create -f https://raw.githubusercontent.com/debezium/debezium-operator/2.4/k8/kubernetes.yml -n debezium 第一个命令安装 Debezium Operator 所需资源的 Custom Resource Definitions,而第二次执行 kubectl 则部署 Operator 本身。
Operator 部署后,您现在可以部署 Debezium Server 实例以开始从数据库流式传输更改了。
将 Debezium Server 部署到 K8s 集群
无论以何种方式部署了 Debezium Operator,我们现在都可以部署 Debezium Server 本身了!
kubectl create -f https://raw.githubusercontent.com/debezium/debezium-examples/main/operator/tutorial-postgresql-kafka/infra/011_debezium-server-ephemeral.yml -n debezium 再次,让我们仔细看看我们刚刚部署的 Kubernetes 清单。
apiVersion: debezium.io/v1alpha1
kind: DebeziumServer (1)
metadata:
name: my-debezium (2)
spec:
image: quay.io/debezium/server:2.4.0.Final (3)
quarkus: (4)
config:
log.console.json: false
kubernetes-config.enabled: true
kubernetes-config.secrets: postgresql-credentials
sink: (5)
type: kafka
config:
producer.bootstrap.servers: dbz-kafka-kafka-bootstrap:9092
producer.key.serializer: org.apache.kafka.common.serialization.StringSerializer
producer.value.serializer: org.apache.kafka.common.serialization.StringSerializer
source: (6)
class: io.debezium.connector.postgresql.PostgresConnector
config:
offset.storage.file.filename: /debezium/data/offsets.dat
database.history: io.debezium.relational.history.FileDatabaseHistory
database.hostname: postgresql
database.port: 5432
database.user: ${POSTGRES_USER}
database.password: ${POSTGRES_PASSWORD}
database.dbname: ${POSTGRES_DB}
topic.prefix: inventory
schema.include.list: inventory | 1 | Debezium Operator 监视的资源类型。 |
| 2 | 已部署的 Debezium Server 实例的名称。 |
| 3 | 一个可选属性,指定容器镜像。 |
| 4 | Debezium Server 使用的 Quarkus 配置。 |
| 5 | Kafka 接收器配置。 |
| 6 | PostgreSQL 源连接器配置。 |
清单的 spec 部分对于任何有 Debezium Server 经验的人来说可能都很熟悉,因为它更结构化地组织了 Debezium Server 的属性配置。在我们的例子中,image 属性尤其冗余,因为它使用了已安装 Operator 版本的默认镜像。
spec 的 quarkus 部分为 Debezium Server 提供了对之前部署的 postgresql-credentials Secret 的访问,该 Secret 包含我们数据库的凭据。您可以看到 POSTGRES_USER 和其他变量在配置中稍后被引用。
在 GitHub 上可以找到 DebeziumServer 自定义资源的更详细描述。
幕后
Debezium Operator 将负责创建在 Kubernetes 中运行 Debezium Server 所需的一切。
-
用于运行 Debezium Server 的服务帐户。
-
允许读取 Debezium Server 部署所在命名空间中配置映射和 Secret 的角色和角色绑定。
-
包含 Debezium Server 原始配置的配置映射。
-
部署本身。
验证部署
您可以通过运行以下命令来检查已部署的 Debezium Server 实例是否正在运行。
$ kubectl get deployments -n debezium
NAME READY UP-TO-DATE AVAILABLE
my-debezium 1/1 1 1 Debezium Server 运行后,我们可以通过运行以下命令来验证它是否已从数据库中消费了所有初始数据。
kubectl exec dbz-kafka-kafka-0 -n debezium -- /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 \
--from-beginning \
--property print.key=true \
--topic inventory.inventory.orders 未来和我们的请求
目前就到这里。在 Operator 完全支持之前,我们打算提供更详细的文档,并能够通过各种方式进一步配置部署,例如自定义拉取 Secret 以支持存储在安全注册表中的自定义 Debezium Server 镜像。
未来还有计划改进 DebeziumServer 资源的结构,提供声明式组装定制化 Debezium Server 发行版的能力,甚至可能改进我们与 Knative eventing 的集成。我们还计划改进嵌入式引擎,进而改进 Debezium Server,这将使我们将来能够利用 Kubernetes 的水平扩展能力。
您可以帮助我们!
我们希望我们的精彩 Debezium 社区能够测试该 Operator,并告诉我们您喜欢和不喜欢什么,以及您缺少哪些功能。这样,我们就可以根据您的需求来塑造这个组件,并且我们将一起为提供云原生 CDC 功能的 Debezium 带来进一步的提升。
关于 Debezium
Debezium 是一个开源的分布式平台,可以将现有数据库转变为事件流,使应用程序能够几乎即时地看到并响应数据库中已提交的每个行级更改。Debezium 构建在 Kafka 之上,并提供了 Kafka Connect 兼容的连接器,用于监控特定的数据库管理系统。Debezium 将数据更改的历史记录在 Kafka 日志中,这样您的应用程序可以随时停止和重新启动,并可以轻松地消费在未运行时错过的所有事件,确保所有事件都被正确且完整地处理。Debezium 在 Apache 许可证 2.0 下是 开源 的。