V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dunhanson
V2EX  ›  Kubernetes

k8s 配置 POD 环境变量 JAVA_TOOL_OPTIONS 报错问题

  •  
  •   dunhanson · 2023-06-28 15:45:26 +08:00 · 1718 次点击
    这是一个创建于 512 天前的主题,其中的信息可能已经有所发展或是发生改变。

    shell 运行时正常的,我手动写入 /etc/profile 运行也是正常的。

    但是放在 yml 里面就报错,不想写死在 dockerfile 里面,用 yml 配置灵活些。

    shell 命令

    java -XX:+UseContainerSupport -XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=70.0 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/data/logs/moose-job/gc-$(date +'%Y-%m-%d').log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/moose-job/dump-$(date +'%Y-%m-%d').hprof -jar moose-job.jar
    

    Invalid file name for use with -Xloggc: Filename can only contain the characters [A-Z][a-z][0-9]-_.%[p|t] but it has been /data/logs/moose-job/gc-$(date
    Note %p or %t can only be used once
    Picked up JAVA_TOOL_OPTIONS: -XX:+UseContainerSupport -XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=70.0 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/data/logs/moose-job/gc-$(date +'%Y-%m-%d').log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/moose-job/dump-$(date +'%Y-%m-%d').hprof
    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.
    
    16 条回复    2023-06-29 12:19:24 +08:00
    dropdatabase
        1
    dropdatabase  
       2023-06-28 15:52:13 +08:00
    1.name: JAVA_OPTS
    value: -Xms1024m -Xmx1024m -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap

    2.java -jar $JAVA_OPTS $APP_JAR -Dfile.encoding=UTF-8 --spring.profiles.active=$1
    aru
        2
    aru  
       2023-06-28 15:53:46 +08:00
    $(date +'%Y-%m-%d')
    这种方式是不行的
    perfectlife
        3
    perfectlife  
       2023-06-28 15:59:14 +08:00
    env:
    - name: NAMESPACE
    valueFrom:
    fieldRef:
    fieldPath: metadata.namespace
    - name: POD_NAME
    valueFrom:
    fieldRef:
    fieldPath: metadata.name
    - name: POD_IP
    valueFrom:
    fieldRef:
    fieldPath: status.podIP
    - name: JAVA_TOOL_OPTIONS
    value: "-XX:MaxRAMPercentage=85.0 -XX:InitialRAMPercentage=85.0 -XX:MinRAMPercentage=85.0 -XX:MetaspaceSize=200m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dump/${POD_NAME}-$(POD_IP).hprof
    可以参考下这个
    perfectlife
        4
    perfectlife  
       2023-06-28 16:00:04 +08:00
    @dunhanson 格式问题自己调整一下
    julyclyde
        5
    julyclyde  
       2023-06-28 16:02:03 +08:00
    $()是 shell 的功能。你这里连 shell 都没有
    dunhanson
        6
    dunhanson  
    OP
       2023-06-28 16:02:34 +08:00
    @aru
    @dropdatabase 有其他方式吗
    dunhanson
        7
    dunhanson  
    OP
       2023-06-28 16:02:48 +08:00
    @perfectlife 哈哈 这个感觉可以
    dunhanson
        8
    dunhanson  
    OP
       2023-06-28 16:27:05 +08:00
    @dropdatabase
    @aru
    @perfectlife
    @julyclyde
    我发现 gc 日志不能用动态名称,dump 可以
    julyclyde
        9
    julyclyde  
       2023-06-28 16:49:08 +08:00
    @dunhanson
    你进去 ps 一下看看 java 的命令行完整内容是咋写的,是替换之前的表达式,还是之后的值
    perfectlife
        10
    perfectlife  
       2023-06-28 16:52:40 +08:00
    @dunhanson 实际上 dump 没啥用,首先要挂载一个共享存储比如 nfs 来存储 dump 文件,其次我对 oomkill 时候几个 g 的 dump 文件能否正常保存下来还是有点怀疑的 ,真排查 拿阿里的阿尔萨斯取容器里排查好点
    xx6412223
        11
    xx6412223  
       2023-06-29 09:37:27 +08:00
    command:
    - /bin/sh
    - -c
    - xxxxxx

    直接把完整的启动命令以 shell 写道 pod command 里
    tudou1514
        12
    tudou1514  
       2023-06-29 10:11:18 +08:00
    目前测试好几种后,最好的就是传脚本进容器,然后用 entrypoint 启动
    dunhanson
        13
    dunhanson  
    OP
       2023-06-29 11:33:06 +08:00
    @julyclyde
    @perfectlife
    @xx6412223
    @tudou1514
    我还是用固定名称了
    ofblyt
        14
    ofblyt  
       2023-06-29 12:04:09 +08:00
    从你的报错信息来看,主要问题在于`-Xloggc`和`-XX:HeapDumpPath`参数中的文件名,你尝试在其中使用了`$(date +'%Y-%m-%d')`这样的 Shell 变量,但这种变量并不能被 Java 虚拟机( JVM )正确地解析。

    在 Kubernetes 中,环境变量在 pod 启动时被解析,而不是在运行命令时。这就意味着,你的`$(date +'%Y-%m-%d')`并没有被替换成实际的日期,而是被原样包含在了字符串中。这就导致了你看到的“Invalid file name for use with -Xloggc”的错误。

    一种解决方法是,你可以创建一个启动脚本,这个脚本会在运行 Java 程序之前,计算出需要的日期,并将其设置为环境变量。然后,你可以在`JAVA_TOOL_OPTIONS`中使用这个环境变量。

    例如,你的启动脚本可能看起来像这样:

    ```bash
    #!/bin/sh

    export LOG_DATE=$(date +'%Y-%m-%d')
    java $JAVA_TOOL_OPTIONS -jar moose-job.jar
    ```

    然后在你的`JAVA_TOOL_OPTIONS`中,你可以使用`$LOG_DATE`,例如:

    ```bash
    -XX:HeapDumpPath=/data/logs/moose-job/dump-$LOG_DATE.hprof
    ```

    这样,`$LOG_DATE`就会在运行 Java 程序时被替换为实际的日期。

    然后,在你的 Kubernetes 配置中,你需要将启动命令更改为运行这个脚本,而不是直接运行 Java 程序。
    julyclyde
        15
    julyclyde  
       2023-06-29 12:18:37 +08:00
    @dunhanson 其实之前你选择用 shell 替换功能给 jvm 传递文件名,存在一个认知问题,就是:loggc 是否自己就支持 logrotate 功能

    如果支持,那它自己会决定文件名变更,它需要一个符号化的文件名模板,而不需要你给它传递一个(已经替换为明文的)明文文件名
    如果不支持,那你给一个明文文件名,会导致不同时刻启动的各容器内的日志文件名不同,对统一处理造成不便
    无论那种,其实都是错的做法
    julyclyde
        16
    julyclyde  
       2023-06-29 12:19:24 +08:00
    另外,不要在 profile/shell rc 里放环境变量
    我敢说绝大多数正常人都没仔细学过,这俩文件到底在什么情况下生效
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2543 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 15:41 · PVG 23:41 · LAX 07:41 · JFK 10:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.