Skip to content

Commit 6140d08

Browse files
committed
feat: fix the helm section
1 parent 8e31674 commit 6140d08

1 file changed

Lines changed: 231 additions & 1 deletion

File tree

docs/helm.md

Lines changed: 231 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,237 @@ curl http://192.168.59.100/hello
9090

9191
## 创建 helm charts
9292

93-
这段代码无法渲染,请查看:https://github.com/guangzhengli/k8s-tutorials#helm
93+
94+
在使用已经创建好的 hello-helm charts 来创建整个 hellok8s 资源后,你可能还是有很多的疑惑,包括 Chart 是如何生成和发布的,如何创建一个新的 Chart?在这节教程中,我们会尝试自己来创建 hello-helm Chart 来完成之前的操作。
95+
96+
首先建议使用 `helm create` 命令来创建一个初始的 Chart,该命令默认会创建一些 k8s 资源定义的初始文件,并且会生成官网推荐的目录结构,如下所示:
97+
98+
```shell
99+
helm create hello-helm
100+
101+
.
102+
├── Chart.yaml
103+
├── charts
104+
├── templates
105+
│   ├── NOTES.txt
106+
│   ├── _helpers.tpl
107+
│   ├── deployment.yaml
108+
│   ├── hpa.yaml
109+
│   ├── ingress.yaml
110+
│   ├── service.yaml
111+
│   ├── serviceaccount.yaml
112+
│   └── tests
113+
│   └── test-connection.yaml
114+
└── values.yaml
115+
```
116+
117+
我们将默认生成在 templates 目录下面的 `yaml` 文件删除,用之前教程中 `yaml` 文件替换它,最终的结构长这样:
118+
119+
```shell
120+
.
121+
├── Chart.yaml
122+
├── Dockerfile
123+
├── _helpers.tpl
124+
├── charts
125+
├── hello-helm-0.1.0.tgz
126+
├── index.yaml
127+
├── main.go
128+
├── templates
129+
│   ├── hellok8s-configmaps.yaml
130+
│   ├── hellok8s-deployment.yaml
131+
│   ├── hellok8s-secret.yaml
132+
│   ├── hellok8s-service.yaml
133+
│   ├── ingress.yaml
134+
│   ├── nginx-deployment.yaml
135+
│   └── nginx-service.yaml
136+
└── values.yaml
137+
```
138+
139+
其中 `main.go` 定义的是 `hellok8s:v6` 版本的代码,主要是从系统中拿到 message,namespace,dbURL,dbPassword 这几个环境变量,拼接成字符串返回。
140+
141+
```go
142+
package main
143+
144+
import (
145+
"fmt"
146+
"io"
147+
"net/http"
148+
"os"
149+
)
150+
151+
func hello(w http.ResponseWriter, r *http.Request) {
152+
host, _ := os.Hostname()
153+
message := os.Getenv("MESSAGE")
154+
namespace := os.Getenv("NAMESPACE")
155+
dbURL := os.Getenv("DB_URL")
156+
dbPassword := os.Getenv("DB_PASSWORD")
157+
158+
io.WriteString(w, fmt.Sprintf("[v6] Hello, Helm! Message from helm values: %s, From namespace: %s, From host: %s, Get Database Connect URL: %s, Database Connect Password: %s", message, namespace, host, dbURL, dbPassword))
159+
}
160+
161+
func main() {
162+
http.HandleFunc("/", hello)
163+
http.ListenAndServe(":3000", nil)
164+
}
165+
```
166+
167+
为了让大家更加了解 helm charts values 的使用和熟悉 k8s 资源配置,这几个环境变量 `MESSAGE`, `NAMESPACE`, `DB_URL`, `DB_PASSWORD` 分别有不同的来源。
168+
169+
首先修改根目录下的 `values.yaml` 文件,定义自定义的配置信息,从之前教程的 k8s 资源文件中,将一些易于变化的参数提取出来,放在 `values.yaml` 文件中。全部配置信息如下所示:
170+
171+
```yaml
172+
application:
173+
name: hellok8s
174+
hellok8s:
175+
image: guangzhengli/hellok8s:v6
176+
replicas: 3
177+
message: "It works with Helm Values!"
178+
database:
179+
url: "http://DB_ADDRESS_DEFAULT"
180+
password: "db_password"
181+
nginx:
182+
image: nginx
183+
replicas: 2
184+
```
185+
186+
那自定义好了这些配置后,如何在 k8s 资源定义中使用这些配置信息呢?Helm 默认使用 [Go template 的方式](https://helm.sh/zh/docs/howto/charts_tips_and_tricks/) 来完成。
187+
188+
例如之前教程中,将环境变量 `DB_URL` 定义在 k8s configmaps 中,那么该资源可以定义成如文件所示 `hellok8s-configmaps.yaml`。其中 `metadata.name` 的值是 `{{ .Values.application.name }}-config`,意思是从 `values.yaml` 文件中获取 `application.name` 的值 `hellok8s`,拼接 `-config` 字符串,这样创建出来的 configmaps 资源名称就是 `hellok8s-config`。
189+
190+
同理 `{{ .Values.application.hellok8s.database.url }}` 就是获取值为 `http://DB_ADDRESS_DEFAULT` 放入 configmaps 对应 key 为 DB_URL 的 value 中。
191+
192+
```yaml
193+
apiVersion: v1
194+
kind: ConfigMap
195+
metadata:
196+
name: {{ .Values.application.name }}-config
197+
data:
198+
DB_URL: {{ .Values.application.hellok8s.database.url }}
199+
```
200+
201+
上面定义的最终效果和之前在 `configmaps` 教程中定义的资源没有区别,这种做的好处是可以将所有可变的参数定义在 `values.yaml` 文件中,使用该 helm charts 的人无需了解具体 k8s 的定义,只需改变成自己想要的参数,即可创建自定义的资源!
202+
203+
同样,我们可以根据之前的教程将 `DB_PASSWORD` 放入 secret 中,并且通过 `b64enc` 方法将值 Base64 编码。
204+
205+
```shell
206+
# hellok8s-secret.yaml
207+
apiVersion: v1
208+
kind: Secret
209+
metadata:
210+
name: {{ .Values.application.name }}-secret
211+
data:
212+
DB_PASSWORD: {{ .Values.application.hellok8s.database.password | b64enc }}
213+
```
214+
215+
最后,修改 `hellok8s-deployment` 文件,根据前面的教程,将 `metadata.name` `replicas` `image` `configMapKeyRef.name` `secretKeyRef.name` 等值修改成从 `values.yaml` 文件中获取。
216+
217+
再添加代码中需要的 `NAMESPACE` 环境变量,从 `.Release.Namespace` [内置对象](https://helm.sh/zh/docs/chart_template_guide/builtin_objects/) 中获取。最后添加 `MESSAGE` 环境变量,直接从 `{{ .Values.application.hellok8s.message }}` 中获取。
218+
219+
```yaml
220+
apiVersion: apps/v1
221+
kind: Deployment
222+
metadata:
223+
name: {{ .Values.application.name }}-deployment
224+
spec:
225+
replicas: {{ .Values.application.hellok8s.replicas }}
226+
selector:
227+
matchLabels:
228+
app: hellok8s
229+
template:
230+
metadata:
231+
labels:
232+
app: hellok8s
233+
spec:
234+
containers:
235+
- image: {{ .Values.application.hellok8s.image }}
236+
name: hellok8s-container
237+
env:
238+
- name: DB_URL
239+
valueFrom:
240+
configMapKeyRef:
241+
name: {{ .Values.application.name }}-config
242+
key: DB_URL
243+
- name: DB_PASSWORD
244+
valueFrom:
245+
secretKeyRef:
246+
name: {{ .Values.application.name }}-secret
247+
key: DB_PASSWORD
248+
- name: NAMESPACE
249+
value: {{ .Release.Namespace }}
250+
- name: MESSAGE
251+
value: {{ .Values.application.hellok8s.message }}
252+
```
253+
254+
修改 `ingress.yaml` 将 `metadata.name` 的值,其它没有变化
255+
256+
``` yaml
257+
apiVersion: networking.k8s.io/v1
258+
kind: Ingress
259+
metadata:
260+
name: {{ .Values.application.name }}-ingress
261+
...
262+
...
263+
...
264+
```
265+
266+
`nginx-deployment.yaml`
267+
268+
```yaml
269+
apiVersion: apps/v1
270+
kind: Deployment
271+
metadata:
272+
name: nginx-deployment
273+
spec:
274+
replicas: {{ .Values.application.nginx.replicas }}
275+
selector:
276+
matchLabels:
277+
app: nginx
278+
template:
279+
metadata:
280+
labels:
281+
app: nginx
282+
spec:
283+
containers:
284+
- image: {{ .Values.application.nginx.image }}
285+
name: nginx-container
286+
```
287+
288+
`nginx-service.yaml` 和 `hellok8s-service.yaml` 没有变化。所有代码可以在 [这里](https://github.com/guangzhengli/k8s-tutorials/tree/main/helm-charts/hello-helm) 查看。
289+
290+
稍微修改下默认生成的`Chart.yaml`
291+
292+
```yaml
293+
apiVersion: v2
294+
name: hello-helm
295+
description: A k8s tutorials in https://github.com/guangzhengli/k8s-tutorials
296+
type: application
297+
version: 0.1.0
298+
appVersion: "1.16.0"
299+
```
300+
301+
定义完成所有的 helm 资源后,首先**将 `hellok8s:v6` 镜像打包推送到 DockerHub**。
302+
303+
之后即可在 `hello-helm` 的目录下执行 `helm upgrade` 命令进行安装,安装成功后,执行 curl 命令便能直接得到结果!查看 pod 和 service 等资源,便会发现 helm 能一键安装所有资源!
304+
305+
```shell
306+
helm upgrade --install hello-helm --values values.yaml .
307+
# Release "hello-helm" does not exist. Installing it now.
308+
# NAME: hello-helm
309+
# NAMESPACE: default
310+
# STATUS: deployed
311+
# REVISION: 1
312+
313+
curl http://192.168.59.100/hello
314+
# [v6] Hello, Helm! Message from helm values: It works with Helm Values!, From namespace: default, From host: hellok8s-deployment-57d7df7964-m6gcc, Get Database Connect URL: http://DB_ADDRESS_DEFAULT, Database Connect Password: db_password
315+
316+
kubectl get pods
317+
# NAME READY STATUS RESTARTS AGE
318+
# hellok8s-deployment-f88f984c6-k8hpz 1/1 Running 0 32m
319+
# hellok8s-deployment-f88f984c6-nzwg6 1/1 Running 0 32m
320+
# hellok8s-deployment-f88f984c6-s89s7 1/1 Running 0 32m
321+
# nginx-deployment-d47fd7f66-6w76b 1/1 Running 0 32m
322+
# nginx-deployment-d47fd7f66-tsqj5 1/1 Running 0 32m
323+
```
94324

95325
## rollback
96326

0 commit comments

Comments
 (0)