yuzutech / kroki

Creates diagrams from textual descriptions!
https://kroki.io
MIT License
2.78k stars 206 forks source link

Kubernetes automatically sets *_PORT to tcp://ip:port causing a ClassCastException #826

Open ggrossetie opened 3 years ago

ggrossetie commented 3 years ago

Follow-up issue of: https://github.com/yuzutech/kroki/issues/576

We fixed this issue for KROKI_PORT but we have the same issue for KROKI_BLOCKDIAG_PORT, KROKI_MERMAID_PORT, KROKI_BPMN_PORT and KROKI_EXCALIDRAW_PORT:

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')
  at io.vertx.core.json.JsonObject.getInteger(JsonObject.java:168)
  at io.vertx.core.json.JsonObject.getInteger(JsonObject.java:435)
  at io.kroki.server.service.Blockdiag.<init>(Blockdiag.java:37)
  at io.kroki.server.Server.start(Server.java:104)
  at io.kroki.server.Server.lambda$start$1(Server.java:61)
  at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:124)
  at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:62)
  at io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:164)
  at io.vertx.core.impl.future.FutureImpl.onComplete(FutureImpl.java:132)

Currently, and as a workaround, you will need to explicitly set the _PORT environment variables if you are using Kubernetes:

KROKI_BLOCKDIAG_PORT=8001
KROKI_MERMAID_PORT=8002
KROKI_BPMN_PORT=8003
KROKI_EXCALIDRAW_PORT=8004

One solution would be to replace all the _PORT and _HOST variables with a _URL variable:

KROKI_BLOCKDIAG_HOST=127.0.0.1
KROKI_BLOCKDIAG_PORT=8001
KROKI_BLOCKDIAG_URL=http://127.0.0.1:8001

It might also be useful when a companion container is available behind a reverse proxy:

KROKI_BLOCKDIAG_URL=https://my-kroki.xyz/blockdiag
jkroepke commented 3 years ago

Hi,

in https://github.com/yuzutech/kroki/issues/576#issuecomment-875317811 the change from KROKI_PORT to KROKI_LISTEN was proposed.

Wouldn't that an option here, too?

ggrossetie commented 3 years ago

Hi @jkroepke

In this case, I don't think LISTEN applies because we want to configure an HTTP(s) URL to connect to a companion container. In theory, companion containers are not exposed, they are "internal services" accessed through the gateway.

Also, LISTEN address cannot contain a path whereas a URL can:

KROKI_BLOCKDIAG_URL=https://my-internal-kroki.xyz/blockdiag

Does it make sense?

jkroepke commented 3 years ago

It makes sense. Thanks for the clarification.

teochenglim commented 2 years ago

i am developing helm charts for kroki and hit this error too. I think something to do with the helm parser before launching the pod. Using kubectl doesn't have any problem at all.

I run the kroki-k8s.zip and helm side by side, and the helm chart version always crash with the same config.

And my final confirmed test is to copy and paste the kroki-k8s.zip version and paste it into the helm version and indeed, it crashed. So this is not an application problem but the helm chart translation problem while launching the pod.

While k8s parse the env it is a string, but the input doesn't have integer either.

And yes, for kubernetes we usually start any pod with "0.0.0.0:8000" or ":8000" the reason being the pod won't know what ip they will get and ":8000" might not work for some application. And sorry for my limited knowledge about java.

I think we need some "debug mode" to confirm what is the error about and we could have troubleshoot more.

prefix with "kroki-" is the pod with helm charts, but another start with "kroki-" is from kroki-k8s.zip version

$ kubectl get pod
NAME                                READY   STATUS             RESTARTS       AGE
blockdiag-7bd6c989b7-q84lv          1/1     Running            0              5m1s
bpmn-6cfccf9bc4-9s27h               1/1     Running            0              5m1s
excalidraw-5b84995fcb-mzwvk         1/1     Running            0              5m1s
kroki-6b49bcb7c4-65hw7              1/1     Running            0              13m
kroki-blockdiag-8577c6849c-hdq9s    1/1     Running            0              8m10s
kroki-bpmn-5568779f59-8f6vt         1/1     Running            0              8m10s
kroki-excalidraw-6f8b6ddcbd-kdxxp   1/1     Running            0              8m10s
kroki-kroki-789576f98-2nsr6         0/1     CrashLoopBackOff   6 (2m5s ago)   8m10s
kroki-mermaid-84f545c78c-297tr      1/1     Running            0              8m10s
mermaid-7bff5c9959-zc7cd            1/1     Running            0              5m1s

The error looks like

$ kubectl logs pod/kroki-6b49bcb7c4-wv8ft  | jq
{
  "timestamp": "1646299799996",
  "level": "ERROR",
  "thread": "vert.x-eventloop-thread-0",
  "logger": "io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer",
  "message": "Failed in deploying verticle",
  "context": "default",
  "exception": "java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')\n\tat io.vertx.core.json.JsonObject.getInteger(JsonObject.java:168)\n\tat io.vertx.core.json.JsonObject.getInteger(JsonObject.java:435)\n\tat io.kroki.server.service.Blockdiag.<init>(Blockdiag.java:37)\n\tat io.kroki.server.Server.start(Server.java:109)\n\tat io.kroki.server.Server.lambda$start$1(Server.java:65)\n\tat io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)\n\tat io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)\n\tat io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:196)\n\tat io.vertx.core.impl.future.FutureImpl.onComplete(FutureImpl.java:164)\n\tat io.vertx.config.impl.ConfigRetrieverImpl.getConfig(ConfigRetrieverImpl.java:175)\n\tat io.kroki.server.Server.start(Server.java:61)\n\tat io.vertx.core.impl.DeploymentManager.lambda$doDeploy$5(DeploymentManager.java:196)\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)\n\tat io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38)\n\tat io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)\n\tat java.base/java.lang.Thread.run(Unknown Source)\n"
}

$ echo -e "java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')\n\tat io.vertx.core.json.JsonObject.getInteger(JsonObject.java:168)\n\tat io.vertx.core.json.JsonObject.getInteger(JsonObject.java:435)\n\tat io.kroki.server.service.Blockdiag.<init>(Blockdiag.java:37)\n\tat io.kroki.server.Server.start(Server.java:109)\n\tat io.kroki.server.Server.lambda$start$1(Server.java:65)\n\tat io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)\n\tat io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)\n\tat io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:196)\n\tat io.vertx.core.impl.future.FutureImpl.onComplete(FutureImpl.java:164)\n\tat io.vertx.config.impl.ConfigRetrieverImpl.getConfig(ConfigRetrieverImpl.java:175)\n\tat io.kroki.server.Server.start(Server.java:61)\n\tat io.vertx.core.impl.DeploymentManager.lambda$doDeploy$5(DeploymentManager.java:196)\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)\n\tat io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38)\n\tat io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)\n\tat java.base/java.lang.Thread.run(Unknown Source)\n"
java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')
    at io.vertx.core.json.JsonObject.getInteger(JsonObject.java:168)
    at io.vertx.core.json.JsonObject.getInteger(JsonObject.java:435)
    at io.kroki.server.service.Blockdiag.<init>(Blockdiag.java:37)
    at io.kroki.server.Server.start(Server.java:109)
    at io.kroki.server.Server.lambda(Server.java:65)
    at io.vertx.core.impl.future.FutureImpl.onSuccess(FutureImpl.java:141)
    at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
    at io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:196)
    at io.vertx.core.impl.future.FutureImpl.onComplete(FutureImpl.java:164)
    at io.vertx.config.impl.ConfigRetrieverImpl.getConfig(ConfigRetrieverImpl.java:175)
    at io.kroki.server.Server.start(Server.java:61)
    at io.vertx.core.impl.DeploymentManager.lambda(DeploymentManager.java:196)
    at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
    at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)
    at io.vertx.core.impl.EventLoopContext.lambda-bash(EventLoopContext.java:38)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:986)
    at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Unknown Source)
teochenglim commented 2 years ago

okay. problem fixed by reading the doc https://github.com/yuzutech/kroki/blob/main/DOCKERHUB.md