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
- 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