Docker images are usually stored in docker repositories. Nexus server provides host, proxy and group type docker repositories. It can be deployed as a docker container itself with persistent storage. See https://hub.docker.com/r/sonatype/nexus3 for more info.
1. Using company PKI, generate nexus cert p12 cert for respective domain; for example, nexus.example.com
2. Store the cert passphrase in a k8s secret
kubectl create secret generic nexus-cert-pass --from-literal="password=**********"
3. Generate java keystore password and store in in k8s secret
openssl rand -base64 32 kubectl create secret generic nexus-keystore-pass --from-literal="password=******"
4. Store the nexus p12 certificate in k8s config map
kubectl create configmap nexus-cert --from-file=nexus.example.com.p12
5. Save CA certificates in k8s config map. They will later be imported into the java trusted store.
kubectl create configmap nexus-trusted-ca --from-file=nexus-trusted-ca.cert
6. Modify jetty-https.xml file from nexus and save it in k8s secret (to get the complete file, you may just run docker run -ti --rm sonatype/nexus3 bash)
... <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory"> <Set name="KeyStorePath"><Property name="ssl.etc"/>/keystore.pkcs12</Set> <Set name="KeyStorePassword">**************</Set> <Set name="KeyManagerPassword">**************</Set> <Set name="TrustStorePath"><Property name="ssl.etc"/>/truststore.pkcs12</Set> <Set name="TrustStorePassword">**************</Set> ... kubectl create secret generic jetty-https --from-file=jetty-https.xml
7. Java comes with elevated security, which needs to be lowered to work with our poor MS AD LDAP servers. So we need to overwrite two java security files with config maps
vi java.security (re-enable MD5) ... #keystore.type=jks keystore.type=pkcs12 #jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ # RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 jdk.certpath.disabledAlgorithms=MD2, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 768, EC keySize < 224 #jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 #jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024 jdk.jar.disabledAlgorithms=MD2, RSA keySize < 1024, DSA keySize < 1024 #jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \ # EC keySize < 224, 3DES_EDE_CBC, anon, NULL jdk.tls.disabledAlgorithms=RC4, DES, DH keySize < 1024, \ EC keySize < 224, anon, NULL ... vi java.config (reduce the key size back to 1024) #cat /etc/crypto-policies/back-ends/java.config #jdk.tls.ephemeralDHKeySize=2048 jdk.tls.ephemeralDHKeySize=1024 #jdk.certpath.disabledAlgorithms=MD2, MD5, DSA, RSA keySize < 2048 jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 1024 #jdk.tls.disabledAlgorithms=DH keySize < 2048, SSLv2, SSLv3, TLSv1, TLSv1.1, DHE_DSS, RSA_EXPORT, DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, DH_anon, ECDH_anon, DH_RSA, DH_DSS, ECDH, 3DES_EDE_CBC, DES_CBC, RC4_40, RC4_128, DES40_CBC, RC2, HmacMD5 jdk.tls.disabledAlgorithms=DH keySize < 1024, SSLv2, DHE_DSS, RSA_EXPORT, DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, DH_anon, ECDH_anon, DH_RSA, DH_DSS, ECDH, 3DES_EDE_CBC, DES_CBC, RC4_40, RC4_128, DES40_CBC, RC2, HmacMD5 jdk.tls.legacyAlgorithms= kubectl create configmap java-security --from-file=java.security kubectl create configmap java-config --from-file=java.config
8. Export NFS mount nexus-data owned by used/group id 200:200 - the account that nexus server runs under mount nfs_server:/export /mnt mkdir /mnt/nexus-data chown 200:200 /mnt/nexus-data
9. Create deployment manifest nexus.yaml and apply it apiVersion: v1 kind: Service metadata: name: nexus spec: selector: app: nexus ports: - port: 8443 --- apiVersion: v1 kind: Service metadata: name: docker-repo spec: type: NodePort selector: app: nexus ports: - port: 8888 nodePort: 30888 --- apiVersion: v1 kind: Service metadata: name: docker spec: type: NodePort selector: app: nexus ports: - port: 4443 nodePort: 31443 --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nexus-ssl-ingress annotations: ingress.kubernetes.io/ssl-passthrough: "true" namespace: default spec: rules: - host: nexus.example.com http: paths: - backend: serviceName: nexus servicePort: 8443 --- apiVersion: apps/v1 kind: Deployment metadata: namespace: default name: nexus labels: app: nexus spec: selector: matchLabels: app: nexus template: metadata: labels: app: nexus spec: containers: - name: nexus image: sonatype/nexus3 imagePullPolicy: IfNotPresent resources: limits: cpu: "4" memory: "8Gi" requests: cpu: "4" memory: "8Gi" ports: - containerPort: 8081 - containerPort: 8443 - containerPort: 4443 - containerPort: 8000 - containerPort: 8888 env: - name: password valueFrom: secretKeyRef: key: password name: nexus-keystore-pass optional: false - name: nexuscertpass valueFrom: secretKeyRef: key: password name: nexus-cert-pass optional: false - name: INSTALL4J_ADD_VM_PARAMS value: "-Xms1200m -Xmx1200m -XX:MaxDirectMemorySize=5g -Djava.util.prefs.userRoot=/nexus-data/javaprefs -Djavax.net.ssl.keyStore=/nexus-data/etc/ssl/keystore.pkcs12 -Djavax.net.ssl.keyStorePassword=$(password) -Djavax.net.ssl.trustStore=/nexus-data/etc/ssl/truststore.jks -Djavax.net.ssl.trustStorePassword=$(password)" args: ['sh', '-c', "if [[ ! -d /nexus-data/etc/ssl ]]; then mkdir -p /nexus-data/etc/ssl; fi && if [[ ! -d /nexus-data/tmp ]]; then mkdir /nexus-data/tmp; fi && rm -f /nexus-data/etc/ssl/*.* && keytool -importkeystore -noprompt -destkeystore /nexus-data/etc/ssl/keystore.pkcs12 -deststoretype PKCS12 -srckeystore /mnt/nexus.lat.internal.p12 -srcstoretype PKCS12 -deststorepass $password -destkeypass $password -srcstorepass $nexuscertpass && cd /nexus-data/tmp && csplit -z -f crt- /etc/pki/ca-trust/source/anchors/nexus-trusted-ca.cert '/-----BEGIN CERTIFICATE-----/' '{*}' && for file in crt-*; do keytool -import -noprompt -keystore /nexus-data/etc/ssl/truststore.jks -file $file -storepass $password -alias crt-$file; done && keytool -importkeystore -noprompt -srcstorepass $password -deststorepass $password -srckeystore /nexus-data/etc/ssl/truststore.jks -srcstoretype JKS -destkeystore /nexus-data/etc/ssl/truststore.pkcs12 -deststoretype PKCS12 && /opt/sonatype/start-nexus-repository-manager.sh"] livenessProbe: httpGet: scheme: HTTP path: / port: 8081 initialDelaySeconds: 30 timeoutSeconds: 30 volumeMounts: - name: data mountPath: /nexus-data - name: jetty-https mountPath: /opt/sonatype/nexus/etc/jetty/jetty-https.xml subPath: jetty-https.xml readOnly: true - name: nexus-cert mountPath: /mnt - name: java-security mountPath: /etc/java/java-1.8.0-openjdk/java-1.8.0-openjdk-1.8.0.232.b09-2.el8_1.x86_64/lib/security/java.security subPath: java.security readOnly: true - name: java-config mountPath: /etc/crypto-policies/back-ends/java.config subPath: java.config readOnly: true - name: nexus-trusted-ca mountPath: /etc/pki/ca-trust/source/anchors volumes: - name: data nfs: path: /export/nexus-data server: nfs_server - name: nexus-cert configMap: name: nexus-cert - name: nexus-trusted-ca configMap: name: nexus-trusted-ca - name: jetty-https secret: secretName: jetty-https - name: java-security configMap: name: java-security - name: java-config configMap: name: java-config --- kubectl apply -f nexus.yaml
10. Once the nexus is up and running, which can be confirmed by kubectl logs nexus-* -f, modify /mnt/nexus-data/nexus.properties file to allow https and reload the server
vi /mnt/nexus-data/etc/nexus.properties nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-https.xml,${jetty.etc}/jetty-requestlog.xml ssl.etc=${karaf.data}/etc/ssl application-port-ssl=8443 umount /mnt kubectl delete pod nexus-***