Skip to content

Commit 2225b34

Browse files
authored
feat: add generic app template arnor (#166)
* feat: add generic app template arnor * feat: enhance vault static secret configuration and update HTTP route references
1 parent d0050df commit 2225b34

16 files changed

+733
-0
lines changed

charts/arnor/.helmignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/

charts/arnor/Chart.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
apiVersion: v2
2+
name: arnor
3+
description: A Helm chart for standard web application
4+
maintainers:
5+
- name: douban
6+
7+
# A chart can be either an 'application' or a 'library' chart.
8+
#
9+
# Application charts are a collection of templates that can be packaged into versioned archives
10+
# to be deployed.
11+
#
12+
# Library charts provide useful utilities or functions for the chart developer. They're included as
13+
# a dependency of application charts to inject those utilities and functions into the rendering
14+
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
15+
type: application
16+
17+
# This is the chart version. This version number should be incremented each time you make changes
18+
# to the chart and its templates, including the app version.
19+
# Versions are expected to follow Semantic Versioning (https://semver.org/)
20+
version: 0.1.0
21+
22+
# This is the version number of the application being deployed. This version number should be
23+
# incremented each time you make changes to the application. Versions are not expected to
24+
# follow Semantic Versioning. They should reflect the version the application is using.
25+
# It is recommended to use it with quotes.
26+
appVersion: "1.16.0"

charts/arnor/README.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Arnor
2+
3+
Arnor 并不是一个具体的 app, 本 Chart 用于一些简单的项目部署, 使用者在填写了镜像及域名配置后, 即可快速拉起一个 HTTP 应用。
4+
5+
## 使用步骤
6+
7+
1. `helm repo add douban https://douban.github.io/charts/`
8+
2. `helm install my-app douban/arnor -f my-values.yaml`
9+
10+
## 镜像
11+
12+
- `image.repository`: 业务镜像仓库 (如 `registry.example.com/my-app`)
13+
- `image.tag`: 镜像版本号 (如 `v1.0.0`)
14+
15+
## 主机名/域名路由
16+
17+
Arnor 可分别启用 Ingress 或 Envoy Gateway HTTPRoute, 两者互不依赖。
18+
19+
### Ingress 配置
20+
21+
```yaml
22+
ingress:
23+
enabled: true
24+
className: nginx
25+
hosts:
26+
- host: app.example.com
27+
paths:
28+
- path: /
29+
pathType: ImplementationSpecific
30+
tls:
31+
- secretName: app-example-com-tls
32+
hosts:
33+
- app.example.com
34+
```
35+
36+
### HTTPRoute 配置
37+
38+
```yaml
39+
httpRoute:
40+
enabled: true
41+
parentRefs:
42+
- name: envoy-gateway-bundle
43+
namespace: envoy-gateway-system
44+
hostnames:
45+
- app.example.com
46+
extraPaths: []
47+
```
48+
49+
## 挂载 Volume 与 Secret
50+
51+
1. 在 `volumes` 中定义所需卷 (ConfigMap、Secret、PVC 等)。
52+
2. 在 `volumeMounts` 中将卷挂载到容器路径。
53+
54+
示例:
55+
56+
```yaml
57+
volumes:
58+
- name: app-config
59+
configMap:
60+
name: my-config
61+
- name: extra-secret
62+
secret:
63+
secretName: my-app-secret
64+
volumeMounts:
65+
- name: app-config
66+
mountPath: /etc/app
67+
- name: extra-secret
68+
mountPath: /var/run/secret
69+
readOnly: true
70+
```
71+
72+
## Vault 静态密钥注入
73+
74+
启用 `vaultStaticSecret.enabled` 后, Chart 会负责拉取 Vault 中的静态密钥并注入到 Kubernetes Secret 中; 需要在 `volumes` 与 `volumeMounts` 手动引用该 Secret 才能在容器内使用。
75+
76+
如果没有设置 `vaultStaticSecret.secretNameOverride`, secret 名字会与 fullname 完全相同, 也就是:
77+
78+
```bash
79+
# release name 和 chart 同名时, 为 release name
80+
arnor
81+
# release name 和 chart 不同时, 为 release name - chart name
82+
my-app-arnor
83+
# 填写了 fullnameOverride 的情况下, 以 fullnameOverride 为准
84+
my-fullname
85+
# 详细逻辑请参考 _helpers.tpl 内的代码
86+
```
87+
88+
```yaml
89+
vaultStaticSecret:
90+
enabled: true
91+
mount: kv-v2
92+
path: secret/data
93+
secretNameOverride: my-secret
94+
95+
volumes:
96+
- name: vault-secret
97+
secret:
98+
secretName: my-secret
99+
volumeMounts:
100+
- name: vault-secret
101+
mountPath: /vault/secrets
102+
readOnly: true
103+
```
104+
105+
> 最终路径与 `path` 完全一致, 请确认 Vault 中已存在该路径。
106+
107+
## 完整示例
108+
109+
```yaml
110+
image:
111+
repository: registry.example.com/frontend
112+
tag: v1.2.3
113+
114+
ingress:
115+
enabled: true
116+
className: nginx
117+
hosts:
118+
- host: frontend.example.com
119+
paths:
120+
- path: /
121+
pathType: ImplementationSpecific
122+
123+
httpRoute:
124+
enabled: false
125+
126+
volumes:
127+
- name: env-secret
128+
secret:
129+
secretName: frontend-env
130+
- name: vault-secret
131+
secret:
132+
secretName: frontend
133+
volumeMounts:
134+
- name: env-secret
135+
mountPath: /app/.env
136+
readOnly: true
137+
- name: vault-secret
138+
mountPath: /vault/data
139+
readOnly: true
140+
141+
vaultStaticSecret:
142+
enabled: true
143+
secretNameOverride: frontend
144+
```
145+

charts/arnor/templates/NOTES.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
1. Get the application URL by running these commands:
2+
{{- if .Values.ingress.enabled }}
3+
{{- range $host := .Values.ingress.hosts }}
4+
{{- range .paths }}
5+
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
6+
{{- end }}
7+
{{- end }}
8+
{{- else if contains "NodePort" .Values.service.type }}
9+
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "arnor.fullname" . }})
10+
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
11+
echo http://$NODE_IP:$NODE_PORT
12+
{{- else if contains "LoadBalancer" .Values.service.type }}
13+
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
14+
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "arnor.fullname" . }}'
15+
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "arnor.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
16+
echo http://$SERVICE_IP:{{ .Values.service.port }}
17+
{{- else if contains "ClusterIP" .Values.service.type }}
18+
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "arnor.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
19+
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
20+
echo "Visit http://127.0.0.1:8080 to use your application"
21+
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
22+
{{- end }}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "arnor.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "arnor.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "arnor.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "arnor.labels" -}}
37+
helm.sh/chart: {{ include "arnor.chart" . }}
38+
{{ include "arnor.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "arnor.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "arnor.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "arnor.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "arnor.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}
63+
64+
{{/*
65+
VaultStaticSecret secretName
66+
*/}}
67+
{{- define "arnor.vaultStaticSecretDestination" -}}
68+
{{- if .Values.vaultStaticSecret.secretNameOverride }}
69+
{{- .Values.vaultStaticSecret.secretNameOverride | trunc 63 | trimSuffix "-" }}
70+
{{- else }}
71+
{{- include "arnor.fullname" . }}
72+
{{- end }}
73+
{{- end }}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "arnor.fullname" . }}
5+
labels:
6+
{{- include "arnor.labels" . | nindent 4 }}
7+
spec:
8+
{{- if not .Values.autoscaling.enabled }}
9+
replicas: {{ .Values.replicaCount }}
10+
{{- end }}
11+
selector:
12+
matchLabels:
13+
{{- include "arnor.selectorLabels" . | nindent 6 }}
14+
template:
15+
metadata:
16+
{{- with .Values.podAnnotations }}
17+
annotations:
18+
{{- toYaml . | nindent 8 }}
19+
{{- end }}
20+
labels:
21+
{{- include "arnor.selectorLabels" . | nindent 8 }}
22+
spec:
23+
{{- with .Values.imagePullSecrets }}
24+
imagePullSecrets:
25+
{{- toYaml . | nindent 8 }}
26+
{{- end }}
27+
serviceAccountName: {{ include "arnor.serviceAccountName" . }}
28+
securityContext:
29+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
30+
containers:
31+
- name: {{ .Chart.Name }}
32+
securityContext:
33+
{{- toYaml .Values.securityContext | nindent 12 }}
34+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
35+
imagePullPolicy: {{ .Values.image.pullPolicy }}
36+
{{- with .Values.args }}
37+
args:
38+
{{- toYaml . | nindent 12 }}
39+
{{- end}}
40+
{{- with .Values.env }}
41+
env:
42+
{{- toYaml . | nindent 12 }}
43+
{{- end}}
44+
{{- with .Values.volumeMounts }}
45+
volumeMounts:
46+
{{- toYaml . | nindent 12 }}
47+
{{- end }}
48+
ports:
49+
- name: http
50+
containerPort: {{ .Values.containerPort }}
51+
protocol: TCP
52+
livenessProbe:
53+
httpGet:
54+
path: /
55+
port: http
56+
readinessProbe:
57+
httpGet:
58+
path: /
59+
port: http
60+
resources:
61+
{{- toYaml .Values.resources | nindent 12 }}
62+
{{- with .Values.volumes }}
63+
volumes:
64+
{{- toYaml . | nindent 8 }}
65+
{{- end }}
66+
{{- with .Values.nodeSelector }}
67+
nodeSelector:
68+
{{- toYaml . | nindent 8 }}
69+
{{- end }}
70+
{{- with .Values.affinity }}
71+
affinity:
72+
{{- toYaml . | nindent 8 }}
73+
{{- end }}
74+
{{- with .Values.tolerations }}
75+
tolerations:
76+
{{- toYaml . | nindent 8 }}
77+
{{- end }}

0 commit comments

Comments
 (0)