feat(account): migrate account-service deployment to Helm chart (#6646)

- 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 <noreply@anthropic.com>
This commit is contained in:
Jiahui
2026-02-02 21:15:47 +08:00
committed by GitHub
parent ac4260954f
commit 0b6e6b4b76
10 changed files with 562 additions and 7 deletions
+5 -7
View File
@@ -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"]
CMD ["bash account-service-entrypoint.sh"]
+264
View File
@@ -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. 测试升级流程:从旧版本升级到新版本
@@ -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}
@@ -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"
@@ -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 }}
@@ -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 }}
@@ -0,0 +1,9 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.regionInfoConfigMapName }}
labels:
{{- include "account-service.labels" . | nindent 4 }}
data:
config.json: |
{}
@@ -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 }}
@@ -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" . }}
@@ -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