DevOps Classroom notes 31/Oct/2026

Install helm

choco install kubernetes-helm --version=3.3.0 -y 

helm version

Basic hel file generate

helm create demo
myapp/
├── Chart.yaml            # Chart metadata (name, version, dependencies)
├── values.yaml           # Default configuration values -- overide this file while deploying 
├── .helmignore           # Files to exclude when packaging
├── charts/               # Dependency charts (subcharts) are stored here additinal charts
└── templates/            # Kubernetes manifest templates
    ├── NOTES.txt         # Message printed after install/upgrade
    ├── _helpers.tpl      # Reusable named templates (no manifest output)
    ├── deployment.yaml
    ├── service.yaml
    ├── serviceaccount.yaml
    ├── ingress.yaml
    ├── hpa.yaml
    └── tests/
        └── test-connection.yaml

Helm template

Helm template [release name] [path folder/url] [flages]

helm create httpd # create sample chart

helm template http-app http/ # out yaml

helm install http-app http/  # install helm chart

helm upgrade http-app http/  # upgrde helm chart


helm upgrade -i http-app http/  # upgrde and install helm chart


helm upgrade http-demo httpd/ --set service.type=NodePort # override value form cmd 

helm upgrade http-demo httpd/ --values override.yaml # override values from file 

helm upgrade -i http-demo httpd/ --values override.yaml --namespace dev-1 --creat
e-namespace # create namespace if doesnot exits and deploy

Kubectl create ns frontend

helm upgrade -i http-demo httpd/ --values override.yaml --namespace frontend

Task

  1. Step nexus
#!/usr/bin/env bash
# Deploy Sonatype Nexus Repository (HTTP only) on Kubernetes using a NodePort service.
# Usage:
#   bash deploy-nexus-nodeport.sh            # install / upgrade
#   bash deploy-nexus-nodeport.sh uninstall  # remove Nexus (keeps the data volume)
#
# Optional environment variables:
#   NAMESPACE      (default: nexus)
#   NODE_PORT      (default: 30081, must be within 30000-32767)
#   STORAGE_SIZE   (default: 10Gi)
#   STORAGE_CLASS  (default: cluster default StorageClass)
#   NEXUS_IMAGE    (default: sonatype/nexus3:latest, pin a version for production)
#   TIMEOUT        seconds to wait for Nexus (default: 900)
#   NODE_IP        override the node IP shown in the final URL

# Re-run under bash if started with sh/dash (this script needs bash features)
if [ -z "${BASH_VERSION:-}" ]; then exec bash "$0" "$@"; fi

set -euo pipefail

NAMESPACE="${NAMESPACE:-nexus}"
NODE_PORT="${NODE_PORT:-30081}"
STORAGE_SIZE="${STORAGE_SIZE:-10Gi}"
STORAGE_CLASS="${STORAGE_CLASS:-}"
NEXUS_IMAGE="${NEXUS_IMAGE:-sonatype/nexus3:latest}"
TIMEOUT="${TIMEOUT:-900}"

log()  { echo -e "\n\033[1;34m==>\033[0m $*"; }
fail() { echo -e "\033[1;31mERROR:\033[0m $*" >&2; exit 1; }

# ---------- storage: install local-path provisioner if no default StorageClass ----------
ensure_default_storageclass() {
  if kubectl get storageclass -o jsonpath='{range .items[*]}{.metadata.annotations.storageclass\.kubernetes\.io/is-default-class}{"\n"}{end}' 2>/dev/null | grep -q "true"; then
    echo "Default StorageClass found."
    return 0
  fi

  log "No default StorageClass found. Installing local-path provisioner"
  if ! kubectl get storageclass local-path >/dev/null 2>&1; then
    kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.26/deploy/local-path-storage.yaml
  fi

  kubectl rollout status deployment/local-path-provisioner -n local-path-storage --timeout=180s \
    || fail "local-path provisioner did not start. Check: kubectl get pods -n local-path-storage"

  kubectl patch storageclass local-path \
    -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
  echo "local-path set as the default StorageClass."
}

# ---------- uninstall ----------
if [[ "${1:-}" == "uninstall" ]]; then
  log "Removing Nexus deployment and service from namespace '$NAMESPACE'"
  kubectl delete deployment nexus -n "$NAMESPACE" --ignore-not-found
  kubectl delete service nexus -n "$NAMESPACE" --ignore-not-found
  echo "The PVC 'nexus-data' is kept to protect your data. To delete it too, run:"
  echo "  kubectl delete pvc nexus-data -n $NAMESPACE"
  exit 0
fi

# ---------- 1. prerequisites ----------
log "Checking prerequisites"
for cmd in kubectl curl; do
  command -v "$cmd" >/dev/null 2>&1 || fail "'$cmd' is not installed"
done
kubectl cluster-info >/dev/null 2>&1 || fail "kubectl cannot reach a cluster"

if [[ -z "$STORAGE_CLASS" ]]; then
  ensure_default_storageclass
fi

# ---------- 2. namespace ----------
log "Creating namespace '$NAMESPACE'"
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - >/dev/null

# ---------- 3. storage ----------
log "Creating persistent volume claim ($STORAGE_SIZE)"
SC_LINE=""
[[ -n "$STORAGE_CLASS" ]] && SC_LINE="storageClassName: ${STORAGE_CLASS}"

kubectl apply -n "$NAMESPACE" -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nexus-data
spec:
  accessModes:
    - ReadWriteOnce
  ${SC_LINE}
  resources:
    requests:
      storage: ${STORAGE_SIZE}
EOF

# ---------- 4. deployment ----------
log "Deploying Nexus (${NEXUS_IMAGE})"
kubectl apply -n "$NAMESPACE" -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nexus
  labels:
    app: nexus
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nexus
  template:
    metadata:
      labels:
        app: nexus
    spec:
      securityContext:
        fsGroup: 200
      containers:
        - name: nexus
          image: ${NEXUS_IMAGE}
          ports:
            - name: http
              containerPort: 8081
          env:
            - name: INSTALL4J_ADD_VM_PARAMS
              value: "-Xms1g -Xmx1g -XX:MaxDirectMemorySize=1g -Djava.util.prefs.userRoot=/nexus-data/javaprefs"
          resources:
            requests:
              cpu: 500m
              memory: 2Gi
            limits:
              cpu: "2"
              memory: 3Gi
          volumeMounts:
            - name: nexus-data
              mountPath: /nexus-data
          readinessProbe:
            httpGet:
              path: /service/rest/v1/status
              port: 8081
            initialDelaySeconds: 90
            periodSeconds: 15
            timeoutSeconds: 5
            failureThreshold: 20
          livenessProbe:
            httpGet:
              path: /service/rest/v1/status
              port: 8081
            initialDelaySeconds: 300
            periodSeconds: 30
            timeoutSeconds: 10
            failureThreshold: 6
      volumes:
        - name: nexus-data
          persistentVolumeClaim:
            claimName: nexus-data
EOF

# ---------- 5. service (NodePort) ----------
log "Creating NodePort service (port ${NODE_PORT})"
kubectl apply -n "$NAMESPACE" -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nexus
  labels:
    app: nexus
spec:
  type: NodePort
  selector:
    app: nexus
  ports:
    - name: http
      port: 8081
      targetPort: 8081
      nodePort: ${NODE_PORT}
EOF

# ---------- 6. node IP ----------
if [[ -z "${NODE_IP:-}" ]]; then
  if command -v minikube >/dev/null 2>&1 && minikube status >/dev/null 2>&1; then
    NODE_IP="$(minikube ip)"
  else
    NODE_IP="$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')"
    [[ -n "$NODE_IP" ]] || NODE_IP="$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')"
  fi
fi
[[ -n "$NODE_IP" ]] || fail "Could not determine node IP. Re-run with NODE_IP=<ip>"

URL="http://${NODE_IP}:${NODE_PORT}"

# ---------- 7. wait for Nexus ----------
log "Waiting for the Nexus pod to be ready (first start takes 2 to 5 minutes)"
kubectl rollout status deployment/nexus -n "$NAMESPACE" --timeout="${TIMEOUT}s" \
  || { kubectl get pods -n "$NAMESPACE"; fail "Nexus did not become ready. Check: kubectl logs deploy/nexus -n $NAMESPACE"; }

log "Checking the HTTP endpoint"
START=$(date +%s)
until curl -fsS --max-time 5 "${URL}/service/rest/v1/status" >/dev/null 2>&1; do
  NOW=$(date +%s)
  if (( NOW - START > 180 )); then
    echo "WARNING: ${URL} is not reachable from this machine."
    echo "         The pod is ready, so check your firewall or security group for port ${NODE_PORT}."
    break
  fi
  printf "."
  sleep 5
done
echo

# ---------- 8. initial admin password ----------
ADMIN_PASS="$(kubectl exec -n "$NAMESPACE" deploy/nexus -- cat /nexus-data/admin.password 2>/dev/null || true)"

# ---------- 9. summary ----------
log "Nexus is up"
kubectl get pods,svc,pvc -n "$NAMESPACE"
cat <<EOF

--------------------------------------------------------------
 UI            : ${URL}
 Status API    : ${URL}/service/rest/v1/status
 Username      : admin
 Initial pass  : ${ADMIN_PASS:-<already changed, or run: kubectl exec -n ${NAMESPACE} deploy/nexus -- cat /nexus-data/admin.password>}
 Namespace     : ${NAMESPACE}
 Data volume   : PVC nexus-data (${STORAGE_SIZE})
--------------------------------------------------------------

Next steps:
  1. Open ${URL}, sign in as admin, and complete the setup wizard (change the password).
  2. Create repositories (Settings > Repository > Repositories).
  3. If the URL is not reachable, open NodePort ${NODE_PORT} in your firewall
     or security group.

Uninstall: bash $(basename "$0") uninstall
EOF

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Please turn AdBlock off
Animated Social Media Icons by Acurax Responsive Web Designing Company
Visit Us On FacebookVisit Us On LinkedinVisit Us On Youtube