iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0

上一章節說明了 Helmc Chart 概念以及安裝 Helm。這章節將會建立一個 Helm chart,並實際操作。

開始建立,透過以下

helm create quarkus-dns

沒錯,預設上會建立以下 templates 下的資源。

$ tree quarkus-dns/
quarkus-dns/
├── Chart.yaml # Chart 資訊檔案
├── charts # 依賴 Chart 的目錄
├── templates # 產生有效的 Kubernetes YAML,預設會與 values.yaml 整合
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml # Chart 預設配置值,templates 下的資源將會引用此檔案產生 Kubernetes 可部署資源

但因為 Quarkus 應用程式需要 ConfigMap 資源,因此多定義以下。

  1. 定義一個 function,副檔名為 .tpl 基本上是寫共用函式。
{{- define "quarkus-dns.applicationTemplate" -}}
{{- with .Values.config.application }}
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- end -}}
  1. 建立 configmap.yaml 模板,當中使用 include 關鍵字引入第一步驟定義的函示
{{- if .Values.config.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "quarkus-dns.fullname" . }}-config
  labels:
    {{- include "quarkus-dns.labels" . | nindent 4 }}
  {{- with .Values.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
data:
  application.yaml: |- 
    {{- include "quarkus-dns.applicationTemplate" . | nindent 2 }}
{{- end }}
  1. 定義 Values.yaml,因為模板需要,所以要定義預設的配置
...
config:
  enabled: false
  application: 

定義完後,該如何驗證 ? 對於 Helm 來說可以使用 template 指令,格式 helm template {RELEASE_NAME} {CHART_CONTEXT} -f {VALUES_YAML} --skip-tests ,如下。基本上有看到 YAML 就是語法沒問題,但不代表可以正常部署。因為渲染結果是吻合 YAML 規範,但不見得符合 Kubernetes 欄位規範。

$ helm template testing . -f env/values-test.yaml --skip-tests 
---
# Source: quarkus-dns/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: quarkus-dns
  labels:
    helm.sh/chart: quarkus-dns-0.1.0
    app.kubernetes.io/name: quarkus-dns
    app.kubernetes.io/instance: testing
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
---
# Source: quarkus-dns/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: testing-quarkus-dns-config
  labels:
    helm.sh/chart: quarkus-dns-0.1.0
    app.kubernetes.io/name: quarkus-dns
    app.kubernetes.io/instance: testing
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
data:
  application.yaml:  |
    a1:
      b: "testing"
---
# Source: quarkus-dns/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: testing-quarkus-dns
  labels:
    helm.sh/chart: quarkus-dns-0.1.0
    app.kubernetes.io/name: quarkus-dns
    app.kubernetes.io/instance: testing
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 8080
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: quarkus-dns
    app.kubernetes.io/instance: testing
---
# Source: quarkus-dns/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: testing-quarkus-dns
  labels:
    helm.sh/chart: quarkus-dns-0.1.0
    app.kubernetes.io/name: quarkus-dns
    app.kubernetes.io/instance: testing
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app.kubernetes.io/name: quarkus-dns
      app.kubernetes.io/instance: testing
  template:
    metadata:
      annotations:
        checksum/configmap-env: 8fa22e3cf3f8f9d86ad5d814cf64e209fe001792bc3bf86ce91b0cba02c52441
      labels:
        app.kubernetes.io/name: quarkus-dns
        app.kubernetes.io/instance: testing
    spec:
      serviceAccountName: quarkus-dns
      securityContext:
        fsGroup: 2000
        runAsGroup: 1001
        runAsNonRoot: true
        runAsUser: 1001
      containers:
        - name: quarkus-dns
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
              - ALL
            privileged: false
            readOnlyRootFilesystem: true
          image: "registry.hub.docker.com/cch0124/helmchartlab:day16"
          imagePullPolicy: IfNotPresent
          env:
            - name: KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: KUBE_POD_NAME 
              valueFrom: 
                fieldRef: 
                  fieldPath: metadata.name
            - name: QUARKUS_CONFIG_LOCATIONS
              value: /opt/config/application.yaml
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /q/health/live
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /q/health/ready
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          startupProbe:
            failureThreshold: 3
            httpGet:
              path: /q/health/started
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          resources:
            limits:
              cpu: 100m
              memory: 256Mi
            requests:
              cpu: 100m
              memory: 128Mi
          volumeMounts:
            - name: vertx-cache
              mountPath: /tmp/vertx-cache
            - name: config-volume
              mountPath: /opt/jboss/config
              readOnly: true
      volumes:
        - name: vertx-cache
          emptyDir: {}
        - name: config-volume
          configMap:
            name: testing-quarkus-dns-config

如果想要確認某個資源呢 ? 可以帶入 -s 參數再搭配指定要渲染的模板檔案,個人認為在很多資源的 template 下滿好用,因為就不會有一長串的東西要看。

 helm template testing -s templates/configmap.yaml . -f env/values-te
st.yaml --skip-tests 
---
# Source: quarkus-dns/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: testing-quarkus-dns-config
  labels:
    helm.sh/chart: quarkus-dns-0.1.0
    app.kubernetes.io/name: quarkus-dns
    app.kubernetes.io/instance: testing
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
data:
  application.yaml:  |-
    a1:

Install Chart

如果要部署時,可以指定 namespace 且搭配 --create-namespace 不存在時建立。特別的是部署後可以看到輸出訊息,而該訊息從 NOTES.txt 預設檔案來,實務也會建議定義此內容。像是提供第一次密碼要如何取得等。不過預設上狀態為 deployed 也不代表資源是確定並且可使用。

$ helm install dns-1 . -f values.yaml --namespace day16 --create-namespace 
NAME: dns-1
LAST DEPLOYED: Sat Sep  7 22:39:53 2024
NAMESPACE: day16
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace day16 -l "app.kubernetes.io/name=quarkus-dns,app.kubernetes.io/instance=dns-1" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace day16 $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace day16 port-forward $POD_NAME 8080:$CONTAINER_PORT

透過 history 可以看到部署歷史紀錄

$ helm history dns-1 -n day16
REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION     
1               Sat Sep  7 22:39:53 2024        deployed        quarkus-dns-0.1.0       1.16.0          Install complete

Upgrade Chart

架設 values.yaml 有異動則透過 upgrade 方式更新當前的 Chart。可以看到 REVISION 從 1 變 2。

$ helm upgrade dns-1 . -f values.yaml --namespace day16 --create-namespace 
Release "dns-1" has been upgraded. Happy Helming!
NAME: dns-1
LAST DEPLOYED: Sat Sep  7 22:48:48 2024
NAMESPACE: day16
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace day16 -l "app.kubernetes.io/name=quarkus-dns,app.kubernetes.io/instance=dns-1" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace day16 $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace day16 port-forward $POD_NAME 8080:$CONTAINER_PORT

透過 history 也是可以看到新增一個版本。

$ helm history dns-1 -n day16
REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION     
1               Sat Sep  7 22:39:53 2024        superseded      quarkus-dns-0.1.0       1.16.0          Install complete
2               Sat Sep  7 22:48:48 2024        deployed        quarkus-dns-0.1.0       1.16.0          Upgrade complete

此時驗證部署上去的資源。

$ kubectl port-forward -n day16 services/dns-1-quarkus-dns 9090:8080
$ curl http://localhost:9090/hello/myip?uri=www.google.com
["172.217.160.68"]

但預設上不能解析 Kubernetes 的 DNS 來獲取 IP。因此要將 dns.server 位置指向 Kubernetes 的 DNS。

config:
  enabled: true
  application: 
    dns:
      server: 10.42.1.178

透過 endpoints 方式來獲取 Kubernetes 中的 DNS 位置。

$ kubectl get endpoints kube-dns -n kube-system 
NAME       ENDPOINTS                                        AGE
kube-dns   10.42.1.178:53,10.42.1.178:53,10.42.1.178:9153   14d

當上述 dns.server 配置好後,在更新一版。

$ helm upgrade dns-1 . -f env/values-dev.yaml --namespace day16 --create-namespace 
Release "dns-1" has been upgraded. Happy Helming!
NAME: dns-1
LAST DEPLOYED: Sun Sep  8 01:33:46 2024
NAMESPACE: day16
STATUS: deployed
REVISION: 11
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace day16 -l "app.kubernetes.io/name=quarkus-dns,app.kubernetes.io/instance=dns-1" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace day16 $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace day16 port-forward $POD_NAME 8080:$CONTAINER_PORT

原則上就可以解析到了~

$ curl http://localhost:9090/hello/myip?uri=dns-1-quarkus-dns.day16.svc
["10.43.121.65"]

對於 Quarkus 應用程式來說,log 也表示當前 dns.server 指向 Kubernetes DNS 服務。

2024-09-07 17:50:51,161 INFO  [ith.cch.ser.ProducerService] (executor-thread-1) dns server: 10.42.1.178

到這邊可以完整 release(部署)一個 Chart。並讓使用者使用。

rollback

假設,當前的內容是錯誤,不應該可以解析 Kubernetes DNS 的內容。則可以使用 rollback 方式。

$ helm -n day16 rollback dns-1 7  --wait

每當執行 rollback,也算在歷史紀錄中,而每個歷史紀錄預設會記 10 筆。如下可以看到。

$ helm history dns-1 -n day16
REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION                                                                                                                                                                                                   
3               Sat Sep  7 23:02:13 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
4               Sun Sep  8 00:47:26 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
5               Sun Sep  8 00:50:02 2024        failed          quarkus-dns-0.1.0       1.16.0          Upgrade "dns-1" failed: cannot patch "dns-1-quarkus-dns" with kind Deployment: Deployment.apps "dns-1-quarkus-dns" is invalid: spec.template.spec.containers[0].volumeMounts[0].name: Not found: "vertx-cache"
6               Sun Sep  8 00:50:25 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
7               Sun Sep  8 01:12:38 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
8               Sun Sep  8 01:14:55 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
9               Sun Sep  8 01:33:46 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
10              Sun Sep  8 01:38:18 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
11              Sun Sep  8 01:49:20 2024        superseded      quarkus-dns-0.1.0       1.16.0          Upgrade complete                                                                                                                                                                                              
12              Sun Sep  8 01:56:09 2024        deployed        quarkus-dns-0.1.0       1.16.0          Rollback to 7

另外,使用 get values 時可以獲取當前部署 Chart 所配置的內容

$ helm get values dns-1 -n day16 
USER-SUPPLIED VALUES:
config:
  application:
    dns:
      server: 10.42.1.178
  enabled: false
securityContext: {}

下個章節會介紹一些工具來驗證 Kubernetes 資源。

參考資源


上一篇
Kubernetes 遇見 Helm charts
下一篇
給 Helm Chart 一些外衣
系列文
當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言