CouchDB Helm Chart 4.5.6 发布说明解读:从发布历史看 Apache CouchDB Helm Chart 的演进与配置实践 CouchDB Helm Chart 4.5.6 发布说明解读从发布历史看 Apache CouchDB Helm Chart 的演进与配置实践【免费下载链接】budibaseAI agents, automations and apps that run your operations. Model agnostic.项目地址: https://gitcode.com/GitHub_Trending/bu/budibase导读本文以 Budibase 仓库中 couchdb 子 Chart 的 NEWS.md即 Apache CouchDB 官方 Helm Chart 的发布说明为主体逐版本梳理 3.6.2 至 4.5.6 之间的功能演进与缺陷修复并结合 values.yaml 与 templates 下的模板源码深入剖析每个发布要点背后的配置参数与实现原理。读完本文你将掌握该 Chart 的端口暴露、网络策略、密钥管理、集群自动初始化、存储保留策略、安全上下文等核心配置能力并能在 Budibase 的 Helm 部署体系中准确落位这些参数。一、Chart 与发布说明的定位在继续逐条解读之前先明确这份 NEWS.md 在仓库中的位置和它对应的是哪个 Chart。Budibase 的 Helm 部署入口是 charts/budibase/Chart.yaml其中声明了依赖dependencies: - name: couchdb version: 4.5.6 repository: https://apache.github.io/couchdb-helm condition: services.couchdb.enabled也就是说仓库charts/budibase/charts/couchdb/目录下的内容包括这份 NEWS.md 及其 Chart 元数据 charts/budibase/charts/couchdb/Chart.yaml正是 Apache CouchDB 官方 Helm Chart4.5.6 版本的 vendored 副本。其appVersion: 3.3.3默认镜像为couchdb:3.3.3。注意NEWS.md 是从旧到新排列的顶部是4.5.6最新底部是3.6.2本文件所记录的最早版本。下文按“从旧到新”的时间线解读以还原真实的演进脉络。在 Budibase 主 Chart 中CouchDB 作为应用的数据层出现因此这份 NEWS.md 涉及的每一项能力最终都会体现在services.couchdb.enabled被开启时实际部署的 StatefulSet、Service、NetworkPolicy 等资源上。Budibase 主 Chart 还在 charts/budibase/values.yaml 的couchdb键下覆写了若干子 Chart 默认值如clusterSize: 1、自定义镜像budibase/database:2.1.0、SQS 端口等这为我们观察上游能力如何被下游消费提供了绝佳视角。二、存储与密钥相关的早期修复3.6.2 – 3.6.42.1 3.6.2erlangCookie 有状态化自动生成Change theerlangCookieto be auto-generated in a stateful fashion (i.e. we auto-generate it once, then leave that value alone).#78erlangCookie是 Erlang 分布式节点间认证的共享密钥。在 CouchDB 集群中所有节点必须使用同一个 cookie 才能互连。此版本之前cookie 可能在每次渲染模板时被重新生成导致集群节点间失联。修复后cookie 在首次生成后保持不变。实现位于 templates/secrets.yaml通过couchdb.defaultsecret-stateful辅助模板完成data: {{- $erlangCookieArgs : dict key erlangCookie ns $.Release.Namespace secretName (include couchdb.fullname .) secret .Values.erlangFlags.setcookie }} erlangCookie: {{ template couchdb.defaultsecret-stateful $erlangCookieArgs }}其语义是优先复用集群中已存在的 Secret 中对应 key 的值只有不存在时才用 values 里提供的值或自动生成新值。这保证了helm upgrade不会因为重新生成 cookie 而破坏既有集群。在 StatefulSet 中该 cookie 通过环境变量注入每个 CouchDB 容器- name: COUCHDB_ERLANG_COOKIE valueFrom: secretKeyRef: name: {{ template couchdb.fullname . }} key: erlangCookie另外 values.yaml 中的erlangFlags也值得注意erlangFlags: name: couchdb # setcookie: make-something-upname标志是节点互连所必需的会被拼进ERL_FLAGSsetcookie选项是为了兼容3.2.1 之前的旧版镜像——那些版本不读取COUCHDB_ERLANG_COOKIE环境变量只能通过 ERL_FLAGS 传入 cookie。2.2 3.6.3PersistentVolume 注解支持Add PersistentVolume annotations此版本允许为持久化卷声明附加注解对应的 values 配置为persistentVolume: enabled: false existingClaims: [] annotations: {} accessModes: - ReadWriteOnce size: 10Gi mountPath: /data # storageClass: -annotations会被模板 persistentvolume.yaml当使用existingClaims时与volumeClaimTemplates在 statefulset.yaml 中通过persistentVolume.metadata辅助模板渲染合并到 PVC 元数据上。典型用途包括为 PVC 打上备份/快照相关的标签或注解标记卷归属团队、环境或成本中心附加存储驱动所需的特定注解。2.3 3.6.4service.labels 与 Ingress 后端切换Addservice.labelsvalue to pass along labels to the client-facing serviceUpdateingressto use the service created byservice.enabledtrue, instead of the headless service#94This allows settingservice.annotations,service.labels, etc. in a way that will be picked up by the ingress这是对外暴露能力的一次重要调整包含两点新增service.labels允许为面向客户端的 Service 附加自定义标签Ingress 的后端从headless Service用于集群内部节点间通信的稳定网络标识切换为service.enabledtrue创建的常规 Service。配置如下values.yamlservice: annotations: {} enabled: true type: ClusterIP externalPort: 5984 targetPort: 5984 labels: {} extraPorts: []模板实现位于 templates/service.yamllabels 与 annotations 均会渲染到 Service 元数据中metadata: name: {{ template couchdb.svcname . }} labels: app: {{ template couchdb.name . }} chart: {{ .Chart.Name }}-{{ .Chart.Version | replace _ }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} {{- with .Values.service.labels }} {{- . | toYaml | nindent 4 }} {{- end }} {{- with .Values.service.annotations }} annotations: {{- . | toYaml | nindent 4 }} {{- end }}而 templates/ingress.yaml 中通过couchdb.svcname辅助模板解析 Service 名{{- $serviceName : include couchdb.svcname . -}} {{- $servicePort : .Values.service.externalPort -}} ... backend: service: name: {{ $serviceName }} port: number: {{ $servicePort }}这解决了什么实际问题此前 Ingress 指向 headless Service而 headless Service 不提供稳定的虚拟 IP 和负载均衡语义且无法灵活附加 annotations/labels例如 AWS 上常用的service.beta.kubernetes.io/aws-load-balancer-*系列注解。切换之后所有针对常规 Service 的定制TLS 终止、负载均衡器类型、内部注解等都能被 Ingress 正确消费。在 Budibase 中的实际应用Budibase 主 Chart 为 CouchDB 定义了 SQS 端口暴露charts/budibase/values.yamlservice: extraPorts: - name: sqs port: 4984 targetPort: 4984 protocol: TCP正是依赖 3.6.4 之后 Service 模板对extraPorts的正确支持详见下文 4.5.4/4.5.5 的演进Budibase 的 SQS 服务hosting/sqs才能经由该 Service 被工作负载访问。三、4.0.0adminHash 简化Simplified theadminHashin the secret4.0.0 将 Secret 中adminHash的写入方式简化。现在的实现templates/secrets.yaml{{- if .Values.adminHash }} adminHash: {{ .Values.adminHash | b64enc | quote }} {{- end }}即直接对 values 中提供的 PBKDF2 哈希做 base64 编码写入 Secret不再进行额外的组合或二次计算。对应 values 中的说明adminUsername: admin # adminPassword: this_is_not_secure # adminHash: -pbkdf2-this_is_not_necessarily_secure_either # cookieAuthSecret: neither_is_thisadminHash的典型使用场景不想让明文密码出现在 values 或 Secret 中。管理员可先离线生成 PBKDF2 哈希如couchdb官方工具或-pbkdf2-前缀格式再通过adminHash注入。当设置了adminHash时StatefulSet 会额外启用一个admin-hash-copyinit 容器templates/statefulset.yaml把哈希写入/local.d/password.ini- name: admin-hash-copy image: {{ .Values.initImage.repository }}:{{ .Values.initImage.tag }} env: - name: ADMINUSERNAME valueFrom: secretKeyRef: name: {{ template couchdb.fullname . }} key: adminUsername - name: ADMINHASH valueFrom: secretKeyRef: name: {{ template couchdb.fullname . }} key: adminHash command: [sh,-c,echo -e [admins]\n$ADMINUSERNAME $ADMINHASH /local.d/password.ini ;]这段命令在容器启动前生成[admins]配置节CouchDB 启动时从local.d加载该管理员定义。整个链路清晰体现了哈希进 Secret → init 容器落地配置文件 → CouchDB 读取的完整闭环。四、4.1.0autoSetup 自动集群初始化Added theautoSetupto automatically finalize the cluster after installation这是本 Chart 最具实战价值的特性之一。手动方式下CouchDB 集群安装完成后还需要调用/_cluster_setupAPIenable_cluster→add_node→finish_cluster才能真正完成集群组建autoSetup通过一个post-install Job自动化了这一过程。4.1.1 配置项autoSetup: enabled: false image: repository: curlimages/curl tag: latest pullPolicy: Always defaultDatabases: - _global_changes4.1.2 前置条件values 中的注释给出了明确约束需要service.enabled: trueJob 通过 Service 的 DNS 名访问集群如果使用adminHashSecret 中必须存在有效的adminPasswordJob 用用户名/密码调用 API安装时应使用--wait标志避免首个 Job 失败helm install --wait ...。4.1.3 Job 实现模板位于 templates/job.yaml核心逻辑{{- if and .Values.autoSetup.enabled .Values.service.enabled -}} apiVersion: batch/v1 kind: Job metadata: name: {{ .Release.Name }}-post-install annotations: helm.sh/hook: post-install spec: template: spec: restartPolicy: OnFailure containers: - name: cluster-setup image: {{ .Values.autoSetup.image.repository }}:{{ .Values.autoSetup.image.tag }} command: - sh - -c - curl -s http://$COUCHDB_ADDRESS/_cluster_setup -X POST -H Content-Type: application/json -d {\action\: \finish_cluster\} -u $COUCHDB_ADMIN:$COUCHDB_PASS export IFS,; for db_name in $DEFAULT_DBS; do curl -X PUT http://$COUCHDB_ADDRESS/$db_name -u $COUCHDB_ADMIN:$COUCHDB_PASS; done env: - name: DEFAULT_DBS value: {{ join , .Values.autoSetup.defaultDatabases }} - name: COUCHDB_ADDRESS value: {{ template couchdb.svcname . }}.{{ .Release.Namespace }}.svc.{{ default cluster.local .Values.dns.clusterDomainSuffix }}:{{ .Values.service.externalPort}} - name: COUCHDB_ADMIN valueFrom: secretKeyRef: name: {{ template couchdb.fullname . }} key: adminUsername - name: COUCHDB_PASS valueFrom: secretKeyRef: name: {{ template couchdb.fullname . }} key: adminPassword backoffLimit: 2 ttlSecondsAfterFinished: 600值得注意的实现细节Job 使用 curl 容器默认curlimages/curl向/_cluster_setup发送{action: finish_cluster}消息自动创建默认数据库DEFAULT_DBS环境变量由defaultDatabases以逗号连接Job 循环执行curl -X PUT .../$db_name创建每个数据库。默认值是_global_changesCouchDB 3.x 集群必需的内部数据库集群内 DNS 解析COUCHDB_ADDRESS使用svcname.namespace.svc.clusterDomainSuffix:externalPort的 FQDN 格式其中clusterDomainSuffix由 values.yaml 的dns.clusterDomainSuffix控制默认cluster.local健壮性restartPolicy: OnFailurebackoffLimit: 2允许有限次重试ttlSecondsAfterFinished: 600让 Job 完成后 10 分钟自动清理避免残留。提醒autoSetup与--wait组合使用时需要 Helm 等待 post-install hook 成功才算安装完成。若 Job 因故失败如 Service 尚未就绪、凭证错误安装会被标记为失败并回滚这正是注释要求加--wait的原因。五、4.3.0Ingress 从 annotation 迁移到 classNameUse IngressclassNameinstead ofkubernetes.io/ingress.classannotation which has been deprecated since Kubernetes 1.18#69Kubernetes 1.18 起kubernetes.io/ingress.class注解被spec.ingressClassName字段取代。4.3.0 完成迁移values 中新增ingress: enabled: false # className: nginx hosts: - chart-example.local path: / annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: true tls: # - secretName: chart-example-tls # hosts: # - chart-example.local模板实现templates/ingress.yamlspec: {{- if .Values.ingress.className }} ingressClassName: {{ .Values.ingress.className }} {{- end }} rules: {{- range $host : .Values.ingress.hosts }} - host: {{ $host }} http: paths: - path: {{ $path }} pathType: Prefix backend: service: name: {{ $serviceName }} port: number: {{ $servicePort }} {{- end -}} {{- if .Values.ingress.tls }} tls: {{ toYaml .Values.ingress.tls | indent 4 }} {{- end -}}配置时只需在className中填写 IngressClass 名称如nginx、alb、traefik无需再依赖注解annotations依然保留用于 TLS 证书签发如kubernetes.io/tls-acme: true等非 class 类注解。六、4.4.1service.targetPort 可定制Add possibility to customizeservice.targetPortfrom values. Set default to 5984.此版本之前targetPort是模板硬编码的 5984现在开放为可配置项默认值仍为 5984。对应 valuesservice: externalPort: 5984 targetPort: 5984模板templates/service.yamlspec: ports: - port: {{ .Values.service.externalPort }} name: couchdb protocol: TCP targetPort: {{ .Values.service.targetPort }}适用场景当 CouchDB 容器内部监听端口被修改例如通过couchdbConfig.chttpd.port改为非 5984 端口或通过自定义镜像改变监听端口时无需改镜像只需调整targetPort让 Service 指向正确的容器端口即可。七、4.5.x端口扩展与安全相关的四个版本7.1 4.5.0pod 与容器级 securityContextAdd capability to set pod and container level securityContext settings.Kubernetes 的安全加固能力在此版本被完整引入对应两个新增 values未在 values.yaml 中显式声明默认值按需提供podSecurityContext作用于 Pod 级别的安全上下文如runAsUser、fsGroup、seccompProfile等containerSecurityContext作用于容器的安全上下文如allowPrivilegeEscalation、capabilities、readOnlyRootFilesystem等。模板中的落位templates/statefulset.yaml{{- if .Values.podSecurityContext }} securityContext: {{ .Values.podSecurityContext | toYaml | nindent 8 }} {{- end }}{{- if .Values.containerSecurityContext }} securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 12 }} {{- end }}同样的两个 values 也被应用到 init 容器init-copy、admin-hash-copy和 autoSetup Jobtemplates/job.yaml中。这意味着只需配置一次Pod 内所有容器都能获得一致的安全约束。7.2 4.5.1默认 CouchDB 版本升至 3.3.3Update default CouchDB version to 3.3.3.对应 Chart.yaml 的appVersion: 3.3.3与 values 默认镜像image: repository: couchdb tag: 3.3.3 pullPolicy: IfNotPresentCouchDB 3.3.3 属于 3.3.x 稳定线随附的couchdb-config、vm.args等默认配置与 clouseauLucene 全文检索兼容性已在官方镜像中验证。7.3 4.5.2PVC 保留策略Allow to specify a persistentVolumeClaimRetentionPolicy in both the primary and secondary StatefulSet.Kubernetes 1.27beta引入的persistentVolumeClaimRetentionPolicy允许控制 StatefulSet 被删除或缩容时 PVC 的去留。values 配置# Experimental - FEATURE STATE: Kubernetes v1.27 [beta] persistentVolumeClaimRetentionPolicy: enabled: false whenScaled: Retain whenDeleted: Retain模板templates/statefulset.yaml中该策略与volumeClaimTemplates绑定{{- if .Values.persistentVolumeClaimRetentionPolicy.enabled }} persistentVolumeClaimRetentionPolicy: whenDeleted: {{ .Values.persistentVolumeClaimRetentionPolicy.whenDeleted }} whenScaled: {{ .Values.persistentVolumeClaimRetentionPolicy.whenScaled }} {{- end }} volumeClaimTemplates: - metadata: {{- include persistentVolume.metadata (dict context .) | nindent 8 }} spec: {{- include persistentVolume.spec (dict context .) | nindent 8 }}可取值包括Retain删除 StatefulSet 或缩容时保留 PVC与Delete级联删除 PVC。默认值Retain/Retain是偏保守的选择即使误删 StatefulSet数据卷也会被保留以便恢复代价是需要手动清理不再需要的 PVC。7.4 4.5.3imagePullSecrets 修复Fix ability to define pull secrets usingimagePullSecrets.此版本修复了imagePullSecrets无法生效的问题。values 中预留了配置位# imagePullSecrets: # - name: myimagepullsecret模板templates/statefulset.yaml{{- if .Values.imagePullSecrets }} imagePullSecrets: {{ .Values.imagePullSecrets | toYaml | nindent 8 }} {{- end }}适用场景使用私有镜像仓库拉取 CouchDB 镜像时如内网镜像源、企业私有 registry需要先创建对应的kubernetes.io/dockerconfigjson类型 Secret然后在 values 中引用。该修复确保列表形式的imagePullSecrets能正确渲染到 Pod spec。7.5 4.5.4extraPorts 与 service.extraPortsExposeextraPortsandservice.extraPortsto allow specifying arbitrary ports to be exposed from the CouchDB pods这是 4.5.x 系列中与端口暴露直接相关的重要特性包含两个层面Pod 容器层extraPorts——为 CouchDB 容器声明额外监听端口# -- If you need to expose any additional ports on the CouchDB container, for example # if youre running CouchDB container with additional processes that need to # be accessible outside of the pod, you can define them here. extraPorts: [] # - name: sqs # containerPort: 4984模板templates/statefulset.yaml中渲染到容器 portsports: - name: couchdb containerPort: 5984 - name: epmd containerPort: 4369 - containerPort: 9100 {{- if .Values.prometheusPort.enabled }} - name: metrics containerPort: {{ .Values.prometheusPort.port }} {{- end }} {{ with .Values.extraPorts }} {{ toYaml . | indent 12 }} {{ end }}Service 层service.extraPorts——为客户端 Service 声明额外转发端口service: extraPorts: [] # - name: sqs # port: 4984 # targetPort: 4984 # protocol: TCP模板templates/service.yamlspec: ports: - port: {{ .Values.service.externalPort }} name: couchdb protocol: TCP targetPort: {{ .Values.service.targetPort }} {{ with .Values.service.extraPorts }} {{- toYaml . | nindent 4 }} {{- end }}Budibase 的实战印证Budibase 主 Chart 在 charts/budibase/values.yaml 中同时使用了这两项来暴露SQS 端口 4984couchdb: extraPorts: - name: sqs containerPort: 4984 service: extraPorts: - name: sqs port: 4984 targetPort: 4984 protocol: TCP这是因为 Budibase 的数据库镜像budibase/database内置了 SQS结构化查询服务二进制位于 hosting/sqs需要对外提供 4984 端口。主 Chart 通过容器端口 Service 端口的成对配置完整打通了从 Pod 到 Service 到工作负载的访问链路。7.6 4.5.5为默认 Service 端口命名Give the default port on the CouchDBServicea name so thatservice.extraPortscan be used properly.这是对 4.5.4 的一个必要修补。Kubernetes Service 要求多端口 Service 中每个端口必须具有唯一的name用于 DNS SRV 记录与协议区分。4.5.4 新增service.extraPorts后若默认端口没有名称多端口场景下模板渲染会校验失败。4.5.5 在 templates/service.yaml 中为默认端口补上了name: couchdbports: - port: {{ .Values.service.externalPort }} name: couchdb protocol: TCP targetPort: {{ .Values.service.targetPort }}同时保留端口声明时的protocol: TCP显式标注确保与extraPorts中的任意协议声明兼容。7.7 4.5.6NetworkPolicy 同步 extraPortsAddextraPortsto the network policy when the network policy is enabled.最后一个版本将端口扩展能力闭环到网络层。Chart 默认启用 NetworkPolicyvalues.yamlnetworkPolicy: enabled: true模板templates/networkpolicy.yaml的 Ingress 规则中除了固定放行 5984及可选的 Prometheus 端口外遍历extraPorts将其全部加入允许列表spec: podSelector: matchLabels: {{ include couchdb.ss.selector . | indent 6 }} ingress: - ports: - protocol: TCP port: 5984 {{- if .Values.prometheusPort.enabled }} - protocol: TCP port: {{ .Values.prometheusPort.port }} {{- end }} {{ range .Values.extraPorts }} - protocol: TCP port: {{ .containerPort }} {{ end }} - ports: - protocol: TCP port: 9100 - protocol: TCP port: 4369 from: - podSelector: matchLabels: {{ include couchdb.ss.selector . | indent 14 }} policyTypes: - Ingress规则拆解第一组端口5984 Prometheus extraPorts允许任意来源访问这些端口——这是客户端包括 Budibase 的 app/worker 服务访问 CouchDB 及扩展服务如 SQS 4984的入口第二组端口9100 与 43699100是 CouchDB 集群内部使用的端口chttpd内部通信4369是 Erlang 的 EPMD 端口两者仅允许来自同 Chart CouchDB Pod 之间的流量即集群节点间通信外部不可达。这意味着什么如果你在extraPorts中声明了额外端口而 NetworkPolicy 未同步放行流量会被网络策略直接丢弃——这正是 4.5.6 修复的核心价值容器端口 → Service 端口 → NetworkPolicy 放行三层必须保持同步端口暴露链路才完整。Budibase 场景下SQS 4984 端口在启用 NetworkPolicy 时同样会获得放行无需额外配置。八、结合 Budibase 主 Chart 的完整配置示例将上述所有能力整合可以看到 Budibase 主 Chart 对 CouchDB 子 Chart 的实际覆写charts/budibase/values.yamlservices: couchdb: enabled: true port: 5984 backup: enabled: false target: interval: resources: {} couchdb: # 默认单节点需要高可用可改为 3 clusterSize: 1 # Budibase 自定义数据库镜像内置 Clouseau 与 SQS不建议更换 image: repository: budibase/database tag: 2.1.0 pullPolicy: Always # CouchDB 数据目录 extraEnvs: - name: DATA_DIR value: /data # 持久化存储 persistentVolume: enabled: true accessModes: - ReadWriteOnce size: 10Gi mountPath: /data # 暴露 SQS 端口容器层 extraPorts: - name: sqs containerPort: 4984 # 暴露 SQS 端口Service 层 service: extraPorts: - name: sqs port: 4984 targetPort: 4984 protocol: TCP # Clouseau 由镜像内置此处保持关闭 enableSearch: false # 固定 UUID couchdbConfig: couchdb: uuid: budibase-couchdb可以清晰看到 4.5.4/4.5.5/4.5.6 三个版本如何在 Budibase 中协同生效extraPorts声明容器端口、service.extraPorts声明 Service 端口、NetworkPolicy 自动放行——三者缺一不可。而persistentVolumeClaimRetentionPolicy、podSecurityContext/containerSecurityContext、imagePullSecrets等能力则为你按需加固生产部署提供了选项。九、结语一份 NEWS 背后的一整套集群运维能力单看表面NEWS.md 只是十数条版本变更记录但结合 Chart 源码与 Budibase 的实际消费方式它实际勾勒出 Apache CouchDB Helm Chart 一条完整的演进主线版本核心能力对应的 values 键3.6.2erlangCookie 有状态化自动生成erlangFlags.setcookie/ SecreterlangCookie3.6.3PersistentVolume 注解persistentVolume.annotations3.6.4service.labelsIngress 指向常规 Serviceservice.labels/service.annotations4.0.0adminHash 简化adminHash4.1.0autoSetup 自动集群初始化autoSetup.*4.3.0Ingress 迁移至ingressClassNameingress.className4.4.1service.targetPort 可定制service.targetPort4.5.0pod/容器级 securityContextpodSecurityContext/containerSecurityContext4.5.1默认 CouchDB 3.3.3image.tag4.5.2PVC 保留策略persistentVolumeClaimRetentionPolicy.*4.5.3imagePullSecrets 修复imagePullSecrets4.5.4extraPorts 与 service.extraPortsextraPorts/service.extraPorts4.5.5默认 Service 端口命名service模板层4.5.6NetworkPolicy 同步 extraPortsnetworkPolicy.enabledextraPorts对使用 Budibase Helm Chart 的开发者而言这份发布说明的价值在于它能告诉你当前部署的 CouchDB 子 Chart 支持哪些运维能力、哪些已知缺陷已修复、以及新端口/新配置上线时需要注意哪些联动关系。当你在生产环境中开启 NetworkPolicy、配置私有镜像拉取、调整持久化策略或加固容器安全时上述每一个版本号都对应着你可以安全依赖的成熟特性。【免费下载链接】budibaseAI agents, automations and apps that run your operations. Model agnostic.项目地址: https://gitcode.com/GitHub_Trending/bu/budibase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考