概要
- Camelマイクロサービスプロジェクトの作成
- Dockerイメージのビルド
- Kubernetesへのデプロイと実行
- マイクロサービスのレジリエンス
- Kubernetes上でのテスト
- その他のツールセット(Fabric8、Helm、Camel K)
マイクロサービスプロジェクトの作成
Camelアプリケーション例
- 5秒おきに
Hello from <hostname>
を出力するだけのルート
HelloRoute.java
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.util.InetAddressUtil;
public class HelloRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:hello?period={{timer.period}}")
.setBody().constant("Hello from " + InetAddressUtil.getLocalHostName())
.log("${body}");
}
}
application.properties
timer.period=5000
Spring Boot
- Apache Camelのdependencyを追加してプロジェクト生成
サンプルプロジェクト
camel-springboot-hello/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src/
├── main/
│ ├── java/
│ │ └── io/github/tadayosi/sample/camel/springboot/hello/
│ │ ├── HelloApplication.java
│ │ └── HelloRoute.java
│ └── resources/
│ └── application.properties
└── test
└── java
└── io/github/tadayosi/sample/camel/springboot/hello/
└── HelloApplicationTests.java
Spring Bootを使う場合の注意点
- HTTPエンドポイント(
spring-boot-starter-web
など)がない場合、デフォルトで起動後すぐにJVMがシャットダウンしてしまう - CamelContextを実行し続けるには以下を
true
に設定する
application.properties
camel.springboot.main-run-controller=true
ローカルで実行
コマンド
$ mvn spring-boot:run
実行結果
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.2)
2021-02-15 16:28:04.233 INFO 19962 --- [ main] i.g.t.s.c.s.hello.HelloApplication : Starting HelloApplication using Java 11.0.10 on racine with PID 19962 (/home/tasato/projects/samples/camel-springboot-hello/target/classes started by tasato in /home/tasato/projects/samples/camel-springboot-hello)
2021-02-15 16:28:04.235 INFO 19962 --- [ main] i.g.t.s.c.s.hello.HelloApplication : No active profile set, falling back to default profiles: default
2021-02-15 16:28:04.988 INFO 19962 --- [ main] o.apache.camel.support.LRUCacheFactory : Detected and using LRUCacheFactory: camel-caffeine-lrucache
2021-02-15 16:28:05.309 INFO 19962 --- [ main] o.a.c.s.boot.SpringBootRoutesCollector : Loading additional Camel XML routes from: classpath:camel/*.xml
2021-02-15 16:28:05.310 INFO 19962 --- [ main] o.a.c.s.boot.SpringBootRoutesCollector : Loading additional Camel XML route templates from: classpath:camel-template/*.xml
2021-02-15 16:28:05.310 INFO 19962 --- [ main] o.a.c.s.boot.SpringBootRoutesCollector : Loading additional Camel XML rests from: classpath:camel-rest/*.xml
2021-02-15 16:28:05.418 INFO 19962 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.7.2 (camel-1) is starting
2021-02-15 16:28:05.419 INFO 19962 --- [ main] o.a.c.impl.engine.AbstractCamelContext : StreamCaching is not in use. If using streams then it's recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2021-02-15 16:28:05.420 INFO 19962 --- [ main] c.s.b.CamelSpringBootApplicationListener : Starting CamelMainRunController to ensure the main thread keeps running
2021-02-15 16:28:05.422 INFO 19962 --- [ main] o.a.c.i.e.InternalRouteStartupManager : Route: route1 started and consuming from: timer://hello
2021-02-15 16:28:05.426 INFO 19962 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Total 1 routes, of which 1 are started
2021-02-15 16:28:05.426 INFO 19962 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.7.2 (camel-1) started in 8ms
2021-02-15 16:28:05.435 INFO 19962 --- [ main] i.g.t.s.c.s.hello.HelloApplication : Started HelloApplication in 1.761 seconds (JVM running for 2.168)
2021-02-15 16:28:06.431 INFO 19962 --- [- timer://hello] route1 : Hello from racine
2021-02-15 16:28:11.423 INFO 19962 --- [- timer://hello] route1 : Hello from racine
2021-02-15 16:28:16.424 INFO 19962 --- [- timer://hello] route1 : Hello from racine
Quarkus
- 必要な
Camel *
エクステンションを追加してプロジェクト生成
サンプルプロジェクト
camel-quarkus-hello/
├── mvnw
├── mvnw.cmd
├── pom.xml
├── README.md
└── src/
├── main/
│ ├── docker/
│ │ ├── Dockerfile.fast-jar
│ │ ├── Dockerfile.jvm
│ │ └── Dockerfile.native
│ ├── java/
│ │ └── io/github/tadayosi/sample/
│ │ ├── camel/quarkus/hello/
│ │ │ └── HelloRoute.java
│ │ └── GreetingResource.java
│ └── resources/
│ ├── application.properties
│ └── META-INF/resources/
│ └── index.html
└── test
└── java
└── io/github/tadayosi/sample/
├── GreetingResourceTest.java
└── NativeGreetingResourceIT.java
ローカルで実行
コマンド
$ mvn compile quarkus:dev
実行結果
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
Powered by Quarkus 1.11.2.Final
2021-02-15 16:31:49,076 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (Quarkus Main Thread) bootstrap runtime: org.apache.camel.quarkus.core.CamelContextRuntime
2021-02-15 16:31:49,149 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Apache Camel 3.7.0 (camel-1) is starting
2021-02-15 16:31:49,151 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) StreamCaching is not in use. If using streams then it's recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2021-02-15 16:31:49,154 INFO [org.apa.cam.imp.eng.InternalRouteStartupManager] (Quarkus Main Thread) Route: route1 started and consuming from: timer://hello
2021-02-15 16:31:49,156 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Total 1 routes, of which 1 are started
2021-02-15 16:31:49,156 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Apache Camel 3.7.0 (camel-1) started in 6ms
2021-02-15 16:31:49,251 INFO [io.quarkus] (Quarkus Main Thread) camel-quarkus-hello 1.0.0-SNAPSHOT on JVM (powered by Quarkus 1.11.2.Final) started in 3.927s. Listening on: http://localhost:8080
2021-02-15 16:31:49,251 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-02-15 16:31:49,252 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [camel-core, camel-support-common, camel-timer, cdi, kubernetes, resteasy]
2021-02-15 16:31:50,162 INFO [route1] (Camel (camel-1) thread #0 - timer://hello) Hello from racine
2021-02-15 16:31:55,157 INFO [route1] (Camel (camel-1) thread #0 - timer://hello) Hello from racine
2021-02-15 16:32:00,156 INFO [route1] (Camel (camel-1) thread #0 - timer://hello) Hello from racine
Dockerイメージのビルド
JavaプロジェクトのDockerイメージ作成方法
- Mavenプラグインを使う
-
docker-maven-plugin
- 使えるけれど少し古い
-
Eclipse JKube
- よりモダン、k8sと統合
-
docker-maven-plugin
- フレームワーク固有
- Spring Boot: Spring Bootプラグイン
- Quarkus: Container Imageエクステンション
docker-maven-plugin
- Fabric8プロジェクトの長らくデファクトだったDocker Mavenプラグイン
- Docker単体で使うなら今でも現役だが、今ならJKubeかフレームワーク固有の機能を使った方がよい
使い方
-
pom.xml
にMavenプラグイン設定を追加する
pom.xml
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.34.1</version>
<configuration>
<images>
<image>
<name>tadayosi/${project.artifactId}:${project.version}</name>
<build>
<from>adoptopenjdk/openjdk11:ubi-minimal</from>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
<cmd>java -jar maven/${project.artifactId}-${project.version}.jar</cmd>
</build>
</image>
</images>
</configuration>
</plugin>
ビルド方法
コマンド
$ mvn package docker:build
確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tadayosi/camel-springboot-hello 0.0.1-SNAPSHOT 457115bcda7e 3 minutes ago 471MB
...
Eclipse JKube
- Fabric8 Mavenプラグインの後継
- Dockerイメージ作成からKubernetes、OpenShiftへのデプロイまでカバーされる
使い方
-
pom.xml
にMavenプラグイン設定を追加する
pom.xml
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>1.1.0</version>
</plugin>
<!-- OpenShiftを使いたい場合は以下も入れる -->
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>openshift-maven-plugin</artifactId>
<version>1.1.0</version>
</plugin>
- Dockerイメージ名を設定したい場合は
jkube.generator.name
プロパティを使う
pom.xml
<properties>
<jkube.generator.name>tadayosi/%a:%v</jkube.generator.name>
</properties>
ビルド方法
$ mvn k8s:build
- ビルドしたイメージをDocker Hubなどのコンテナレジストリーにプッシュする場合
$ mvn k8s:push
OpenShiftの場合
-
oc:build
を使うとローカルでなくOpenShift上に直接ImageStreamがビルドされる
$ mvn oc:build
Spring Bootプラグイン
- Spring Boot 2.3.0から追加のMavenプラグインなしでDockerイメージをビルドできる
https://spring.io/guides/topicals/spring-boot-docker/
$ mvn spring-boot:build-image
Quarkus Container Imageエクステンション
-
container-image-docker
エクステンションを使う
https://quarkus.io/guides/container-image - プロジェクト生成時に選ぶか、以下のコマンドで後から追加する
$ mvn quarkus:add-extension -Dextensions="container-image-docker"
- Dockerイメージ名やコンテナレジストリーをカスタマイズしたい場合は
application.properties
に書く
application.properties
quarkus.container-image.group=...
quarkus.container-image.name=...
quarkus.container-image.tag=...
quarkus.container-image.registry=docker.io
ビルド方法
$ mvn package -Dquarkus.container-image.build=true
- コンテナレジストリーにプッシュする場合
$ mvn package -Dquarkus.container-image.push=true
Dockerコンテナの実行
camel-springboot-hello
$ docker run -it tadayosi/camel-springboot-hello:0.0.1-SNAPSHOT
camel-quarkus-hello
$ docker run -it tadayosi/camel-quarkus-hello:1.0.0-SNAPSHOT
Kubernetesへのデプロイと実行
JavaプロジェクトのKubernetesへのデプロイ方法
- JKube - kubernetes-maven-plugin
- 主にSpring Boot
- fabric8-maven-pluginはdeprecated
- Quarkus
コンテナイメージを直接実行する
- あくまでお試し用の方法
-
Pod
しか作られない
-
- 事前にイメージを
docker.io
にプッシュしておく
$ docker push tadayosi/camel-springboot-hello:0.0.1-SNAPSHOT
- イメージの実行
$ kubectl run camel-springboot-hello --labels="app=camel" \
--image=tadayosi/camel-springboot-hello:0.0.1-SNAPSHOT
- 削除
$ kubectl delete pods -l app=camel
JKube kubernetes-maven-plugin
- Dockerビルドのところでも使ったMavenプラグイン
-
target/classes/META-INF/jkube/
以下にマニフェストファイル(*.yml
)を生成 -
Deployment
やService
も作ってくれる
-
- インストール方法はそちらを参照
使い方
デプロイ
$ mvn k8s:resource k8s:deploy
アンデプロイ
$ mvn k8s:undeploy
- sternを使って実行結果を確認
$ stern camel-springboot-hello -o raw
+ camel-springboot-hello-6fdc989599-wzlff › spring-boot
Starting the Java application using /opt/jboss/container/java/run/run-java.sh ...
INFO exec java -javaagent:/usr/share/java/jolokia-jvm-agent/jolokia-jvm.jar=config=/opt/jboss/container/jolokia/etc/jolokia.properties -javaagent:/usr/share/java/prometheus-jmx-exporter/jmx_prometheus_javaagent.jar=9779:/opt/jboss/container/prometheus/etc/jmx-exporter-config.yaml -XX:+UseParallelOldGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MaxMetaspaceSize=100m -XX:+ExitOnOutOfMemoryError -cp "." -jar /deployments/camel-springboot-hello-0.0.1-SNAPSHOT.jar
[...]
I> No access restrictor found, access to any MBean is allowed
Jolokia: Agent started with URL https://10.131.0.28:8778/jolokia/
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.2)
2021-02-15 12:01:50.337 INFO 1 --- [ main] i.g.t.s.c.s.hello.HelloApplication : Starting HelloApplication v0.0.1-SNAPSHOT using Java 11.0.9.1 on camel-springboot-hello-6fdc989599-wzlff with PID 1 (/deployments/camel-springboot-hello-0.0.1-SNAPSHOT.jar started by jboss in /deployments)
2021-02-15 12:01:50.340 INFO 1 --- [ main] i.g.t.s.c.s.hello.HelloApplication : No active profile set, falling back to default profiles: default
2021-02-15 12:01:51.396 INFO 1 --- [ main] o.apache.camel.support.LRUCacheFactory : Detected and using LRUCacheFactory: camel-caffeine-lrucache
2021-02-15 12:01:51.715 INFO 1 --- [ main] o.a.c.s.boot.SpringBootRoutesCollector : Loading additional Camel XML routes from: classpath:camel/*.xml
2021-02-15 12:01:51.715 INFO 1 --- [ main] o.a.c.s.boot.SpringBootRoutesCollector : Loading additional Camel XML route templates from: classpath:camel-template/*.xml
2021-02-15 12:01:51.716 INFO 1 --- [ main] o.a.c.s.boot.SpringBootRoutesCollector : Loading additional Camel XML rests from: classpath:camel-rest/*.xml
2021-02-15 12:01:51.850 INFO 1 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.7.2 (camel-1) is starting
2021-02-15 12:01:51.852 INFO 1 --- [ main] o.a.c.impl.engine.AbstractCamelContext : StreamCaching is not in use. If using streams then it's recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2021-02-15 12:01:51.855 INFO 1 --- [ main] c.s.b.CamelSpringBootApplicationListener : Starting CamelMainRunController to ensure the main thread keeps running
2021-02-15 12:01:51.856 INFO 1 --- [ main] o.a.c.i.e.InternalRouteStartupManager : Route: route1 started and consuming from: timer://hello
2021-02-15 12:01:51.861 INFO 1 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Total 1 routes, of which 1 are started
2021-02-15 12:01:51.861 INFO 1 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.7.2 (camel-1) started in 10ms
2021-02-15 12:01:51.869 INFO 1 --- [ main] i.g.t.s.c.s.hello.HelloApplication : Started HelloApplication in 2.014 seconds (JVM running for 2.836)
2021-02-15 12:01:52.867 INFO 1 --- [- timer://hello] route1 : Hello from camel-springboot-hello-6fdc989599-wzlff
2021-02-15 12:01:57.857 INFO 1 --- [- timer://hello] route1 : Hello from camel-springboot-hello-6fdc989599-wzlff
2021-02-15 12:02:02.858 INFO 1 --- [- timer://hello] route1 : Hello from camel-springboot-hello-6fdc989599-wzlff
...
Quarkus Kubernetesエクステンション
- 最初にインストールしていなければ追加
-
quarkus-container-image-*
エクステンションが既に1つ追加されている必要あり
-
$ mvn quarkus:add-extension -Dextensions="kubernetes"
使い方
$ mvn package -Dquarkus.kubernetes.deploy=true \
-Dquarkus.kubernetes-client.trust-certs=true
-
quarkus.kubernetes-client.trust-certs=true
は本当は良くないがこれがないと動かなかったので…- 後で正しいやり方を調査
ラベルを付ける
-
application.properties
にquarkus.kubernetes.labels.*
を定義する
application.properties
quarkus.kubernetes.labels.app=camel
マイクロサービス間の呼び出し
- KubernetesのDNS
- 推奨の方法
- 以下はDNS以前の古い方法(オススメしない)
- Propertiesコンポーネントの
{{service:xxxxx}}
表記 - Service Call EIP
- Propertiesコンポーネントの
KubernetesのDNS
-
another-camel-service
サービスが定義されていたらそのままDNSでルックアップできる- Kubernetes 1.9以前はサポートされていなかった
from("timer:hello?period=5000")
.to("http://another-camel-service:8080")
.log("${body}");
{{service:xxxxx}}
- Propertiesコンポーネントのビルトイン関数
- 環境変数に定義された以下の
xxx-yyy-zzz
サービスを自動的に参照できるXXX_YYY_ZZZ_SERVICE_HOST
XXX_YYY_ZZZ_SERVICE_PORT
from("timer:hello?period=5000")
.to("http://{{service:another-camel-service}}")
.log("${body}");
参考
- k8sにデプロイしたPodには以下のような環境変数が提供されている
$ kubectl exec camel-quarkus-hello-867767dbf8-62h48 -- env | grep _SERVICE_ | sort -n
CAMEL_QUARKUS_HELLO_SERVICE_HOST=172.30.110.100
CAMEL_QUARKUS_HELLO_SERVICE_PORT=8080
CAMEL_QUARKUS_HELLO_SERVICE_PORT_HTTP=8080
CAMEL_SPRINGBOOT_HELLO_SERVICE_HOST=172.30.200.231
CAMEL_SPRINGBOOT_HELLO_SERVICE_PORT=8080
CAMEL_SPRINGBOOT_HELLO_SERVICE_PORT_HTTP=8080
KUBERNETES_SERVICE_HOST=172.30.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
Service Call EIP
- Camelのサービスレジストリーに登録された外部サービスを呼び出すためのEIP
- Kubernetes, Consul, Etcd, Zookeeper, DNS
from("timer:hello?period=5000")
.serviceCall("another-camel-service")
.log("${body}");
- Kubernetesのサービスを呼び出すには以下の依存が必要
Spring Boot
pom.xml
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-kubernetes-starter</artifactId>
</dependency>
Quarkus
$ mvn quarkus:add-extension \
-Dextensions="org.apache.camel.quarkus:camel-quarkus-kubernetes"
マイクロサービスのリモートデバッグ
JKube
- デフォルト
5005
ポートでリモートデバッグできる
$ mvn k8s:debug
- ポートを変えたい場合
$ mvn k8s:debug -Djkube.debug.port=12345
Quarkus
-
quarkus:remote-dev
を使えばできそう- 要調査
$ mvn quarkus:remote-dev ...
マイクロサービスのレジリエンス
ReplicaSet
- K8Sに元々備わっている冗長化の機能
- Podが落ちても自動で復旧してくれる
$ kubectl scale deployment camel-springboot-hello --replicas=2
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: camel
group: io.github.tadayosi.sample
provider: jkube
name: camel-springboot-hello
...
spec:
replicas: 2
selector:
matchLabels:
app: camel
group: io.github.tadayosi.sample
provider: jkube
...
JKube
- リソースフラグメントを使ってカスタマイズできる
https://www.eclipse.org/jkube/docs/kubernetes-maven-plugin#_resource_fragments-
src/main/jkube
以下にリソース毎の断片を設定できるdeployment.yml
service.yml
configmap.yml
sa.yml
- ... etc.
-
src/main/jkube/deployment.yml
spec:
replicas: 2
Quarkusエクステンション
- なんでも
application.properties
で設定する
https://quarkus.io/guides/deploying-to-kubernetes#tuning-the-generated-resources-using-application-properties
src/main/resources/application.properties
quarkus.kubernetes.replicas=2
Readiness/Liveness Probe
- Podのヘルスチェック
- サービス可能(Ready)になったか
- 生存しているか
- ReplicaSetだけではPodの中身の死活監視まではできない
- Readiness/Liveness Probeの方法
- コマンド実行
- HTTPリクエスト
- TCPソケット
- SB、QuarkusアプリではHTTPを使うのが一般的
Deployment
spec:
template:
spec:
containers:
- livenessProbe:
failureThreshold: 3
httpGet:
path: /actuator/health
port: 8080
scheme: HTTP
initialDelaySeconds: 180
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /actuator/health
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
JKube
- POMに
spring-boot-starter-actuator
があれば自動でReadiness/Liveness Probeを設定してくれる
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.properties
management.endpoints.web.exposure.include=health
ヘルスチェック
$ kubectl port-forward camel-springboot-hello-ff7d6fc84-djw4l 8080:8080 9779:9779 &
$ curl -s localhost:8080/actuator/health | jq
{
"status": "UP",
"groups": [
"liveness",
"readiness"
]
}
Prometheus
- Prometheusもデフォルトでアタッチしてくれている(ポート:
9779
)
$ curl localhost:9779/metrics
# HELP org_xnio_xnio_coreworkerpoolsize CoreWorkerPoolSize (org.xnio<type=Xnio, provider="nio", worker="XNIO-1"><>CoreWorkerPoolSize)
# TYPE org_xnio_xnio_coreworkerpoolsize untyped
org_xnio_xnio_coreworkerpoolsize{provider="\"nio\"",worker="\"XNIO-1\"",} 16.0
# HELP org_xnio_xnio_maxworkerpoolsize MaxWorkerPoolSize (org.xnio<type=Xnio, provider="nio", worker="XNIO-1"><>MaxWorkerPoolSize)
# TYPE org_xnio_xnio_maxworkerpoolsize untyped
org_xnio_xnio_maxworkerpoolsize{provider="\"nio\"",worker="\"XNIO-1\"",} 16.0
...
Quarkusエクステンション
- MicroProfile Healthを使う
-
smallrye-health
エクステンションを追加するだけで自動的にReadiness/Liveness Probeを設定してくれる
https://quarkus.io/guides/microprofile-health
$ mvn quarkus:add-extension -Dextensions="smallrye-health"
Deployment
livenessProbe:
failureThreshold: 3
httpGet:
path: /q/health/live
port: 8080
scheme: HTTP
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /q/health/ready
port: 8080
scheme: HTTP
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
ヘルスチェック
$ kubectl port-forward camel-quarkus-hello-77f8464467-d9t8t 8080:8080 &
$ curl -s localhost:8080/q/health/live | jq
{
"status": "UP",
"checks": []
}
Circuit Breaker EIP
- Circuit BreakerパターンをCamelルートの中で使える
https://camel.apache.org/components/3.7.x/eips/circuitBreaker-eip.html- Camel 2.xでは
.hystrix()
だったが.circuitBreaker()
に名前変更された
- Camel 2.xでは
from("timer:hello?period={{timer.period}}")
.circuitBreaker()
.to("http://another-camel-service:8080")
.onFallback()
.transform().constant("Remote service is down!")
.end()
.log("${body}");
使い方
Spring Boot
- POMに
camel-resilience4j-starter
を追加- Hystrixはdeprecatedなので使わない
pom.xml
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-resilience4j-starter</artifactId>
</dependency>
Quarkus
-
camel-quarkus-microprofile-fault-tolerance
エクステンションを追加
$ mvn quarkus:add-extension -Dextensions="camel-quarkus-microprofile-fault-tolerance"
Kubernetes上でのテスト
Fabric8 Kubernetes Client
-
Arquillian Cubeは2018年以降メンテされていない
- JUnit 5(Jupiter)非対応
- JavaでKubernetes上の統合テストをするならFabric8 Kubernetes Client一択
使い方
Spring Boot
- POMに
kubernetes-client
を追加
pom.xml
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>5.1.1</version>
<scope>test</scope>
</dependency>
Quarkus
-
kubernetes-clientエクステンションを追加
-
quarkus-kubernetes-client
のスコープはtest
にしておく
-
$ mvn quarkus:add-extension -Dextensions="kubernetes-client"
OpenShift
- それぞれ対になる
openshift-client
があるので、そちらに置き換える
統合テストの書き方
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class HelloApplicationIT {
private KubernetesClient client;
@BeforeEach
void setUp() {
client = new DefaultKubernetesClient();
}
@Test
void testPodsReady() {
PodList podList = client.pods()
.withLabel("app", "camel")
.withLabel("group", "io.github.tadayosi.sample")
.withLabel("provider", "jkube")
.list();
assertEquals(2, podList.getItems().size());
podList.getItems().forEach(pod -> {
pod.getStatus().getConditions().stream()
.filter(c -> "Ready".equals(c.getType()))
.forEach(c -> {
assertEquals("True", c.getStatus());
});
});
}
}
統合テストの実行
-
maven-failsafe-plugin
を使う
pom.xml
<profiles>
<profile>
<id>itests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
</plugins>
</build>
</profile>
</profiles>
実行
$ mvn verify -P itests
その他の選択肢
- Testcontainers
- https://www.testcontainers.org/
- ローカルのDockerコンテナ上で統合テストを行いたい場合
その他のツールセット
Fabric8
- Fabric8 v1 ― まったく別物だった
- Before K8Sの時代にZooKeeperベースでK8S的なプラットフォームを実現しようとしていた
- Fabric8 v2 ― Java開発者向けK8S/OpenShiftツールセット・ライブラリ
- 現役なのは以下の2つのみ
- Kubernetes Client ― https://github.com/fabric8io/kubernetes-client
- Docker Maven Plugin ― https://github.com/fabric8io/docker-maven-plugin
- Fabric8 Maven Pluginはdeprecated
Helm
- K8S上のデフォルトのパッケージマネージャ
- JKubeにはHelmサポートあり
JKubeのHelmサポート
$ mvn k8s:helm
-
target/jkube/helm/camel-springboot-hello/kubernetes
にHelm chartが生成される
target/jkube/helm/camel-springboot-hello/kubernetes/
├── Chart.yaml
├── templates
│ ├── camel-springboot-hello-deployment.yaml
│ └── camel-springboot-hello-service.yaml
└── values.yaml
- Helmを使ったアプリのインストール
$ helm install camel-springboot-hello target/jkube/helm/camel-springboot-hello/kubernetes
$ helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
camel-springboot-hello test 1 2021-03-01 15:05:24.784538587 +0900 JST deployed camel-springboot-hello-0.0.1-SNAPSHOT
Camel K
- Operatorベースでさらにクラウドネイティブに突き詰めたサブプロジェクト
- Camelルートを
Integration
カスタムリソースとしてデプロイできる - Java、XML、YAML、Groovy、Kotlin、JSをサポート
- Camelルートを
Camel-Kアーキテクチャ 1