S3 存储配置
本文档说明如何为 Tekton Results 日志归档配置兼容 S3 的存储(例如 Ceph)。
概述
Tekton Results 支持将归档日志存储到 Ceph、AWS S3、MinIO 等兼容 S3 的对象存储系统中。这提供了一种可扩展且持久的长期日志保留方案,用于替代基于 PVC 的存储等效率较低的存储机制。
主要优势
- 可扩展性:对象存储可水平扩展,不受块存储的限制
- 持久性:对象存储系统内置冗余和复制机制
- 成本效益:与持久卷相比,存储成本更低
- 长期保留:适用于合规性要求和历史故障排查
前提条件
存储系统要求
- 兼容 S3 的对象存储服务(Ceph、AWS S3、MinIO 等)
- 能够创建 bucket 并管理凭证
- Kubernetes 集群到 S3 endpoint 的网络连通性
权限
- 能够创建 bucket
- 对指定的日志 bucket 具有读/写/删除权限
- 已正确配置 IAM policy 或访问控制
配置概述
Tekton Results 的 S3 存储配置包含两个主要部分:
- S3 凭证和连接参数存储在 Kubernetes Secret 中
- 在 TektonConfig 自定义资源的
spec.result 下启用 S3 配置
配置参数参考
Secret 中的 S3 专用参数
参数详情
- S3_BUCKET_NAME:Tekton 日志将存储到的 S3 bucket 名称。请确保该 bucket 已存在并具有适当权限。
- S3_ENDPOINT:S3 服务的 endpoint 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:用于某些要求 hostname 不可变的兼容 S3 服务。
- S3_MULTI_PART_SIZE:定义何时使用分片上传的大小阈值。更大的值可提升大文件的性能。
基础配置
对于基础的 S3 存储设置,请按以下步骤操作:
1. 准备 S3 存储
在配置 Tekton Results 之前,请确保你已经具备:
- 已准备好兼容 S3 的存储系统(Ceph、AWS S3、MinIO 等)
- 用于 Tekton 日志的专用 bucket
- 具有适当权限的有效访问凭证(读、写、删)
- Kubernetes 集群到 S3 endpoint 的网络连通性
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 endpoint 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 集群提供的正确 endpoint URL
- 确保 Ceph RGW(RADOS Gateway)已正确配置为兼容 S3
完整的生产环境配置示例
结合 S3 存储和外部数据库的完整配置,并附带详细说明:
---
# S3 credentials secret
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: tekton-results-s3-credentials
namespace: tekton-pipelines
stringData:
# S3 Configuration
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 multipart threshold
---
# TektonConfig configuration
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
result:
# Enable S3-based log storage
logs_api: true
logs_type: S3
# External database configuration
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 # Separate DB credentials
secret_name: tekton-results-s3-credentials # S3 credentials
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
Max Log Size 配置
如果要限制每个 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 # This should match the container name in the original deployment
env:
- name: FEATURE_GATES
value: "PartialResponse=true,MaxLogSize=true"
注意:MaxLogSize feature flag 通常通过 Tekton feature flags 中的 MaxResultSize 配置实现(如 FeatureFlags struct 所示),用于控制可存储结果的最大大小。
Max Log Size 配置示例
启用 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 配置 max log size 限制
options:
configMaps:
tekton-results-api-config: # This ConfigMap must exist
data:
max-log-size: "5242880" # Size in bytes (5 MiB)
配置详情:
- 目的:限制每个 TaskRun 日志的大小,以防止存储无限增长并确保查询性能稳定
- 默认值:默认使用 5 MiB(5242880 字节)
- 行为:当 TaskRun 日志超过配置限制时,系统会保留日志的 Head 并丢弃尾部。将
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
验证命令
# Check TektonConfig status
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"
# Check pod logs for S3 connectivity
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"}
# Verify Secret exists
kubectl get secret my-s3-secret -n tekton-pipelines
# Verify pods are running with S3 configuration
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 access key 的流程(例如每季度一次)
- 网络安全:确保集群与 S3 endpoint 之间的网络连接安全,优先使用专用网络或 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 endpoint 详情和访问流程文档
兼容 S3 存储的专项建议
- Ceph:确保你的 Ceph RGW 已正确配置并经过兼容 S3 的测试
- MinIO:验证 MinIO server 设置,以获得 Tekton Results 的最佳性能
- AWS S3:检查 AWS IAM policy,并在适用情况下确保正确的跨账号访问
- 性能调优:不同的兼容 S3 存储系统可能需要不同的分片大小或连接设置
安全注意事项
凭证管理
- 安全存储:将 S3 凭证存储在 Kubernetes Secrets 中,切勿放在明文配置文件里
- 访问控制:使用 RBAC 限制对包含 S3 凭证的 Secret 的访问
- 轮换流程:为 S3 访问凭证制定定期轮换计划
- 最小权限原则:仅授予最低必要权限(针对特定 bucket 的读、写、删)
网络安全
- 加密连接:始终使用 HTTPS/SSL 连接到兼容 S3 的存储
- 专用网络:在可能的情况下,使用专用网络或 VPN 连接到 S3 endpoint
- 防火墙规则:配置适当的防火墙规则以限制对 S3 endpoint 的访问
- 证书校验:确保 SSL 连接已正确配置证书校验
监控与审计
- 访问日志:在兼容 S3 的存储上启用访问日志,以跟踪操作
- 异常检测:监控异常访问模式或身份验证失败尝试
- 审计追踪:保留凭证访问和配置变更的审计追踪
- 安全告警:为安全相关事件设置告警
故障排查
常见问题
-
S3 连接错误:
- 验证 S3 endpoint URL 是否正确且可访问
- 检查集群到 S3 endpoint 的网络连通性
- 如果使用 HTTPS,请验证 SSL 证书
- 确认从集群内部可访问该 endpoint
-
身份验证失败:
- 确认 access key 和 secret key 正确
- 验证 IAM policy 授予了所需权限
- 检查地域配置是否与 S3 服务地域一致
- 确认凭证未过期或未被轮换
-
权限被拒绝:
- 确认凭证对 bucket 具有读/写/删权限
- 验证 bucket policy 允许来自你的集群的访问
- 检查 bucket 是否存在并可使用提供的凭证访问
-
日志上传缓慢:
- 调整分片大小以获得最佳性能
- 检查集群与 S3 endpoint 之间的网络带宽
- 验证 S3 服务性能
- 监控网络拥塞或限流情况
-
日志缺失:
- 验证 watcher 组件是否正确捕获日志
- 检查日志是否已存入 S3,但无法通过 API 访问
- 确认保留策略没有过早删除日志
-
配置问题:
- 确保所有必需的 S3 参数都已正确指定
- 验证 TektonConfig 资源是否配置正确
- 检查 Secret 的格式是否正确且可访问
安全相关问题
-
凭证泄露:
- 检查 Secret 是否未在日志或错误消息中暴露
- 验证凭证未存储在配置文件中
- 确保 RBAC policy 正确限制对敏感资源的访问
-
未授权访问:
- 监控异常访问模式
- 验证只有授权服务可以访问 S3 存储
- 检查身份验证是否已正确强制执行
诊断命令
# Check TektonConfig resource status
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"
# View detailed status
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
# .....
# Check all related pods
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
# View API server logs for S3-related messages
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"}
# View watcher logs for upload operations
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"}
# Verify secret contents (carefully!)
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
# Test S3 connectivity from within cluster
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
# Look for tekton-results-api, tekton-results-watcher, and optionally 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:
# Create a simple test 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 command requires metrics-server to be installed in the cluster
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 endpoint 之间的带宽
- 监控丢包或高延迟
-
调整分片设置:
- 在高延迟网络中增大
S3_MULTI_PART_SIZE 以获得更好的性能
- 如果要处理大量日志,可以考虑调整 worker pool 大小