Subsections of AI Agent
Hermes
OpenCode
🚀Installation
Preliminary
1. Kubernetes is installed; if not, check 🔗link2. Helm is installed; if not, check 🔗link3. ArgoCD is installed; if not, check 🔗link1.prepare `opencode-configuration.yaml`
Details
kubectl get namespaces opencode > /dev/null 2>&1 || kubectl create namespace opencode
kubectl -n opencode create secret generic opencode-server-secret \
--from-literal=OPENCODE_SERVER_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 16)1.1.choose different LLM configuration
kubectl -n opencode apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: opencode-config
data:
opencode.json: |
{
"provider": {
"openai": {
"options": {
"baseURL": "https://v2.qixuw.com/v1",
"apiKey": "sk-ss"
},
"models": {
"gpt-5.3-codex-spark": {
"name": "GPT-5.3 Codex Spark",
"limit": {
"context": 128000,
"output": 32000
},
"options": {
"store": false
},
"variants": {
"low": {},
"medium": {},
"high": {},
"xhigh": {}
}
}
}
}
},
"agent": {
"build": {
"options": {
"store": false
}
},
"plan": {
"options": {
"store": false
}
}
},
"$schema": "https://opencode.ai/config.json"
}
EOFkubectl -n opencode apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: opencode-config
data:
opencode.json: |
{
"provider": {
"openai": {
"options": {
"baseURL": "https://v2.qixuw.com/v1",
"apiKey": "sk-ss"
},
"models": {
"gpt-5.3-codex-spark": {
"name": "GPT-5.3 Codex Spark",
"limit": {
"context": 128000,
"output": 32000
},
"options": {
"store": false
},
"variants": {
"low": {},
"medium": {},
"high": {},
"xhigh": {}
}
}
}
}
},
"mcp": {
"euclid-catalog": {
"type": "remote",
"url": "https://catalog.euclid.mcp.dev.72602.online:32443/sse",
"enabled": true
},
"astro_k3s_mcp": {
"type": "remote",
"url": "http://eva24002-entrance.lab.zverse.space:30082/mcp",
"enabled": true,
"oauth": false,
"timeout": 15000
}
},
"agent": {
"build": {
"options": {
"store": false
}
},
"plan": {
"options": {
"store": false
}
}
},
"$schema": "https://opencode.ai/config.json"
}
EOFkubectl -n opencode apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: opencode-config
data:
opencode.json: |
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"minimax": {
"npm": "@ai-sdk/openai-compatible",
"name": "MiniMax M2.5",
"options": {
"baseURL": "http://10.200.92.41:31551/v1",
"apiKey": "sk-sss"
},
"models": {
"minimax-m2.5": {
"name": "MiniMax M2.5",
"id": "MiniMaxAI/MiniMax-M2.5",
"limit": {
"context": 196608,
"output": 8192
}
}
}
}
},
"model": "minimax/minimax-m2.5"
}
EOFkubectl -n opencode apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: opencode-config
data:
opencode.json: |
{
"$schema": "https://opencode.ai/config.json",
"model": "opencode/minimax-m2.5-free",
"small_model": "opencode/minimax-m2.5-free"
}
EOFkubectl -n opencode apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: opencode-config
data:
opencode.json: |
{
"provider": {
"qiniu": {
"options": {
"baseURL": "https://api.qnaigc.com/v1",
"apiKey": "sk-sss"
},
"models": {
"minimax-m2.5": {
"name": "Minimax-M2.5",
"limit": {
"context": 128000,
"output": 32000
},
"options": {
"store": false
},
"variants": {
"low": {},
"medium": {},
"high": {},
"xhigh": {}
}
}
}
}
},
"agent": {
"build": {
"options": {
"store": false
}
},
"plan": {
"options": {
"store": false
}
}
},
"$schema": "https://opencode.ai/config.json"
}
EOF2.prepare `deploy-opencode.yaml`; change the default model when you apply a different ConfigMap
Details
kubectl -n argocd apply -f - <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: opencode
namespace: argocd
spec:
project: default
source:
repoURL: oci://ghcr.io/aaronyang0628/opencode
targetRevision: 0.20.0
chart: opencode
helm:
values: |
image:
repository: ghcr.io/nimbleflux/opencode-docker
tag: 1.2.26
pullPolicy: Always
replicaCount: 1
command:
- opencode
args:
- serve
- --port
- "4000"
- --hostname
- "0.0.0.0"
service:
type: ClusterIP
port: 4000
env:
OPENCODE_PORT: "4000"
extraVolumes:
- name: opencode-config
configMap:
name: opencode-config
extraVolumeMounts:
- name: opencode-config
mountPath: /home/opencode/.config/opencode/opencode.json
subPath: opencode.json
readOnly: true
persistence:
enabled: true
storageClass: local-path
config:
enabled: false
data:
enabled: true
size: 1Gi
workspace:
enabled: true
size: 5Gi
playbook:
enabled: true
mountPath: /home/opencode/workspace/playbook
example:
enabled: true
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
probes:
liveness:
tcpSocket:
port: 4000
initialDelaySeconds: 15
periodSeconds: 30
readiness:
tcpSocket:
port: 4000
initialDelaySeconds: 10
periodSeconds: 10
startup:
tcpSocket:
port: 4000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 30
ingress:
enabled: true
className: nginx
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: self-signed-ca-issuer
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "50"
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
hosts:
- host: opencode.dev.72602.online
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- opencode.dev.72602.online
secretName: opencode.dev.72602.online-tls
globalLabels:
app.kubernetes.io/part-of: opencode
environment: production
bridge:
enabled: true
image:
repository: crpi-wixjy6gci86ms14e.cn-hongkong.personal.cr.aliyuncs.com/ay-dev/opencode-bridge
tag: "v20260326r4"
env:
defaultModel: "opencode/minimax-m2.5-free"
openaiStreamChunkSize: "4"
openaiStreamChunkDelayMs: "10"
enableLeadingEchoFilter: "false"
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: self-signed-ca-issuer
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "50"
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
hosts:
- host: opencode-bridge.dev.72602.online
paths:
- path: /
pathType: Prefix
tls:
- secretName: opencode-bridge-tls
hosts:
- opencode-bridge.dev.72602.online
destination:
server: https://kubernetes.default.svc
namespace: opencode
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
EOF3.sync by argocd
Details
argocd app sync argocd/opencode4.then you can talk with LLM with rest api
Details
curl -k -X POST https://opencode.dev.72602.online:32443/session \
-H "Content-Type: application/json" \
-d '{"model": "opencode/minimax-m2.5-free"}'
## {"id":"ses_30a879abeffe6KRC0Rmg4aPrmK","slug":"brave-eagle","version":"1.2.26","projectID":"global","directory":"/home/opencode/workspace","title":"New session - 2026-03-16T07:07:14.113Z","time":{"created":1773644834113,"updated":1773644834113}}5.reuse the same session
Details
curl -k -X POST https://opencode.dev.72602.online:32443/session/ses_30a879abeffe6KRC0Rmg4aPrmK/message \
-H "Content-Type: application/json" \
-d '{"parts": [{"type": "text", "text": "你好"}]}'
## {"info":{"role":"assistant","time":{"created":1773644844131,"completed":1773644848700},"parentID":"msg_cf5788c12001RS4wX3hwMRe0If","modelID":"minimax-m2.5","providerID":"minimax","mode":"build","agent":"build","path":{"cwd":"/home/opencode/workspace","root":"/"},"cost":0,"tokens":{"total":10628,"input":10567,"output":61,"reasoning":0,"cache":{"read":0,"write":0}},"finish":"stop","id":"msg_cf5788c63001hBrorYejcHc1tO","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK"},"parts":[{"type":"step-start","id":"prt_cf57899120016WXp4jT4AHeTiG","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK","messageID":"msg_cf5788c63001hBrorYejcHc1tO"},{"type":"text","text":"<think>The user said \"你好\" which means \"Hello\" in Chinese. According to the instructions, I should be concise and direct. I should respond briefly without unnecessary preamble. Since this is a simple greeting, I can just respond with a greeting back.\n</think>\n\n你好!有什么可以帮你的吗?","time":{"start":1773644848689,"end":1773644848689},"id":"prt_cf5789913001dUZnoW9w63ThkC","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK","messageID":"msg_cf5788c63001hBrorYejcHc1tO"},{"type":"step-finish","reason":"stop","cost":0,"tokens":{"total":10628,"input":10567,"output":61,"reasoning":0,"cache":{"read":0,"write":0}},"id":"prt_cf5789e35001dLGIXJb5WHizMX","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK","messageID":"msg_cf5788c63001hBrorYejcHc1tO"}]}Preliminary
1. Kubernetes is installed; if not, check 🔗link2. Helm is installed; if not, check 🔗link3. ArgoCD is installed; if not, check 🔗link0. (optional) deploy `oauth2-proxy` for GitHub OAuth 2FA
Details
kubectl get namespaces oauth2-proxy > /dev/null 2>&1 || kubectl create namespace oauth2-proxy
kubectl -n oauth2-proxy create secret generic oauth2-proxy-secret \
--from-literal=client-id=<your-github-oauth-client-id> \
--from-literal=client-secret=<your-github-oauth-client-secret> \
--from-literal=cookie-secret=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 32)
kubectl -n argocd apply -f - <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: oauth2-proxy
namespace: argocd
spec:
project: default
source:
repoURL: oci://ghcr.io/aaronyang0628/oauth2-proxy
targetRevision: 7.7.0
chart: oauth2-proxy
helm:
values: |
config:
clientID: ""
existingSecret: oauth2-proxy-secret
extraEnv:
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: client-id
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: client-secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: cookie-secret
provider: github
upstreams:
- http://opencode:4000
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt
hosts:
- host: ops.agent.72602.online
paths:
- /
tls:
- secretName: ops.agent.72602.online-tls
hosts:
- ops.agent.72602.online
destination:
server: https://kubernetes.default.svc
namespace: oauth2-proxy
syncPolicy:
syncOptions:
- CreateNamespace=true
EOF1.prepare `opencode-configuration.yaml`
Details
kubectl get namespaces opencode > /dev/null 2>&1 || kubectl create namespace opencode
kubectl -n opencode create secret generic opencode-server-secret \
--from-literal=OPENCODE_SERVER_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 16)2.prepare `deploy-opencode.yaml`
Details
kubectl -n argocd apply -f - <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: opencode
namespace: argocd
spec:
project: default
source:
repoURL: oci://ghcr.io/aaronyang0628/opencode
targetRevision: 0.20.0
chart: opencode
helm:
values: |
image:
repository: ghcr.io/nimbleflux/opencode-docker
tag: 1.2.26
pullPolicy: Always
replicaCount: 1
command:
- opencode
args:
- serve
- --port
- "4000"
- --hostname
- "0.0.0.0"
service:
type: ClusterIP
port: 4000
env:
OPENCODE_PORT: "4000"
extraVolumes:
- name: opencode-config
configMap:
name: opencode-config
extraVolumeMounts:
- name: opencode-config
mountPath: /home/opencode/.config/opencode/opencode.json
subPath: opencode.json
readOnly: true
persistence:
enabled: true
storageClass: local-path
config:
enabled: false
data:
enabled: true
size: 1Gi
workspace:
enabled: true
size: 5Gi
playbook:
enabled: true
mountPath: /home/opencode/workspace/playbook
example:
enabled: true
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
probes:
liveness:
tcpSocket:
port: 4000
initialDelaySeconds: 15
periodSeconds: 30
readiness:
tcpSocket:
port: 4000
initialDelaySeconds: 10
periodSeconds: 10
startup:
tcpSocket:
port: 4000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 30
ingress:
enabled: true
className: nginx
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "50"
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
hosts:
- host: ops.agent.72602.online
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- ops.agent.72602.online
secretName: ops.agent.72602.online-tls
globalLabels:
app.kubernetes.io/part-of: opencode
environment: production
bridge:
enabled: true
image:
repository: crpi-wixjy6gci86ms14e.cn-hongkong.personal.cr.aliyuncs.com/ay-dev/opencode-bridge
tag: "v20260326r4"
env:
defaultModel: "openai/gpt-5.3-codex-spark"
openaiStreamChunkSize: "4"
openaiStreamChunkDelayMs: "10"
enableLeadingEchoFilter: "false"
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "50"
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
hosts:
- host: opencode-bridge.72602.online
paths:
- path: /
pathType: Prefix
tls:
- secretName: opencode-bridge-tls
hosts:
- opencode-bridge.72602.online
destination:
server: https://kubernetes.default.svc
namespace: opencode
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
EOF3.sync by argocd
Details
argocd app sync argocd/opencode4.then you can talk with LLM with rest api
Details
curl -s "https://opencode-bridge.72602.online/v1/models"
## {"id":"ses_30a879abeffe6KRC0Rmg4aPrmK","slug":"brave-eagle","version":"1.2.26","projectID":"global","directory":"/home/opencode/workspace","title":"New session - 2026-03-16T07:07:14.113Z","time":{"created":1773644834113,"updated":1773644834113}}4.then you can talk with LLM with rest api
Details
curl -k -X POST https://ops.agent.72602.online/session \
-H "Content-Type: application/json" \
-d '{"model": "MiniMaxAI/MiniMax-M2.5"}'
## {"id":"ses_30a879abeffe6KRC0Rmg4aPrmK","slug":"brave-eagle","version":"1.2.26","projectID":"global","directory":"/home/opencode/workspace","title":"New session - 2026-03-16T07:07:14.113Z","time":{"created":1773644834113,"updated":1773644834113}}5.reuse the same session
Details
curl -k -X POST https://ops.agent.72602.online/session/ses_30a879abeffe6KRC0Rmg4aPrmK/message \
-H "Content-Type: application/json" \
-d '{"parts": [{"type": "text", "text": "你好"}]}'
## {"info":{"role":"assistant","time":{"created":1773644844131,"completed":1773644848700},"parentID":"msg_cf5788c12001RS4wX3hwMRe0If","modelID":"minimax-m2.5","providerID":"minimax","mode":"build","agent":"build","path":{"cwd":"/home/opencode/workspace","root":"/"},"cost":0,"tokens":{"total":10628,"input":10567,"output":61,"reasoning":0,"cache":{"read":0,"write":0}},"finish":"stop","id":"msg_cf5788c63001hBrorYejcHc1tO","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK"},"parts":[{"type":"step-start","id":"prt_cf57899120016WXp4jT4AHeTiG","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK","messageID":"msg_cf5788c63001hBrorYejcHc1tO"},{"type":"text","text":"<think>The user said \"你好\" which means \"Hello\" in Chinese. According to the instructions, I should be concise and direct. I should respond briefly without unnecessary preamble. Since this is a simple greeting, I can just respond with a greeting back.\n</think>\n\n你好!有什么可以帮你的吗?","time":{"start":1773644848689,"end":1773644848689},"id":"prt_cf5789913001dUZnoW9w63ThkC","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK","messageID":"msg_cf5788c63001hBrorYejcHc1tO"},{"type":"step-finish","reason":"stop","cost":0,"tokens":{"total":10628,"input":10567,"output":61,"reasoning":0,"cache":{"read":0,"write":0}},"id":"prt_cf5789e35001dLGIXJb5WHizMX","sessionID":"ses_30a879abeffe6KRC0Rmg4aPrmK","messageID":"msg_cf5788c63001hBrorYejcHc1tO"}]}1. following the steps in `https://opencode.ai`
Details
curl -fsSL https://opencode.ai/install | bash6.use bridge to manage session

🌐Hugo Docs Site
The Hugo documentation site is deployed via ArgoCD on ops.docs.72602.online (formerly port.72602.online).
Preliminary
1. Kubernetes is installed; if not, check 🔗link2. Helm is installed; if not, check 🔗link3. ArgoCD is installed; if not, check 🔗link1.prepare `deploy-hugo-docs.yaml`
Details
kubectl -n argocd apply -f - <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: hugo-docs
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/aaronyang0628/ops-docs.git
targetRevision: main
path: .
destination:
server: https://kubernetes.default.svc
namespace: hugo-docs
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
prune: true
selfHeal: true
EOF2.sync by argocd
Details
argocd app sync argocd/hugo-docs🤖Multi-Agent System
The opencode deployment includes two specialized agents for cluster and documentation maintenance:
| Agent | Role | Target |
|---|---|---|
k3s-maintainer | Cluster operations | k3s cluster health, pod management, node maintenance |
doc-maintainer | Documentation updates | Hugo docs site content, ArgoCD Application updates |
Agent Configuration (applied as ConfigMaps)
Details
kubectl -n opencode apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: k3s-maintainer-config
data:
opencode.json: |
{
"provider": {
"openai": {
"options": {
"baseURL": "https://v2.qixuw.com/v1",
"apiKey": "sk-ss"
},
"models": {
"gpt-5.3-codex-spark": {
"name": "GPT-5.3 Codex Spark",
"limit": { "context": 128000, "output": 32000 }
}
}
}
},
"mcp": {
"k8s-mcp": {
"type": "remote",
"url": "http://k8s-mcp.opencode.svc.cluster.local:8080/mcp",
"enabled": true,
"timeout": 15000
}
},
"agent": {
"build": { "options": { "store": false } },
"plan": { "options": { "store": false } }
}
}
EOFDeploy agents via ArgoCD - each agent runs as a separate opencode server Pod with its own ConfigMap
Details
kubectl -n argocd apply -f - <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: k3s-maintainer
namespace: argocd
spec:
project: default
source:
repoURL: oci://ghcr.io/aaronyang0628/opencode
targetRevision: 0.20.0
chart: opencode
helm:
values: |
image:
repository: ghcr.io/nimbleflux/opencode-docker
tag: 1.2.26
replicaCount: 1
command: ["opencode"]
args: ["serve", "--port", "4001", "--hostname", "0.0.0.0"]
service:
type: ClusterIP
port: 4001
env:
OPENCODE_PORT: "4001"
extraVolumes:
- name: agent-config
configMap:
name: k3s-maintainer-config
extraVolumeMounts:
- name: agent-config
mountPath: /home/opencode/.config/opencode/opencode.json
subPath: opencode.json
persistence:
enabled: true
storageClass: local-path
config:
enabled: false
data:
enabled: true
size: 1Gi
workspace:
enabled: true
size: 5Gi
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
destination:
server: https://kubernetes.default.svc
namespace: opencode
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
EOF⚡Optimizations
Several optimizations were applied to improve the ArgoCD workflow:
| Optimization | Before | After |
|---|---|---|
| GitHub proxy for ArgoCD | Direct GitHub access | ghfast.top mirror |
| Git repo size | 117 MB | 44 MB |
| ArgoCD sync time | slow (~minutes) | ~7 seconds |
1. GitHub Proxy - configure ArgoCD to use `ghfast.top` for faster OCI/Helm chart pulls
Details
# In argocd-cm ConfigMap:
data:
repositories: |
- url: oci://ghcr.io
proxy: https://ghfast.top2. Repo Size Reduction - cleaned large files and unused assets from the git repository
Details
# Remove git history and prune
git filter-repo --strip-blobs-bigger-than 1M
git gc --aggressive --prune=now3. Fast ArgoCD Sync - achieved by combining ServerSideApply, lean manifests, and cached images
Details
syncPolicy:
syncOptions:
- ServerSideApply=true🛎️FAQ
ClaudeCode
Ops Agent
🚀Installation
Preliminary
1. Kubernetes is installed; if not, check 🔗link1.build and push Ops Agent image
Details
cd /home/aaron/Ops/docs
./manifests/ops-agent/build-and-push.shThe image contains OpenCode, kubectl, Argo CD CLI, Git, SSH, opencode-vibeguard, DCP, and Goal Mode. The repository is not baked into the image; the Pod mounts /home/aaron/Ops/docs at /workspace.
2.prepare runtime Secrets
Details
export OPENAI_API_KEY='<rotated-api-key>'
./manifests/ops-agent/create-secrets.shThe script creates or updates model, SSH, Git credential, Registry, and Basic Auth Secrets without writing their values into Git.
3.apply Ops Agent resources
Details
kubectl apply -k manifests/ops-agent
kubectl -n application rollout status deployment/ops-agent --timeout=600sThe Deployment uses application/ops-agent-sa, mounts the host workspace read-write, and stores OpenCode session data in the opencode-data PVC.
4.verify configuration and access
Details
kubectl -n application get pod,svc,ingress,certificate \
-l app.kubernetes.io/name=ops-agent
kubectl -n application exec deployment/ops-agent -c ops-agent -- \
opencode debug agent hugo-doc-maintainer
PASSWORD="$(kubectl -n application get secret opencode-basic-auth \
-o jsonpath='{.data.password}' | base64 -d)"
curl -sS -o /dev/null -w '%{http_code}\n' \
-u "aaron:$PASSWORD" https://ops.agent.72602.online/Expected result: the Pod is Ready, the certificate is True, anonymous access returns 401, and authenticated access returns 200.
🤖Agents
| Agent | Responsibility | Operational source |
|---|---|---|
72602-k3s-maintainer | Operate the local 72602 cluster | Live cluster, then content/CSP/72602/_index.md |
zjlab-ops-maintainer | Operate ZJLAB through private SSH aliases | Live cluster, then the private inventory |
hugo-doc-maintainer | Maintain Relearn layout and runbooks | Relearn and Installation skills |
All three are subagents and inherit the model selected by the active conversation. Cluster agents verify live state before following a runbook and delegate verified documentation updates to the Hugo agent.
Aliyun operations for 72602-k3s-maintainer are documented by the public .opencode/skills/aliyun-72602-operations/SKILL.md, introduced in commit 96a9354.
🔌Plugins
opencode-vibeguard@0.1.0: redacts configured credential patterns before model requests.@tarquinen/opencode-dcp@3.1.14: prunes stale context while protecting agent, skill, and cluster-profile files.@prevalentware/opencode-goal-plugin@0.1.24: persists long-running goals and evidence-gated completion state.
Langfuse is not installed or enabled.
↩️Rollback
kubectl -n application delete ingress ops-agent
kubectl -n application scale deployment/ops-agent --replicas=0OpenClaw
🚀Installation
Preliminary
1. Kubernetes is installed; if not, check 🔗link2. Helm is installed; if not, check 🔗link3. ArgoCD is installed; if not, check 🔗link1.prepare `openclaw-env-secret.yaml`
Details
kubectl get namespaces claw > /dev/null 2>&1 || kubectl create namespace claw
kubectl create secret generic openclaw-env-secret -n claw \
--from-literal=ANTHROPIC_API_KEY=REPLACE_WITH_YOUR_API_KEY \
--from-literal=OPENCLAW_GATEWAY_TOKEN=REPLACE_WITH_YOUR_TOKEN_KEY2.prepare `deploy-openclaw.yaml`
Details
kubectl -n argocd apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: openclaw
namespace: argocd
spec:
project: default
source:
repoURL: https://serhanekicii.github.io/openclaw-helm
chart: openclaw
targetRevision: 1.4.4
helm:
releaseName: openclaw
values: |
app-template:
openclawVersion: "2026.2.23"
chromiumVersion: "124"
configMode: merge
controllers:
main:
containers:
main:
image:
repository: ghcr.io/openclaw/openclaw
tag: "2026.2.23"
pullPolicy: IfNotPresent
envFrom:
- secretRef:
name: openclaw-env-secret
args:
- "gateway"
- "--bind"
- "lan"
- "--port"
- "18789"
- "--allow-unconfigured"
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
chromium:
image:
repository: zenika/alpine-chrome
tag: "124"
pullPolicy: IfNotPresent
args:
- "--no-sandbox"
- "--disable-dev-shm-usage"
- "--remote-debugging-address=0.0.0.0"
- "--remote-debugging-port=9222"
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
persistence:
data:
enabled: true
type: persistentVolumeClaim
accessMode: ReadWriteOnce
size: 10Gi
globalMounts:
- path: /root/.openclaw
ingress:
main:
enabled: true
className: nginx
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: lets-encrypt
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "50"
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
hosts:
- host: openclaw.dev.72602.online
paths:
- path: /
pathType: Prefix
service:
identifier: main
port: http
tls:
- secretName: openclaw-tls
hosts:
- openclaw.dev.72602.online
configMaps:
config:
data:
openclaw.json: |
{
gateway: {
controlUi: {
allowedOrigins: ["https://openclaw.dev.72602.online"],
dangerouslyAllowHostHeaderOriginFallback: true,
},
},
browser: {
gatewayToken: "${OPENCLAW_GATEWAY_TOKEN}",
},
agents: {
main: {
brain: {
provider: "anthropic",
model: "claude-sonnet-4-20250514",
apiKey: "${ANTHROPIC_API_KEY}",
},
},
},
}
destination:
server: https://kubernetes.default.svc
namespace: claw
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=false
EOF3.sync by argocd
Details
argocd app sync argocd/openclawPreliminary
1. Kubernetes is installed; if not, check 🔗link2. Helm is installed; if not, check 🔗link3. ArgoCD is installed; if not, check 🔗link1.prepare `openclaw-env-secret.yaml`
Details
kubectl get namespaces claw > /dev/null 2>&1 || kubectl create namespace claw
kubectl create secret generic openclaw-env-secret -n claw \
--from-literal=ANTHROPIC_API_KEY=REPLACE_WITH_YOUR_API_KEY \
--from-literal=OPENCLAW_GATEWAY_TOKEN=REPLACE_WITH_YOUR_TOKEN_KEY2.prepare `deploy-openclaw.yaml`
Details
kubectl -n argocd apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: openclaw
namespace: argocd
spec:
project: default
source:
repoURL: https://serhanekicii.github.io/openclaw-helm
chart: openclaw
targetRevision: 1.4.4
helm:
releaseName: openclaw
values: |
app-template:
openclawVersion: "2026.2.23"
chromiumVersion: "124"
configMode: merge
controllers:
main:
containers:
main:
image:
repository: ghcr.io/openclaw/openclaw
tag: "2026.2.23"
pullPolicy: IfNotPresent
envFrom:
- secretRef:
name: openclaw-env-secret
args:
- "gateway"
- "--bind"
- "lan"
- "--port"
- "18789"
- "--allow-unconfigured"
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
chromium:
image:
repository: zenika/alpine-chrome
tag: "124"
pullPolicy: IfNotPresent
args:
- "--no-sandbox"
- "--disable-dev-shm-usage"
- "--remote-debugging-address=0.0.0.0"
- "--remote-debugging-port=9222"
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
persistence:
data:
enabled: true
type: persistentVolumeClaim
accessMode: ReadWriteOnce
size: 10Gi
globalMounts:
- path: /root/.openclaw
ingress:
main:
enabled: true
className: nginx
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: lets-encrypt
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "50"
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
hosts:
- host: openclaw.72602.online
paths:
- path: /
pathType: Prefix
service:
identifier: main
port: http
tls:
- secretName: openclaw-tls
hosts:
- openclaw.72602.online
configMaps:
config:
data:
openclaw.json: |
{
gateway: {
controlUi: {
allowedOrigins: ["https://openclaw.72602.online"],
dangerouslyAllowHostHeaderOriginFallback: true,
},
},
browser: {
gatewayToken: "${OPENCLAW_GATEWAY_TOKEN}",
},
agents: {
main: {
brain: {
provider: "anthropic",
model: "claude-sonnet-4-20250514",
apiKey: "${ANTHROPIC_API_KEY}",
},
},
},
}
destination:
server: https://kubernetes.default.svc
namespace: claw
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=false
EOF3.sync by argocd
Details
argocd app sync argocd/openclaw