原文地址: https://debezium.io/blog/2019/12/13/externalized-secrets/
欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯.
使用 Debezium 连接器实现秘密外部化
十二月 13, 2019 作者: Jiri Pechanec
mysql 的 秘密示例
当 Debezium 连接器部署到 Kafka Connect 实例时,有时需要对 Connect API 的其他用户隐藏数据库凭据。
让我们回顾一下 MySQL Debezium 连接器的连接器注册请求:
{
“name”: “inventory-connector”,
“config”: {
“connector.class”: “io.debezium.connector.mysql.MySqlConnector”,
“tasks.max”: “1”,
“database.hostname”: “mysql”,
“database.port”: “3306”,
“database.user”: “debezium”,
“database.password”: “dbz”,
“database.server.id”: “184054”,
“database.server.name”: “dbserver1”,
“database.whitelist”: “inventory”,
“database.history.kafka.bootstrap.servers”: “kafka:9092”,
“database.history.kafka.topic”: “schema-changes.inventory”
}
}
和作为纯字符串传递给 API username。password更糟糕的是,任何有权访问 Kafka Connect 集群及其 REST API 的人都可以发出请求GET来获取连接器的配置,包括数据库凭据:
curl -s http://localhost:8083/connectors/inventory-connector | jq .
{
“name”: “inventory-connector”,
“config”: {
“connector.class”: “io.debezium.connector.mysql.MySqlConnector”,
“database.user”: “debezium”,
“database.server.id”: “184054”,
“tasks.max”: “1”,
“database.hostname”: “mysql”,
“database.password”: “dbz”,
“database.history.kafka.bootstrap.servers”: “kafka:9092”,
“database.history.kafka.topic”: “schema-changes.inventory”,
“name”: “inventory-connector”,
“database.server.name”: “dbserver1”,
“database.whitelist”: “inventory”,
“database.port”: “3306”
},
“tasks”: [
{
“connector”: “inventory-connector”,
“task”: 0
}
],
“type”: “source”
}
如果一个 Kafka Connect 集群由多个连接器/团队共享,那么出于安全原因,这种行为可能是不可取的。
为了解决这个问题,Kafka 2.0 中实现了KIP-297 (“连接配置的外部化秘密”)。
外部化期望至少有一个org.apache.kafka.common.config.provider.ConfigProvider接口的实现类。org.apache.kafka.common.config.provider.FileConfigProviderKafka Connect 提供了从文件读取机密的参考实现。可用的配置提供程序在 Kafka Connect 工作线程级别进行配置(例如在 中connect-distributed.properties),并从连接器配置中引用。
工作人员配置的一个示例如下:
config.providers=file
config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider
连接器注册请求将像这样引用它:
{
“name”: “inventory-connector”,
“config”: {
“connector.class”: “io.debezium.connector.mysql.MySqlConnector”,
“tasks.max”: “1”,
“database.hostname”: “mysql”,
“database.port”: “3306”,
“database.user”: “
f
i
l
e
:
/
s
e
c
r
e
t
s
/
m
y
s
q
l
.
p
r
o
p
e
r
t
i
e
s
:
u
s
e
r
"
,
"
d
a
t
a
b
a
s
e
.
p
a
s
s
w
o
r
d
"
:
"
{file:/secrets/mysql.properties:user}", "database.password": "
file:/secrets/mysql.properties:user","database.password":"{file:/secrets/mysql.properties:password}”,
“database.server.id”: “184054”,
“database.server.name”: “dbserver1”,
“database.whitelist”: “inventory”,
“database.history.kafka.bootstrap.servers”: “kafka:9092”,
“database.history.kafka.topic”: “schema-changes.inventory”
}
}
在这里,占位符${file:/secrets/mysql.properties:user}表示应该使用文件配置提供程序,读取属性文件并从中/secrets/mysql.properties提取属性。user
文件配置提供程序可能是最简单的实现,并且可以预期将会出现与秘密存储库或身份管理系统集成的其他提供程序。应该注意的是,文件配置提供程序在 Kubernetes/OpenShift 部署中是令人满意的,因为secrets对象可以作为文件注入到集群 pod 中,从而被集群 pod 消耗。
我们创建了 Debezium教程示例的一个版本,它演示了外部化机密的部署。请注意 Docker Compose 服务中的两个环境变量connect:
- CONNECT_CONFIG_PROVIDERS=file
- CONNECT_CONFIG_PROVIDERS_FILE_CLASS=org.apache.kafka.common.config.provider.FileConfigProvider
这些环境变量作为图像的功能直接映射到 Kafka Connect 工作线程属性中debezium/connect。
当您发出 REST 调用来获取连接器配置时,您将看到敏感信息已被外部化并且对未经授权的用户屏蔽:
curl -s http://localhost:8083/connectors/inventory-connector | jq .
{
“name”: “inventory-connector”,
“config”: {
“connector.class”: “io.debezium.connector.mysql.MySqlConnector”,
“database.user”: “
f
i
l
e
:
/
s
e
c
r
e
t
s
/
m
y
s
q
l
.
p
r
o
p
e
r
t
i
e
s
:
u
s
e
r
"
,
"
d
a
t
a
b
a
s
e
.
s
e
r
v
e
r
.
i
d
"
:
"
184054
"
,
"
t
a
s
k
s
.
m
a
x
"
:
"
1
"
,
"
d
a
t
a
b
a
s
e
.
h
o
s
t
n
a
m
e
"
:
"
m
y
s
q
l
"
,
"
d
a
t
a
b
a
s
e
.
p
a
s
s
w
o
r
d
"
:
"
{file:/secrets/mysql.properties:user}", "database.server.id": "184054", "tasks.max": "1", "database.hostname": "mysql", "database.password": "
file:/secrets/mysql.properties:user","database.server.id":"184054","tasks.max":"1","database.hostname":"mysql","database.password":"{file:/secrets/mysql.properties:password}”,
“database.history.kafka.bootstrap.servers”: “kafka:9092”,
“database.history.kafka.topic”: “schema-changes.inventory”,
“name”: “inventory-connector”,
“database.server.name”: “dbserver1”,
“database.whitelist”: “inventory”,
“database.port”: “3306”
},
“tasks”: [
{
“connector”: “inventory-connector”,
“task”: 0
}
],
“type”: “source”
}
请参阅教程示例的自述文件以获取完整说明。