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

Turn on JavaScript to leave a comment.

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

Please turn AdBlock off
Social Media Icons Powered by Acurax Web Design Company
Exit mobile version
%%footer%%