iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0
Kubernetes

當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 系列 第 3

地端部署 Quarkus 專案至 Kubernetes 環境

  • 分享至 

  • xImage
  •  

本次目標

  1. 透過 K3d 建置一座 Kubernetes
  2. 部署 Quarkus 資源
  3. 存取 Quarkus 專案 API 資源
  4. Deployment 的回滾
  5. 探討 Label 和 Annotation

K3d 建置一座 Kubernetes

在執行之前本機端也需要安裝 kubectl 工具。K3d 安裝這邊不贅述,可以參考官方安裝部分。使用 K3d 原因是,建立起來的環境包含了 Ingress controller、Metric Server 等資源,因此可以作快速驗證。

透過 K3d 的 API 可以配置 Kubernetes 相關的資訊。

apiVersion: k3d.io/v1alpha4 # this will change in the future as we make everything more stable
kind: Simple # internally, we also have a Cluster config, which is not yet available externally
metadata:
  name: ithome-lab-cluster # name that you want to give to your cluster (will still be prefixed with `k3d-`)
servers: 1 # same as `--servers 1`
agents: 2 # same as `--agents 2`
kubeAPI: # same as `--api-port myhost.my.domain:6445` (where the name would resolve to 127.0.0.1)
  host: "ithome.cch.com" # important for the `server` setting in the kubeconfig
  hostIP: "127.0.0.1" # where the Kubernetes API will be listening on
  hostPort: "6500"
image: rancher/k3s:v1.27.7-k3s1
ports:
  - port: 8580:80
    nodeFilters:
      - loadbalancer
  - port: 8543:443
    nodeFilters:
      - loadbalancer

注意,上述配置 ithome.cch.com 此值要映射至 /etc/hosts 檔案,讓地端的 dns 可以解析到。

透過以下指令建置,Kubernetes 並限制其記憶體。

$ k3d cluster create -c infra/config.yaml --servers-memory 2G --agents-memory 2G

成功安裝後,透過 kubectl 方式可以檢查是否存在,如下,應當要看到 k3d-ithome-lab-cluster。K3d 建置完 Kubernetes 環境後會將其 API 位置、憑證等資訊加至 .kube/config 檔案中。

$ kubectl config get-clusters
k3d-ithome-lab-cluster

切換至 k3d-ithome-lab-cluster 的資源。接著使用 kubectl cluster-info 可獲取相對應的資訊有 API 位置和一些資源部署資訊。

$ kubectl config use-context k3d-ithome-lab-cluster
$ kubectl cluster-info 
Kubernetes control plane is running at https://ithome.cch.com:6500
CoreDNS is running at https://ithome.cch.com:6500/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://ithome.cch.com:6500/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

到這邊已經建置一個可以使用的 Kubernetes 環境。接著要將 Quarkus API 給部署至這環境中。

部署 Quarkus 資源

上一章節,藉由 quarkus-kubernetes 自動產生 kubernetes YAML 資源。此章節透過 kubectl apply 部署該資源。

kubectl apply -f kubernetes/kubernetes.yml

部署完後,可以看到以下資源 Service、Deployment、ReplicaSet 和 Pod。

$ kubectl get all
NAME                                 READY   STATUS    RESTARTS   AGE
pod/ithome2024lab-77468c897c-rgrqv   1/1     Running   0          39m

NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes      ClusterIP   10.43.0.1       <none>        443/TCP   113m
service/ithome2024lab   ClusterIP   10.43.107.205   <none>        80/TCP    39m

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ithome2024lab   1/1     1            1           39m

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/ithome2024lab-77468c897c   1         1         1       39m

由於 Quarkus 專案沒有定義 Ingress 資源暴露服務,因此我們透過 port-forward 來驗證 API,其格式是:

kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]

期可以針對 Pod 或是 Server 資源,將服務流量透過本機進行轉發。下面的指令可以看到最後成功驗證服務是正常運行。

$ kubectl port-forward service/ithome2024lab 8080:80
$ curl http://localhost:8080/hello
Hello RESTEasy hello

但,Quarkus 能作的事情不只是這樣。如果在地端可以省去 kubectl apply 的話更好,沒錯就是使用 quarkus.kubernetes.deployquarkus.kubernetes.deployment-target 預設上前者為 false 後者為 kubernetes。這過程會需要與 Kubernetes API 進行溝通所以需要新增以下的依賴

implementation 'io.quarkus:quarkus-kubernetes-client'

下面來試試,首先在定義新的 API

// GreetingResource.java
    @GET
    @Path("/day03")
    @Produces(MediaType.APPLICATION_JSON)
    public String day03() {
        return "Hello RESTEasy %s".formatted("day03");
    }

定義好後重新打包 Image,相較於上一篇,這次把 quarkus.kubernetes.deploy 設定為 true,並指定要部署到的 namespace。因此會達到打包 Image 後順便部署的好處。

gradle build -Dquarkus.package.type=native -Dquarkus.native.container-build=true -Dquarkus.kubernetes.deploy=true  -Dquarkus.container-image.push=true  -Dquarkus.container-image.build=true -Dquarkus.container-image.additional-tags=day03  -Dquarkus.container-image.username=${USER} -Dquarkus.container-image.password=${PASSWORD} -Dquarkus.kubernetes.namespace=default

最後,確實也多新增了一個 ithome2024lab-cccd555bd 的 ReplicaSet 資源,注意第一次部署的 ithome2024lab-77468c897c ReplicaSet 資源還在,也表示隨時都可以回滾到之前的版本。

$ kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/ithome2024lab-cccd555bd-qlcl5   1/1     Running   0          54s

NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/kubernetes      ClusterIP   10.43.0.1      <none>        443/TCP   3h26m
service/ithome2024lab   ClusterIP   10.43.73.110   <none>        80/TCP    54s

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ithome2024lab   1/1     1            1           2m15s

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/ithome2024lab-cccd555bd    1         1         1       54s
replicaset.apps/ithome2024lab-77468c897c   0         0         0       39m15s

驗證,新 API /hello/day03 確實被部署了。

$  kubectl port-forward service/ithome2024lab 8080:80
$ curl http://localhost:8080/hello/day03
Hello RESTEasy day03

如果要嘗試回滾,可以如下操作

$ kubectl rollout history  deployment ithome2024lab # 查看歷史版本紀錄
deployment.apps/ithome2024lab 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
$ kubectl rollout undo deployment ithome2024lab --to-revision 1 # 回滾至版本 1
deployment.apps/ithome2024lab rolled back

探討 Label 和 Annotation

Quarkus 提供了一個讓開發者簡易整合 Kubernetes 的依賴套件,作為開發端如果要在地端驗證某些功能其實是滿方便也夠用,該套件如果注意看,預設上所提供的 Labels 和 Annotations 欄位資訊滿豐富,對於時常上版的 DEV 環境可以清楚知道該版本的 commit 和建置時間與版本。壞處是如果真的要上 QAS 等以上環境其實要定義的資源滿多,反到會開始用 Helm Charts 或是 Kustomzie 等工具進行 YAML 管理。

itachi@DESKTOP-5L93DSL:~/github/ithome2024/ithome2024lab$ kubectl describe pod ithome2024lab-74959699f7-zq5gx 
Name:             ithome2024lab-74959699f7-zq5gx
Namespace:        default
Priority:         0
Service Account:  ithome2024lab
Node:             k3d-ithome-lab-cluster-agent-1/172.24.0.3
Start Time:       Sat, 24 Aug 2024 18:23:51 +0800
Labels:           app.kubernetes.io/managed-by=quarkus
                  app.kubernetes.io/name=ithome2024lab
                  app.kubernetes.io/version=1.0.0-SNAPSHOT
                  pod-template-hash=74959699f7
Annotations:      app.quarkus.io/build-timestamp: 2024-08-24 - 10:06:23 +0000
                  app.quarkus.io/commit-id: 1935a62ca5ef3e7242ba80b9ee3f27ed08d875b4
                  app.quarkus.io/quarkus-version: 3.13.3
                  app.quarkus.io/vcs-uri: https://xxxxxxxxx/quarkus-sandbox.git
....

這邊探討一下 Labels(標籤) 和 Annotations(註釋)。

  1. Labels 是附加在 Kubernetes 資源(Deployment/Service...)上的鍵值對,用於標識和篩選資源。定義範例如下
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: ithome2024lab
    app.kubernetes.io/version: v1.0.0
  1. Annotations 也是附加在 Kubernetes 資源(Deployment/Service...)上的鍵值對,但與 Labels 不同,Annotations 的用途更廣泛,可以用來儲存任何想要儲存的元數據。另外 Annotation 可以塞的內容會比 Labels 多。定義範例如下
apiVersion: v1
kind: Service
metadata:
  annotations:
    app.quarkus.io/quarkus-version: 3.13.3
    app.quarkus.io/commit-id: 1935a62ca5ef3e7242ba80b9ee3f27ed08d875b4
    app.quarkus.io/vcs-uri: https://xxxxx/quarkus-sandbox.git
    app.quarkus.io/build-timestamp: 2024-08-24 - 10:11:15 +0000

定義這些鍵值時會希望是 prefix/name 這樣規範定義。這由助於團隊溝通、識別服務(可能像是屬於哪個團隊、業務是什麼類型之類)或是管理者進行除錯都很有幫助。

  • prefix: 如果指定,則前綴應該是不超過 253 個字元並以斜線結尾的 DNS 子網域。例如: app.kubernetes.io/
  • name: 不得為空,長度不得超過 63 個字元。

它們兩之間的主要區別在於它們是否是可識別的。可以根據這些標籤值來篩選和分組資源,則應將數據映射為標籤。如果元數據不是標識碼,而是與 Kubernetes 資源相關的其他數據,則考慮用註釋。


上一篇
Quarkus 整合 Jib 與 Kubernetes
下一篇
Quarkus 與 Pod Security Context
系列文
當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言