chore: 清理调试脚本并收敛到 Ansible 流程

移除已废弃的调试/验证脚本与空目录,统一文档与脚本说明到 ansible-playbook 的部署方式,避免失效引用和误用路径。

Made-with: Cursor
This commit is contained in:
2026-03-23 19:18:55 +08:00
parent 8a54cac61f
commit be97836e0d
92 changed files with 3463 additions and 4855 deletions

View File

@@ -0,0 +1,287 @@
#!/usr/bin/env bash
# 按「集群里实际存在的资源」遍历删除(全部由 kubectl 发现,不读仓库 YAML 目录)
# 在任意目录执行均可;建议在仓库根:./scripts/k3s-delete-lab-stacks.sh [选项]
#
# 默认跳过系统命名空间kube-system、kube-public、kube-node-lease
# 每个命名空间内会跳过 Service/kubernetesAPI 内置 Service
# 可选PVC / ConfigMap / Secret默认不删 Secret避免误伤账号 token
#
# 环境kubectl 可用export KUBECONFIG=... 按需设置
set -euo pipefail
DRY_RUN=false
YES=false
PREVIEW_ONLY=false
INCLUDE_KUBE_SYSTEM=false
WITH_PVC=false
WITH_CONFIGMAPS=false
WITH_SECRETS=false
# 空 = 自动枚举「非系统」命名空间;非空 = 仅处理列出的 NS逗号分隔
NAMESPACES_ARG=""
usage() {
cat <<'EOF'
用法: k3s-delete-lab-stacks.sh [选项]
按 kubectl 当前集群中已部署的资源逐项删除(常见工作负载 + Ingress/IngressRoute 等)。
不依赖本仓库 ansible/files 目录。
选项:
--preview 只列出将参与删除的命名空间及各资源kubectl get不执行删除
--dry-run 删除时使用 kubectl 的 --dry-run=client不落库部分环境仍会做校验
-y, --yes 跳过确认
--namespaces NS[,NS...]
只处理这些命名空间(仍受 --include-kube-system 与系统 NS 规则约束)
--include-kube-system
也处理 kube-system极危险可能拆掉 Traefik/Coredns 等)
--with-pvc 删除 PersistentVolumeClaim数据卷默认不删
--with-configmaps 删除 ConfigMap会跳过 kube-root-ca.crt
--with-secrets 删除 Secret会跳过 default-token-* 及 type=kubernetes.io/service-account-token
-h, --help 帮助
示例:
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
./scripts/k3s-delete-lab-stacks.sh --preview
./scripts/k3s-delete-lab-stacks.sh --namespaces default -y
./scripts/k3s-delete-lab-stacks.sh --dry-run -y
EOF
exit 0
}
ARGS=("$@")
i=0
while [[ $i -lt ${#ARGS[@]} ]]; do
case "${ARGS[$i]}" in
--dry-run) DRY_RUN=true ;;
-y|--yes) YES=true ;;
--preview) PREVIEW_ONLY=true ;;
--include-kube-system) INCLUDE_KUBE_SYSTEM=true ;;
--with-pvc) WITH_PVC=true ;;
--with-configmaps) WITH_CONFIGMAPS=true ;;
--with-secrets) WITH_SECRETS=true ;;
-h|--help) usage ;;
--namespaces)
i=$((i + 1))
if [[ $i -ge ${#ARGS[@]} ]]; then echo "[ERROR] --namespaces 需要参数" >&2; exit 1; fi
NAMESPACES_ARG="${ARGS[$i]}"
;;
*)
echo "[ERROR] 未知参数: ${ARGS[$i]},使用 -h 查看帮助" >&2
exit 1
;;
esac
i=$((i + 1))
done
if ! command -v kubectl &>/dev/null; then
echo "[ERROR] 未找到 kubectl" >&2
exit 1
fi
KUBECTL_DELETE=(kubectl delete)
if [[ "${DRY_RUN}" == true ]]; then
KUBECTL_DELETE=(kubectl delete --dry-run=client)
fi
# 系统命名空间:默认不扫(除非 --include-kube-system 且用户未用 --namespaces 限制)
SYSTEM_NS="kube-system kube-public kube-node-lease"
is_system_ns() {
local n="$1"
for s in ${SYSTEM_NS}; do
[[ "${n}" == "${s}" ]] && return 0
done
return 1
}
collect_namespaces() {
if [[ -n "${NAMESPACES_ARG}" ]]; then
IFS=',' read -r -a arr <<< "${NAMESPACES_ARG}"
for raw in "${arr[@]}"; do
n="${raw//[[:space:]]/}"
[[ -z "${n}" ]] && continue
if ! is_system_ns "${n}" || [[ "${INCLUDE_KUBE_SYSTEM}" == true ]]; then
echo "${n}"
else
echo "[WARN] 已忽略系统命名空间(加 --include-kube-system 可处理): ${n}" >&2
fi
done
return
fi
local all
all=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
while IFS= read -r n; do
[[ -z "${n}" ]] && continue
if is_system_ns "${n}" && [[ "${INCLUDE_KUBE_SYSTEM}" != true ]]; then
continue
fi
echo "${n}"
done <<< "${all}"
}
# 若 kind 在当前集群不存在,静默跳过
list_kind_in_ns() {
local ns="$1"
local kind="$2"
kubectl get "${kind}" -n "${ns}" -o name 2>/dev/null || true
}
preview_kind_in_ns() {
local ns="$1"
local kind="$2"
if kubectl get "${kind}" -n "${ns}" &>/dev/null; then
echo "===== ${ns} / ${kind} ====="
kubectl get "${kind}" -n "${ns}" -o wide 2>/dev/null || true
fi
}
# 删除某 kind 在 ns 下 kubectl -o name 列出的所有资源
delete_kind_all_by_name() {
local ns="$1"
local kind="$2"
local line name
while IFS= read -r line; do
[[ -z "${line}" ]] && continue
# line 形如 deployment.apps/foo 或 pod/bar
name="${line##*/}"
echo "[DEL] ${line} -n ${ns}"
"${KUBECTL_DELETE[@]}" "${line}" -n "${ns}" --ignore-not-found || true
done < <(list_kind_in_ns "${ns}" "${kind}")
}
delete_services_safe() {
local ns="$1"
local names
names=$(kubectl get svc -n "${ns}" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null || true)
while IFS= read -r n; do
[[ -z "${n}" ]] && continue
[[ "${n}" == "kubernetes" ]] && continue
echo "[DEL] service/${n} -n ${ns}"
"${KUBECTL_DELETE[@]}" "svc" "${n}" -n "${ns}" --ignore-not-found || true
done <<< "${names}"
}
delete_configmaps_safe() {
local ns="$1"
local cm
while IFS= read -r cm; do
[[ -z "${cm}" ]] && continue
[[ "${cm}" == "kube-root-ca.crt" ]] && continue
echo "[DEL] configmap/${cm} -n ${ns}"
"${KUBECTL_DELETE[@]}" "configmap" "${cm}" -n "${ns}" --ignore-not-found || true
done < <(kubectl get configmap -n "${ns}" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null || true)
}
delete_secrets_safe() {
local ns="$1"
if ! command -v jq &>/dev/null; then
echo "[WARN] 未安装 jq无法安全过滤 Secret已跳过 ${ns}" >&2
return 0
fi
local names
names=$(kubectl get secret -n "${ns}" -o json 2>/dev/null | jq -r '
.items[]?
| select(.type != "kubernetes.io/service-account-token")
| select(.metadata.name | test("^default-token-") | not)
| .metadata.name' 2>/dev/null || true)
while IFS= read -r sn; do
[[ -z "${sn}" ]] && continue
echo "[DEL] secret/${sn} -n ${ns}"
"${KUBECTL_DELETE[@]}" "secret" "${sn}" -n "${ns}" --ignore-not-found || true
done <<< "${names}"
}
# Traefik / 扩展:不存在则 list 为空
TRAEFIK_KINDS=(ingressroute middleware tlsoption traefikservice serverstransport)
process_namespace() {
local ns="$1"
if [[ "${PREVIEW_ONLY}" == true ]]; then
echo "######## 命名空间: ${ns} ########"
for k in cronjob job deployment statefulset daemonset ingress networkpolicy horizontalpodautoscaler hpa \
"${TRAEFIK_KINDS[@]}" service pvc configmap secret; do
preview_kind_in_ns "${ns}" "${k}" || true
done
return
fi
echo "######## 删除: ${ns} ########"
# 1) 定时与任务
delete_kind_all_by_name "${ns}" "cronjob"
delete_kind_all_by_name "${ns}" "job"
# 2) 路由Traefik CRD 可能未装list 为空)
delete_kind_all_by_name "${ns}" "ingress"
for tk in "${TRAEFIK_KINDS[@]}"; do
delete_kind_all_by_name "${ns}" "${tk}"
done
# 3) 工作负载
delete_kind_all_by_name "${ns}" "deployment"
delete_kind_all_by_name "${ns}" "statefulset"
delete_kind_all_by_name "${ns}" "daemonset"
delete_kind_all_by_name "${ns}" "replicaset"
# 4) 其它常见附属(不主动删 Pod由上层负载级联回收避免误伤系统静态 Pod
delete_kind_all_by_name "${ns}" "networkpolicy"
delete_kind_all_by_name "${ns}" "horizontalpodautoscaler"
delete_kind_all_by_name "${ns}" "hpa"
# 5) Service保留 kubernetes
delete_services_safe "${ns}"
# 6) PVC
if [[ "${WITH_PVC}" == true ]]; then
delete_kind_all_by_name "${ns}" "persistentvolumeclaim"
fi
if [[ "${WITH_CONFIGMAPS}" == true ]]; then
delete_configmaps_safe "${ns}"
fi
if [[ "${WITH_SECRETS}" == true ]]; then
if command -v jq &>/dev/null; then
delete_secrets_safe "${ns}"
else
echo "[WARN] ${ns}: 未安装 jq已跳过 --with-secrets" >&2
fi
fi
}
NS_LIST=()
while IFS= read -r _ns; do
[[ -z "${_ns}" ]] && continue
NS_LIST+=("${_ns}")
done < <(collect_namespaces | sort -u)
if [[ ${#NS_LIST[@]} -eq 0 ]]; then
echo "[ERROR] 没有可处理的命名空间(检查 --namespaces / 集群连接)" >&2
exit 1
fi
if [[ -n "${KUBECONFIG:-}" ]]; then
echo "[INFO] KUBECONFIG=${KUBECONFIG}"
else
echo "[INFO] KUBECONFIG 未设置,使用 kubectl 默认配置"
fi
echo "[INFO] 命名空间 (${#NS_LIST[@]}): ${NS_LIST[*]}"
echo "[INFO] include-kube-system=${INCLUDE_KUBE_SYSTEM} with-pvc=${WITH_PVC} with-configmaps=${WITH_CONFIGMAPS} with-secrets=${WITH_SECRETS} preview=${PREVIEW_ONLY} dry-run=${DRY_RUN}"
if [[ "${PREVIEW_ONLY}" != true && "${YES}" != true && "${DRY_RUN}" != true ]]; then
echo "[WARN] 将按上述命名空间删除工作负载与路由等资源(见脚本内顺序)。输入 yes 继续:"
read -r confirm
if [[ "${confirm}" != "yes" ]]; then
echo "已取消"
exit 1
fi
fi
for ns in "${NS_LIST[@]}"; do
process_namespace "${ns}"
done
echo "[DONE] 完成"