如何在Helm Values文件中访问Dockerfile定义的环境变量并追加参数
我已在Dockerfile中定义了带有默认值的CATALINA_OPTS并构建了Docker镜像。使用Helm Chart部署到Kubernetes集群时,发现无法向CATALINA_OPTS追加额外选项,只能在Helm Values文件中完全覆盖该变量。
Dockerfile代码:
ENV CATALINA_OPTS="$CATALINA_OPTS -XshowSettings:vm \ --add-opens=java.base/java.io=ALL-UNNAMED \ --add-opens=java.base/java.lang.invoke=ALL-UNNAMED \ --add-opens=java.base/java.lang.reflect=ALL-UNNAMED"
Helm Values文件代码:
envVars: - name: CATALINA_OPTS value: "$CATALINA_OPTS -XX:+UseG1GC \ -XX:+UnlockExperimentalVMOptions \ -XX:InitialRAMPercentage=60.0 \ -XX:MinRAMPercentage=60.0 \ -XX:MaxRAMPercentage=60.0"
错误信息:
Error: Could not find or load main class ${CATALINA_OPTS} Caused by: java.lang.ClassNotFoundException: ${CATALINA_OPTS} Could not load Logmanager "org.apache.juli.ClassLoaderLogManager" java.lang.ClassNotFoundException: org.apache.juli.ClassLoaderLogManager
已确认Shell脚本字符串拼接无法在Helm Values文件中使用,Helm模板在容器启动前处理,目前似乎只能完全覆盖。请问如何在Helm Values文件中访问Dockerfile定义的环境变量并追加额外JVM参数?
方法一:通过Shell启动命令拼接变量
Kubernetes直接设置环境变量时,$CATALINA_OPTS不会被Shell解析(容器默认直接执行启动命令而非Shell)。可以修改Helm Deployment模板,用Shell执行启动逻辑,实现变量拼接:
在Deployment模板中调整容器的command和args:
containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" command: ["sh", "-c"] args: - | CATALINA_OPTS="$CATALINA_OPTS {{ .Values.catalinaOptsExtra }}" exec catalina.sh run
对应的Helm Values仅需定义额外参数:
catalinaOptsExtra: "-XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:InitialRAMPercentage=60.0 -XX:MinRAMPercentage=60.0 -XX:MaxRAMPercentage=60.0"
启动时Shell会先读取Dockerfile中定义的CATALINA_OPTS默认值,再追加额外参数,最后执行Tomcat启动命令。
方法二:在Dockerfile中预留追加参数的环境变量
在Dockerfile中新增一个用于存储额外参数的环境变量,再通过Tomcat的启动脚本合并两个变量:
修改Dockerfile:
ENV CATALINA_OPTS="$CATALINA_OPTS -XshowSettings:vm \ --add-opens=java.base/java.io=ALL-UNNAMED \ --add-opens=java.base/java.lang.invoke=ALL-UNNAMED \ --add-opens=java.base/java.lang.reflect=ALL-UNNAMED" ENV CATALINA_OPTS_EXTRA="" # 将变量合并逻辑写入Tomcat的setenv.sh RUN echo 'CATALINA_OPTS="$CATALINA_OPTS $CATALINA_OPTS_EXTRA"' >> ${CATALINA_HOME}/bin/setenv.sh
然后在Helm Values中仅设置额外参数变量:
envVars: - name: CATALINA_OPTS_EXTRA value: "-XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:InitialRAMPercentage=60.0 -XX:MinRAMPercentage=60.0 -XX:MaxRAMPercentage=60.0"
Tomcat启动时会自动加载setenv.sh,完成两个变量的合并。
方法三:在Helm模板中直接合并默认值与额外参数
如果默认参数变动频率低,可以在Helm模板中同步Dockerfile里的默认值,直接拼接额外参数:
在Deployment模板中定义环境变量:
containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" env: - name: CATALINA_OPTS value: "-XshowSettings:vm --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED {{ .Values.catalinaOptsExtra }}"
Values文件中定义额外参数:
catalinaOptsExtra: "-XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:InitialRAMPercentage=60.0 -XX:MinRAMPercentage=60.0 -XX:MaxRAMPercentage=60.0"
这种方式无需修改Dockerfile,但需要在Helm模板中维护默认参数的同步。
内容的提问来源于stack exchange,提问作者nayakam

