Custom Certificates
Familiarize yourself with the detailed instructions on adding certificates to KubeRocketCI resources as well as with the respective setup for Keycloak.
KubeRocketCI components that support custom certificates can be found in the table below:
| Helm Chart | Sub Resources |
|---|---|
| gerrit-operator | edp-gerrit |
| sonar-operator | sonar-operator, edp-sonar |
| keycloak-operator | keycloak-operator |
| nexus-operator | oauth2-proxy |
| edp-install | oauth2-proxy |
| edp-headlamp | edp-headlamp |
Prerequisitesβ
- The certificate in the
*.crtformat is used; - Kubectl version 1.28.0+ is installed. Please refer to the Kubernetes official website for details.
- Helm version 3.14.0+ is installed. Please refer to the Helm page on GitHub for details.
- Java with the
keytoolcommand inside; - jq is installed.
Enable the SPI Truststore of Keycloakβ
To import custom certificates to Keycloak, follow the steps below:
-
Generate the
cacertslocal keystore and import the certificate there using the keytool tool:keytool -importcert -file CA.crt \
-alias CA.crt -keystore ./cacerts \
-storepass changeit -trustcacerts \
-noprompt -
Create the
custom-keycloak-keystorekeystore secret from thecacertsfile in thesecuritynamespace:kubectl -n security create secret generic custom-keycloak-keystore \
--from-file=./cacerts -
Create the
spi-truststore-dataSPI truststore secret in thesecuritynamespace:kubectl -n security create secret generic spi-truststore-data \
--from-literal=KC_SPI_TRUSTSTORE_FILE_FILE=/opt/keycloak/spi-certs/cacerts \
--from-literal=KC_SPI_TRUSTSTORE_FILE_PASSWORD=changeit -
Update the Keycloak
values.yamlfile from the Install Keycloak page.values.yaml
...
extraVolumeMounts: |
...
# Use the Keycloak truststore for SPI connection over HTTPS/TLS
- name: spi-certificates
mountPath: /opt/keycloak/spi-certs
readOnly: true
...
extraVolumes: |
...
# Use the Keycloak truststore for SPI connection over HTTPS/TLS
- name: spi-certificates
secret:
secretName: custom-keycloak-keystore
defaultMode: 420
...
...
extraEnvFrom: |
- secretRef:
name: spi-truststore-data
...
Enable Custom Certificates in KubeRocketCI Componentsβ
Creating custom certificates is a necessary but not sufficient condition for applying, therefore, certificates should be enabled as well.
-
Create the
custom-ca-certificatessecret in the platform namespace (e.gkrci).kubectl -n krci create secret generic custom-ca-certificates \
--from-file=CA.crt -
Add the certificate by mounting the
custom-ca-certificatessecret to the operator pod as a volume.Example of specifying custom certificates for the
keycloak-operator:...
keycloak-operator:
enabled: true
# -- Additional volumes to be added to the pod
extraVolumes:
- name: custom-ca
secret:
defaultMode: 420
secretName: custom-ca-certificates
# -- Additional volumeMounts to be added to the container
extraVolumeMounts:
- name: custom-ca
mountPath: /etc/ssl/certs/CA.crt
readOnly: true
subPath: CA.crt
...warningBefore moving ahead, be aware that starting from version 3.3.0, our development team has officially deprecated the Jenkins deploy scenario. This means that as of version 3.3.0 and in all subsequent versions (3.3.x and above), the Jenkins deploy scenario is no longer supported.
For users running versions 3.3.x and below, the Jenkins deploy scenario remains available. However, we encourage you to plan for the transition to a supported deployment method to ensure continued compatibility and access to the latest features and enhancements. To perform migration, please familiarize yourself with the Migrate CI Pipelines From Jenkins to Tekton.
For those who still use EDP v3.3.x and below, the information below remains valid and applicable. -
For Sonar, Jenkins and Gerrit, change the flag in the
caCerts.enabledfield totrue. Also, change the name of the secret in thecaCerts.secretfield tocustom-ca-certificates.Example of specifying custom certificates for
Gerritvia thegerrit-operatorhelm chart values:...
gerrit-operator:
enabled: true
gerrit:
caCerts:
# -- Flag for enabling additional CA certificates
enabled: true
# -- Change init CA certificates container image
image: adoptopenjdk/openjdk11:alpine
# -- Name of the secret containing additional CA certificates
secret: custom-ca-certificates
...
Integrate Custom Certificates Into Jenkins Agentsβ
This section describes how to add custom certificates to Jenkins agents to use them from Java applications.
For example, curl doesn't use keystore files specified in this part of the documentation.
Jenkins agents keep keystore files in two places:
/etc/ssl/certs/javafolder with thecacertsfile;/opt/java/openjdk/lib/securityfolder with theblocked.certs,cacerts,default.policyandpublic_suffix_list.datfiles.
-
Copy the files in
/etc/ssl/certs/javaand/opt/java/openjdk/lib/securitydirectories from Jenkins agent pod to the localtmpfolder.
There is acopy_certs.shscript below that can manage this. It copies the files in/etc/ssl/certs/javaand/opt/java/openjdk/lib/securitydirectories from Jenkins agent pod to the localtmpfolder and imports the custom certificate into the keystore files, after which it creates thejenkins-agent-opt-java-openjdk-lib-security-cacertsandjenkins-agent-etc-ssl-certs-java-cacertssecrets from updated keystore files in KubeRocketCI namespace. Also, thejenkins-agent-opt-java-openjdk-lib-security-cacertssecret contains three additional files:blocked.certs,default.policyandpublic_suffix_list.datwhich managed by thecopy_certs.shscript as well. Expand the drop-down button below to see the contents of thecopy_certs.shscript.copy_certs.sh
# Fill in the variables `ns` and `ca_file`
ns="krci"
ca_file="/tmp/CA.crt"
images=$(kubectl get -n "${ns}" cm jenkins-slaves -ojson | jq -r ".data[]" | grep image\> | sed 's/\s*<.*>\(.*\)<.*>/\1/')
image=$(for i in ${images[@]}; do echo $i; done | grep maven-java8)
pod_name=$(echo "${image}" | tr '.:/' '-')
overrides="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"${pod_name}\", \"namespace\": \"${ns}\"},
\"spec\":{\"containers\":[{\"name\":\"${pod_name}\",\"image\":\"${image}\",
\"command\":[\"sh\",\"-c\",\"while true;do sleep 30;done;\"]}]}}"
kubectl run -n "${ns}" "${pod_name}" --image "${image}" --overrides="${overrides}"
kubectl wait --for=condition=ready pod "${pod_name}" -n "${ns}"
cacerts_location=$(kubectl exec -n "${ns}" "${pod_name}" \
-- find / -name cacerts -exec ls -la "{}" \; 2>/dev/null | grep -v ^l | awk '{print $9}')
for cacerts in ${cacerts_location[@]}; do echo $(dirname "${cacerts}"); kubectl exec -n "${ns}" "${pod_name}" -- ls $(dirname "${cacerts}"); done
for cacerts in ${cacerts_location[@]}; do \
echo $(dirname "${cacerts}"); \
mkdir -p "/tmp$(dirname "${cacerts}")"; \
from_files=''; \
for file in $(kubectl exec -n "${ns}" "${pod_name}" -- ls $(dirname "${cacerts}")); do \
kubectl exec -n "${ns}" "${pod_name}" -- cat "$(dirname "${cacerts}")/${file}" > "/tmp$(dirname "${cacerts}")/${file}"; \
from_files="${from_files} --from-file=/tmp$(dirname "${cacerts}")/${file}"
done ; \
keytool -import -storepass changeit -alias kubernetes -file ${ca_file} -noprompt -keystore "/tmp${cacerts}"; \
kubectl -n "${ns}" create secret generic "jenkins-agent${cacerts//\//-}" $from_files \
done
kubectl delete -n "${ns}" pod "${pod_name}" --force --grace-period=0Before using the
copy_certs.shscript, keep in mind the following:- assign actual values to the variables
nsandca_file; - the script collects all the images from the
jenkins-slavesConfigMap and uses the image of themaven-java8agent as the base image of the temporary pod to get the keystore files; - custom certificate is imported using the
keytoolapplication; - the
jenkins-agent-opt-java-openjdk-lib-security-cacertsandjenkins-agent-etc-ssl-certs-java-cacertssecrets will be created in thekrcinamespace.
- assign actual values to the variables
-
Run the
copy_certs.shscript from the previous point after the requirements are met. -
Update manually the
jenkins-slavesConfigMap.Add this block with the mount of secrets to the
<volumes></volumes>block of each Jenkins agent:...
<org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
<mountPath>/etc/ssl/certs/java</mountPath>
<secretName>jenkins-agent-etc-ssl-certs-java-cacerts</secretName>
</org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
<org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
<mountPath>/opt/java/openjdk/lib/security</mountPath>
<secretName>jenkins-agent-opt-java-openjdk-lib-security-cacerts</secretName>
</org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
...As an example, the template of
gradle-java11-templateis shown below:...
</workspaceVolume>
<volumes>
<org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
<mountPath>/etc/ssl/certs/java</mountPath>
<secretName>jenkins-agent-etc-ssl-certs-java-cacerts</secretName>
</org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
<org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
<mountPath>/opt/java/openjdk/lib/security</mountPath>
<secretName>jenkins-agent-opt-java-openjdk-lib-security-cacerts</secretName>
</org.csanchez.jenkins.plugins.kubernetes.volumes.SecretVolume>
</volumes>
<containers>
... -
Reload the Jenkins pod:
ns="krci"
kubectl rollout restart -n "${ns}" deployment/jenkins