news 2026/10/13 7:33:41

kgateway mTLS 测试客户端证书指南:verify-certificate-hash 与 FrontendTLSConfig 的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
kgateway mTLS 测试客户端证书指南:verify-certificate-hash 与 FrontendTLSConfig 的完整实践
  • API网关
  • 云原生
  • 微服务

【免费下载链接】kgateway

The Cloud-Native API Gateway and AI Gateway

项目地址:https://gitcode.com/gh_mirrors/kg/kgateway
点击查看免费下载

本篇指南基于 kgateway 仓库中test/e2e/features/frontendtls/testdata/下的客户端证书体系(CLIENT_CERTS_README.md),系统讲解 kgateway 双向 TLS(mTLS)端到端测试所需的 CA 与客户端证书的生成、指纹计算、Kubernetes 资源封装方式,以及它们如何被verify-certificate-hash注解、verify-subject-alt-names注解和 Gateway API 的FrontendTLSConfig验证机制消费。读完本文,你将掌握一套可复现的 mTLS 测试证书生产流程,并理解 kgateway 前端 TLS 验证链路的底层实现。

背景:为什么需要一套专门的 mTLS 测试证书

kgateway 作为云原生 API 网关,支持在 HTTPS 监听器上启用双向 TLS(mutual TLS)认证。在 test/e2e/features/frontendtls/ 目录下的端到端测试套件中,验证了多种客户端证书校验机制:

  • verify-certificate-hash注解:基于客户端证书的 SHA256 指纹做"证书钉扎"(certificate pinning),只接受指纹匹配的特定证书;
  • FrontendTLSConfig:基于 CA 证书链校验客户端证书,并通过AllowValidOnly/AllowInsecureFallback两种模式控制客户端证书是"必需"还是"可选";
  • verify-subject-alt-names注解:校验客户端证书的 SAN(Subject Alternative Name)扩展;
  • signature-algorithms注解:校验客户端证书所使用的签名算法。

这些机制对应的注解与 TLS 选项定义在 api/annotations/gateway.go 中,包括kgateway.dev/verify-subject-alt-names、kgateway.dev/verify-certificate-hash、kgateway.dev/signature-algorithms、kgateway.dev/alpn-protocols、kgateway.dev/cipher-suites、kgateway.dev/ecdh-curves、kgateway.dev/min-tls-version与kgateway.dev/max-tls-version。

为了让测试能够精确覆盖"证书指纹匹配 / 不匹配""CA 链有效 / 无效""SAN 匹配 / 不匹配""签名算法受支持 / 不受支持"等正反场景,测试仓库维护了多套由不同 CA 签发的客户端证书。证书本身不直接存放原始.crt/.key/.pem文件(仓库中仅保留少量用于说明的原始文件,如certs/ca1/下的client-8443.crt),而是以 base64 编码的 Kubernetes Secret 与 ConfigMap 形态提交,并配有一份详细的生成文档。

证书目录结构

证书按照用途组织在 test/e2e/features/frontendtls/testdata/certs/ 下,每个子目录对应一组测试场景:

目录用途关键资源
certs/ca1/CA 证书 1 及其签发的客户端证书ca-cert-configmap.yaml(CA 1 ConfigMap)、client-cert-secret.yaml(FrontendTLSConfig 测试用客户端证书)、client-certs-8443-9443-secret.yaml(8443/9443 端口用客户端证书)
certs/ca2/CA 证书 2 及其签发的客户端证书ca-cert-2-configmap.yaml(CA 2 ConfigMap,位于独立命名空间ca-cert-2)、client-cert-2-secret.yaml(多 CA 测试用客户端证书)
certs/ca-alt-names/verify-subject-alt-names 测试的 CA 与客户端证书ca-alt-names-configmap.yaml、client-matching-san-secret.yaml(SAN 为DNS:mtls.example.com,应通过)、client-non-matching-san-secret.yaml(SAN 为DNS:mtls-alt.example.com,应拒绝)
certs/ca-sigalgs/signature-algorithms 测试的 CA 与客户端证书ca-sigalgs-configmap.yaml、client-matching-signature-secret.yaml(RSA+SHA256 签名,应通过)、client-non-matching-signature-secret.yaml(ECDSA+SHA256 签名,应拒绝)

关于该目录结构,有几点需要注意:

  1. 测试只消费 YAML 清单中的 base64 编码证书。原始证书文件(.crt、.key、.pem)是证书生成的产物,仓库中一般不提交,可通过下文"证书生成"一节的命令重新生成。
  2. 中间产物不提交。生成过程中产生的.csr(证书签名请求)和.srl(序列号)文件属于临时工件,同样不进入仓库,只有最终封装进 YAML 清单的证书才是必需的。
  3. 服务端 TLS 证书单独存放。服务端证书tls-rsa-secret.yaml、tls-ecdsa-p256-secret.yaml位于 testdata 根目录,与gw.yaml、curl-pod-with-certs.yaml、curl-namespace.yaml(负责创建curl命名空间、curl Pod 及其挂载的客户端证书 Secret)并列。
  4. 两类验证机制共享同一套 CA。ca1与ca2的 CA 证书同时支撑两种校验路径:verify-certificate-hash校验具体证书的指纹,FrontendTLSConfig校验证书链是否由受信 CA 签发。也正因为如此,gw.yaml的 8443/9443 监听器可以在同一监听器上同时配置这两个机制。

证书生成:完整的 openssl 流程

以下命令来自关联文档的"Certificate Generation"章节,是当前测试证书体系的可复现生产流程。所有证书均使用 RSA 2048 密钥。

Step 1:生成 CA 证书与私钥

openssl genrsa -out ca-key.pem 2048 openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem \ -subj "/CN=Test CA/O=Test Org"

CA 证书(CN=Test CA, O=Test Org)随后以 PEM 格式写入 ConfigMap。参考 ca-cert-configmap.yaml,其data.ca.crt字段即该证书文本,kgateway 从 ConfigMap 中读取该值作为信任锚。

Step 2:生成 8443 端口客户端证书

openssl genrsa -out client-8443.key 2048 openssl req -new -key client-8443.key -out client-8443.csr \ -subj "/C=US/ST=California/L=San Francisco/O=Client Inc./CN=client.example.com" openssl x509 -req -days 3650 -in client-8443.csr -CA ca-cert.pem -CAkey ca-key.pem \ -CAcreateserial -out client-8443.crt

Step 3:生成 9443 端口客户端证书

openssl genrsa -out client-9443.key 2048 openssl req -new -key client-9443.key -out client-9443.csr \ -subj "/C=US/ST=California/L=San Francisco/O=Client Inc./CN=client-alt.example.com" openssl x509 -req -days 3650 -in client-9443.csr -CA ca-cert.pem -CAkey ca-key.pem \ -CAcreateserial -out client-9443.crt

8443 与 9443 两套证书均被封装进 client-certs-8443-9443-secret.yaml,字段为client-8443.crt、client-8443.key、client-9443.crt、client-9443.key。由于两者由同一 CA 签发且证书指纹不同,正好用于验证"跨监听器交叉使用证书必然失败"的负向场景。

Step 4:生成 FrontendTLSConfig 测试客户端证书(8444/8445 端口)

openssl genrsa -out client-frontend.key 2048 openssl req -new -key client-frontend.key -out client-frontend.csr \ -subj "/CN=client.example.com/O=Test Org" openssl x509 -req -days 3650 -in client-frontend.csr -CA ca-cert.pem -CAkey ca-key.pem \ -CAcreateserial -out client-frontend.crt # Base64 encode and update certs/ca1/client-cert-secret.yaml: base64 -i client-frontend.crt | tr -d '\n' base64 -i client-frontend.key | tr -d '\n'

生成的证书与私钥分别写入 client-cert-secret.yaml 的data.tls.crt与data.tls.key。该 Secret 的tls.crt/tls.key键名与 Kubernetes 标准的kubernetes.io/tls类型 Secret 一致,挂载后可直接作为tls.crt/tls.key文件使用(参见下文 curl Pod 挂载路径/etc/client-certs-frontend/tls.crt)。

Step 5:生成第二套 CA(多 CA 测试)

# Generate second CA certificate and key openssl genrsa -out ca2-key.pem 2048 openssl req -new -x509 -days 365 -key ca2-key.pem -out ca2-cert.pem \ -subj "/CN=Test CA 2/O=Test Org" # Base64 encode and update certs/ca2/ca-cert-2-configmap.yaml: base64 -i ca2-cert.pem | tr -d '\n'

第二套 CA 的 ConfigMap 比较特殊:它所在的命名空间为ca-cert-2(见 ca-cert-2-configmap.yaml,清单内同时声明了该 Namespace)。这意味着在网关配置中引用它时必须显式给出namespace字段(参见下文gw.yaml中 8446 端口的caCertificateRefs)。

Step 6:生成由第二套 CA 签发的客户端证书(8446 端口)

# Generate client certificate signed by CA 2 openssl genrsa -out client2-key.pem 2048 openssl req -new -key client2-key.pem -out client2.csr \ -subj "/CN=client2.example.com/O=Test Org" openssl x509 -req -days 3650 -in client2.csr -CA ca2-cert.pem -CAkey ca2-key.pem \ -CAcreateserial -out client2-cert.pem # Base64 encode and update certs/ca2/client-cert-2-secret.yaml: base64 -i client2-cert.pem | tr -d '\n' base64 -i client2-key.pem | tr -d '\n'

除上述命令外,SAN 与签名算法测试的证书还涉及两个额外要点(记录在对应 Secret 清单的生成注释中):

  • SAN 证书需要在req与x509阶段附加扩展:openssl req ... -addext "subjectAltName = DNS:mtls.example.com",并在签发时通过-extfile <(echo "subjectAltName = DNS:mtls.example.com")保留 SAN;
  • 签名算法测试中,匹配证书以 RSA 密钥 + SHA256 签名(对应rsa_pss_rsae_sha256),不匹配证书使用 ECDSA 密钥,用于验证签名算法白名单的拒绝行为。

SHA256 指纹计算

verify-certificate-hash注解要求提供客户端证书的 SHA256 指纹。关联文档给出了从证书文件计算冒号分隔大写指纹的命令:

# For port 8443 certificate openssl x509 -in client-8443.crt -noout -fingerprint -sha256 | cut -d= -f2 | \ tr -d ':' | awk '{for(i=1;i<=length($0);i+=2) printf "%s:", substr($0,i,2); print ""}' | \ sed 's/:$//' | tr '[:lower:]' '[:upper:]' # For port 9443 certificate openssl x509 -in client-9443.crt -noout -fingerprint -sha256 | cut -d= -f2 | \ tr -d ':' | awk '{for(i=1;i<=length($0);i+=2) printf "%s:", substr($0,i,2); print ""}' | \ sed 's/:$//' | tr '[:lower:]' '[:upper:]'

该流程依次执行:提取-fingerprint输出的等号后指纹、去掉冒号、按两个字符一组重新插入冒号、去掉尾部冒号并转为大写。

已计算好的指纹如下:

  • Port 8443 cert:59:CF:81:16:72:71:C7:17:23:4E:CE:4F:F9:B9:68:B5:B0:40:2A:00:BB:14:64:E0:42:B9:AD:DA:61:C7:03:F0
  • Port 9443 cert:E8:44:3B:AA:87:7C:DD:71:31:59:02:77:A4:2F:20:C6:B6:F5:7B:02:29:07:E0:F7:8C:21:DE:41:5B:28:CF:BB

注解值的底层解析与校验

从源码看,kgateway.dev/verify-certificate-hash注解的解析位于 pkg/kgateway/translator/sslutils/ssl_utils.go 的ApplyVerifyCertificateHash函数:

  • 注解值先经splitFakeYamlArray切分——该函数支持以逗号(,)或连字符(-)分隔、允许空白填充的"伪 YAML 数组"语法,因此单个监听器可配置多个允许的证书指纹;
  • 每个 hash 再经validateCertificateHash校验:合法形式是 64 个十六进制字符(无分隔),或由冒号分隔成 32 对十六进制字符(对应正则^[[:xdigit:]]{2}(:[[:xdigit:]]{2}){31}$);
  • 校验通过后写入 IR 结构ir.TLSConfig.VerifyCertificateHash(定义于 pkg/pluginsdk/ir/gw2.go)。

注解常量本身定义在 api/annotations/gateway.go:值可以是 "7D:86:..."(冒号分隔)或 "7D86..."(连续 hex)等格式,且受 Gateway API AnnotationValue 规范约 4096 字符长度限制。TLSExtensionOptionFuncs映射(见 ssl_utils.go)统一将kgateway.dev/前缀下的 8 个 TLS 扩展选项分发到各自的解析函数,并保证"未知键报错、拼写错误不静默忽略"。

证书在测试中的挂载与使用

curl Pod 与 Secret 挂载

测试通过 curl-pod-with-certs.yaml 创建一个curl命名空间下的 Pod(镜像ghcr.io/kgateway-dev/curl:8.20.0),以只读方式挂载 7 个 Secret,并设置defaultMode: 0444。挂载路径与证书来源的对应关系如下:

Pod 内路径对应 Secret来源清单用途
/etc/client-certs/client-8443.crt/client-8443.keyclient-certsclient-certs-8443-9443-secret.yaml8443 监听器(verify-certificate-hash)
/etc/client-certs/client-9443.crt/client-9443.keyclient-certs同上9443 监听器(verify-certificate-hash)
/etc/client-certs-frontend/tls.crt/tls.keyclient-certclient-cert-secret.yaml(CA 1 签发)8444/8445 端口 FrontendTLSConfig 测试
/etc/client-certs-2-frontend/tls.crt/tls.keyclient-cert-2client-cert-2-secret.yaml(CA 2 签发)8446 端口多 CA 测试
/etc/client-matching-san/tls.crt/tls.keyclient-matching-sanclient-matching-san-secret.yaml(SANDNS:mtls.example.com)verify-subject-alt-names 正向用例
/etc/client-non-matching-san/tls.crt/tls.keyclient-non-matching-sanclient-non-matching-san-secret.yaml(SANDNS:mtls-alt.example.com)verify-subject-alt-names 负向用例
/etc/client-matching-signature/tls.crt/tls.keyclient-matching-signaturecerts/ca-sigalgs/下对应 Secret(RSA 签名)signature-algorithms 正向用例
/etc/client-non-matching-signature/tls.crt/tls.keyclient-non-matching-signaturecerts/ca-sigalgs/下对应 Secret(ECDSA 签名)signature-algorithms 负向用例

在 test/e2e/features/frontendtls/suite.go 中,prerequisiteManifests()将这些 Secret、CA ConfigMap 与服务端证书清单统一收集,由SetupSuite在 curl Pod 调度之前按顺序应用——因为 kubelet 若在 Secret 尚不存在时挂载卷,会因失败进入指数退避,导致 Pod 卡在ContainerCreating超过基础套件的 60s 就绪超时。TearDownSuite则负责清理这些前置资源(遵循框架不删除命名空间的规则,ca-cert-2与curl命名空间得以保留)。

网关配置:验证机制如何接线

gw.yaml 是理解各机制如何协同的关键。它同时使用了两种配置入口:

入口一:Gateway 的spec.tls.frontend(FrontendTLSConfig 风格)

在spec.tls.frontend下通过default与perPort定义全局与按端口的前端 TLS 校验:

  • default.validation.mode: AllowValidOnly+caCertificateRefs: [ca-cert]——默认要求客户端证书且必须由 CA 签发;
  • 端口 443:AllowInsecureFallback——允许无客户端证书(用于测试 TLS 选项本身,而非证书校验);
  • 端口 8444:AllowInsecureFallback——专门验证"客户端证书可选"的降级模式;
  • 端口 8446:AllowValidOnly+两个caCertificateRefs(ca-cert与命名空间ca-cert-2下的ca-cert-2)——验证多 CA 支持(对应 issue #12938),客户端证书由任一 CA 签发均可被接受;
  • 端口 8447:AllowValidOnly+ CAca-alt-names-cert——配合监听器上的verify-subject-alt-names做 SAN 校验;
  • 端口 8448:AllowValidOnly+ CAca-sigalgs-cert——配合监听器上的signature-algorithms做签名算法校验。

其中mode的两个取值语义为:AllowValidOnly要求必须提供客户端证书且必须验证通过;AllowInsecureFallback在客户端未提供证书时降级放行(提供证书时仍会验证)。

入口二:Listener 的tls.options注解

在具体监听器的tls.options中配置 kgateway 扩展注解:

  • https-mtls(8443,主机mtls.example.com):kgateway.dev/verify-certificate-hash: "59:CF:81:16:72:71:C7:17:23:4E:CE:4F:F9:B9:68:B5:B0:40:2A:00:BB:14:64:E0:42:B9:AD:DA:61:C7:03:F0"——该值即 8443 客户端证书的 SHA256 指纹,与 FrontendTLSConfig 默认配置(AllowInsecureFallback)叠加;
  • https-mtls-alt(9443,主机mtls-alt.example.com):verify-certificate-hash指向 9443 证书指纹;
  • https-verify-subject-alt-names(8447):kgateway.dev/verify-subject-alt-names: "mtls.example.com"——客户端证书必须携带该 SAN;
  • https-client-signature-algorithms(8448):kgateway.dev/signature-algorithms: "rsa_pss_rsae_sha256,rsa_pkcs1_sha256"——客户端证书签名算法必须命中白名单。

注意verify-certificate-hash与 FrontendTLSConfig 可以在同一监听器上并存:前者做"证书钉扎"(校验特定证书指纹),后者做"链校验"(校验证书链可信性),两者是互补关系。此外 api/annotations/gateway.go 明确指出verify-subject-alt-names注解要求先配置受信 CA。

对应地,gw.yaml为每个 mTLS 监听器都定义了指向httpbin服务的 HTTPRoute(如mtls-route关联https-mtls、mtls-alt-route关联https-mtls-alt、frontend-tls-multiple-ca-route使用通配主机*.example.com),测试通过 curl 携带--cert/--key发起真实请求来断言结果。

测试验证:四组用例的行为矩阵

测试套件注册了 11 个测试用例(见 suite.go),其中与客户端证书直接相关的是TestVerifyCertificateHash、TestFrontendTLSConfig、TestMultipleCACertificates、TestVerifySubjectAltNames与TestClientSignatureAlgorithms。

verify-certificate-hash 测试(TestVerifyCertificateHash)

对应 suite.go,使用 curl 的--cert/--key参数携带证书断言:

  1. 8443 监听器上,使用指纹匹配的 8443 证书 → 连接成功;
  2. 8443 监听器上,使用 9443 证书(指纹不匹配)→ 连接失败;
  3. 8443 监听器上,不提供客户端证书 → 连接失败(mTLS 强制校验);
  4. 9443 监听器上,使用 9443 证书 → 成功;使用 8443 证书 → 失败;不提供证书 → 失败(端口间交叉验证);
  5. 常规监听器 443 无需客户端证书即可正常工作——证明 mTLS 仅作用于配置过的监听器。

verify-subject-alt-names 测试(TestVerifySubjectAltNames)

对应 suite.go,针对 8447 监听器(要求 SANmtls.example.com):

  1. 使用client-matching-san.crt(SAN 为DNS:mtls.example.com)→ 握手成功;
  2. 使用client-non-matching-san.crt(SAN 为DNS:mtls-alt.example.com)→ 握手被拒(断言 curl 错误码 55,CURLE_SEND_ERROR)。

该用例确保缺少必需 SAN 的证书在 mTLS 握手阶段即被正确拒绝。

signature-algorithms 测试(TestClientSignatureAlgorithms)

对应 suite.go,针对 8448 监听器(要求rsa_pss_rsae_sha256):

  1. 使用 RSA+SHA256 签名的client-matching-signature.crt→ 成功;
  2. 使用 ECDSA+SHA256 签名的client-non-matching-signature.crt→ 失败(错误码 55)。

该用例保证签名算法白名单之外的证书被拒绝。

FrontendTLSConfig 测试(TestFrontendTLSConfig)

对应 suite.go:

  1. 8445(AllowValidOnly):无客户端证书 → 失败(错误码 55,SSL 错误);
  2. 8445(AllowValidOnly):携带 CA 1 签发的有效客户端证书 → 成功;
  3. 8444(AllowInsecureFallback):无客户端证书 → 成功;
  4. 8444(AllowInsecureFallback):携带有效证书 → 成功。

多 CA 证书测试(TestMultipleCACertificates)

对应 suite.go,针对 8446 监听器(AllowValidOnly + 多 CA 引用 + 通配域*.example.com,访问test.example.com):

  1. 使用 CA 1 签发的证书 → 成功;
  2. 使用 CA 2 签发的证书 → 成功;
  3. 不提供证书 → 失败(错误码 55)。

多 CA 支持的关键结论:FrontendTLSConfig 的caCertificateRefs数组支持多个 CA 引用;配置多个 CA 后,由其中任意一个 CA 签发的客户端证书都会被接受。这在 CA 迁移或需要同时服务多个客户组织(不同证书颁发机构)的场景下非常实用;并且该能力与通配域协同工作——同一通配域模式(如*.example.com)可以对应多个根 CA 证书。

源码实现链路小结

把上文内容串起来,kgateway 对这几类校验的执行路径是:

  1. 配置读取:Gateway 的spec.tls.frontend(FrontendTLSConfig)与监听器tls.options注解(kgateway.dev/前缀)分别承载 CA 引用与指纹/SAN/签名算法约束,注解常量见 api/annotations/gateway.go;
  2. IR 翻译:ApplyTLSExtensionOptions将选项解析进ir.TLSConfig(VerifyCertificateHash、VerifySubjectAltNames等字段定义于 pkg/pluginsdk/ir/gw2.go),其中指纹解析与格式校验在 ssl_utils.go 完成;
  3. XDS 下发与握手执行:最终由 Envoy 依据 IR 生成下行 TLS 配置,在握手阶段执行证书指纹比对、CA 链校验、SAN 校验与签名算法筛选;
  4. 端到端验证:测试套件以 curl Pod 挂载的各类证书驱动真实请求,断言成功或失败(错误码 35/55),形成闭环回归保障。

若要在本地复现这套证书体系,只需按本文的 openssl 命令依次执行并更新对应 ConfigMap/Secret 的 base64 数据即可;若只是运行现有 e2e 测试,则仓库中的 YAML 清单已经开箱即用,无需自行生成证书。

  • API网关
  • 云原生
  • 微服务

【免费下载链接】kgateway

The Cloud-Native API Gateway and AI Gateway

项目地址:https://gitcode.com/gh_mirrors/kg/kgateway
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 7:33:29

后缀表达式求值:栈结构实现的轻量计算器内核

1. 这不是教科书里的“栈”——而是一个能立刻跑起来的计算器内核你有没有试过在终端里敲下3 4 5 *&#xff0c;回车就直接输出35&#xff1f;没有图形界面、不依赖 Python 的eval()、不调用任何数学库——就靠一个数组加两个指针&#xff0c;从左到右扫一遍&#xff0c;结果稳…

作者头像 李华
网站建设 2026/10/13 7:33:17

外置式V型永磁游标电机建模:磁场调制让25A产出122.8N·m

简介&#xff1a;面向电机设计与电气工程方向的毕业设计&#xff0c;这套外置式V型永磁游标电机资料围绕24槽19极、额定转速300rpm、额定电流25A、输出转矩122.8N.m的新型结构展开&#xff0c;重点展现低速大扭矩场景下的选型与参数化建模思路&#xff0c;适合研究生、本科生及…

作者头像 李华
网站建设 2026/10/13 7:32:55

PowerShell配置Conda环境全攻略与性能优化

1. 为什么需要PowerShell激活Conda环境作为Windows平台最强大的脚本工具&#xff0c;PowerShell与Python数据科学黄金搭档Conda的强强联合&#xff0c;能极大提升开发效率。但很多人在初次使用时都会遇到环境激活失败的问题&#xff0c;这通常是因为没有正确配置执行策略或环境…

作者头像 李华
网站建设 2026/10/13 7:32:34

冰袋热力学原理与使用时长优化方案

1. 项目背景与核心价值冰袋作为常见的降温工具&#xff0c;在医疗冷链、食品保鲜、户外活动等领域应用广泛。但很多人都有这样的困惑&#xff1a;为什么同样大小的冰袋&#xff0c;有时能持续降温8小时&#xff0c;有时却只能维持3小时&#xff1f;这背后其实涉及到冰融化过程中…

作者头像 李华
网站建设 2026/10/13 7:32:15

Airflow 2.7+ 快速启动指南:Docker Compose 零配置运行 DAG

简介&#xff1a;本资源是面向Python数据工程师与DevOps实践者的Apache Airflow生态学习导航包&#xff0c;聚焦工作流编排、调度优化与生产级落地场景&#xff0c;帮助初学者快速入门、进阶者系统梳理最佳实践。压缩包共7个文件&#xff08;54KB&#xff09;&#xff0c;含2份…

作者头像 李华
网站建设 2026/10/13 7:32:12

zan彩色虚拟打印机5.0.10安装与图片转PDF参数调优实战

简介&#xff1a;zan彩色虚拟打印机中文版5.0.10是一款面向办公人员、设计工作者及需要频繁转换文件格式用户的虚拟打印工具&#xff0c;通过模拟物理打印机将任意可打印文档输出为JPEG、PNG等图片或PDF文件&#xff0c;解决在线分享、存档与格式转换需求。压缩包为rar格式&…

作者头像 李华