本篇主要學習目標是讓 Quarkus 的 Pod 透過 ServiceAccount 的 token 對 Kubernetes API 進行交互。
部署上一章節 YAML 檔案。
kubectl apply -f kubernetes/ServiceAccount.yaml
kubectl apply -f kubernetes/Deployment.yaml
查看部署結果
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/ithomerbaclab-f967c6ccc-5v9h8 0/1 Running 0 7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 13d
service/gracefulshutdown ClusterIP 10.43.100.69 <none> 80/TCP 6d13h
service/ithomerbaclab ClusterIP 10.43.186.70 <none> 80/TCP 7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ithomerbaclab 0/1 1 0 7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ithomerbaclab-f967c6ccc 1 1 0 7s
查看 ServiceAccount 是否建立。
$ kubectl get sa
NAME SECRETS AGE
default 0 12d
ithomerbaclab 0 107s
最重要的令牌
$ kubectl get secrets ithomerbaclab-token
NAME TYPE DATA AGE
ithomerbaclab-token kubernetes.io/service-account-token 3 2m29s
$ kubectl describe secrets ithomerbaclab-token
Name: ithomerbaclab-token
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: ithomerbaclab
kubernetes.io/service-account.uid: 20469ebb-d0f3-4733-9ed4-1ca0b8980151
Type: kubernetes.io/service-account-token
Data
====
token: ...
ca.crt: 570 bytes
namespace: 7 bytes
對於 Quarkus 範例,有撰寫一隻 API GET /hello
。
@Path("/hello")
public class HelloResource {
@ConfigProperty(name = "greeting.message")
String message;
@GET
public String hello() {
return message;
}
}
測試該 API
$ kubectl port-forward services/ithomerbaclab 9090:80
$ curl http://localhost:9090/hello
ithome123
假設一個需求來了,需要變換環境變數。將 greeting.message
變成 "ithome-Day14"。
apiVersion: v1
kind: ConfigMap
metadata:
name: ithomerbaclab
namespace: default
data:
application.yaml: |
watch:
dir:
path: /home/jboss/config
greeting:
message: "ithome-Day14"
k8s:
kubernetes:
deployment:
name: ${DEPLOYMENT_NAME}
namespace: ${KUBERNETES_NAMESPACE}
trust-certs: true
api-server: "https://kubernetes.default.svc"
token: ...
quarkus:
config:
locations: /home/jboss/config/application.yaml
此時可以變更 YAML 重新佈署 ConfigMap 資源或是 kubectl edit
方式進行異動。接著從日誌就看到說其偵測到檔案變化後
File event: CREATE occurred on file ..2024_09_07_02_54_22.1199477851 at 1725677662483
,就進行重啟 Deployment 動作。
2024-09-07 02:54:23,075 INFO [restart-replica] (Camel (camel-1) thread #2 - CamelFileWatchPoll) upgrade replica: ithomerbaclab
2024-09-07 02:54:23,089 INFO [ith.cch.ser.KubernetesService] (Camel (camel-1) thread #2 - CamelFileWatchPoll) rollout deployment
$ kubectl logs -f ithomerbaclab-f967c6ccc-5v9h8
...
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2024-09-07 02:52:59,594 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) Apache Camel Quarkus 3.14.0 is starting
2024-09-07 02:52:59,595 INFO [org.apa.cam.mai.MainSupport] (main) Apache Camel (Main) 4.7.0 is starting
2024-09-07 02:52:59,682 INFO [org.apa.cam.sup.LifecycleStrategySupport] (main) Autowired property: kubernetesClient on component: kubernetes-deployments as exactly one instance of type: io.fabric8.kubernetes.client.KubernetesClient (io.fabric8.kubernetes.client.impl.KubernetesClientImpl) found in the registry
2024-09-07 02:52:59,689 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 4.7.0 (camel-1) is starting
2024-09-07 02:52:59,700 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup (total:3)
2024-09-07 02:52:59,700 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route1 (direct://trigger)
2024-09-07 02:52:59,700 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started Watch File (file-watch:///home/jboss/config)
2024-09-07 02:52:59,701 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started restart-replica (direct://restart-replica)
2024-09-07 02:52:59,701 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 4.7.0 (camel-1) started in 11ms (build:0ms init:0ms start:11ms)
2024-09-07 02:52:59,754 INFO [io.quarkus] (main) ithomerbaclab 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.14.1) started in 1.085s. Listening on: http://0.0.0.0:8080
2024-09-07 02:52:59,754 INFO [io.quarkus] (main) Profile prod activated.
2024-09-07 02:52:59,754 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-direct, camel-file-watch, camel-kubernetes, camel-log, camel-timer, cdi, config-yaml, kubernetes, kubernetes-client, rest, rest-jackson, smallrye-context-propagation, smallrye-health, vertx]
2024-09-07 02:54:22,488 INFO [Watch File] (Camel (camel-1) thread #2 - CamelFileWatchPoll) File event: CREATE occurred on file ..2024_09_07_02_54_22.1199477851 at 1725677662483
2024-09-07 02:54:22,996 INFO [restart-replica] (Camel (camel-1) thread #2 - CamelFileWatchPoll) upgrade replica: ithomerbaclab
2024-09-07 02:54:23,066 INFO [ith.cch.ser.KubernetesService] (Camel (camel-1) thread #2 - CamelFileWatchPoll) rollout deployment
2024-09-07 02:54:23,067 INFO [Watch File] (Camel (camel-1) thread #2 - CamelFileWatchPoll) File event: MODIFY occurred on file application.yaml at 1725677662484
2024-09-07 02:54:23,075 INFO [restart-replica] (Camel (camel-1) thread #2 - CamelFileWatchPoll) upgrade replica: ithomerbaclab
2024-09-07 02:54:23,089 INFO [ith.cch.ser.KubernetesService] (Camel (camel-1) thread #2 - CamelFileWatchPoll) rollout deployment
2024-09-07 02:54:43,515 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Shutdown thread) Apache Camel 4.7.0 (camel-1) is shutting down (timeout:45s)
2024-09-07 02:54:43,519 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Shutdown thread) Routes stopped (total:3)
2024-09-07 02:54:43,519 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Shutdown thread) Stopped restart-replica (direct://restart-replica)
2024-09-07 02:54:43,519 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Shutdown thread) Stopped Watch File (file-watch:///home/jboss/config)
2024-09-07 02:54:43,520 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Shutdown thread) Stopped route1 (direct://trigger)
2024-09-07 02:54:43,521 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Shutdown thread) Apache Camel 4.7.0 (camel-1) shutdown in 6ms (uptime:1m43s)
2024-09-07 02:54:43,535 INFO [io.quarkus] (Shutdown thread) ithomerbaclab stopped in 0.024s
從以下可以看到說,ReplicaSet 換了一個。ithomerbaclab-f967c6ccc 變成 ithomerbaclab-7bf85657bc。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/ithomerbaclab-7bf85657bc-fg9lw 1/1 Running 0 2m41s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 13d
service/gracefulshutdown ClusterIP 10.43.100.69 <none> 80/TCP 6d13h
service/ithomerbaclab ClusterIP 10.43.186.70 <none> 80/TCP 4m8s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ithomerbaclab 1/1 1 1 4m8s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ithomerbaclab-7fb57c8457 0 0 0 2m41s
replicaset.apps/ithomerbaclab-7bf85657bc 1 1 1 2m41s
replicaset.apps/ithomerbaclab-f967c6ccc 0 0 0 4m8s
因此最後配置也隨之變化,透過 API 可以看到回復訊息。
$ curl http://localhost:9090/hello
ithome-Day14
總體來說,hot-reload 是可以自行實現,不過本範例還沒到很完整。考慮部屬多個 Quarkus 應用程式,如果都收到會重複觸發,而這又是另外要設計的場景。
如果 roleBinding 綁定權限不足會發生以下錯誤訊息,即 403 forbidden。
Caused by: io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://kubernetes.default.svc/apis/apps/v1/namespaces/default/deployments/ithomerbaclab. Message: deployments.apps "ithomerbaclab" is forbidden: User "system:serviceaccount:default:ithomerbaclab" cannot get resource "deployments" in API group "apps" in the namespace "default". Received status: Status(apiVersion=v1, code=403, details=StatusDetails(causes=[], group=apps, kind=deployments, name=ithomerbaclab, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=deployments.apps "ithomerbaclab" is forbidden: User "system:serviceaccount:default:ithomerbaclab" cannot get resource "deployments" in API group "apps" in the namespace "default", metadata=ListMeta(_continue=null, remainingItemCount=null, resourceVer