Installing Nexus on Kubernetes

Installing sonatype nexus on Kubernetes with a Persistent volume.

 

Prerequisites

 

  • NFS server
  • Internet connection

 

Create persistent volume

Make sure your NFS server is exporting the /data/k8s-pvs/pv015 directory and that all cluster nodes can reach the NFS server network wise.

apiVersion: v1
kind: PersistentVolume
metadata:
 name: nexuspv
spec:
 capacity:
   storage: 100Gi
 volumeMode: Filesystem
 accessModes:
   - ReadWriteOnce
 persistentVolumeReclaimPolicy: Retain
 storageClassName: slow
 mountOptions:
   - hard
   - nfsvers=4.1
 nfs:
   path: /data/k8s-pvs/pv015
   server: nfsserver.example.com

 

 

Note: The above yaml can be changed and edited for example:

  • The nfs server name (nfsserver.example.com) should point to the hostname or IP of your NFS server
  • Name: nexuspv can be any name for the persistent volume.
  • Storage capacity can be edited (100Gi in the example above)

Deploy Nexus

Now it’s time to deploy the nexus deployment, services (admin and docker repo) and ingress objects.

 

Kubectl apply -f  the following file:

apiVersion: v1
kind: List
metadata:
items:
- apiVersion: v1
  kind: Namespace
  metadata:
    name: infraproject      
  spec:
    finalizers:
    - kubernetes
- apiVersion: v1
  kind: PersistentVolumeClaim
  metadata:
    name: nexuspvc
    namespace: infraproject
  spec:
    accessModes:
      - ReadWriteOnce
    volumeMode: Filesystem
    resources:
      requests:
        storage: 80Gi
    storageClassName: slow
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    namespace: infraproject
    labels:
      app: nexus
    name: nexus
  spec:
    progressDeadlineSeconds: 600
    replicas: 1
    revisionHistoryLimit: 10
    selector:
      matchLabels:
        app: nexus
    strategy:
      type: Recreate
    template:
      metadata:
        creationTimestamp: null
        labels:
          app: nexus
      spec:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
              - matchExpressions:
                - key: node-role.kubernetes.io/master
                  operator: DoesNotExist
        containers:
        - image: sonatype/nexus3
          imagePullPolicy: Always
          name: nsqlookupd
          ports:
          - containerPort: 5000
            protocol: TCP
          - containerPort: 8081
            protocol: TCP
          - containerPort: 8082
            protocol: TCP
          resources:
            limits:
              cpu: "4"
              memory: 2500Mi
            requests:
              cpu: 500m
              memory: 1000Mi
          volumeMounts:
          - mountPath: "nexus-data"
            name: nexusvol
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
        volumes:
          - name: nexusvol
            persistentVolumeClaim:
             claimName: nexuspvc
        dnsPolicy: ClusterFirst
        restartPolicy: Always
        schedulerName: default-scheduler
        securityContext: {}
        terminationGracePeriodSeconds: 30
- apiVersion: v1
  kind: Service
  metadata:
    labels:
      app: nexus
    name: nexus
    namespace: infraproject
  spec:
    ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 8081
    selector:
      app: nexus
- apiVersion: v1
  kind: Service
  metadata:
    labels:
      app: docker
    name: docker
    namespace: infraproject
  spec:
    ports:
    - name: docker
      port: 5000
      protocol: TCP
      targetPort: 5000
    selector:
      app: nexus

- apiVersion: networking.k8s.io/v1beta1
  kind: Ingress
  metadata:
    namespace: infraproject
    name: nexusdocker
    annotations:
      # use the shared ingress-nginx
      kubernetes.io/ingress.class: "nginx"
      nginx.ingress.kubernetes.io/proxy-body-size: 8g
  spec:
    rules:
    - host: images.example.com
      http:
        paths:
        - backend:
            serviceName: docker
            servicePort: 5000
- apiVersion: networking.k8s.io/v1beta1
  kind: Ingress
  metadata:
    namespace: infraproject
    name: nexusadmin
    annotations:
      # use the shared ingress-nginx
      kubernetes.io/ingress.class: "nginx"
  spec:
    rules:
    - host: nexus.example.com
      http:
        paths:
        - backend:
            serviceName: nexus
            servicePort: 80

 

 

 

Note: Port 5000 can be used to have access to a docker repository through a nexus repo connector:

Troubleshooting

After deployment you make sure you have successfuly created a persistent volume:

 

Kubectl get pv

 

Look for the name of the persistent volume you created

 

Make sure that a persistent volume claim is bound to the persistent volume:

 

Kubectl get pvc -n <your namespace name>