S3 存储配置
本文档介绍如何为 Tekton Results 日志归档配置与 S3 兼容的存储(例如 Ceph)。
概述
Tekton Results 支持将归档日志存储到 S3 兼容的对象存储系统中,例如 Ceph、AWS S3、MinIO 等。这提供了一种可扩展且持久的长期日志保留方案,替代了效率较低的基于 PVC 的存储机制。
主要优势
- 可扩展性:对象存储可水平扩展,不受块存储的限制
- 持久性:对象存储系统内置冗余和复制能力
- 成本效益:与持久卷相比,存储成本更低
- 长期保留:适用于合规性要求和历史故障排查
前提条件
存储系统要求
- S3 兼容的对象存储服务(Ceph、AWS S3、MinIO 等)
- 能够创建 bucket 和管理凭证的访问权限
- Kubernetes 集群到 S3 端点的网络连通性
权限
- 能够创建 bucket
- 对指定日志 bucket 具备读/写/删除权限
- 已正确配置 IAM 策略或访问控制
配置概述
Tekton Results 的 S3 存储配置包含两个主要部分:
- S3 凭证和连接参数 存储在 Kubernetes Secrets 中
- 在 TektonConfig 自定义资源的
spec.result 下启用 S3 配置
配置参数参考
Secret 中的 S3 专用参数
参数详情
- S3_BUCKET_NAME:Tekton 日志将存储到的 S3 bucket 名称。请确保该 bucket 已存在并具备适当权限。
- S3_ENDPOINT:S3 服务端点 URL。对于 AWS S3,可以省略。对于 Ceph、MinIO 等 S3 兼容服务,这是必需的。
- S3_REGION:S3 服务所在的地域。对于 AWS S3,请使用对应的 AWS 地域标识符。对于 S3 兼容服务,请使用服务中配置的地域标识符。
- S3_ACCESS_KEY_ID 和 S3_SECRET_ACCESS_KEY:用于向 S3 服务进行身份验证的凭证。
- S3_HOSTNAME_IMMUTABLE:用于某些需要主机名不可变性的 S3 兼容服务。
- S3_MULTI_PART_SIZE:定义何时使用分段上传的大小阈值。较大的值可提升大文件的性能。
基本配置
若要进行基本的 S3 存储设置,请按以下步骤操作:
1. 准备 S3 存储
在配置 Tekton Results 之前,请确保已具备:
- 可用的 S3 兼容存储系统(Ceph、AWS S3、MinIO 等)
- 专用于 Tekton 日志的 bucket
- 具备适当权限(读、写、删除)的有效访问凭证
- Kubernetes 集群到 S3 端点的网络连通性
2. 创建 S3 凭证 Secret
创建一个包含 S3 凭证和配置的 Kubernetes Secret:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-s3-secret
namespace: tekton-pipelines
stringData:
S3_BUCKET_NAME: tekton-logs
S3_ENDPOINT: https://your-ceph-endpoint.example.com
S3_HOSTNAME_IMMUTABLE: "false"
S3_REGION: region-1
S3_ACCESS_KEY_ID: your-access-key-id
S3_SECRET_ACCESS_KEY: your-secret-access-key
S3_MULTI_PART_SIZE: "5242880"
逐步创建过程:
-
识别你的 S3 参数:
- 将存储日志的 bucket 名称
- S3 端点 URL(例如,Ceph 使用
https://ceph.example.com)
- 合适的地域标识符
- 具备读/写/删除权限的访问凭证
-
使用 kubectl 创建 Secret:
kubectl create secret generic my-s3-secret \
--namespace="tekton-pipelines" \
--from-literal=S3_BUCKET_NAME=tekton-logs \
--from-literal=S3_ENDPOINT=https://your-ceph-endpoint.example.com \
--from-literal=S3_HOSTNAME_IMMUTABLE=false \
--from-literal=S3_REGION=region-1 \
--from-literal=S3_ACCESS_KEY_ID=your-access-key-id \
--from-literal=S3_SECRET_ACCESS_KEY=your-secret-access-key \
--from-literal=S3_MULTI_PART_SIZE=5242880
示例输出:
secret/my-s3-secret created
-
验证 Secret 已创建:
kubectl get secret my-s3-secret -n tekton-pipelines
示例输出:
NAME TYPE DATA AGE
my-s3-secret Opaque 7 5m
3. 配置 TektonConfig 资源
在 TektonConfig 配置中启用 S3 存储:
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
# 启用 logs API 并指定 S3 作为存储类型
logs_api: true
logs_type: S3
# 引用 S3 凭证 Secret
secret_name: my-s3-secret
# 如果使用外部数据库(生产环境推荐)
is_external_db: true
db_host: your-postgres-host.example.com
db_port: 5432
db_name: tekton_results
db_sslmode: require
db_secret_name: tekton-results-postgres
TIP
你可以将 S3 存储配置与外部数据库配置结合起来,形成完整的生产环境部署。
4. 应用配置
-
应用 TektonConfig 配置:
kubectl apply -f tekton-config-s3-config.yaml
示例输出:
tektonconfig.operator.tekton.dev/config configured
-
等待组件重启:
kubectl rollout status -n tekton-pipelines deployment/tekton-results-api
示例输出:
deployment "tekton-results-api" successfully rolled out
kubectl rollout status -n tekton-pipelines deployment/tekton-results-watcher
示例输出:
deployment "tekton-results-watcher" successfully rolled out
-
验证配置已生效:
kubectl get pods -n tekton-pipelines
示例输出:
NAME READY STATUS RESTARTS AGE
tekton-results-api-7d5b8c9c4-xl2v9 1/1 Running 0 10m
tekton-results-watcher-6b4f7c8d5-z3n4p 1/1 Running 0 10m
tekton-results-retention-policy-agent-5c9g2 1/1 Running 0 10m
高级配置
自定义分段大小
为了优化上传性能,你可以调整分段大小:
# 在你的 S3 Secret 中
stringData:
S3_MULTI_PART_SIZE: "10485760" # 10MB 分段大小
Ceph 专用配置
当使用 Ceph 作为 S3 兼容存储时:
- 如果 Ceph 配置要求,将
S3_HOSTNAME_IMMUTABLE 设置为 "true"
- 使用 Ceph 集群提供的正确端点 URL
- 确保 Ceph RGW(RADOS Gateway)已正确配置为支持 S3 兼容性
完整生产环境配置示例
下面是结合 S3 存储和外部数据库的完整配置示例,并附带详细说明:
---
# S3 凭证 Secret
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: tekton-results-s3-credentials
namespace: tekton-pipelines
stringData:
# S3 配置
S3_BUCKET_NAME: tekton-logs-prod
S3_ENDPOINT: https://ceph-storage.company.com
S3_HOSTNAME_IMMUTABLE: "false"
S3_REGION: ceph-region
S3_ACCESS_KEY_ID: your-ceph-access-key
S3_SECRET_ACCESS_KEY: your-ceph-secret-key
S3_MULTI_PART_SIZE: "5242880" # 5MB 分段阈值
---
# TektonConfig 配置
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
# 启用基于 S3 的日志存储
logs_api: true
logs_type: S3
# 外部数据库配置
is_external_db: true
db_host: postgres.company.com
db_port: 5432
db_name: tekton_results
db_sslmode: require
db_secret_name: tekton-results-postgres # 单独的数据库凭证
secret_name: tekton-results-s3-credentials # S3 凭证
MinIO 专用配置示例
MinIO 对象存储的配置示例:
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: minio-s3-credentials
namespace: tekton-pipelines
stringData:
S3_BUCKET_NAME: tekton-logs
S3_ENDPOINT: https://minio.company.com
S3_HOSTNAME_IMMUTABLE: "false"
S3_REGION: us-east-1
S3_ACCESS_KEY_ID: MINIO_ACCESS_KEY
S3_SECRET_ACCESS_KEY: MINIO_SECRET_KEY
S3_MULTI_PART_SIZE: "5242880"
---
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
logs_api: true
logs_type: S3
secret_name: minio-s3-credentials
最大日志大小配置
若要限制每个 TaskRun 存储的日志大小,可以在 TektonConfig 中使用 spec.result.options 字段配置 max-log-size 参数。重要:此功能需要先启用 MaxLogSize feature gate。 这是一个增强功能(基于 patch),当前在社区版 Tekton Results 中尚不可用。
Feature Gate 配置
在配置 max-log-size 之前,你需要通过设置相应的 feature flags 来启用 MaxLogSize feature gate。
要启用该 feature gate,可以将 FEATURE_GATES 环境变量设置为包含 MaxLogSize=true:
FEATURE_GATES='PartialResponse=true,MaxLogSize=true'
另一种方法是通过 TektonConfig 选项,直接在 tekton-results-api deployment 上配置 FEATURE_GATES 环境变量:
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
options:
deployments:
tekton-results-api:
spec:
template:
spec:
containers:
- name: api # 这应与原始 deployment 中的容器名称匹配
env:
- name: FEATURE_GATES
value: "PartialResponse=true,MaxLogSize=true"
注意:MaxLogSize feature flag 通常通过 Tekton feature flags 中的 MaxResultSize 配置实现(如 FeatureFlags 结构中所示),它用于控制可存储结果的最大大小。
最大日志大小配置示例
启用 feature gate 后,你可以配置 max-log-size 参数:
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
logs_api: true
logs_type: S3
secret_name: my-s3-secret
# 可选:通过 options 配置最大日志大小限制
options:
configMaps:
tekton-results-api-config: # 该 ConfigMap 必须存在
data:
max-log-size: "5242880" # 字节数(5 MiB)
配置详情:
- 用途:限制每个 TaskRun 日志的大小,防止存储无限增长并确保查询性能稳定
- 默认值:默认使用 5 MiB(5242880 字节)
- 行为:当 TaskRun 日志超过配置限制时,系统会保留日志的 开头部分,并丢弃尾部。将
max-log-size 设置为 "0" 可禁用此大小限制功能并上传完整日志内容。
- 注意:这是一个 增强功能(基于 patch),当前在上游 Tekton Results 中不可用
- 前提:要使此功能生效,必须启用 MaxLogSize feature gate。
WARNING
重要警告
这是一个 alpha 阶段功能,后续发布版本中其行为可能会发生变化。
运维
更新 S3 配置
修改 S3 配置后,需要重启 Tekton Results 组件才能使更改生效。
重启 API server:
kubectl delete pod -n tekton-pipelines -l app.kubernetes.io/name=tekton-results-api
示例输出:
pod "tekton-results-api-7d5b8c9c4-xl2v9" deleted
重启 watcher:
kubectl delete pod -n tekton-pipelines -l app.kubernetes.io/name=tekton-results-watcher
示例输出:
pod "tekton-results-watcher-6b4f7c8d5-z3n4p" deleted
验证命令
# 检查 TektonConfig 状态
kubectl get tektonconfig config -o yaml
示例输出:
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
logs_api: true
logs_type: S3
secret_name: my-s3-secret
is_external_db: true
db_host: postgres.company.com
status:
conditions:
- type: Ready
status: "True"
reason: InstallSucceeded
message: "Install successful"
# 检查 pod 日志中的 S3 连通性
kubectl logs -n tekton-pipelines -l app.kubernetes.io/name=tekton-results-api
示例输出:
{"level":"info","ts":"2023-05-15T10:30:45.123Z","caller":"api/main.go:89","msg":"Starting Tekton Results API server"}
{"level":"info","ts":"2023-05-15T10:30:45.124Z","caller":"s3/client.go:45","msg":"Successfully connected to S3 storage"}
{"level":"info","ts":"2023-05-15T10:30:45.125Z","caller":"api/server.go:123","msg":"API server listening on :8080"}
# 验证 Secret 是否存在
kubectl get secret my-s3-secret -n tekton-pipelines
# 验证 pod 是否使用 S3 配置运行
kubectl get pods -n tekton-pipelines -l app.kubernetes.io/name=tekton-results-api
示例输出:
NAME READY STATUS RESTARTS AGE
tekton-results-api-7d5b8c9c4-xl2v9 1/1 Running 0 10m
kubectl get pods -n tekton-pipelines -l app.kubernetes.io/name=tekton-results-watcher
示例输出:
NAME READY STATUS RESTARTS AGE
tekton-results-watcher-6b4f7c8d5-z3n4p 1/1 Running 0 10m
最佳实践
安全注意事项
- 使用专用凭证:为 Tekton Results 创建专用的 S3 凭证,仅授予所需的最小权限(针对特定 bucket 的读、写、删除)
- 安全存储凭证:将凭证存储在 Kubernetes Secrets 中,而不是明文配置文件中
- 定期轮换凭证:建立流程,定期轮换 S3 访问密钥(例如每季度一次)
- 网络安全:确保集群与 S3 端点之间的网络连接安全,优先使用私有网络或 VPN
- 最小权限原则:仅向 S3 凭证授予最少必需权限
- 加密:确保你的 S3 兼容存储支持存储日志的服务器端加密
性能优化
- 合适的分段大小:根据网络状况调整
S3_MULTI_PART_SIZE(默认 5MB,但在高延迟网络中 10-15MB 可能更合适)
- bucket 放置位置:尽可能将 S3 bucket 放在与集群相同的地域,以减少延迟
- 监控:为 S3 存储使用率、上传/下载性能以及错误率建立监控
- 连接池:Tekton Results 会自动管理到 S3 服务的连接池
- 带宽考虑:确保集群与 S3 存储之间有足够的网络带宽
存储管理
- 保留策略:为 S3 bucket 实施生命周期策略,自动清理旧日志
- 存储类:根据不同的日志保留周期考虑使用不同的 S3 存储类
- 压缩:如果 S3 兼容存储支持,可启用压缩
- 对象标签:使用 S3 对象标签按 namespace、pipeline 或其他条件组织日志
命名规范
- 使用包含环境信息的描述性 bucket 名称(例如
tekton-logs-prod、tekton-logs-staging)
- 为 Secret 使用一致的命名(例如
tekton-results-s3-credentials)
- 在运行多个实例时使用环境特定前缀
- 为配置资源使用清晰且一致的命名
运维建议
- 健康监控:定期监控 Tekton Results 组件和 S3 存储连通性的健康状况
- 备份策略:虽然 S3 具备持久性,但仍应确保在系统故障时能够访问日志
- 容量规划:根据常见的 PipelineRun/TaskRun 数量规划日志存储增长
- 测试:定期测试日志检索功能,确保 S3 连通性持续正常
- 文档:维护最新的 S3 端点详情和访问流程文档
S3 兼容存储专用建议
- Ceph:确保 Ceph RGW 已正确配置并经过 S3 兼容性测试
- MinIO:验证 MinIO server 设置,以获得 Tekton Results 的最佳性能
- AWS S3:检查 AWS IAM 策略,并在适用时确保正确的跨账户访问
- 性能调优:不同的 S3 兼容存储系统可能需要不同的分段大小或连接设置
安全注意事项
凭证管理
- 安全存储:将 S3 凭证存储在 Kubernetes Secrets 中,绝不要放在明文配置文件中
- 访问控制:使用 RBAC 限制对包含 S3 凭证的 Secret 的访问
- 轮换流程:为 S3 访问凭证建立定期轮换计划
- 最小权限原则:仅授予最少必需权限(针对特定 bucket 的读、写、删除)
网络安全
- 加密连接:始终使用 HTTPS/SSL 连接到 S3 兼容存储
- 私有网络:尽可能使用私有网络或 VPN 连接到 S3 端点
- 防火墙规则:配置适当的防火墙规则以限制对 S3 端点的访问
- 证书验证:确保 SSL 连接已正确配置证书验证
监控与审计
- 访问日志:在 S3 兼容存储上启用访问日志以跟踪操作
- 异常检测:监控异常访问模式或身份验证失败尝试
- 审计轨迹:保留凭证访问和配置变更的审计轨迹
- 安全告警:为安全相关事件设置告警
故障排查
常见问题
-
S3 连接错误:
- 验证 S3 端点 URL 是否正确且可访问
- 检查集群到 S3 端点的网络连通性
- 如果使用 HTTPS,请验证 SSL 证书
- 确认可从集群内部访问该端点
-
身份验证失败:
- 确认访问密钥和密钥访问密钥正确
- 验证 IAM 策略是否授予了所需权限
- 检查地域配置是否与 S3 服务地域匹配
- 确保凭证未过期或未被轮换
-
权限被拒绝:
- 确保凭证对 bucket 具有读/写/删除权限
- 验证 bucket 策略允许来自你的集群的访问
- 检查 bucket 是否存在,以及是否可使用提供的凭证访问
-
日志上传缓慢:
- 调整分段大小以获得最佳性能
- 检查集群与 S3 端点之间的网络带宽
- 验证 S3 服务性能
- 监控网络拥塞或限流情况
-
日志缺失:
- 验证 watcher 组件是否正确捕获日志
- 检查日志是否已存储在 S3 中,但无法通过 API 访问
- 确认保留策略未过早删除日志
-
配置问题:
- 确保所有必需的 S3 参数都已正确指定
- 验证 TektonConfig 资源是否已正确配置
- 检查 Secret 格式是否正确且可访问
安全相关问题
-
凭证泄露:
- 检查 Secret 是否未在日志或错误消息中暴露
- 验证凭证是否未存储在配置文件中
- 确保 RBAC 策略正确限制了对敏感资源的访问
-
未授权访问:
- 监控异常访问模式
- 验证只有授权服务才能访问 S3 存储
- 检查身份验证是否已正确强制执行
诊断命令
# 检查 TektonConfig 资源状态
kubectl get tektonconfig config -o yaml
示例输出:
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
logs_api: true
logs_type: S3
secret_name: my-s3-secret
status:
conditions:
- type: Ready
status: "True"
reason: ReconcileSuccess
message: "All components are reconciled successfully"
# 查看详细状态
kubectl describe tektonconfig config
示例输出:
Name: config
Namespace:
Labels: operator.tekton.dev/release-version=v0.76.0-1070dfb
Annotations: <none>
API Version: operator.tekton.dev/v1alpha1
Kind: TektonConfig
Metadata:
Creation Timestamp: 2026-01-26T04:40:31Z
Finalizers:
tektonconfigs.operator.tekton.dev
Generation: 16
Resource Version: 2363257
UID: 4ae317c9-7bb9-40b5-94fe-2c3cf708a21d
Spec:
Result:
auth_disable: false
db_enable_auto_migration: true
db_host: postgresql.example.svc.cluster.local
db_name: tekton_results
db_port: 5432
db_secret_name: tekton-results-postgres
db_sslmode: verify-full
db_sslrootcert: /etc/tls/db/ca.crt
Disabled: false
# .....
# 检查所有相关 pod
kubectl get pods -n tekton-pipelines | grep tekton-results
示例输出:
NAME READY STATUS RESTARTS AGE
tekton-results-api-7d5b8c9c4-xl2v9 1/1 Running 0 10m
tekton-results-watcher-6b4f7c8d5-z3n4p 1/1 Running 0 10m
tekton-results-retention-policy-agent-5c9g2 1/1 Running 0 10m
# 查看 API server 日志中的 S3 相关消息
kubectl logs -n tekton-pipelines deployment/tekton-results-api | grep -i s3
示例输出:
{"level":"info","ts":"2023-05-15T10:30:45.123Z","caller":"s3/client.go:45","msg":"Successfully connected to S3 storage"}
{"level":"info","ts":"2023-05-15T10:30:45.124Z","caller":"api/server.go:123","msg":"S3 storage configured with bucket: tekton-logs"}
# 查看 watcher 日志中的上传操作
kubectl logs -n tekton-pipelines deployment/tekton-results-watcher | grep -i upload
示例输出:
{"level":"info","ts":"2023-05-15T10:30:46.234Z","caller":"watcher/upload.go:67","msg":"Successfully uploaded log to S3: namespace/pipeline-run-name"}
{"level":"info","ts":"2023-05-15T10:30:47.345Z","caller":"watcher/upload.go:67","msg":"Log upload completed for task-run: namespace/task-run-name"}
# 验证 Secret 内容(请谨慎!)
kubectl get secret my-s3-secret -n tekton-pipelines -o yaml
示例输出:
apiVersion: v1
kind: Secret
metadata:
name: my-s3-secret
namespace: tekton-pipelines
data:
s3-secret-key: <s3 secret data>
......
type: Opaque
# 在集群内部测试 S3 连通性
kubectl run s3-test --image=minio/mc --restart=Never -n tekton-pipelines --rm -it -- \
mc alias set my-s3 https://your-endpoint your-access-key your-secret-key || echo "Connection failed"
示例输出:
s3-test
If you don't see a command prompt, try pressing enter.
Connection established. Waiting for command completion.
Pod s3-test terminated
验证步骤
-
验证组件正在运行:
kubectl get pods -n tekton-pipelines
# 查找 tekton-results-api、tekton-results-watcher,以及可选的 tekton-results-retention-policy-agent
示例输出:
NAME READY STATUS RESTARTS AGE
tekton-results-api-7d5b8c9c4-xl2v9 1/1 Running 0 10m
tekton-results-watcher-6b4f7c8d5-z3n4p 1/1 Running 0 10m
tekton-results-retention-policy-agent-5c9g2 1/1 Running 0 10m
-
创建用于日志上传的 PipelineRun:
# 创建一个简单的测试 pipelinerun
kubectl get pods -n tekton-pipelines -l app.kubernetes.io/name=tekton-results-watcher
示例输出:
NAME READY STATUS RESTARTS AGE
tekton-results-watcher-6b4f7c8d5-z3n4p 1/1 Running 0 10m
-
验证 S3 连通性:
- 检查日志是否出现在你的 S3 bucket 中
- 验证日志结构是否符合预期
- 确认保留策略按预期工作
日志分析
监控以下关键日志以排查 S3 配置问题:
- Tekton Results API 日志中的 S3 上传/下载操作
- Tekton Results Watcher 日志中的初始日志捕获和转发
- S3 服务日志(如可用),用于确认对象创建/删除
- Kubernetes 事件日志中的任何资源相关问题
请关注以下特定错误模式:
- 身份验证失败
- 连接超时
- 权限错误
- 网络连通性问题
- SSL/TLS 握手失败
性能问题
如果遇到性能问题:
-
检查资源使用情况:
# kubectl top 命令要求集群中已安装 metrics-server
kubectl top pods -n tekton-pipelines
示例输出:
NAME CPU(cores) MEMORY(bytes)
tekton-results-api-7d5b8c9c4-xl2v9 15m 55Mi
tekton-results-watcher-6b4f7c8d5-z3n4p 8m 32Mi
tekton-results-retention-policy-agent-5c9g2 5m 28Mi
-
监控网络性能:
- 检查集群与 S3 端点之间的带宽
- 监控丢包或高延迟情况
-
调整分段设置:
- 在高延迟网络中增加
S3_MULTI_PART_SIZE 以提升性能
- 如果需要处理大量日志,可考虑调优 worker pool 大小