Created
July 10, 2025 14:52
-
-
Save corbtastik/0e23ff3c7185946018de00ed24338407 to your computer and use it in GitHub Desktop.
Bash script to install kind on podman for MacOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
# =========[ Configurable Environment Variables ]========= | |
PODMAN_MACHINE_NAME="${PODMAN_MACHINE_NAME:-podman-machine-default}" | |
CLUSTER_NAME="podman-kind" | |
KIND_CONFIG_FILE="kind-podman.yaml" | |
KIND_NODE_IMAGE="kindest/node:v1.29.1" | |
EXTRA_PORT_RANGE="${EXTRA_PORT_RANGE:-30000-30010}" | |
KIND_HOST_VOLUME_DIR="${KIND_HOST_VOLUME_DIR:-$HOME/kind-volumes/mongodb}" # Host path to persist MongoDB | |
# =========[ Dependency Check ]========= | |
function check_dependencies() { | |
echo "π§ Checking dependencies..." | |
for cmd in podman kind kubectl; do | |
if ! command -v $cmd &>/dev/null; then | |
echo "β '$cmd' is not installed. Please run: brew install $cmd" | |
exit 1 | |
fi | |
done | |
} | |
# =========[ Kind Config Generation ]========= | |
function setup_kind_config() { | |
echo "π Writing kind config to '$KIND_CONFIG_FILE'..." | |
# Ensure host volume path exists | |
echo "π Ensuring host volume path exists: $KIND_HOST_VOLUME_DIR" | |
mkdir -p "$KIND_HOST_VOLUME_DIR" | |
# Parse extra port mappings | |
PORT_MAPPINGS="" | |
IFS='-' read -r START_PORT END_PORT <<< "$EXTRA_PORT_RANGE" | |
for (( PORT=START_PORT; PORT<=END_PORT; PORT++ )); do | |
PORT_MAPPINGS+=" | |
- containerPort: $PORT | |
hostPort: $PORT | |
protocol: TCP" | |
done | |
cat > "$KIND_CONFIG_FILE" <<EOF | |
kind: Cluster | |
apiVersion: kind.x-k8s.io/v1alpha4 | |
networking: | |
disableDefaultCNI: false | |
ipFamily: ipv4 | |
apiServerAddress: "0.0.0.0" | |
nodes: | |
- role: control-plane | |
image: $KIND_NODE_IMAGE | |
extraPortMappings: | |
- containerPort: 80 | |
hostPort: 8080 | |
protocol: TCP | |
- containerPort: 80 | |
hostPort: 8081 | |
protocol: TCP | |
- containerPort: 27017 | |
hostPort: 27017 | |
protocol: TCP$PORT_MAPPINGS | |
extraMounts: | |
- hostPath: $(realpath "$KIND_HOST_VOLUME_DIR") | |
containerPath: /data/kind/mongodb | |
- role: worker | |
image: $KIND_NODE_IMAGE | |
extraMounts: | |
- hostPath: $(realpath "$KIND_HOST_VOLUME_DIR") | |
containerPath: /data/kind/mongodb | |
EOF | |
} | |
# =========[ Cluster Setup ]========= | |
function setup_cluster() { | |
check_dependencies | |
echo "π Initializing podman machine: $PODMAN_MACHINE_NAME" | |
if ! podman machine list | grep "$PODMAN_MACHINE_NAME.*running"; then | |
if ! podman machine list | grep "$PODMAN_MACHINE_NAME"; then | |
podman machine init --cpus 4 --memory 4096 --name "$PODMAN_MACHINE_NAME" | |
fi | |
podman machine start "$PODMAN_MACHINE_NAME" | |
else | |
echo "β Podman machine '$PODMAN_MACHINE_NAME' already running." | |
fi | |
echo "π± Setting KIND_EXPERIMENTAL_PROVIDER=podman..." | |
export KIND_EXPERIMENTAL_PROVIDER=podman | |
setup_kind_config | |
echo "π§Ή Deleting existing cluster (if any)..." | |
kind delete cluster --name "$CLUSTER_NAME" || true | |
echo "π οΈ Creating kind cluster with Podman..." | |
kind create cluster --name "$CLUSTER_NAME" --config "$KIND_CONFIG_FILE" | |
echo "π·οΈ Labeling control-plane node for Ingress..." | |
kubectl label node "$CLUSTER_NAME-control-plane" ingress-ready=true --overwrite | |
echo "π Verifying cluster..." | |
kubectl cluster-info --context kind-$CLUSTER_NAME | |
kubectl get nodes | |
setup_nginx_ingress | |
echo "β Cluster is ready with Ingress and persistent MongoDB volume!" | |
echo "π Ingress test: http://localhost:8081" | |
echo "π MongoDB access: mongodb://localhost:27017" | |
echo "πΎ MongoDB volume (host): $KIND_HOST_VOLUME_DIR" | |
} | |
# =========[ Ingress Setup ]========= | |
function setup_nginx_ingress() { | |
echo "π Installing NGINX Ingress Controller..." | |
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/kind/deploy.yaml | |
echo "β³ Waiting for Ingress controller to be ready..." | |
kubectl wait --namespace ingress-nginx \ | |
--for=condition=ready pod \ | |
--selector=app.kubernetes.io/component=controller \ | |
--timeout=120s | |
} | |
# =========[ Teardown ]========= | |
function teardown_cluster() { | |
echo "𧨠Deleting kind cluster named '$CLUSTER_NAME'..." | |
kind delete cluster --name "$CLUSTER_NAME" || echo "β οΈ Kind cluster not found." | |
echo "π§Ό Stopping Podman machine '$PODMAN_MACHINE_NAME'..." | |
if podman machine list | grep "$PODMAN_MACHINE_NAME.*running"; then | |
podman machine stop "$PODMAN_MACHINE_NAME" | |
fi | |
read -p "ποΈ Do you want to **delete the Podman VM** '$PODMAN_MACHINE_NAME'? (yes/no): " CONFIRM | |
if [[ "$CONFIRM" == "yes" ]]; then | |
echo "π₯ Deleting Podman VM..." | |
podman machine rm -f "$PODMAN_MACHINE_NAME" | |
echo "β Podman VM '$PODMAN_MACHINE_NAME' removed." | |
else | |
echo "β Podman VM left intact." | |
fi | |
echo "β Teardown complete." | |
} | |
# =========[ Connect ]========= | |
function connect() { | |
echo "π Connecting to MongoDB via port-forward..." | |
MONGO_USER="${MONGO_USER:-root}" | |
MONGO_PASS="${MONGO_PASS:-example}" | |
AUTH_DB="${AUTH_DB:-admin}" | |
NAMESPACE="mongodb" | |
SERVICE_NAME="mongodb" | |
LOCAL_PORT=27017 | |
if ! kubectl get svc "$SERVICE_NAME" -n "$NAMESPACE" &>/dev/null; then | |
echo "β MongoDB service '$SERVICE_NAME' not found in namespace '$NAMESPACE'." | |
exit 1 | |
fi | |
echo "π Starting port-forward on localhost:$LOCAL_PORT..." | |
kubectl port-forward svc/"$SERVICE_NAME" $LOCAL_PORT:$LOCAL_PORT -n "$NAMESPACE" >/tmp/mongo-pf.log 2>&1 & | |
PF_PID=$! | |
cleanup() { | |
echo "π Stopping port-forward (PID $PF_PID)..." | |
kill "$PF_PID" >/dev/null 2>&1 || true | |
} | |
trap cleanup EXIT | |
# Wait for readiness | |
for i in {1..10}; do | |
if nc -z localhost $LOCAL_PORT; then | |
break | |
fi | |
sleep 1 | |
done | |
echo "π Verifying MongoDB connection via mongosh..." | |
mongosh "mongodb://$MONGO_USER:$MONGO_PASS@localhost:$LOCAL_PORT/?authSource=$AUTH_DB" --quiet <<EOF | |
db.runCommand({ ping: 1 }) | |
EOF | |
echo "β Connection verified!" | |
} | |
# =========[ Help ]========= | |
function show_help() { | |
cat <<EOF | |
π§° Usage: $0 [command] | |
Commands: | |
setup Create a kind cluster using Podman CLI on macOS with Ingress and MongoDB volume | |
teardown Delete the kind cluster and optionally remove the Podman VM\ | |
connect Port-forward MongoDB to localhost and verify connection via mongosh | |
help Show this help message | |
Environment Variables: | |
PODMAN_MACHINE_NAME Name of the Podman VM (default: podman-machine-default) | |
EXTRA_PORT_RANGE Extra NodePort range to expose (default: 30000-30010) | |
KIND_HOST_VOLUME_DIR Host directory for MongoDB volume (default: ~/kind-volumes/mongodb) | |
Access: | |
- Ingress β http://localhost:8081 | |
- MongoDB β mongodb://localhost:27017 | |
- MongoDB data β persisted at \$KIND_HOST_VOLUME_DIR | |
Examples: | |
KIND_HOST_VOLUME_DIR=~/data/mongo ./kind-podman-tool.sh setup | |
PODMAN_MACHINE_NAME=devbox ./kind-podman-tool.sh setup | |
EOF | |
} | |
# =========[ Entry Point ]========= | |
case "$1" in | |
setup) | |
setup_cluster | |
;; | |
teardown) | |
teardown_cluster | |
;; | |
help|"") | |
show_help | |
;; | |
connect|"") | |
connect | |
;; | |
*) | |
echo "β Unknown command: '$1'" | |
show_help | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment