'Using Keytool in InitContainer
I am trying to import corporate certificate, so that Java/Spark will be correctly authorizing to access the corporate Cluster.
For this I'm building an Image in Docker and deploy it with kubernetes. I don't want to copy the file in the Dockerfile, because I think it should be a secret file. Thus I'm forcing myself to not execute keytool inside my dockerfile.
Also, I don't want to run as root my application container, in case if there is a security issue, the usee could potentially access to everything as root.
I'm trying to use an InitContainer to load the certificate. This it is a totally separate container that would run as root to execute keytool. By default it will save the new file at ~/.keystore. Since it's a separate container, it won't be find by my applicative container. So I try to change the default directory for keytool and to point it to a mounted volume.
Part of Dockerfile:
FROM Our_corporate_base_image
ENV JAVA_HOME="/opt/jdk"
ENV _JAVA_OPTIONS="-Djavax.net.ssl.keyStore=/work-dir/keystore.jks -Djavax.net.ssl.trustStore=/work-dir/truststore.jks"
USER root
WORKDIR /opt
RUN curl -L -o openjdk.tar.gz https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz \
&& mkdir jdk \
&& tar zxf openjdk.tar.gz -C jdk --strip-components=1 \
&& rm -rf openjdk.tar.gz \
&& apt-get -y --purge autoremove curl \
&& ln -sf /opt/jdk/bin/* /usr/local/bin/ \
&& rm -rf /var/lib/apt/lists/* \
&& java --version \
&& javac --version \
&& jlink --version
When building the image, it tells me the JVM does take into account my _JAVA_OPTIONS (I think I should use JAVA_TOOL_OPTIONS)
19:02:23 Picked up _JAVA_OPTIONS: -Djavax.net.ssl.keyStore=/work-dir/keystore.jks -Djavax.net.ssl.trustStore=/work-dir/truststore.jks
19:02:23 openjdk 11.0.1 2018-10-16
19:02:23 OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
19:02:23 OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
19:02:23 Picked up _JAVA_OPTIONS: -Djavax.net.ssl.keyStore=/work-dir/keystore.jks -Djavax.net.ssl.trustStore=/work-dir/truststore.jks
19:02:24 javac 11.0.1
19:02:24 Picked up _JAVA_OPTIONS: -Djavax.net.ssl.keyStore=/work-dir/keystore.jks -Djavax.net.ssl.trustStore=/work-dir/truststore.jks
19:02:24 11.0.1
/work-dir/ is a mounted volume in my app container and init container:
initContainers:
- name: "{{ k8s.deploy.name }}-init"
image: imageRepo
imagePullPolicy: "Always"
securityContext:
runAsUser: 0
command: ['/bin/bash']
args: ['-c', "env && keytool -import -alias ca-bundle -file {{ k8s.mountpath.secret }}/ca-bundle.crt -keypass changeit -storepass changeit -noprompt"]
volumeMounts:
- name: "{{ k8s.volumemounts.secret }}"
mountPath: "{{ k8s.mountpath.secret }}/"
- name: workdir
mountPath: "/work-dir"
containers:
- name: "{{ k8s.deploy.name }}-app"
image: imageRepo
imagePullPolicy: "Always"
// Lot of other stuff to set app and variables and launch a script for the app
volumeMounts:
- name: workdir
mountPath: "/work-dir"
When I deploy the solution, the Init container does launch and execute the command as root.
In kubectl I get logs saving it is at least importing the java options and the cert file:
Picked up _JAVA_OPTIONS: -Djavax.net.ssl.keyStore=/work-dir/keystore.jks -Djavax.net.ssl.trustStore=/work-dir/truststore.jks
Certificate was added to keystore
When I run a bash in the app container to keytool -list:
Picked up _JAVA_OPTIONS: -Djavax.net.ssl.keyStore=/work-dir/keystore.jks -Djavax.net.ssl.trustStore=/work-dir/truststore.jks
keytool error: java.lang.Exception: Keystore file does not exist: /home/user/.keystore
So I'm kind of confuse on how keytool works since the documentation does explicitly says that I need to modify Djavax.net.ssl.keyStore and Djavax.net.ssl.trustStore to change the default location of keytool https://docs.oracle.com/cd/E19830-01/819-4712/ablqy/index.html
Is it that my JVM does not take into account the options? I don't want to use the -keystore option in keytool to specify the location of the file while importing the cert file. Else I don't think java will load it nativly.
Should I try to mount a volume at /home/user/?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
