添加qiming-rcoder模块
This commit is contained in:
39
qiming-rcoder/k8s/helm/rcoder/templates/NOTES.txt
Normal file
39
qiming-rcoder/k8s/helm/rcoder/templates/NOTES.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
RCoder {{ .Chart.AppVersion }} 已安装到 namespace "{{ .Release.Namespace }}" (release: {{ .Release.Name }}).
|
||||
|
||||
环境: {{ .Values.environment }}
|
||||
副本数: {{ .Values.rcoder.replicas }}
|
||||
NodePort: {{ .Values.rcoder.service.nodePort }}
|
||||
StorageClass: {{ include "rcoder.storageClassName" . }}
|
||||
|
||||
1. 查看部署状态:
|
||||
kubectl get pods -n {{ .Release.Namespace }}
|
||||
kubectl get svc -n {{ .Release.Namespace }}
|
||||
kubectl get pvc -n {{ .Release.Namespace }}
|
||||
|
||||
2. 等待就绪(首次部署 PostgreSQL + MinIO + JuiceFS mount 约需 2-5 分钟):
|
||||
kubectl rollout status deploy/rcoder -n {{ .Release.Namespace }} --timeout=300s
|
||||
|
||||
3. 访问服务 (NodePort):
|
||||
{{- if eq .Values.rcoder.service.type "NodePort" }}
|
||||
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
|
||||
curl http://${NODE_IP}:{{ .Values.rcoder.service.nodePort }}/health
|
||||
{{- else }}
|
||||
kubectl port-forward svc/rcoder {{ .Values.rcoder.service.port }}:{{ .Values.rcoder.service.port }} -n {{ .Release.Namespace }}
|
||||
curl http://localhost:{{ .Values.rcoder.service.port }}/health
|
||||
{{- end }}
|
||||
|
||||
4. 查看日志:
|
||||
kubectl logs -n {{ .Release.Namespace }} -l app=rcoder -f
|
||||
|
||||
{{- if eq .Values.environment "prod" }}
|
||||
|
||||
⚠️ 生产环境安全提醒:
|
||||
- credentials.postgresql.password / credentials.minio.rootPassword 不应使用默认值
|
||||
- 建议使用 --set 动态注入或 SealedSecret / ExternalSecret 方案
|
||||
- 当前密码: {{ .Values.credentials.postgresql.password }} (如为 CHANGE-ME-BEFORE-DEPLOY 请立即替换)
|
||||
{{- end }}
|
||||
|
||||
升级: helm upgrade {{ .Release.Name }} k8s/helm/rcoder -f <values>
|
||||
卸载: helm uninstall {{ .Release.Name }} --namespace {{ .Release.Namespace }}
|
||||
(注意:StorageClass 与 ClusterRoleBinding 是集群级资源,会随 release 删除;
|
||||
PostgreSQL / MinIO 的 PVC 由 reclaimPolicy 决定是否保留数据)
|
||||
140
qiming-rcoder/k8s/helm/rcoder/templates/_helpers.tpl
Normal file
140
qiming-rcoder/k8s/helm/rcoder/templates/_helpers.tpl
Normal file
@@ -0,0 +1,140 @@
|
||||
{{/*
|
||||
RCoder chart 公共 helper
|
||||
*/}}
|
||||
|
||||
{{/* 应用全名 (Release + chart) */}}
|
||||
{{- define "rcoder.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Chart 标识 */}}
|
||||
{{- define "rcoder.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* 通用标签 (所有资源都带) */}}
|
||||
{{- define "rcoder.labels" -}}
|
||||
helm.sh/chart: {{ include "rcoder.chart" . }}
|
||||
app.kubernetes.io/name: rcoder
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
environment: {{ .Values.environment | quote }}
|
||||
{{- end -}}
|
||||
|
||||
{{/* 应用层的 selector label (app=rcoder 与 Kustomize 完全一致, 保证 Service 选得到 pod) */}}
|
||||
{{- define "rcoder.selectorLabels" -}}
|
||||
app: rcoder
|
||||
component: rcoder-main
|
||||
{{- end -}}
|
||||
|
||||
{{/* ============================================================
|
||||
镜像地址拼装
|
||||
rcoder-own image -> {{ .Values.global.imageRegistry }}/{repo}:{tag}
|
||||
third-party image -> {{ .Values.global.thirdPartyRegistry }}/{repo}:{tag}
|
||||
(若 thirdPartyRegistry 为空, 保留原始 repo)
|
||||
============================================================ */}}
|
||||
|
||||
{{/* 自有镜像: 入参 dict {repository, tag, chartContext} */}}
|
||||
{{- define "rcoder.ownImage" -}}
|
||||
{{- $repo := .repository -}}
|
||||
{{- $tag := .tag -}}
|
||||
{{- $registry := .ctx.Values.global.imageRegistry -}}
|
||||
{{- if empty $tag -}}{{- $tag = .ctx.Chart.AppVersion -}}{{- end -}}
|
||||
{{- if $registry -}}
|
||||
{{- printf "%s/%s:%s" $registry $repo $tag -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" $repo $tag -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* 第三方镜像: 入参 dict {repository, tag, ctx} */}}
|
||||
{{- define "rcoder.thirdPartyImage" -}}
|
||||
{{- $repo := .repository -}}
|
||||
{{- $tag := .tag -}}
|
||||
{{- $registry := .ctx.Values.global.thirdPartyRegistry -}}
|
||||
{{- if $registry -}}
|
||||
{{- printf "%s/%s:%s" $registry $repo $tag -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" $repo $tag -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* 快捷: rcoder 主服务 image */}}
|
||||
{{- define "rcoder.image" -}}
|
||||
{{- include "rcoder.ownImage" (dict "repository" .Values.rcoder.image.repository "tag" .Values.rcoder.image.tag "ctx" .) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* 快捷: agent-runner image (供 rcoder env var 使用) */}}
|
||||
{{- define "rcoder.agentRunnerImage" -}}
|
||||
{{- include "rcoder.ownImage" (dict "repository" .Values.agentRunner.image.repository "tag" .Values.agentRunner.image.tag "ctx" .) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* 镜像仓库前缀 (config.yml 里 docker_config.multi_image_config.global_defaults.registry_prefix 使用) */}}
|
||||
{{- define "rcoder.registryPrefix" -}}
|
||||
{{- default "" .Values.global.imageRegistry -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* ============================================================
|
||||
StorageClass 名 (集群级资源, Release 之间必须独立)
|
||||
- 用户显式指定 juicefs.storageClass.name -> 照用
|
||||
- 否则回退到 "juicefs-sc-{release}"
|
||||
============================================================ */}}
|
||||
{{- define "rcoder.storageClassName" -}}
|
||||
{{- if .Values.juicefs.storageClass.name -}}
|
||||
{{- .Values.juicefs.storageClass.name -}}
|
||||
{{- else -}}
|
||||
{{- printf "juicefs-sc-%s" .Release.Name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* ============================================================
|
||||
ClusterRoleBinding 名 (集群级资源, 同上)
|
||||
============================================================ */}}
|
||||
{{- define "rcoder.clusterRoleBindingName" -}}
|
||||
{{- printf "%s-pods-crb" .Release.Name -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* ClusterRole 共享名 —— 多个 release 绑到同一个 ClusterRole, 规则相同故无冲突 */}}
|
||||
{{- define "rcoder.clusterRoleName" -}}
|
||||
rcoder-pods-clusterrole
|
||||
{{- end -}}
|
||||
|
||||
{{/* imagePullSecrets 渲染块 */}}
|
||||
{{- define "rcoder.imagePullSecrets" -}}
|
||||
{{- if .Values.global.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- range .Values.global.imagePullSecrets }}
|
||||
- name: {{ .name }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* PostgreSQL service 主机名 (namespace 内) */}}
|
||||
{{- define "rcoder.postgresqlHost" -}}
|
||||
{{- printf "postgresql.%s.svc.cluster.local" .Release.Namespace -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* MinIO service 主机名 */}}
|
||||
{{- define "rcoder.minioHost" -}}
|
||||
{{- printf "minio-service.%s.svc.cluster.local" .Release.Namespace -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* JuiceFS metaurl */}}
|
||||
{{- define "rcoder.juicefsMetaurl" -}}
|
||||
{{- printf "postgres://%s:%s@postgresql.%s:5432/juicefs" .Values.credentials.postgresql.user .Values.credentials.postgresql.password .Release.Namespace -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* JuiceFS bucket URL */}}
|
||||
{{- define "rcoder.juicefsBucketUrl" -}}
|
||||
{{- printf "http://minio-service.%s:9000/%s" .Release.Namespace .Values.juicefs.bucket -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,29 @@
|
||||
{{- if .Values.rcoder.clusterRole.create }}
|
||||
# 集群级 ClusterRole —— 多 release 共享同一个 (规则与 namespace 无关, 重复 apply 幂等)
|
||||
# 与 Kustomize 并存时, 把 .Values.rcoder.clusterRole.create 置 false, 让 Kustomize 持有所有权
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "rcoder.clusterRoleName" . }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
# 避免多 release 互相 helm uninstall 时删除共享 ClusterRole
|
||||
"helm.sh/resource-policy": keep
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/exec"]
|
||||
verbs: ["create"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/status"]
|
||||
verbs: ["get"]
|
||||
- apiGroups: [""]
|
||||
resources: ["persistentvolumeclaims"]
|
||||
verbs: ["get", "list", "watch", "create", "delete"]
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
# 集群级 ClusterRoleBinding —— 每个 release 独立, 解决同集群多 release 冲突
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "rcoder.clusterRoleBindingName" . }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: rcoder-pods-sa
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: {{ include "rcoder.clusterRoleName" . }}
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
@@ -0,0 +1,70 @@
|
||||
# ConfigMap: 渲染 config.yml —— 保持与 k8s/manifests/overlays 下 rcoder-configmap.yaml 结构对齐
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: rcoder-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yml: |
|
||||
default_agent: {{ .Values.config.defaultAgent | quote }}
|
||||
|
||||
projects_dir: {{ .Values.config.projectsDir | quote }}
|
||||
port: {{ .Values.config.port }}
|
||||
|
||||
cleanup_config:
|
||||
enabled: {{ .Values.config.cleanup.enabled }}
|
||||
idle_timeout_seconds: {{ .Values.config.cleanup.idleTimeoutSeconds }}
|
||||
cleanup_interval_seconds: {{ .Values.config.cleanup.cleanupIntervalSeconds }}
|
||||
docker_stop_timeout_seconds: {{ .Values.config.cleanup.dockerStopTimeoutSeconds }}
|
||||
|
||||
proxy_config:
|
||||
listen_port: {{ .Values.config.proxy.listenPort }}
|
||||
default_backend_port: {{ .Values.config.proxy.defaultBackendPort }}
|
||||
backend_host: {{ .Values.config.proxy.backendHost | quote }}
|
||||
port_param: {{ .Values.config.proxy.portParam | quote }}
|
||||
health_check:
|
||||
enabled: {{ .Values.config.proxy.healthCheck.enabled }}
|
||||
interval_seconds: {{ .Values.config.proxy.healthCheck.intervalSeconds }}
|
||||
timeout_seconds: {{ .Values.config.proxy.healthCheck.timeoutSeconds }}
|
||||
healthy_threshold: {{ .Values.config.proxy.healthCheck.healthyThreshold }}
|
||||
unhealthy_threshold: {{ .Values.config.proxy.healthCheck.unhealthyThreshold }}
|
||||
|
||||
docker_config:
|
||||
multi_image_config:
|
||||
global_defaults:
|
||||
registry_prefix: {{ include "rcoder.registryPrefix" . | quote }}
|
||||
services:
|
||||
rcoder:
|
||||
service_type: "RCoder"
|
||||
arm64_image: {{ include "rcoder.image" . | quote }}
|
||||
amd64_image: {{ include "rcoder.image" . | quote }}
|
||||
default_image: {{ include "rcoder.image" . | quote }}
|
||||
image_tag_prefix: "rcoder"
|
||||
enabled: true
|
||||
computer-agent-runner:
|
||||
service_type: "ComputerAgentRunner"
|
||||
arm64_image: {{ include "rcoder.agentRunnerImage" . | quote }}
|
||||
amd64_image: {{ include "rcoder.agentRunnerImage" . | quote }}
|
||||
default_image: {{ include "rcoder.agentRunnerImage" . | quote }}
|
||||
image_tag_prefix: "rcoder-computer-agent-runner"
|
||||
enabled: true
|
||||
selection_strategy: "ServiceOnly"
|
||||
cache_config:
|
||||
enabled: {{ .Values.config.dockerConfig.cache.enabled }}
|
||||
ttl_seconds: {{ .Values.config.dockerConfig.cache.ttlSeconds }}
|
||||
max_entries: {{ .Values.config.dockerConfig.cache.maxEntries }}
|
||||
|
||||
network_base_name: {{ .Values.config.dockerConfig.networkBaseName | quote }}
|
||||
network_mode: {{ .Values.config.dockerConfig.networkMode | quote }}
|
||||
work_dir: {{ .Values.config.dockerConfig.workDir | quote }}
|
||||
auto_cleanup: {{ .Values.config.dockerConfig.autoCleanup }}
|
||||
container_ttl_seconds: {{ .Values.config.dockerConfig.containerTtlSeconds }}
|
||||
|
||||
api_key_auth:
|
||||
enabled: {{ .Values.config.apiKeyAuth.enabled }}
|
||||
api_key: {{ .Values.config.apiKeyAuth.apiKey | quote }}
|
||||
|
||||
kubernetes_config:
|
||||
storage_class: {{ include "rcoder.storageClassName" . | quote }}
|
||||
@@ -0,0 +1,65 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: rcoder
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.rcoder.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "rcoder.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 8 }}
|
||||
{{- include "rcoder.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
terminationGracePeriodSeconds: {{ .Values.rcoder.terminationGracePeriodSeconds }}
|
||||
serviceAccountName: rcoder-pods-sa
|
||||
{{- include "rcoder.imagePullSecrets" . | nindent 6 }}
|
||||
containers:
|
||||
- name: rcoder
|
||||
image: {{ include "rcoder.image" . }}
|
||||
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
|
||||
command: ["/app/bin/rcoder"]
|
||||
args: ["--port", "{{ .Values.rcoder.service.port }}"]
|
||||
ports:
|
||||
- containerPort: {{ .Values.rcoder.service.port }}
|
||||
env:
|
||||
- name: CONTAINER_RUNTIME
|
||||
value: "kubernetes"
|
||||
- name: RCODER_K8S_NAMESPACE
|
||||
value: {{ .Release.Namespace | quote }}
|
||||
- name: RUST_LOG
|
||||
value: {{ .Values.rcoder.rustLog | quote }}
|
||||
- name: RCODER_K8S_STORAGE_CLASS
|
||||
value: {{ include "rcoder.storageClassName" . | quote }}
|
||||
- name: RCODER_DOCKER_IMAGE
|
||||
value: {{ include "rcoder.image" . | quote }}
|
||||
- name: RCODER_DOCKER_IMAGE_COMPUTER
|
||||
value: {{ include "rcoder.agentRunnerImage" . | quote }}
|
||||
resources:
|
||||
{{- toYaml .Values.rcoder.resources | nindent 12 }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.rcoder.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.rcoder.readinessProbe | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: rcoder-config
|
||||
mountPath: /app/config.yml
|
||||
subPath: config.yml
|
||||
- name: project-workspace
|
||||
mountPath: /app/project_workspace
|
||||
subPath: project_workspace
|
||||
- name: project-workspace
|
||||
mountPath: /app/computer-project-workspace
|
||||
subPath: computer_workspace
|
||||
volumes:
|
||||
- name: rcoder-config
|
||||
configMap:
|
||||
name: rcoder-config
|
||||
- name: project-workspace
|
||||
persistentVolumeClaim:
|
||||
claimName: rcoder-workspace
|
||||
@@ -0,0 +1,62 @@
|
||||
{{- if .Values.rcoder.networkPolicy.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: rcoder-network-policy
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: rcoder
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
# 同 namespace 入站流量
|
||||
- from:
|
||||
- podSelector: {}
|
||||
ports:
|
||||
- { protocol: TCP, port: {{ .Values.rcoder.service.port }} }
|
||||
- { protocol: TCP, port: {{ .Values.config.proxy.listenPort }} }
|
||||
egress:
|
||||
# DNS
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
ports:
|
||||
- { protocol: UDP, port: 53 }
|
||||
# K8s API Server
|
||||
- to:
|
||||
- namespaceSelector: {}
|
||||
podSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/service-name: kubernetes
|
||||
ports:
|
||||
- { protocol: TCP, port: 443 }
|
||||
# PostgreSQL
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: postgresql
|
||||
ports:
|
||||
- { protocol: TCP, port: {{ .Values.postgresql.service.port }} }
|
||||
# MinIO
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: minio
|
||||
ports:
|
||||
- { protocol: TCP, port: {{ .Values.minio.service.apiPort }} }
|
||||
- { protocol: TCP, port: {{ .Values.minio.service.consolePort }} }
|
||||
# 动态 agent pod (rcoder -> agent gRPC/HTTP)
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
managed-by: rcoder-runtime
|
||||
ports:
|
||||
- { protocol: TCP, port: 50051 }
|
||||
- { protocol: TCP, port: 8086 }
|
||||
{{- end }}
|
||||
14
qiming-rcoder/k8s/helm/rcoder/templates/rcoder/pdb.yaml
Normal file
14
qiming-rcoder/k8s/helm/rcoder/templates/rcoder/pdb.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.rcoder.pdb.enabled }}
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: rcoder-pdb
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
maxUnavailable: {{ .Values.rcoder.pdb.maxUnavailable }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: rcoder
|
||||
{{- end }}
|
||||
19
qiming-rcoder/k8s/helm/rcoder/templates/rcoder/service.yaml
Normal file
19
qiming-rcoder/k8s/helm/rcoder/templates/rcoder/service.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: rcoder
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.rcoder.service.type }}
|
||||
# component=rcoder-main 把动态创建的 rcoder-agent / computer-agent-runner pod
|
||||
# (它们也带 app=rcoder 标签) 排除在外, 避免 NodePort 把流量路由到不监听 8087 的 agent pod
|
||||
selector:
|
||||
{{- include "rcoder.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- port: {{ .Values.rcoder.service.port }}
|
||||
targetPort: {{ .Values.rcoder.service.port }}
|
||||
{{- if eq .Values.rcoder.service.type "NodePort" }}
|
||||
nodePort: {{ .Values.rcoder.service.nodePort }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: rcoder-pods-sa
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: rcoder-credentials
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
POSTGRES_USER: {{ .Values.credentials.postgresql.user | quote }}
|
||||
POSTGRES_PASSWORD: {{ .Values.credentials.postgresql.password | quote }}
|
||||
MINIO_ROOT_USER: {{ .Values.credentials.minio.rootUser | quote }}
|
||||
MINIO_ROOT_PASSWORD: {{ .Values.credentials.minio.rootPassword | quote }}
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: rcoder-workspace
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: rcoder
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
# JuiceFS 原生支持 RWX, 多节点 rcoder pod 共享工作空间
|
||||
accessModes: ["ReadWriteMany"]
|
||||
storageClassName: {{ include "rcoder.storageClassName" . | quote }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.workspace.size | quote }}
|
||||
@@ -0,0 +1,26 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: juicefs-secret
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
# JuiceFS CE 必需字段 (小写键名)
|
||||
name: "rcoder-juicefs"
|
||||
metaurl: {{ include "rcoder.juicefsMetaurl" . | quote }}
|
||||
storage: "minio"
|
||||
bucket: {{ include "rcoder.juicefsBucketUrl" . | quote }}
|
||||
access-key: {{ .Values.credentials.minio.rootUser | quote }}
|
||||
secret-key: {{ .Values.credentials.minio.rootPassword | quote }}
|
||||
|
||||
# 兼容字段 (保留给脚本/日志使用)
|
||||
METAURL: {{ include "rcoder.juicefsMetaurl" . | quote }}
|
||||
MINIO_ACCESS_KEY: {{ .Values.credentials.minio.rootUser | quote }}
|
||||
MINIO_SECRET_KEY: {{ .Values.credentials.minio.rootPassword | quote }}
|
||||
MINIO_ADDRESS: {{ printf "minio-service.%s:%d" .Release.Namespace (int .Values.minio.service.apiPort) | quote }}
|
||||
|
||||
# 其他配置
|
||||
APPEND_FSYNC: {{ .Values.juicefs.meta.appendFsync | quote }}
|
||||
CACHE_SIZE: {{ .Values.juicefs.meta.cacheSize | quote }}
|
||||
@@ -0,0 +1,25 @@
|
||||
{{- if .Values.juicefs.storageClass.create }}
|
||||
# JuiceFS StorageClass —— 集群级资源, 每个 release 独立命名
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: {{ include "rcoder.storageClassName" . }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
storageclass.kubernetes.io/is-default-class: "false"
|
||||
provisioner: csi.juicefs.com
|
||||
parameters:
|
||||
csi.storage.k8s.io/provisioner-secret-name: juicefs-secret
|
||||
csi.storage.k8s.io/provisioner-secret-namespace: {{ .Release.Namespace }}
|
||||
csi.storage.k8s.io/controller-expand-secret-name: juicefs-secret
|
||||
csi.storage.k8s.io/controller-expand-secret-namespace: {{ .Release.Namespace }}
|
||||
csi.storage.k8s.io/node-publish-secret-name: juicefs-secret
|
||||
csi.storage.k8s.io/node-publish-secret-namespace: {{ .Release.Namespace }}
|
||||
juicefs/controllerQuotaSet: "false"
|
||||
juicefs/mountImage: {{ include "rcoder.thirdPartyImage" (dict "repository" .Values.juicefs.mountImage.repository "tag" .Values.juicefs.mountImage.tag "ctx" .) | quote }}
|
||||
juicefs/mountOptions: {{ .Values.juicefs.storageClass.mountOptions | quote }}
|
||||
reclaimPolicy: {{ .Values.juicefs.storageClass.reclaimPolicy }}
|
||||
allowVolumeExpansion: true
|
||||
volumeBindingMode: Immediate
|
||||
{{- end }}
|
||||
@@ -0,0 +1,47 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: minio-init
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
# 每次 helm upgrade 强制重新运行 (确保 bucket 一定存在, 即使 Job 已清理)
|
||||
helm.sh/hook: post-install,post-upgrade
|
||||
helm.sh/hook-weight: "5"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
{{- include "rcoder.imagePullSecrets" . | nindent 6 }}
|
||||
containers:
|
||||
- name: mc
|
||||
image: {{ include "rcoder.thirdPartyImage" (dict "repository" .Values.minio.initImage.repository "tag" .Values.minio.initImage.tag "ctx" .) }}
|
||||
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
echo "Waiting for MinIO to be ready..."
|
||||
until mc alias set myminio http://minio:{{ .Values.minio.service.apiPort }} ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD}; do
|
||||
echo "MinIO not ready, retrying..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "MinIO is ready, creating bucket..."
|
||||
mc mb myminio/{{ .Values.minio.bucket }} --ignore-existing
|
||||
mc ls myminio/
|
||||
echo "MinIO initialization completed!"
|
||||
env:
|
||||
- name: MINIO_ROOT_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: rcoder-credentials
|
||||
key: MINIO_ROOT_USER
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: rcoder-credentials
|
||||
key: MINIO_ROOT_PASSWORD
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# Headless Service for StatefulSet
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: minio
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: minio
|
||||
ports:
|
||||
- name: api
|
||||
port: {{ .Values.minio.service.apiPort }}
|
||||
targetPort: {{ .Values.minio.service.apiPort }}
|
||||
- name: console
|
||||
port: {{ .Values.minio.service.consolePort }}
|
||||
targetPort: {{ .Values.minio.service.consolePort }}
|
||||
---
|
||||
# ClusterIP Service for internal access
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: minio-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: minio
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
app: minio
|
||||
ports:
|
||||
- name: api
|
||||
port: {{ .Values.minio.service.apiPort }}
|
||||
targetPort: {{ .Values.minio.service.apiPort }}
|
||||
- name: console
|
||||
port: {{ .Values.minio.service.consolePort }}
|
||||
targetPort: {{ .Values.minio.service.consolePort }}
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: minio-pvc
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: minio
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
{{- if .Values.minio.storage.storageClass }}
|
||||
storageClassName: {{ .Values.minio.storage.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.minio.storage.size | quote }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: minio
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
serviceName: minio
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: minio
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: minio
|
||||
{{- include "rcoder.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- include "rcoder.imagePullSecrets" . | nindent 6 }}
|
||||
containers:
|
||||
- name: minio
|
||||
image: {{ include "rcoder.thirdPartyImage" (dict "repository" .Values.minio.image.repository "tag" .Values.minio.image.tag "ctx" .) }}
|
||||
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.minio.service.apiPort }}
|
||||
name: api
|
||||
- containerPort: {{ .Values.minio.service.consolePort }}
|
||||
name: console
|
||||
env:
|
||||
- name: MINIO_ROOT_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: rcoder-credentials
|
||||
key: MINIO_ROOT_USER
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: rcoder-credentials
|
||||
key: MINIO_ROOT_PASSWORD
|
||||
args:
|
||||
- server
|
||||
- /data
|
||||
- --console-address
|
||||
- ":{{ .Values.minio.service.consolePort }}"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /minio/health/live
|
||||
port: {{ .Values.minio.service.apiPort }}
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /minio/health/ready
|
||||
port: {{ .Values.minio.service.apiPort }}
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
volumeMounts:
|
||||
- name: minio-data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: minio-data
|
||||
persistentVolumeClaim:
|
||||
claimName: minio-pvc
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: postgresql
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
app: postgresql
|
||||
ports:
|
||||
- name: postgres
|
||||
port: {{ .Values.postgresql.service.port }}
|
||||
targetPort: {{ .Values.postgresql.service.port }}
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgresql-pvc
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: postgresql
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
{{- if .Values.postgresql.storage.storageClass }}
|
||||
storageClassName: {{ .Values.postgresql.storage.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.postgresql.storage.size | quote }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: postgresql
|
||||
{{- include "rcoder.labels" . | nindent 4 }}
|
||||
spec:
|
||||
serviceName: postgresql
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgresql
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgresql
|
||||
{{- include "rcoder.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- include "rcoder.imagePullSecrets" . | nindent 6 }}
|
||||
initContainers:
|
||||
- name: cleanup
|
||||
image: {{ include "rcoder.thirdPartyImage" (dict "repository" .Values.postgresql.image.repository "tag" .Values.postgresql.image.tag "ctx" .) }}
|
||||
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
|
||||
command: ["rm", "-rf", "/var/lib/postgresql/data/lost+found"]
|
||||
volumeMounts:
|
||||
- name: postgres-data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
containers:
|
||||
- name: postgresql
|
||||
image: {{ include "rcoder.thirdPartyImage" (dict "repository" .Values.postgresql.image.repository "tag" .Values.postgresql.image.tag "ctx" .) }}
|
||||
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.postgresql.service.port }}
|
||||
name: postgres
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: "juicefs"
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: rcoder-credentials
|
||||
key: POSTGRES_USER
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: rcoder-credentials
|
||||
key: POSTGRES_PASSWORD
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["pg_isready", "-U", {{ .Values.credentials.postgresql.user | quote }}]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["pg_isready", "-U", {{ .Values.credentials.postgresql.user | quote }}]
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
volumeMounts:
|
||||
- name: postgres-data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: postgres-data
|
||||
persistentVolumeClaim:
|
||||
claimName: postgresql-pvc
|
||||
Reference in New Issue
Block a user