Helm 部署
Chart 结构
Section titled “Chart 结构”Helm chart 位于:
helm/synctv默认会创建:
- SyncTV Deployment。
- HTTP/API Service。
- gRPC Service。
- PostgreSQL。
- Redis。
- ConfigMap。
- Secret。
- Ingress。
- ServiceAccount、Role、RoleBinding。
- 可选 metrics、ServiceMonitor、VMServiceScrape、PrometheusRule、NetworkPolicy、HPA、PDB。
安装发布版 Chart
Section titled “安装发布版 Chart”通过 OCI registry 安装:
helm install synctv oci://ghcr.io/synctv-org/synctv/charts/synctv \ --version 0.1.0 \ --namespace synctv \ --create-namespace默认父级 OCI repository 是 ghcr.io/synctv-org/synctv/charts。Helm 会追加 chart 名,因此安装引用最后仍是 /synctv。维护者可以通过 HELM_OCI_REPOSITORY 覆盖发布目标。
通过传统 Helm repository 安装:
helm repo add synctv https://synctv-org.github.io/synctvhelm repo updatehelm install synctv synctv/synctv \ --version 0.1.0 \ --namespace synctv \ --create-namespace发布版 Chart 由 release workflow 自动生成。源码仓库只维护 helm/synctv 下的 chart 源码;打包后的 .tgz 和 Helm repository 的 index.yaml 在发布时生成。公开安装要求 GHCR chart package 设为 public,并且 GitHub Pages 使用 helm-charts 分支提供内容。
helm install synctv ./helm/synctv \ --namespace synctv \ --create-namespace生产环境建议使用自己的 values 文件:
helm install synctv ./helm/synctv \ --namespace synctv \ --create-namespace \ --values my-values.yamlHTTP 和 gRPC Service
Section titled “HTTP 和 gRPC Service”SyncTV 进程内部 HTTP REST 和 gRPC 使用同一个容器端口,但 Helm chart 会创建两个独立 Service:
| Service | 用途 | 端口名 |
|---|---|---|
synctv | HTTP/REST,同时包含 RTMP、STUN、metrics 等端口 | api |
synctv-grpc | gRPC 专用入口 | grpc |
为什么拆开:
- Ingress controller 通常需要对 gRPC backend 使用独立协议配置。
- HTTP 和 gRPC 虽然同端口,但 Kubernetes Service/Ingress 层需要不同语义。
- metrics selector 也能只匹配 HTTP/API Service,避免误抓 gRPC Service。
Ingress
Section titled “Ingress”默认 HTTP Ingress 使用:
ingress: enabled: true hosts: - host: synctv.example.comgRPC Ingress 独立配置:
ingress: grpc: enabled: true hosts: - host: grpc.synctv.example.com paths: - path: / pathType: Prefix annotations: nginx.ingress.kubernetes.io/backend-protocol: "GRPC"注意:gRPC annotations 是独立的 ingress.grpc.annotations,不会复用 HTTP Ingress annotations。
Secret
Section titled “Secret”Chart 默认会生成并保存 Secret。生产环境建议显式配置:
secrets: jwt: secret: "replace-with-strong-secret" cluster: grpcSecret: "replace-with-cluster-secret" security: credentialEncryptionKey: "64-hex-character-key" opaqueServerSetupSecret: "stable-random-secret" bootstrap: rootPassword: "StrongRootPass12345"如果使用外部 Secret:
existingSecret: "my-external-synctv-secret"需要提供这些 key:
SYNCTV_DATABASE_PASSWORD,除非 PostgreSQL 使用 KubeBlocks 模式。SYNCTV_REDIS_PASSWORD,除非 Redis 使用 KubeBlocks 模式。SYNCTV_JWT_SECRETSYNCTV_SERVER_CLUSTER_SECRETSYNCTV_SECURITY_CREDENTIAL_ENCRYPTION_KEYSYNCTV_SECURITY_OPAQUE_SERVER_SETUP_SECRETSYNCTV_BOOTSTRAP_ROOT_PASSWORD,如果config.bootstrap.createRootUser=true。SYNCTV_MANAGEMENT_AUTH_TOKEN,如果 management 使用 TCP。SYNCTV_EMAIL_SMTP_USERNAME和SYNCTV_EMAIL_SMTP_PASSWORD,如果配置了config.email.smtpHost且 SMTP 需要认证。SYNCTV_METRICS_AUTH_BEARER_TOKEN,如果metrics.enabled=true且metrics.auth.mode=bearer_token。SYNCTV_METRICS_AUTH_BASIC_USERNAME和SYNCTV_METRICS_AUTH_BASIC_PASSWORD,如果metrics.enabled=true且metrics.auth.mode=basic。SYNCTV_LIVESTREAM_HLS_OSS_ACCESS_KEY_ID和SYNCTV_LIVESTREAM_HLS_OSS_SECRET_ACCESS_KEY,如果config.livestream.hlsStorageBackend=oss。
PostgreSQL 和 Redis 模式
Section titled “PostgreSQL 和 Redis 模式”standard
Section titled “standard”默认模式。Chart 自己创建 StatefulSet/Service。
postgresql: mode: standard
redis: mode: standardkubeblocks
Section titled “kubeblocks”如果集群安装了 KubeBlocks,可以让 chart 创建 KubeBlocks Cluster。
postgresql: mode: kubeblocks
redis: mode: kubeblocksKubeBlocks 模式下,数据库账号密码来自 KubeBlocks 生成的 Secret。
注意:KubeBlocks Redis Sentinel 组件属于数据库 Operator 的内部拓扑,不等同于把 SyncTV 配置成 redis.deployment_mode=sentinel。Helm 默认仍向 SyncTV 注入稳定 Redis Service endpoint;SyncTV 集群模式不能与 SyncTV Sentinel mode 同时使用。
config.dataDir
Section titled “config.dataDir”Helm 默认:
config: dataDir: "/data"Deployment 会挂载 /data。默认是 emptyDir,适合运行时临时文件。如果需要持久化运行时文件,可以设置 persistence.data.existingClaim。
HLS 多副本注意事项
Section titled “HLS 多副本注意事项”Helm 默认不启用集群模式,也不把 HLS 声明为共享存储。多副本 HLS 有两种模型:本地 backend 通过 publisher-node HLS proxy 工作;共享文件系统或 OSS 让任意副本直接读取分片,更适合生产高流量。
本地 backend 示例:
config: cluster: enabled: true livestream: hlsStorageBackend: "memory"这种配置不需要 HLS PVC,但非 publisher Pod 的 playlist/segment 请求会通过 gRPC 回源到 publisher Pod。
共享文件系统示例:
config: cluster: enabled: true livestream: hlsStorageBackend: "file" hlsSharedStorage: true hlsStoragePath: "/var/lib/synctv/hls"
persistence: hls: existingClaim: "synctv-hls-rwx"Helm 会提前拒绝以下组合:
hlsStorageBackend不是memory、file或oss。hlsStorageBackend=file但hlsStoragePath为空。- Kubernetes 中
hlsStorageBackend=file但hlsStoragePath不是绝对路径。 hlsSharedStorage=true但没有配置persistence.hls.existingClaim,避免把emptyDir误当成共享存储。
OSS 示例:
config: cluster: enabled: true livestream: hlsStorageBackend: "oss" hlsOss: endpoint: "https://s3.example.com" bucket: "synctv-hls" basePath: "synctv/hls/"
secrets: livestream: hlsOss: accessKeyId: "..." secretAccessKey: "..."只要开启 config.cluster.enabled=true,应用启动校验还要求 Redis 可用、SYNCTV_SERVER_CLUSTER_SECRET 稳定且所有副本一致,并且每个 Pod 具备可用于节点互联的 SYNCTV_SERVER_ADVERTISE_HOST。Helm 默认会注入 Redis 连接、自动生成 cluster secret,并用 Pod IP 作为 advertise host;如果你裁剪 values 或使用外部 Secret,需要保留这些条件。直播 HLS 选择本地 backend 时,还要确保 Pod 间 gRPC 路径可达,因为远端分片读取依赖 publisher-node proxy。
如果 config.cluster.discoveryMode=k8s_dns,Chart 会自动渲染 headless Service,并注入 HEADLESS_SERVICE_NAME 和 POD_NAMESPACE。如果 config.cluster.leaderElectionMode=k8s_lease,Chart 会注入 POD_NAME 和 POD_NAMESPACE。这两种模式都要求镜像构建包含 k8s feature。
Metrics
Section titled “Metrics”开启 metrics:
metrics: enabled: true auth: mode: bearer_tokenServiceMonitor:
metrics: serviceMonitor: enabled: trueVMServiceScrape:
metrics: vmServiceScrape: enabled: truemetrics Service selector 会只匹配 app.kubernetes.io/component: api 的 Service,避免抓到 gRPC Service。
如果使用 metrics.auth.mode=kubernetes,镜像内的 SyncTV 二进制必须启用 k8s feature。Helm 只负责 RBAC、ServiceAccount token 和抓取资源,不能改变镜像编译特性。
临时检查:
helm lint ./helm/synctvhelm template synctv ./helm/synctvhelm template synctv ./helm/synctv --set ingress.grpc.enabled=true如果模板能渲染,不代表业务配置一定安全。还要在实际容器中运行配置校验或检查启动日志。