本次學習目標是
建立 Quarkus 專案可以使用 Maven 或是 Gradle 等專案自動工具建置。此範例將使用 Gradle,而現行的 IDE 都相當方便直接用勾選方式即可建置一個專案,或是至 Quarkus 官方也可以建置。
主要需要的相依套件有以下
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation enforcedPlatform("${quarkusPlatformGroupId}:quarkus-camel-bom:${quarkusPlatformVersion}")
implementation 'org.apache.camel.quarkus:camel-quarkus-log'
implementation 'org.apache.camel.quarkus:camel-quarkus-core'
implementation 'org.apache.camel.quarkus:camel-quarkus-microprofile-health'
implementation 'org.apache.camel.quarkus:camel-quarkus-kubernetes'
implementation 'io.quarkus:quarkus-config-yaml'
implementation 'io.quarkus:quarkus-resteasy-jackson'
implementation 'org.apache.camel.quarkus:camel-quarkus-micrometer'
implementation 'io.quarkus:quarkus-smallrye-health'
implementation 'io.quarkus:quarkus-container-image-jib'
implementation 'io.quarkus:quarkus-kubernetes'
implementation 'io.quarkus:quarkus-micrometer'
implementation 'io.quarkus:quarkus-arc'
implementation 'io.quarkus:quarkus-resteasy'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
本次會注重於 quarkus-container-image-jib
與 quarkus-kubernetes
。首先介紹一下 Jib,用來為 Java 應用程式快速且簡易建立 Docker 或 OCI 容器 Image。相比傳統 Dockerfile 方式,Jib 提供了一種更直觀、更自動化的方式來整合 Java 應用程式並打包成容器 Image。
Jib
優勢可帶來
再來是, quarkus-kubernetes
套件。Quarkus 使用 dekorate 透過框架安全預設值和使用者提供的配置自動產生 Kubernetes YAML 資源。其支援 Kubernetes、OpenShift 和 Knative 來產生對應的 YAML 資源。前面產生了 YAML 清單,當然可部署到目標 Kubernetes,透過 Kubernetes API 來實現。
透過 Jib 建構 Image 再透過 quarkus-kubernetes
來產生 YAML 清單,這樣可以在地端輕鬆的快速驗證內容。
前面大致說明了重點套件。接下來來實作吧! 理論上建置完 Quarkus 專案後會產生一個範例 API
@Path("/hello")
public class GreetingResource {
@Inject
GreetingConfig greetingConfig;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy %s".formatted(greetingConfig.message());
}
}
對於 quarkus-kubernetes
套件配置以下,讓 Quarkus 被建構時,將 Kubernetes YAML 儲存至 kubernetes
目錄,這在 CI 時非常有用。
kubernetes:
output-directory: kubernetes
再來透過 gradle: build
編譯專案,這時在 kubernetes 目錄可以發現一個 yml 和 json 檔案,原則上部署都是用 yml,除非想透過 API 方式,那就可以使用 json。裡面內容是預設框架給的 kubernetes 資源 YAML 清單。
$ tree kubernetes/
kubernetes/
├── kubernetes.json
└── kubernetes.yml
其資源分別是 Service
與 Deployment
資源。
---
apiVersion: v1
kind: Service
metadata:
annotations:
app.quarkus.io/quarkus-version: 3.13.3
app.quarkus.io/commit-id: 0ea6717ad4a8c436ab47cdffc6e1786e21aeb608
app.quarkus.io/vcs-uri: https://gitlab.devpack.cc/Itachi_Chen/quarkus-sandbox.git
app.quarkus.io/build-timestamp: 2024-08-23 - 18:57:59 +0000
labels:
app.kubernetes.io/name: ithome2024lab
app.kubernetes.io/version: 1.0.0-SNAPSHOT
app.kubernetes.io/managed-by: quarkus
name: ithome2024lab
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app.kubernetes.io/name: ithome2024lab
app.kubernetes.io/version: 1.0.0-SNAPSHOT
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
app.quarkus.io/quarkus-version: 3.13.3
app.quarkus.io/commit-id: 0ea6717ad4a8c436ab47cdffc6e1786e21aeb608
app.quarkus.io/vcs-uri: https://gitlab.devpack.cc/Itachi_Chen/quarkus-sandbox.git
app.quarkus.io/build-timestamp: 2024-08-23 - 18:57:59 +0000
labels:
app.kubernetes.io/name: ithome2024lab
app.kubernetes.io/version: 1.0.0-SNAPSHOT
app.kubernetes.io/managed-by: quarkus
name: ithome2024lab
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/version: 1.0.0-SNAPSHOT
app.kubernetes.io/name: ithome2024lab
template:
metadata:
annotations:
app.quarkus.io/quarkus-version: 3.13.3
app.quarkus.io/commit-id: 0ea6717ad4a8c436ab47cdffc6e1786e21aeb608
app.quarkus.io/vcs-uri: https://gitlab.devpack.cc/Itachi_Chen/quarkus-sandbox.git
app.quarkus.io/build-timestamp: 2024-08-23 - 18:57:59 +0000
labels:
app.kubernetes.io/managed-by: quarkus
app.kubernetes.io/version: 1.0.0-SNAPSHOT
app.kubernetes.io/name: ithome2024lab
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: registry.hub.docker.com/cch0124/ithome2024lab:1.0.0-SNAPSHOT
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: /q/health/live
port: 8080
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
name: ithome2024lab
ports:
- containerPort: 8080
name: http
protocol: TCP
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
從結果來看其實 Deployment
和 Service
在地端驗證配置已經很足夠了。如果要上到 DEV、QAS 等環境則需要再配置一些資源,例如 resource
、Ingress
等資源。
Deployment
是 Kubernetes 中用於管理 ReplicaSet
的資源,而 ReplicaSet
用於管理 Pod
的副本數量。基本上 Deployment
有以下特性
Pod
副本,且會自動維護這個數量。當 Pod
突然故障或被刪除,Deployment
會自動創建新的 Pod
來替換Deployment
預設是執行滾動更新,即逐個替換舊 Pod
為新 Pod
,保證服務在更新過程中保持可用性Deployment
版本出現問題,可以回滾到之前的版本Pod
副本,當資源到達一定程度時可透過放大 Pod
數量來分配流量,以提高系統穩定性和可用性順帶提一下,ReplicaSet
不支持滾動更新、回滾等高級功能。因此實務上會使用 Deployment
資源。而 Deployment
在做回滾時則需要 ReplicaSet
的存在,因為 Deployment
在作異動時就是新增一個新 ReplicaSet
和保留舊 ReplicaSet
。
下面為資源之間關係
Deployment -----> ReplicaSet -----> Pod
Service
,透過 Endpoints
定義了一組 Pod
的邏輯集合,並提供一個穩定的網路端點(IP 和 Port)來存取這些 Pod
。其主要特性有以下
Pod
,並將這些 Pod
暴露為一個服務Pod
上,實現負載均衡Pod
IP 發生變化,Service
資源的 IP 地址也不會改變下面為資源之間關係
Service -----> Endpoints -----> Pod
接著在 application.yaml
配置 Jib 內容,如下
quarkus:
container-image:
group: cch0124
name: ${quarkus.application.name:unset}
tag: ${quarkus.application.version:latest}
builder: jib
labels:
"maintainer": cch
"app": ${quarkus.application.name}
registry: registry.hub.docker.com
jib:
base-native-image: quay.io/quarkus/quarkus-micro-image:2.0
user: itachi
working-directory: /home/jboss
platforms: linux/amd64
配置完後,嘗試建置 Image,如下指令並搭配變數來進行彈性的配置。相對應參數可以參閱官方。
gradle build -Dquarkus.package.type=native -Dquarkus.native.container-build=true -Dquarkus.kubernetes.deploy=false -Dquarkus.container-image.push=true -Dquarkus.container-image.build=true -Dquarkus.container-image.additional-tags="$(git log -1 --pretty=format:%h),day02" -Dquarkus.container-image.username=${USER} -Dquarkus.container-image.password=${PASSWORD} -Dquarkus.kubernetes.version=$(git log -1 --pretty=format:%h)
執行後 Jib 建置了 Image 也將 Image 推到 docker hub 上,當中 tag 會有當下的 commit sha、day02 以及 1.0.0-SNAPSHOT。