2

I have a K3s cluster with system pods (i.e. kube-system namespace) and my application pods:

kube-system   pod/calico-node-xxxx                          
kube-system   pod/calico-kube-controllers-xxxxxx   
kube-system   pod/metrics-server-xxxxx
kube-system   pod/local-path-provisioner-xxxxx
kube-system   pod/coredns-xxxxx
app-system    pod/my-app-xxxx
db-system     pod/my-db-xxxxx

I am looking for a shell/kubectl command (for automation script) that can delete my application namespace (want to modify kubectl delete namespace app-system db-system) without mentioning the app namespaces name in the command (as in future if more app namespace would come in cluster, I have to edit this script every time).

That means I want to delete all namespace in cluster except kube-system

something like - kubectl delete namespace -v kube-system (I know -v is not a valid parameter here, just showing how in grep -v is used to except the following words. Similar thing looking for kubectl delete ns... )

solveit
  • 255
  • 2
  • 11
  • 1
    You can write a wrapper yourself something like: `{ read -r; while read -r ns _; do [[ $ns == *kube-system* ]] && continue ; echo "$ns"; done ;} < <(kubectl get namespaces)` If the result looks good you can then change `echo` to `kubectl delete "$ns"` – Valentin Bajrami Sep 02 '21 at 14:29

3 Answers3

4

I've created the following code , so you can use it as a wrapper. You can name the script whatever you want. For example exclude_ns_removal

#!/usr/bin/env bash

die () 
{ 
    echo "$@" 1>&2
    exit 1
}

usage () 
{ 
    echo "usage: $0 [-h] [-v namespace_to_ignore] " 1>&2
    exit 0
}

inarray () 
{ 
    local n=$1 h
    shift
    for h in "$@"
    do
        [[ $n = "$h" ]] && return
    done
    return 1
}

while getopts ":v:h" opt; do
    case $opt in 
        h)
            usage
        ;;
        v)
            case $OPTARG in 
                '' | *[0-9]*)
                    die "Digits not allowed $OPTARG"
                ;;
                *)
                    val=$OPTARG
                ;;
            esac
        ;;
        :)
            die "argument needed to -$OPTARG"
        ;;
        *)
            die "invalid switch -$OPTARG"
        ;;
    esac
done

shift $((OPTIND - 1))

while IFS='/' read -r _ ns; do
    a+=("$ns")
done < <(kubectl get namespaces --no-headers -o name)

if inarray "$val" "${a[@]}"; then
    unset 'a'
    { 
        while IFS='/' read -r _ ns; do
            a+=("$ns")
            for i in "${!a[@]}"
            do
                if [[ ${a[i]} == $val ]]; then
                    unset 'a[i]'
                fi
            done
        done
    } < <(kubectl get namespaces --no-headers -o name)

    printf '%s\n\n' "Excluding ... $val"
    for namespace in "${a[@]}"
    do
        printf 'Deleting ... %s\n' "$namespace"
    done
else
    die "No namespace found"
fi

Make the script executable:

chmod u+x exclude_ns_removal

Run it as follows:

./exclude_ns_removal -v kube-system

The result will be something like:

Excluding ... kube-system

Deleting ... app-system
Deleting ... db-system

If the output looks good, you should modify this line

printf 'Deleting ... %s\n' "$namespace"

to

kubectl delete namespace "$namespace"
Valentin Bajrami
  • 3,870
  • 1
  • 17
  • 25
2

May be simpler than the previous answers -- writing scripts or loops here is overkill, kubernetes does it all for you:

kubectl label ns foo=bar --all
kubectl label ns kube-system foo-
kubectl delete ns --selector foo=bar
SYN
  • 1,751
  • 8
  • 14
  • I do agree that the script is an overkill for just this simple task. The question was to somehow mimic `grep -v` functionality. Also the script offers more flexibility, does check if a `namespace` exists and can be expanded for more functionality. – Valentin Bajrami Sep 05 '21 at 20:47
  • Using labels, you wouldn't have to check a namespace exists though. – SYN Sep 08 '21 at 08:17
1

That's a lot for something that could be solved with

for i in `k get ns -o name | grep -v kube-system`; do
k delete $i;
done
Dave M
  • 4,494
  • 21
  • 30
  • 30