addon-creator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

IMPORTANT: Structure Requirements

重要提示:结构要求

⚠️ MANDATORY: All new addons MUST use the NEW structure described below.
The repository may contain some addons using an older structure (with
app-yamls/*.yaml
and configuration in
default.yaml
). DO NOT use this old structure for new addons. The old structure is deprecated and exists only for backward compatibility with existing addons.
⚠️ 强制要求:所有新插件必须使用下文所述的新结构。
仓库中可能包含一些使用旧结构的插件(带有
app-yamls/*.yaml
default.yaml
中的配置)。请勿为新插件使用此旧结构。旧结构已被弃用,仅为与现有插件向后兼容而保留。

When to Use This Skill

何时使用此技能

Use this skill when:
  • Creating a new addon with one or more applications
  • Adding a new application to an existing addon
  • Setting up developer tools, monitoring, testing, or operational utilities for Mojaloop environments
  • Creating reusable application bundles that can be deployed across multiple environments
在以下场景使用此技能:
  • 创建包含一个或多个应用的新插件
  • 为现有插件添加新应用
  • 为Mojaloop环境设置开发工具、监控、测试或运维实用程序
  • 创建可在多环境中部署的可复用应用包

Addon Structure Overview

插件结构概述

NEW Structure (REQUIRED for all new addons)

新结构(所有新插件必须使用)

addons/
└── <app-name>/
    ├── .config/
    │   └── <app-name>.yaml         # App configuration (REQUIRED)
    ├── <app-name>.app.yaml         # ArgoCD Application definition (REQUIRED)
    ├── kustomization.yaml          # Kustomize manifest (REQUIRED)
    ├── values-default.yaml         # Default Helm values (if using Helm)
    ├── values-override.yaml        # Template for env-specific overrides (if using Helm)
    ├── vs.yaml                     # Virtual Service for ingress (optional)
    ├── <resource>.yaml             # Additional K8s resources
    ├── README.md                   # Documentation (recommended)
    └── <subfolder>/                # Optional: misc files without templating
Key characteristics of the NEW structure:
  • Configuration is in
    .config/<app-name>.yaml
    (self-contained per app)
  • App definition is in
    <app-name>.app.yaml
    at the app root
  • Template variables use
    ${app.*}
    to reference config from
    .config/<app-name>.yaml
  • No entries needed in
    default.yaml
    or
    app-yamls/
    directory
addons/
└── <app-name>/
    ├── .config/
    │   └── <app-name>.yaml         # 应用配置(必填)
    ├── <app-name>.app.yaml         # ArgoCD应用定义(必填)
    ├── kustomization.yaml          # Kustomize清单(必填)
    ├── values-default.yaml         # 默认Helm值(使用Helm时)
    ├── values-override.yaml        # 环境特定覆盖模板(使用Helm时)
    ├── vs.yaml                     # 用于入口的Virtual Service(可选)
    ├── <resource>.yaml             # 其他K8s资源
    ├── README.md                   # 文档(推荐)
    └── <subfolder>/                # 可选:无模板的杂项文件
新结构的关键特性:
  • 配置位于
    .config/<app-name>.yaml
    (每个应用独立包含)
  • 应用定义位于应用根目录的
    <app-name>.app.yaml
  • 模板变量使用
    ${app.*}
    引用
    .config/<app-name>.yaml
    中的配置
  • 无需在
    default.yaml
    app-yamls/
    目录中添加条目

OLD Structure (DEPRECATED - Do NOT use for new addons)

旧结构(已弃用 - 请勿用于新插件)

addons/
├── app-yamls/
│   └── <app-name>.yaml            # ArgoCD Application (OLD - deprecated)
├── default.yaml                   # Global configuration (OLD - deprecated)
└── <app-name>/
    ├── kustomization.yaml
    ├── deployment.yaml
    └── ...
The OLD structure is deprecated because:
  • Configuration scattered across
    default.yaml
    and app-specific files
  • App definitions in separate
    app-yamls/
    directory
  • Harder to manage and understand dependencies
  • Less modular and reusable
When you encounter old-structure addons in the repository, do NOT replicate their pattern. Always use the NEW structure.
addons/
├── app-yamls/
│   └── <app-name>.yaml            # ArgoCD应用(旧版 - 已弃用)
├── default.yaml                   # 全局配置(旧版 - 已弃用)
└── <app-name>/
    ├── kustomization.yaml
    ├── deployment.yaml
    └── ...
旧结构被弃用的原因:
  • 配置分散在
    default.yaml
    和应用特定文件中
  • 应用定义位于单独的
    app-yamls/
    目录
  • 更难管理和理解依赖关系
  • 模块化和可复用性较差
当你在仓库中遇到旧结构的插件时,请勿复制其模式。始终使用新结构。

Step-by-Step Instructions

分步说明

1. Determine App Name

1. 确定应用名称

Questions to answer:
  • What is the app name? (e.g.,
    redis-insight
    ,
    mongo-express
    ,
    cloud-beaver
    )
  • What namespace should the app use? (default: same as app name)
  • Does it need persistent storage?
  • Does it need ingress/virtual service?
Naming conventions:
  • Use lowercase with hyphens:
    redis-insight
    ,
    chaos-mesh
    ,
    mongo-express
  • App names should be descriptive and match the tool being deployed
  • Namespace typically matches the app name
⚠️ IMPORTANT: Do NOT create files in
app-yamls/
directory or add configuration to
default.yaml
. These are part of the deprecated old structure.
需要回答的问题:
  • 应用名称是什么?(例如:
    redis-insight
    ,
    mongo-express
    ,
    cloud-beaver
  • 应用应使用哪个命名空间?(默认:与应用名称相同)
  • 是否需要持久化存储?
  • 是否需要入口/Virtual Service?
命名约定:
  • 使用小写字母加连字符:
    redis-insight
    ,
    chaos-mesh
    ,
    mongo-express
  • 应用名称应具有描述性,与要部署的工具匹配
  • 命名空间通常与应用名称相同
⚠️ 重要提示:请勿在
app-yamls/
目录中创建文件,也不要在
default.yaml
中添加配置。这些属于已弃用的旧结构。

2. Create App Directory Structure

2. 创建应用目录结构

Navigate to the addons repository (e.g.,
/home/kalin/work/deploy/addons-dev/
) and create:
bash
mkdir -p <app-name>/.config
cd <app-name>
Directory structure you will create:
<app-name>/
├── .config/
│   └── <app-name>.yaml      # Start here
├── <app-name>.app.yaml      # Then create this
├── kustomization.yaml       # Then this
└── ... other resources
导航到插件仓库(例如:
/home/kalin/work/deploy/addons-dev/
)并创建:
bash
mkdir -p <app-name>/.config
cd <app-name>
你将创建的目录结构:
<app-name>/
├── .config/
│   └── <app-name>.yaml      # 从这里开始
├── <app-name>.app.yaml      # 然后创建此文件
├── kustomization.yaml       # 接着创建此文件
└── ... 其他资源

3. Create App Configuration File

3. 创建应用配置文件

This is the FIRST file to create:
.config/<app-name>.yaml
This file contains all configuration for your app. Template variables in your manifests will reference fields from this file using
${app.<field>}
.
Create
.config/<app-name>.yaml
with default configuration:
yaml
undefined
这是第一个需要创建的文件
.config/<app-name>.yaml
此文件包含应用的所有配置。清单中的模板变量将使用
${app.<field>}
引用此文件中的字段。
创建包含默认配置的
.config/<app-name>.yaml
yaml
undefined

.config/<app-name>.yaml

.config/<app-name>.yaml

enabled: true version: <chart-version> # For Helm charts tag: <image-tag> # For container images namespace: <app-name> # Default namespace syncWave: 0 # ArgoCD sync wave (use negative for dependencies) values: {} # Helm chart value overrides

**Common configuration fields:**
- `enabled`: Boolean to enable/disable the app
- `version`: Helm chart version (if using Helm)
- `tag`: Docker image tag (if using plain manifests)
- `namespace`: Kubernetes namespace for deployment
- `syncWave`: ArgoCD sync wave for ordering (-1 for infrastructure, 0 for apps, 99+ for tests)
- `values`: Hash for Helm chart value overrides
- `image`: Full image reference (for non-Helm deployments)

**Examples from existing addons:**

```yaml
enabled: true version: <chart-version> # 用于Helm图表 tag: <image-tag> # 用于容器镜像 namespace: <app-name> # 默认命名空间 syncWave: 0 # ArgoCD同步波(依赖项使用负数) values: {} # Helm图表值覆盖

**常见配置字段:**
- `enabled`: 启用/禁用应用的布尔值
- `version`: Helm图表版本(使用Helm时)
- `tag`: Docker镜像标签(使用纯清单时)
- `namespace`: Kubernetes部署的命名空间
- `syncWave`: ArgoCD同步波,用于排序(基础设施使用-1,应用使用0,测试和部署后任务使用99+)
- `values`: Helm图表值覆盖的哈希表
- `image`: 完整镜像引用(非Helm部署时)

**现有插件的示例:**

```yaml

chaosmesh

chaosmesh

enabled: true version: 2.7.0 namespace: chaosmesh syncWave: 0 values: {}

```yaml
enabled: true version: 2.7.0 namespace: chaosmesh syncWave: 0 values: {}

```yaml

cloud-beaver

cloud-beaver

enabled: true image: dbeaver/cloudbeaver:25.0.4 namespace: cloud-beaver syncWave: 0 secrets: account-lookup: common-mojaloop-db-secret central-ledger: common-mojaloop-db-secret

```yaml
enabled: true image: dbeaver/cloudbeaver:25.0.4 namespace: cloud-beaver syncWave: 0 secrets: account-lookup: common-mojaloop-db-secret central-ledger: common-mojaloop-db-secret

```yaml

k6

k6

enabled: true version: 3.9.0 namespace: k6 syncWave: 0 prometheusEndpoint: http://prom-kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090/api/v1/write values: {}
undefined
enabled: true version: 3.9.0 namespace: k6 syncWave: 0 prometheusEndpoint: http://prom-kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090/api/v1/write values: {}
undefined

4. Create ArgoCD Application Definition

4. 创建ArgoCD应用定义

Create
<app-name>.app.yaml
:
yaml
undefined
创建
<app-name>.app.yaml
yaml
undefined

<app-name>.app.yaml

<app-name>.app.yaml

apiVersion: argoproj.io/v1alpha1 kind: Application metadata: annotations: argocd.argoproj.io/sync-wave: "${app.syncWave}" name: ${app.name} namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: source: path: apps/${app.name} repoURL: ${cluster.gitlabProjectUrl} targetRevision: HEAD kustomize: commonAnnotations: addons-dev: ${app.name} destination: namespace: ${app.namespace} server: https://kubernetes.default.svc project: default ignoreDifferences: - group: batch kind: CronJob jsonPointers: - /spec/suspend syncPolicy: automated: prune: true selfHeal: true retry: limit: 5 backoff: duration: 5s maxDuration: 3m0s factor: 2 syncOptions: - CreateNamespace=true - PrunePropagationPolicy=background - PruneLast=true

**Key elements:**
- `path`: Points to the addon's app directory
- `repoURL`: Uses `${cluster.gitlabProjectUrl}` template variable
- `destination.namespace`: Uses `${app.namespace}` template variable
- `syncWave`: Uses `${app.syncWave}` template variable
- `syncPolicy.automated`: Enables auto-sync and self-healing
- `syncOptions`: Common options for namespace creation and pruning
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: annotations: argocd.argoproj.io/sync-wave: "${app.syncWave}" name: ${app.name} namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: source: path: apps/${app.name} repoURL: ${cluster.gitlabProjectUrl} targetRevision: HEAD kustomize: commonAnnotations: addons-dev: ${app.name} destination: namespace: ${app.namespace} server: https://kubernetes.default.svc project: default ignoreDifferences: - group: batch kind: CronJob jsonPointers: - /spec/suspend syncPolicy: automated: prune: true selfHeal: true retry: limit: 5 backoff: duration: 5s maxDuration: 3m0s factor: 2 syncOptions: - CreateNamespace=true - PrunePropagationPolicy=background - PruneLast=true

**关键元素:**
- `path`: 指向插件的应用目录
- `repoURL`: 使用`${cluster.gitlabProjectUrl}`模板变量
- `destination.namespace`: 使用`${app.namespace}`模板变量
- `syncWave`: 使用`${app.syncWave}`模板变量
- `syncPolicy.automated`: 启用自动同步和自我修复
- `syncOptions`: 用于命名空间创建和清理的常见选项

5. Create Kustomization File

5. 创建Kustomization文件

The
kustomization.yaml
defines which Kubernetes resources to include.
For Helm-based apps:
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - vs.yaml                    # Optional: if app has ingress
  - <additional-resources>.yaml
helmCharts:
  - name: <chart-name>
    releaseName: <release-name>
    version: ${app.version}
    repo: https://<chart-repo-url>
    valuesFile: values-default.yaml
    namespace: <app-name>
    includeCRDs: true
    additionalValuesFiles:
      - values-override.yaml
Example (k6):
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - vs.yaml
  - k6-test-als-configmap.yaml
  - kronic.yaml
helmCharts:
  - name: k6-operator
    releaseName: k6-operator
    version: ${app.version}
    repo: https://grafana.github.io/helm-charts
    valuesFile: values-default.yaml
    namespace: k6
    includeCRDs: true
    additionalValuesFiles:
      - values-override.yaml
For plain manifest apps:
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml
  - vs.yaml
  - external-secret.yaml
  - pvc.yaml
configMapGenerator:
  - name: <app-name>
    files:
      - config-file.conf
Example (cloud-beaver):
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - external-secret.yaml
  - password-policy.yaml
  - pvc.yaml
  - random-secret.yaml
  - service.yaml
  - vault-secret.yaml
  - vs.yaml
configMapGenerator:
  - name: cloud-beaver
    files:
      - cloudbeaver.conf
      - initial-data-sources.conf
kustomization.yaml
定义要包含的Kubernetes资源。
基于Helm的应用:
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - vs.yaml                    # 可选:如果应用有入口
  - <additional-resources>.yaml
helmCharts:
  - name: <chart-name>
    releaseName: <release-name>
    version: ${app.version}
    repo: https://<chart-repo-url>
    valuesFile: values-default.yaml
    namespace: <app-name>
    includeCRDs: true
    additionalValuesFiles:
      - values-override.yaml
示例(k6):
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - vs.yaml
  - k6-test-als-configmap.yaml
  - kronic.yaml
helmCharts:
  - name: k6-operator
    releaseName: k6-operator
    version: ${app.version}
    repo: https://grafana.github.io/helm-charts
    valuesFile: values-default.yaml
    namespace: k6
    includeCRDs: true
    additionalValuesFiles:
      - values-override.yaml
纯清单应用:
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml
  - vs.yaml
  - external-secret.yaml
  - pvc.yaml
configMapGenerator:
  - name: <app-name>
    files:
      - config-file.conf
示例(cloud-beaver):
yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - external-secret.yaml
  - password-policy.yaml
  - pvc.yaml
  - random-secret.yaml
  - service.yaml
  - vault-secret.yaml
  - vs.yaml
configMapGenerator:
  - name: cloud-beaver
    files:
      - cloudbeaver.conf
      - initial-data-sources.conf

6. Create Helm Values Files (for Helm-based apps)

6. 创建Helm值文件(基于Helm的应用)

values-default.yaml - Default values with templating:
yaml
undefined
values-default.yaml - 带有模板的默认值:
yaml
undefined

values-default.yaml

values-default.yaml

image: tag: ${app.tag}
resources: limits: cpu: 1000m memory: 512Mi requests: cpu: 100m memory: 128Mi
image: tag: ${app.tag}
resources: limits: cpu: 1000m memory: 512Mi requests: cpu: 100m memory: 128Mi

App-specific configuration

应用特定配置

config: option1: value1 option2: value2

**Example (chaosmesh):**
```yaml
chaosDaemon:
  runtime: containerd
  socketPath: /var/snap/microk8s/common/run/containerd.sock
Example (home/nginx):
yaml
image:
  tag: ${app.tag}

resources:
  limits:
    cpu: 200m
    memory: 256Mi
  requests:
    cpu: 50m
    memory: 64Mi

serverBlock: |-
  server {
    listen 8080;
    server_name _;
    location / {
      root /app;
      index index.html;
    }
  }
values-override.yaml - Template for environment-specific overrides:
yaml
undefined
config: option1: value1 option2: value2

**示例(chaosmesh):**
```yaml
chaosDaemon:
  runtime: containerd
  socketPath: /var/snap/microk8s/common/run/containerd.sock
示例(home/nginx):
yaml
image:
  tag: ${app.tag}

resources:
  limits:
    cpu: 200m
    memory: 256Mi
  requests:
    cpu: 50m
    memory: 64Mi

serverBlock: |-
  server {
    listen 8080;
    server_name _;
    location / {
      root /app;
      index index.html;
    }
  }
values-override.yaml - 环境特定覆盖的模板:
yaml
undefined

values-override.yaml

values-override.yaml

Environment-specific overrides can be added here

环境特定覆盖可在此处添加

These typically come from custom-config/<app-name>.yaml

这些通常来自custom-config/<app-name>.yaml

Example structure (commented out by default):

示例结构(默认已注释):

${app.values}

${app.values}

undefined
undefined

7. Create Kubernetes Resources

7. 创建Kubernetes资源

Create necessary Kubernetes resources based on deployment needs.
Common resources:
Virtual Service (vs.yaml) - For apps with web UI:
yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: <app-name>
spec:
  gateways:
    - istio-ingress-int/internal-wildcard-gateway
  hosts:
    - <app-name>.int.${cluster.env}.${cluster.domain}
  http:
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: <app-name>
            port:
              number: 80
Deployment (deployment.yaml) - For non-Helm apps:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: <app-name>
  labels:
    app: <app-name>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: <app-name>
  template:
    metadata:
      labels:
        app: <app-name>
    spec:
      containers:
        - name: <app-name>
          image: ${app.image}
          imagePullPolicy: IfNotPresent
          resources:
            limits:
              cpu: 1000m
              memory: 256Mi
            requests:
              cpu: 100m
              memory: 128Mi
          ports:
            - containerPort: 8080
              name: http
Service (service.yaml):
yaml
apiVersion: v1
kind: Service
metadata:
  name: <app-name>
spec:
  selector:
    app: <app-name>
  ports:
    - name: http
      port: 80
      targetPort: 8080
  type: ClusterIP
PersistentVolumeClaim (pvc.yaml) - For apps needing storage:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: <app-name>
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
根据部署需求创建必要的Kubernetes资源。
常见资源:
Virtual Service(vs.yaml) - 适用于带有Web UI的应用:
yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: <app-name>
spec:
  gateways:
    - istio-ingress-int/internal-wildcard-gateway
  hosts:
    - <app-name>.int.${cluster.env}.${cluster.domain}
  http:
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: <app-name>
            port:
              number: 80
Deployment(deployment.yaml) - 适用于非Helm应用:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: <app-name>
  labels:
    app: <app-name>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: <app-name>
  template:
    metadata:
      labels:
        app: <app-name>
    spec:
      containers:
        - name: <app-name>
          image: ${app.image}
          imagePullPolicy: IfNotPresent
          resources:
            limits:
              cpu: 1000m
              memory: 256Mi
            requests:
              cpu: 100m
              memory: 128Mi
          ports:
            - containerPort: 8080
              name: http
Service(service.yaml):
yaml
apiVersion: v1
kind: Service
metadata:
  name: <app-name>
spec:
  selector:
    app: <app-name>
  ports:
    - name: http
      port: 80
      targetPort: 8080
  type: ClusterIP
PersistentVolumeClaim(pvc.yaml) - 适用于需要存储的应用:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: <app-name>
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

8. Template Variables Reference

8. 模板变量参考

Use these template variables in your manifests:
App Configuration (
app.*
):
  • ${app.enabled}
    - Boolean to enable/disable app
  • ${app.namespace}
    - Target namespace
  • ${app.syncWave}
    - ArgoCD sync wave
  • ${app.version}
    - Helm chart version
  • ${app.tag}
    - Docker image tag
  • ${app.image}
    - Full image reference
  • ${app.values}
    - Helm chart value overrides
  • ${app.<custom-field>}
    - Any custom field from .config file
Cluster Configuration (
cluster.*
):
  • ${cluster.gitlabProjectUrl}
    - Git repository URL
  • ${cluster.env}
    - Environment name (dev, staging, prod)
  • ${cluster.domain}
    - Base domain
  • ${cluster.domainSuffix}
    - Domain suffix
  • ${cluster.cc}
    - Control center name
  • ${cluster.sc}
    - Storage cluster name
  • ${cluster.cloud_platform}
    - Cloud platform type
Other Apps (
apps.*
):
  • ${apps.<other-app-name>.<field>}
    - Access config from other apps
Conditional templating:
  • %{ if condition }
    ...
    %{ endif }
    - Conditional blocks
  • %{ for item in list }
    ...
    %{ endfor }
    - Loop blocks
在清单中使用以下模板变量:
应用配置(
app.*
):
  • ${app.enabled}
    - 启用/禁用应用的布尔值
  • ${app.namespace}
    - 目标命名空间
  • ${app.syncWave}
    - ArgoCD同步波
  • ${app.version}
    - Helm图表版本
  • ${app.tag}
    - Docker镜像标签
  • ${app.image}
    - 完整镜像引用
  • ${app.values}
    - Helm图表值覆盖
  • ${app.<custom-field>}
    - 来自.config文件的任何自定义字段
集群配置(
cluster.*
):
  • ${cluster.gitlabProjectUrl}
    - Git仓库URL
  • ${cluster.env}
    - 环境名称(dev, staging, prod)
  • ${cluster.domain}
    - 基础域名
  • ${cluster.domainSuffix}
    - 域名后缀
  • ${cluster.cc}
    - 控制中心名称
  • ${cluster.sc}
    - 存储集群名称
  • ${cluster.cloud_platform}
    - 云平台类型
其他应用(
apps.*
):
  • ${apps.<other-app-name>.<field>}
    - 访问其他应用的配置
条件模板:
  • %{ if condition }
    ...
    %{ endif }
    - 条件块
  • %{ for item in list }
    ...
    %{ endfor }
    - 循环块

9. Environment-Specific Configuration

9. 环境特定配置

Users can override addon configuration by creating
custom-config/<app-name>.yaml
:
yaml
undefined
用户可以通过创建
custom-config/<app-name>.yaml
来覆盖插件配置:
yaml
undefined

custom-config/<app-name>.yaml

custom-config/<app-name>.yaml

enabled: true # Enable the app namespace: custom-ns # Override namespace syncWave: 5 # Override sync wave version: 2.0.0 # Override chart version tag: custom-tag # Override image tag values: # Helm chart overrides resources: limits: cpu: 2000m memory: 1Gi
undefined
enabled: true # 启用应用 namespace: custom-ns # 覆盖命名空间 syncWave: 5 # 覆盖同步波 version: 2.0.0 # 覆盖图表版本 tag: custom-tag # 覆盖镜像标签 values: # Helm图表覆盖 resources: limits: cpu: 2000m memory: 1Gi
undefined

10. Testing the Addon

10. 测试插件

Local validation:
bash
undefined
本地验证:
bash
undefined

Navigate to the addon directory

导航到插件目录

cd <addon-name>/<app-name>
cd <addon-name>/<app-name>

Validate kustomization

验证kustomization

kustomize build .
kustomize build .

Check for template syntax (if using envsubst or similar)

检查模板语法(如果使用envsubst或类似工具)

Set required variables

设置所需变量

export app='{"enabled": true, "namespace": "test", "syncWave": "0", "version": "1.0.0"}' export cluster='{"gitlabProjectUrl": "https://git.example.com/repo", "env": "dev", "domain": "example.com"}'
export app='{"enabled": true, "namespace": "test", "syncWave": "0", "version": "1.0.0"}' export cluster='{"gitlabProjectUrl": "https://git.example.com/repo", "env": "dev", "domain": "example.com"}'

Test ArgoCD application rendering (requires gomplate or similar)

测试ArgoCD应用渲染(需要gomplate或类似工具)

gomplate -f <app-name>.app.yaml

**Deployment testing:**

1. Push addon to git repository
2. Enable in environment: Create `custom-config/<app-name>.yaml` with `enabled: true`
3. Sync ArgoCD app-of-apps
4. Monitor deployment: `kubectl get applications -n argocd`
5. Check app status: `kubectl get all -n <namespace>`
gomplate -f <app-name>.app.yaml

**部署测试:**

1. 将插件推送到Git仓库
2. 在环境中启用:创建`custom-config/<app-name>.yaml`并设置`enabled: true`
3. 同步ArgoCD应用集合(app-of-apps)
4. 监控部署:`kubectl get applications -n argocd`
5. 检查应用状态:`kubectl get all -n <namespace>`

Common Patterns and Examples

常见模式和示例

Pattern 1: Simple Helm Chart Deployment

模式1:简单Helm图表部署

Use case: Deploy a standard Helm chart with minimal customization
Files needed:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
  • values-default.yaml
  • values-override.yaml
Example: Headlamp (K8s dashboard)
使用场景: 使用最少自定义部署标准Helm图表
所需文件:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
  • values-default.yaml
  • values-override.yaml
示例: Headlamp(K8s仪表板)

Pattern 2: Plain Manifests with ConfigMaps

模式2:带有ConfigMap的纯清单

Use case: Deploy application without Helm, using custom manifests
Files needed:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
  • deployment.yaml
  • service.yaml
  • vs.yaml
    (optional)
  • Configuration files
Example: Cloud Beaver (database UI)
使用场景: 不使用Helm,使用自定义清单部署应用
所需文件:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
  • deployment.yaml
  • service.yaml
  • vs.yaml
    (可选)
  • 配置文件
示例: Cloud Beaver(数据库UI)

Pattern 3: CronJob-based Addon

模式3:基于CronJob的插件

Use case: Scheduled jobs for testing or maintenance
Files needed:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
  • cronjob.yaml
  • ConfigMaps for job scripts
Example: Benchmark MySQL
使用场景: 用于测试或维护的定时任务
所需文件
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
  • cronjob.yaml
  • 用于任务脚本的ConfigMap
示例: Benchmark MySQL

Pattern 4: Operator-based Deployment

模式4:基于Operator的部署

Use case: Deploy operator + custom resources
Files needed:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
    (with Helm chart)
  • values-default.yaml
  • Custom resource definitions (schedules, tests, etc.)
Example: Chaos Mesh, K6 Operator
使用场景: 部署Operator + 自定义资源
所需文件:
  • .config/<app-name>.yaml
  • <app-name>.app.yaml
  • kustomization.yaml
    (带有Helm图表)
  • values-default.yaml
  • 自定义资源定义(调度、测试等)
示例: Chaos Mesh, K6 Operator

Best Practices

最佳实践

  1. Naming Conventions:
    • Use lowercase with hyphens
    • Keep names concise but descriptive
    • Match the tool's common name when possible
  2. Configuration:
    • Set sensible defaults in
      .config/<app-name>.yaml
    • Document all configuration options
    • Use template variables for environment-specific values
  3. Resource Limits:
    • Always set resource requests and limits
    • Start conservative, tune based on actual usage
    • Document expected resource usage
  4. Security:
    • Never hardcode secrets
    • Use ExternalSecrets or Vault integration
    • Follow principle of least privilege for RBAC
  5. Documentation:
    • Add README.md to addon directory if complex
    • Document configuration options
    • Include usage examples
  6. Sync Waves:
    • Use negative waves (-1, -2) for infrastructure dependencies
    • Use 0 for standard applications
    • Use high values (99+) for tests and post-deployment tasks
  7. Virtual Services:
    • Use internal gateway for admin/development tools
    • Follow domain naming convention:
      <app>.int.<env>.<domain>
    • Add appropriate security headers
  8. Helm Values:
    • Keep
      values-default.yaml
      minimal
    • Use template variables for dynamic values
    • Let
      values-override.yaml
      be environment-specific
  9. Testing:
    • Test locally with kustomize build
    • Deploy to dev environment first
    • Validate all template variables resolve correctly
  10. Version Control:
    • Commit all files including empty values-override.yaml
    • Use descriptive commit messages
    • Tag stable versions for reuse
  1. 命名约定:
    • 使用小写字母加连字符
    • 保持名称简洁但具有描述性
    • 尽可能与工具的通用名称匹配
  2. 配置:
    • .config/<app-name>.yaml
      中设置合理的默认值
    • 记录所有配置选项
    • 对环境特定值使用模板变量
  3. 资源限制:
    • 始终设置资源请求和限制
    • 从保守值开始,根据实际使用情况调整
    • 记录预期的资源使用情况
  4. 安全性:
    • 永远不要硬编码密钥
    • 使用ExternalSecrets或Vault集成
    • 遵循RBAC的最小权限原则
  5. 文档:
    • 如果插件复杂,在插件目录中添加README.md
    • 记录配置选项
    • 包含使用示例
  6. 同步波:
    • 对基础设施依赖项使用负波(-1, -2)
    • 对标准应用使用0
    • 对测试和部署后任务使用高值(99+)
  7. Virtual Service:
    • 对管理/开发工具使用内部网关
    • 遵循域名命名约定:
      <app>.int.<env>.<domain>
    • 添加适当的安全头
  8. Helm值:
    • 保持
      values-default.yaml
      简洁
    • 对动态值使用模板变量
    • values-override.yaml
      针对特定环境
  9. 测试:
    • 使用kustomize build本地测试
    • 先部署到开发环境
    • 验证所有模板变量是否正确解析
  10. 版本控制:
    • 提交所有文件,包括空的values-override.yaml
    • 使用描述性的提交消息
    • 标记稳定版本以供复用

Troubleshooting

故障排除

App not appearing in ArgoCD:
  • Verify
    .app.yaml
    has correct path
  • Check
    app.enabled
    is true in config
  • Confirm ArgoCD has synced the app-of-apps
Template variables not resolving:
  • Verify variable names match config structure
  • Check for typos in
    ${...}
    references
  • Ensure config files are in correct location
Helm chart not found:
  • Verify chart repository URL is correct
  • Check chart name and version exist
  • Ensure network access to chart repository
Namespace issues:
  • Verify namespace in
    .app.yaml
    matches config
  • Check
    CreateNamespace=true
    in syncOptions
  • Ensure namespace doesn't conflict with existing resources
Sync failures:
  • Check ArgoCD application status
  • Review K8s events in target namespace
  • Verify all referenced secrets/configmaps exist
应用未出现在ArgoCD中:
  • 验证
    .app.yaml
    的路径是否正确
  • 检查配置中的
    app.enabled
    是否为true
  • 确认ArgoCD已同步应用集合
模板变量未解析:
  • 验证变量名称与配置结构匹配
  • 检查
    ${...}
    引用中的拼写错误
  • 确保配置文件位于正确位置
Helm图表未找到:
  • 验证图表仓库URL是否正确
  • 检查图表名称和版本是否存在
  • 确保可以访问图表仓库的网络
命名空间问题:
  • 验证
    .app.yaml
    中的命名空间与配置匹配
  • 检查syncOptions中是否设置了
    CreateNamespace=true
  • 确保命名空间不与现有资源冲突
同步失败:
  • 检查ArgoCD应用状态
  • 查看目标命名空间中的K8s事件
  • 验证所有引用的密钥/ConfigMap是否存在

Examples Directory

示例目录

Refer to existing addons for working examples. Note: Some addons use the old structure - do NOT replicate that pattern.
Addons using the NEW structure (correct to reference):
  • Look for addons with
    .config/
    directory and
    <app-name>.app.yaml
    at the root
  • These follow the correct pattern for new addons
Addons using the OLD structure (do NOT replicate):
  • Addons with configuration only in
    default.yaml
  • Addons with app definitions in
    app-yamls/
    directory
  • These exist for backward compatibility only
参考现有插件获取可用示例。注意: 一些插件使用旧结构 - 请勿复制该模式。
使用新结构的插件(可参考):
  • 查找带有
    .config/
    目录和根目录下
    <app-name>.app.yaml
    的插件
  • 这些遵循新插件的正确模式
使用旧结构的插件(请勿复制):
  • 仅在
    default.yaml
    中包含配置的插件
  • 应用定义位于
    app-yamls/
    目录的插件
  • 这些仅为向后兼容而存在

Common Mistakes to Avoid

常见错误避免

❌ DO NOT:

❌ 请勿:

  1. Create app definition files in
    app-yamls/
    directory
    bash
    # WRONG - do not do this:
    app-yamls/my-new-app.yaml
  2. Add configuration to
    default.yaml
    yaml
    # WRONG - do not add to default.yaml:
    my-new-app:
        image: my-image:latest
        ...
  3. Use old template variable patterns
    yaml
    # WRONG - old structure pattern:
    image: ${my-app.image}
  1. app-yamls/
    目录中创建应用定义文件
    bash
    # 错误 - 请勿这样做:
    app-yamls/my-new-app.yaml
  2. default.yaml
    中添加配置
    yaml
    # 错误 - 请勿添加到default.yaml:
    my-new-app:
        image: my-image:latest
        ...
  3. 使用旧模板变量模式
    yaml
    # 错误 - 旧结构模式:
    image: ${my-app.image}

✅ DO:

✅ 请:

  1. Create app definition in the app's own directory
    bash
    # CORRECT:
    <app-name>/<app-name>.app.yaml
  2. Put configuration in
    .config/<app-name>.yaml
    yaml
    # CORRECT - in .config/<app-name>.yaml:
    enabled: true
    image: my-image:latest
    namespace: my-app
    syncWave: 0
  3. Use
    ${app.*}
    template variables
    yaml
    # CORRECT - references .config/<app-name>.yaml:
    image: ${app.image}
    namespace: ${app.namespace}
  4. Make the addon self-contained
    • All configuration in
      .config/
      directory
    • All manifests in the app directory
    • App definition at the root of the app directory
  1. 在应用自身目录中创建应用定义
    bash
    # 正确:
    <app-name>/<app-name>.app.yaml
  2. 将配置放在
    .config/<app-name>.yaml
    yaml
    # 正确 - 在.config/<app-name>.yaml中:
    enabled: true
    image: my-image:latest
    namespace: my-app
    syncWave: 0
  3. 使用
    ${app.*}
    模板变量
    yaml
    # 正确 - 引用.config/<app-name>.yaml:
    image: ${app.image}
    namespace: ${app.namespace}
  4. 使插件独立包含
    • 所有配置位于
      .config/
      目录
    • 所有清单位于应用目录
    • 应用定义位于应用目录的根目录

Structure Comparison

结构对比

NEW Structure (Use This) ✅

新结构(使用此结构) ✅

mongo-express/
├── .config/
│   └── mongo-express.yaml       # Configuration here
├── mongo-express.app.yaml       # App definition here
├── kustomization.yaml
├── deployment.yaml
├── service.yaml
├── vs.yaml
└── README.md
Template variables:
${app.image}
,
${app.mongoUrl}
, etc.
mongo-express/
├── .config/
│   └── mongo-express.yaml       # 配置在此处
├── mongo-express.app.yaml       # 应用定义在此处
├── kustomization.yaml
├── deployment.yaml
├── service.yaml
├── vs.yaml
└── README.md
模板变量:
${app.image}
,
${app.mongoUrl}

OLD Structure (Don't Use) ❌

旧结构(请勿使用) ❌

app-yamls/
└── mongo-express.yaml           # App definition (OLD location)
default.yaml                     # Configuration (OLD location)
mongo-express/
├── kustomization.yaml
├── deployment.yaml
└── service.yaml
Template variables:
${mongo-express.image}
(OLD pattern)
app-yamls/
└── mongo-express.yaml           # 应用定义(旧位置)
default.yaml                     # 配置(旧位置)
mongo-express/
├── kustomization.yaml
├── deployment.yaml
└── service.yaml
模板变量:
${mongo-express.image}
(旧模式)

References

参考资料