addon-creator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseIMPORTANT: Structure Requirements
重要提示:结构要求
⚠️ MANDATORY: All new addons MUST use the NEW structure described below.
The repository may contain some addons using an older structure (with and configuration in ). 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/*.yamldefault.yaml⚠️ 强制要求:所有新插件必须使用下文所述的新结构。
仓库中可能包含一些使用旧结构的插件(带有和中的配置)。请勿为新插件使用此旧结构。旧结构已被弃用,仅为与现有插件向后兼容而保留。
app-yamls/*.yamldefault.yamlWhen 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 templatingKey characteristics of the NEW structure:
- Configuration is in (self-contained per app)
.config/<app-name>.yaml - App definition is in at the app root
<app-name>.app.yaml - Template variables use to reference config from
${app.*}.config/<app-name>.yaml - No entries needed in or
default.yamldirectoryapp-yamls/
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 and app-specific files
default.yaml - App definitions in separate directory
app-yamls/ - 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-meshmongo-express - App names should be descriptive and match the tool being deployed
- Namespace typically matches the app name
⚠️ IMPORTANT: Do NOT create files in directory or add configuration to . These are part of the deprecated old structure.
app-yamls/default.yaml需要回答的问题:
- 应用名称是什么?(例如:,
redis-insight,mongo-express)cloud-beaver - 应用应使用哪个命名空间?(默认:与应用名称相同)
- 是否需要持久化存储?
- 是否需要入口/Virtual Service?
命名约定:
- 使用小写字母加连字符:,
redis-insight,chaos-meshmongo-express - 应用名称应具有描述性,与要部署的工具匹配
- 命名空间通常与应用名称相同
⚠️ 重要提示:请勿在目录中创建文件,也不要在中添加配置。这些属于已弃用的旧结构。
app-yamls/default.yaml2. Create App Directory Structure
2. 创建应用目录结构
Navigate to the addons repository (e.g., ) and create:
/home/kalin/work/deploy/addons-dev/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>.yamlThis file contains all configuration for your app. Template variables in your manifests will reference fields from this file using .
${app.<field>}Create with default configuration:
.config/<app-name>.yamlyaml
undefined这是第一个需要创建的文件:
.config/<app-name>.yaml此文件包含应用的所有配置。清单中的模板变量将使用引用此文件中的字段。
${app.<field>}创建包含默认配置的:
.config/<app-name>.yamlyaml
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:**
```yamlenabled: 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部署时)
**现有插件的示例:**
```yamlchaosmesh
chaosmesh
enabled: true
version: 2.7.0
namespace: chaosmesh
syncWave: 0
values: {}
```yamlenabled: true
version: 2.7.0
namespace: chaosmesh
syncWave: 0
values: {}
```yamlcloud-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
```yamlenabled: 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
```yamlk6
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: {}
undefinedenabled: 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: {}
undefined4. Create ArgoCD Application Definition
4. 创建ArgoCD应用定义
Create :
<app-name>.app.yamlyaml
undefined创建:
<app-name>.app.yamlyaml
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 pruningapiVersion: 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 defines which Kubernetes resources to include.
kustomization.yamlFor 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.yamlExample (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.yamlFor 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.confExample (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.confkustomization.yaml基于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.conf6. Create Helm Values Files (for Helm-based apps)
6. 创建Helm值文件(基于Helm的应用)
values-default.yaml - Default values with templating:
yaml
undefinedvalues-default.yaml - 带有模板的默认值:
yaml
undefinedvalues-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.sockExample (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
undefinedconfig:
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
undefinedvalues-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}
undefinedundefined7. 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: 80Deployment (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: httpService (service.yaml):
yaml
apiVersion: v1
kind: Service
metadata:
name: <app-name>
spec:
selector:
app: <app-name>
ports:
- name: http
port: 80
targetPort: 8080
type: ClusterIPPersistentVolumeClaim (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: 80Deployment(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: httpService(service.yaml):
yaml
apiVersion: v1
kind: Service
metadata:
name: <app-name>
spec:
selector:
app: <app-name>
ports:
- name: http
port: 80
targetPort: 8080
type: ClusterIPPersistentVolumeClaim(pvc.yaml) - 适用于需要存储的应用:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: <app-name>
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi8. Template Variables Reference
8. 模板变量参考
Use these template variables in your manifests:
App Configuration ():
app.*- - Boolean to enable/disable app
${app.enabled} - - Target namespace
${app.namespace} - - ArgoCD sync wave
${app.syncWave} - - Helm chart version
${app.version} - - Docker image tag
${app.tag} - - Full image reference
${app.image} - - Helm chart value overrides
${app.values} - - Any custom field from .config file
${app.<custom-field>}
Cluster Configuration ():
cluster.*- - Git repository URL
${cluster.gitlabProjectUrl} - - Environment name (dev, staging, prod)
${cluster.env} - - Base domain
${cluster.domain} - - Domain suffix
${cluster.domainSuffix} - - Control center name
${cluster.cc} - - Storage cluster name
${cluster.sc} - - Cloud platform type
${cluster.cloud_platform}
Other Apps ():
apps.*- - Access config from other apps
${apps.<other-app-name>.<field>}
Conditional templating:
- ...
%{ if condition }- Conditional blocks%{ endif } - ...
%{ for item in list }- Loop blocks%{ endfor }
在清单中使用以下模板变量:
应用配置():
app.*- - 启用/禁用应用的布尔值
${app.enabled} - - 目标命名空间
${app.namespace} - - ArgoCD同步波
${app.syncWave} - - Helm图表版本
${app.version} - - Docker镜像标签
${app.tag} - - 完整镜像引用
${app.image} - - Helm图表值覆盖
${app.values} - - 来自.config文件的任何自定义字段
${app.<custom-field>}
集群配置():
cluster.*- - Git仓库URL
${cluster.gitlabProjectUrl} - - 环境名称(dev, staging, prod)
${cluster.env} - - 基础域名
${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>.yamlyaml
undefined用户可以通过创建来覆盖插件配置:
custom-config/<app-name>.yamlyaml
undefinedcustom-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
undefinedenabled: true # 启用应用
namespace: custom-ns # 覆盖命名空间
syncWave: 5 # 覆盖同步波
version: 2.0.0 # 覆盖图表版本
tag: custom-tag # 覆盖镜像标签
values: # Helm图表覆盖
resources:
limits:
cpu: 2000m
memory: 1Gi
undefined10. Testing the Addon
10. 测试插件
Local validation:
bash
undefined本地验证:
bash
undefinedNavigate 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.yamlkustomization.yamlvalues-default.yamlvalues-override.yaml
Example: Headlamp (K8s dashboard)
使用场景: 使用最少自定义部署标准Helm图表
所需文件:
.config/<app-name>.yaml<app-name>.app.yamlkustomization.yamlvalues-default.yamlvalues-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.yamlkustomization.yamldeployment.yamlservice.yaml- (optional)
vs.yaml - Configuration files
Example: Cloud Beaver (database UI)
使用场景: 不使用Helm,使用自定义清单部署应用
所需文件:
.config/<app-name>.yaml<app-name>.app.yamlkustomization.yamldeployment.yamlservice.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.yamlkustomization.yamlcronjob.yaml- ConfigMaps for job scripts
Example: Benchmark MySQL
使用场景: 用于测试或维护的定时任务
所需文件:
.config/<app-name>.yaml<app-name>.app.yamlkustomization.yamlcronjob.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- (with Helm chart)
kustomization.yaml values-default.yaml- Custom resource definitions (schedules, tests, etc.)
Example: Chaos Mesh, K6 Operator
使用场景: 部署Operator + 自定义资源
所需文件:
.config/<app-name>.yaml<app-name>.app.yaml- (带有Helm图表)
kustomization.yaml values-default.yaml- 自定义资源定义(调度、测试等)
示例: Chaos Mesh, K6 Operator
Best Practices
最佳实践
-
Naming Conventions:
- Use lowercase with hyphens
- Keep names concise but descriptive
- Match the tool's common name when possible
-
Configuration:
- Set sensible defaults in
.config/<app-name>.yaml - Document all configuration options
- Use template variables for environment-specific values
- Set sensible defaults in
-
Resource Limits:
- Always set resource requests and limits
- Start conservative, tune based on actual usage
- Document expected resource usage
-
Security:
- Never hardcode secrets
- Use ExternalSecrets or Vault integration
- Follow principle of least privilege for RBAC
-
Documentation:
- Add README.md to addon directory if complex
- Document configuration options
- Include usage examples
-
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
-
Virtual Services:
- Use internal gateway for admin/development tools
- Follow domain naming convention:
<app>.int.<env>.<domain> - Add appropriate security headers
-
Helm Values:
- Keep minimal
values-default.yaml - Use template variables for dynamic values
- Let be environment-specific
values-override.yaml
- Keep
-
Testing:
- Test locally with kustomize build
- Deploy to dev environment first
- Validate all template variables resolve correctly
-
Version Control:
- Commit all files including empty values-override.yaml
- Use descriptive commit messages
- Tag stable versions for reuse
-
命名约定:
- 使用小写字母加连字符
- 保持名称简洁但具有描述性
- 尽可能与工具的通用名称匹配
-
配置:
- 在中设置合理的默认值
.config/<app-name>.yaml - 记录所有配置选项
- 对环境特定值使用模板变量
- 在
-
资源限制:
- 始终设置资源请求和限制
- 从保守值开始,根据实际使用情况调整
- 记录预期的资源使用情况
-
安全性:
- 永远不要硬编码密钥
- 使用ExternalSecrets或Vault集成
- 遵循RBAC的最小权限原则
-
文档:
- 如果插件复杂,在插件目录中添加README.md
- 记录配置选项
- 包含使用示例
-
同步波:
- 对基础设施依赖项使用负波(-1, -2)
- 对标准应用使用0
- 对测试和部署后任务使用高值(99+)
-
Virtual Service:
- 对管理/开发工具使用内部网关
- 遵循域名命名约定:
<app>.int.<env>.<domain> - 添加适当的安全头
-
Helm值:
- 保持简洁
values-default.yaml - 对动态值使用模板变量
- 让针对特定环境
values-override.yaml
- 保持
-
测试:
- 使用kustomize build本地测试
- 先部署到开发环境
- 验证所有模板变量是否正确解析
-
版本控制:
- 提交所有文件,包括空的values-override.yaml
- 使用描述性的提交消息
- 标记稳定版本以供复用
Troubleshooting
故障排除
App not appearing in ArgoCD:
- Verify has correct path
.app.yaml - Check is true in config
app.enabled - 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 matches config
.app.yaml - Check in syncOptions
CreateNamespace=true - 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 - 检查配置中的是否为true
app.enabled - 确认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 directory and
.config/at the root<app-name>.app.yaml - 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 directory
app-yamls/ - These exist for backward compatibility only
参考现有插件获取可用示例。注意: 一些插件使用旧结构 - 请勿复制该模式。
使用新结构的插件(可参考):
- 查找带有目录和根目录下
.config/的插件<app-name>.app.yaml - 这些遵循新插件的正确模式
使用旧结构的插件(请勿复制):
- 仅在中包含配置的插件
default.yaml - 应用定义位于目录的插件
app-yamls/ - 这些仅为向后兼容而存在
Common Mistakes to Avoid
常见错误避免
❌ DO NOT:
❌ 请勿:
-
Create app definition files indirectory
app-yamls/bash# WRONG - do not do this: app-yamls/my-new-app.yaml -
Add configuration to
default.yamlyaml# WRONG - do not add to default.yaml: my-new-app: image: my-image:latest ... -
Use old template variable patternsyaml
# WRONG - old structure pattern: image: ${my-app.image}
-
在目录中创建应用定义文件
app-yamls/bash# 错误 - 请勿这样做: app-yamls/my-new-app.yaml -
在中添加配置
default.yamlyaml# 错误 - 请勿添加到default.yaml: my-new-app: image: my-image:latest ... -
使用旧模板变量模式yaml
# 错误 - 旧结构模式: image: ${my-app.image}
✅ DO:
✅ 请:
-
Create app definition in the app's own directorybash
# CORRECT: <app-name>/<app-name>.app.yaml -
Put configuration in
.config/<app-name>.yamlyaml# CORRECT - in .config/<app-name>.yaml: enabled: true image: my-image:latest namespace: my-app syncWave: 0 -
Usetemplate variables
${app.*}yaml# CORRECT - references .config/<app-name>.yaml: image: ${app.image} namespace: ${app.namespace} -
Make the addon self-contained
- All configuration in directory
.config/ - All manifests in the app directory
- App definition at the root of the app directory
- All configuration in
-
在应用自身目录中创建应用定义bash
# 正确: <app-name>/<app-name>.app.yaml -
将配置放在中
.config/<app-name>.yamlyaml# 正确 - 在.config/<app-name>.yaml中: enabled: true image: my-image:latest namespace: my-app syncWave: 0 -
使用模板变量
${app.*}yaml# 正确 - 引用.config/<app-name>.yaml: image: ${app.image} namespace: ${app.namespace} -
使插件独立包含
- 所有配置位于目录
.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.mdTemplate variables: , , etc.
${app.image}${app.mongoUrl}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.yamlTemplate variables: (OLD pattern)
${mongo-express.image}app-yamls/
└── mongo-express.yaml # 应用定义(旧位置)
default.yaml # 配置(旧位置)
mongo-express/
├── kustomization.yaml
├── deployment.yaml
└── service.yaml模板变量: (旧模式)
${mongo-express.image}References
参考资料
- ArgoCD Documentation: https://argo-cd.readthedocs.io/
- Kustomize Documentation: https://kustomize.io/
- Helm Documentation: https://helm.sh/docs/
- Mojaloop IAC Modules Addon Spec: addons.md
- ArgoCD文档:https://argo-cd.readthedocs.io/
- Kustomize文档:https://kustomize.io/
- Helm文档:https://helm.sh/docs/
- Mojaloop IAC模块插件规范:addons.md