From 0b6e6b4b763014a0fa16c8525a6f75cd2b974809 Mon Sep 17 00:00:00 2001 From: Jiahui <4543bxy@gmail.com> Date: Mon, 2 Feb 2026 21:15:47 +0800 Subject: [PATCH] feat(account): migrate account-service deployment to Helm chart (#6646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace manifest-based deployment with Helm chart structure - Add Helm chart with standard templates (deployment, service, configmap) - Create account-service-entrypoint.sh for Helm installation - Update Kubefile to use Helm chart instead of manifests - Simplify deployment by reusing account-controller-manager service account - Remove unnecessary components (no webhook, RBAC, metrics, certificates) - Use compatible selector labels for seamless migration from manifests - Add comprehensive README.md with configuration examples and troubleshooting guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude --- service/account/deploy/Kubefile | 12 +- service/account/deploy/README.md | 264 ++++++++++++++++++ .../deploy/account-service-entrypoint.sh | 31 ++ .../deploy/charts/account-service/Chart.yaml | 6 + .../account-service/templates/NOTES.txt | 8 + .../account-service/templates/_helpers.tpl | 60 ++++ .../account-service/templates/configmap.yaml | 9 + .../account-service/templates/deployment.yaml | 84 ++++++ .../account-service/templates/service.yaml | 15 + .../deploy/charts/account-service/values.yaml | 80 ++++++ 10 files changed, 562 insertions(+), 7 deletions(-) create mode 100644 service/account/deploy/README.md create mode 100644 service/account/deploy/account-service-entrypoint.sh create mode 100644 service/account/deploy/charts/account-service/Chart.yaml create mode 100644 service/account/deploy/charts/account-service/templates/NOTES.txt create mode 100644 service/account/deploy/charts/account-service/templates/_helpers.tpl create mode 100644 service/account/deploy/charts/account-service/templates/configmap.yaml create mode 100644 service/account/deploy/charts/account-service/templates/deployment.yaml create mode 100644 service/account/deploy/charts/account-service/templates/service.yaml create mode 100644 service/account/deploy/charts/account-service/values.yaml diff --git a/service/account/deploy/Kubefile b/service/account/deploy/Kubefile index a5adccfe0..a6d9c8e3f 100644 --- a/service/account/deploy/Kubefile +++ b/service/account/deploy/Kubefile @@ -1,11 +1,9 @@ FROM scratch +COPY charts charts COPY registry registry -COPY manifests manifests -COPY scripts scripts +COPY account-service-entrypoint.sh account-service-entrypoint.sh -ENV DEFAULT_NAMESPACE account-system -ENV cloudDomain="127.0.0.1.nip.io" -ENV cloudPort="" -ENV certSecretName="wildcard-cert" +ENV RELEASE_NAMESPACE=account-system +ENV RELEASE_NAME=account-service -CMD ["bash scripts/init.sh"] \ No newline at end of file +CMD ["bash account-service-entrypoint.sh"] diff --git a/service/account/deploy/README.md b/service/account/deploy/README.md new file mode 100644 index 000000000..89cba5aec --- /dev/null +++ b/service/account/deploy/README.md @@ -0,0 +1,264 @@ +# account-service + +## 说明 +sealos run 镜像时会在目标节点执行 Kubefile,本镜像通过 Helm 安装/升级 account-service Deployment。 + +## 必填参数 + +**无** + +## 如何运行 + +```shell +# 最简配置 +sealos run labring/account-service:latest + +# 自定义命名空间 +sealos run labring/account-service:latest \ + --env RELEASE_NAMESPACE=my-account-system + +# 自定义镜像 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set image=ghcr.io/labring/sealos-account-service:v1.0.0" + +# 自定义副本数 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set replicaCount=3" +``` + +## 可选参数 + +- RELEASE_NAMESPACE: Helm 安装命名空间,默认 `account-system` +- RELEASE_NAME: Helm release 名称,默认 `account-service` +- HELM_OPTS: 透传 Helm 参数(例如 `--set replicaCount=3 --set image.tag=latest`) +- CHART_PATH: Helm chart 路径,默认 `./charts/account-service` + +## Helm Chart 可配置参数 + +可通过 `HELM_OPTS` 传递以下参数: + +### 基础配置 + +- `replicaCount`: 副本数,默认 `1` +- `image`: 容器镜像,默认 `ghcr.io/labring/sealos-account-service:latest` +- `imagePullPolicy`: 镜像拉取策略,默认 `Always` +- `imagePullSecrets`: 镜像拉取密钥,默认 `[]` + +### 服务配置 + +- `service.type`: 服务类型,默认 `ClusterIP` +- `service.port`: 服务端口,默认 `2333` + +### 资源配置 + +- `resources.limits.cpu`: CPU 限制,默认 `500m` +- `resources.limits.memory`: 内存限制,默认 `256Mi` +- `resources.requests.cpu`: CPU 请求,默认 `50m` +- `resources.requests.memory`: 内存请求,默认 `25Mi` + +### 健康检查 + +- `livenessProbe.httpGet.path`: 存活探针路径,默认 `/health` +- `livenessProbe.httpGet.port`: 存活探针端口,默认 `2333` +- `livenessProbe.initialDelaySeconds`: 存活探针初始延迟,默认 `3` +- `livenessProbe.periodSeconds`: 存活探针周期,默认 `10` +- `readinessProbe.httpGet.path`: 就绪探针路径,默认 `/health` +- `readinessProbe.httpGet.port`: 就绪探针端口,默认 `2333` +- `readinessProbe.initialDelaySeconds`: 就绪探针初始延迟,默认 `3` +- `readinessProbe.periodSeconds`: 就绪探针周期,默认 `5` +- `readinessProbe.failureThreshold`: 就绪探针失败阈值,默认 `6` + +### 调度配置 + +- `nodeSelector`: 节点选择器,默认 `{}` +- `tolerations`: 容忍度配置,默认 `[]` +- `affinity`: 亲和性配置,默认 `{}` + +### 自动伸缩 + +- `autoscaling.enabled`: 是否启用自动伸缩,默认 `false` +- `autoscaling.minReplicas`: 最小副本数,默认 `1` +- `autoscaling.maxReplicas`: 最大副本数,默认 `1` +- `autoscaling.targetCPUUtilizationPercentage`: 目标 CPU 利用率,默认 `80` + +### 其他配置 + +- `serviceAccountName`: 服务账户名称,默认 `account-controller-manager` +- `envConfigMapName`: 环境 ConfigMap 名称,默认 `account-manager-env` +- `paymentSecretName`: 支付密钥名称,默认 `payment-secret` +- `regionInfoConfigMapName`: 区域信息 ConfigMap 名称,默认 `region-info` +- `nameOverride`: 名称覆盖,默认 `""` +- `fullnameOverride`: 完全限定名称覆盖,默认 `account-service` + +## 示例 + +```shell +# 1. 最简配置 +sealos run labring/account-service:latest + +# 2. 自定义命名空间 +sealos run labring/account-service:latest \ + --env RELEASE_NAMESPACE=my-account-system + +# 3. 自定义镜像和标签 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set image=ghcr.io/labring/sealos-account-service:v1.0.0" + +# 4. 自定义副本数和资源限制 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set replicaCount=3 --set resources.limits.cpu=1000m --set resources.limits.memory=512Mi" + +# 5. 自定义服务端口 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set service.port=8080" + +# 6. 配置节点选择器 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set nodeSelector.node-role.kubernetes.io/worker=" + +# 7. 启用自动伸缩 +sealos run labring/account-service:latest \ + --env HELM_OPTS="--set autoscaling.enabled=true --set autoscaling.minReplicas=2 --set autoscaling.maxReplicas=5" + +# 8. 完整配置示例 +sealos run labring/account-service:latest \ + --env RELEASE_NAMESPACE=production-account \ + --env HELM_OPTS="--set replicaCount=3 \ + --set image=ghcr.io/labring/sealos-account-service:v1.0.0 \ + --set resources.limits.cpu=1000m \ + --set resources.limits.memory=512Mi \ + --set resources.requests.cpu=100m \ + --set resources.requests.memory=50Mi \ + --set livenessProbe.initialDelaySeconds=10 \ + --set readinessProbe.initialDelaySeconds=10" +``` + +## 架构说明 + +### 组件说明 + +- **Deployment**: account-service 的无状态应用部署 +- **Service**: 提供集群内部服务发现 +- **ConfigMap**: 存储配置信息(region-info、account-manager-env) +- **Secret**: 存储敏感信息(payment-secret) + +### 服务账户 + +使用现有的 `account-controller-manager` service account,与 account-controller 共享权限。 + +### 依赖组件 + +- **account-controller**: 提供 account-manager-env ConfigMap 和 service account +- **payment-secret**: 支付配置密钥(可选) + +## 部署流程 + +1. **Adopt 现有资源**: 如果是从旧版本 manifest 部署迁移,会将现有资源标记为 Helm 管理 +2. **创建命名空间**: 如果命名空间不存在,Helm 会自动创建(通过 `--create-namespace` 参数) +3. **安装/升级 Helm Release**: 使用 Helm chart 部署或更新应用 + +## 故障排查 + +### 检查 Pod 状态 + +```shell +kubectl get pods -n account-system +kubectl describe pod -n account-system -l app=account-service +``` + +### 查看日志 + +```shell +kubectl logs -n account-system deployment/account-service +kubectl logs -n account-system deployment/account-service --tail=100 -f +``` + +### 检查 Helm Release + +```shell +helm status account-service -n account-system +helm get all account-service -n account-system +``` + +### 检查配置 + +```shell +# 查看 ConfigMap +kubectl get configmap account-manager-env -n account-system -o yaml +kubectl get configmap region-info -n account-system -o yaml + +# 查看 Secret +kubectl get secret payment-secret -n account-system -o yaml +``` + +### 重启服务 + +```shell +kubectl rollout restart deployment/account-service -n account-system +``` + +### 卸载 + +```shell +helm uninstall account-service -n account-system +``` + +## 从旧版本迁移 + +如果之前使用 manifest 部署(`manifests/deploy.yaml`),entrypoint 脚本会自动: + +1. Adopt 现有的 Deployment、Service、ConfigMap 资源 +2. 为资源添加 Helm 管理标签 +3. 使用 Helm 接管这些资源 + +无需手动删除旧资源,直接运行新的 sealos run 命令即可。 + +## 与 account-controller 的区别 + +| 特性 | account-service | account-controller | +|------|-----------------|-------------------| +| 类型 | 无状态服务(HTTP API) | Kubernetes 控制器 | +| Webhook | 无 | 有(validating webhook) | +| RBAC | 复用 controller 的 SA | 独立的完整 RBAC | +| Metrics | 无 | 有(可选启用) | +| Certificates | 无 | 需要 cert-manager 证书 | +| 功能 | 提供 Account API 服务 | 管理 Account CRD 和计费逻辑 | + +## 开发指南 + +### 本地测试 + +```shell +# 模板渲染测试 +helm template account-service ./charts/account-service + +# 干跑安装 +helm install account-service ./charts/account-service --dry-run --debug + +# Lint 检查 +helm lint ./charts/account-service +``` + +### 构建镜像 + +```shell +# 在 deploy 目录下执行 +cd service/account/deploy +sealos build -t labring/account-service:latest . +``` + +### 本地运行测试 + +```shell +# 直接运行 entrypoint 脚本(需要 kubectl 访问权限) +bash account-service-entrypoint.sh +``` + +## 贡献指南 + +修改 Chart 时请注意: + +1. 更新 `Chart.yaml` 中的版本号 +2. 在 README.md 中记录新增的配置参数 +3. 使用 `helm template` 和 `helm lint` 验证模板 +4. 测试升级流程:从旧版本升级到新版本 diff --git a/service/account/deploy/account-service-entrypoint.sh b/service/account/deploy/account-service-entrypoint.sh new file mode 100644 index 000000000..0c6ddf09d --- /dev/null +++ b/service/account/deploy/account-service-entrypoint.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -ex + +HELM_OPTS=${HELM_OPTS:-""} +RELEASE_NAME=${RELEASE_NAME:-"account-service"} +RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"account-system"} +CHART_PATH=${CHART_PATH:-"./charts/account-service"} + +adopt_namespaced_resource() { + local kind="$1" + local name="$2" + if kubectl -n "${RELEASE_NAMESPACE}" get "${kind}" "${name}" >/dev/null 2>&1; then + kubectl -n "${RELEASE_NAMESPACE}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true + kubectl -n "${RELEASE_NAMESPACE}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true + fi +} + +# Adopt existing resources if this is a fresh helm install +if ! helm status "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then + if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then + kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true + kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true + fi + + adopt_namespaced_resource configmap account-manager-env + adopt_namespaced_resource configmap region-info + adopt_namespaced_resource service account-service + adopt_namespaced_resource deployment account-service +fi + +helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" ${HELM_OPTS} diff --git a/service/account/deploy/charts/account-service/Chart.yaml b/service/account/deploy/charts/account-service/Chart.yaml new file mode 100644 index 000000000..93910d8cb --- /dev/null +++ b/service/account/deploy/charts/account-service/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: account-service +description: Helm chart for the sealos account service +type: application +version: 0.1.0 +appVersion: "0.1.0" diff --git a/service/account/deploy/charts/account-service/templates/NOTES.txt b/service/account/deploy/charts/account-service/templates/NOTES.txt new file mode 100644 index 000000000..5e02ed2a0 --- /dev/null +++ b/service/account/deploy/charts/account-service/templates/NOTES.txt @@ -0,0 +1,8 @@ +Thank you for installing {{ .Chart.Name }}! + +Your release is named {{ .Release.Name }}. + +To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} diff --git a/service/account/deploy/charts/account-service/templates/_helpers.tpl b/service/account/deploy/charts/account-service/templates/_helpers.tpl new file mode 100644 index 000000000..0fbdb464f --- /dev/null +++ b/service/account/deploy/charts/account-service/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "account-service.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "account-service.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 }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "account-service.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "account-service.labels" -}} +helm.sh/chart: {{ include "account-service.chart" . }} +{{ include "account-service.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "account-service.selectorLabels" -}} +app.kubernetes.io/name: {{ include "account-service.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "account-service.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "account-service.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/service/account/deploy/charts/account-service/templates/configmap.yaml b/service/account/deploy/charts/account-service/templates/configmap.yaml new file mode 100644 index 000000000..4fe3f5b5f --- /dev/null +++ b/service/account/deploy/charts/account-service/templates/configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.regionInfoConfigMapName }} + labels: + {{- include "account-service.labels" . | nindent 4 }} +data: + config.json: | + {} diff --git a/service/account/deploy/charts/account-service/templates/deployment.yaml b/service/account/deploy/charts/account-service/templates/deployment.yaml new file mode 100644 index 000000000..4eb1d67e4 --- /dev/null +++ b/service/account/deploy/charts/account-service/templates/deployment.yaml @@ -0,0 +1,84 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "account-service.fullname" . }} + labels: + {{- include "account-service.labels" . | nindent 4 }} + app: {{ include "account-service.name" . }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + app: {{ include "account-service.name" . }} + template: + metadata: + annotations: + originImageName: {{ .Values.image }} + labels: + app: {{ include "account-service.name" . }} + {{- include "account-service.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ .Values.serviceAccountName }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: account-service + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + image: "{{ .Values.image }}" + imagePullPolicy: {{ .Values.imagePullPolicy }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + envFrom: + - configMapRef: + name: {{ .Values.envConfigMapName }} + - secretRef: + name: {{ .Values.paymentSecretName }} + optional: true + ports: + - containerPort: {{ .Values.service.port }} + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 10 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 10 }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + volumeMounts: + - mountPath: /config/config.json + name: region-info + subPath: ./config/config.json + volumes: + - configMap: + defaultMode: 420 + items: + - key: config.json + path: ./config/config.json + name: {{ .Values.regionInfoConfigMapName }} + name: region-info + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/service/account/deploy/charts/account-service/templates/service.yaml b/service/account/deploy/charts/account-service/templates/service.yaml new file mode 100644 index 000000000..12a3a24cc --- /dev/null +++ b/service/account/deploy/charts/account-service/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "account-service.fullname" . }} + labels: + {{- include "account-service.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.port }} + protocol: TCP + name: http + selector: + app: {{ include "account-service.name" . }} diff --git a/service/account/deploy/charts/account-service/values.yaml b/service/account/deploy/charts/account-service/values.yaml new file mode 100644 index 000000000..64fedef28 --- /dev/null +++ b/service/account/deploy/charts/account-service/values.yaml @@ -0,0 +1,80 @@ +# Default values for account service helm chart + +replicaCount: 1 + +image: ghcr.io/labring/sealos-account-service:latest +imagePullPolicy: Always + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "account-service" + +serviceAccount: + create: false + annotations: {} + name: "" + +podAnnotations: {} +podLabels: {} + +podSecurityContext: {} + # runAsNonRoot: true + # runAsUser: 1000 + +securityContext: {} + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + +service: + type: ClusterIP + port: 2333 + +resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 50m + memory: 25Mi + +livenessProbe: + httpGet: + path: /health + port: 2333 + initialDelaySeconds: 3 + periodSeconds: 10 + +readinessProbe: + httpGet: + path: /health + port: 2333 + initialDelaySeconds: 3 + periodSeconds: 5 + failureThreshold: 6 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 1 + targetCPUUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Service account for the pod (using existing account-controller-manager service account) +serviceAccountName: account-controller-manager + +# ConfigMap for environment variables +envConfigMapName: account-manager-env + +# Secret for payment configuration +paymentSecretName: payment-secret + +# ConfigMap for region info +regionInfoConfigMapName: region-info