#!/usr/bin/env bash
set -euo pipefail
# =========================
# 按需修改
# =========================
NAMESPACE="${NAMESPACE:-project-a}"
ACCOUNT="${ACCOUNT:-project-a-admin}"
KUBECONFIG_OUT="${KUBECONFIG_OUT:-${ACCOUNT}.kubeconfig}"
# Token 有效期。API Server 可能限制实际有效期
TOKEN_DURATION="${TOKEN_DURATION:-24h}"
# =========================
# 1. 创建命名空间
# =========================
kubectl create namespace "${NAMESPACE}" \
--dry-run=client -o yaml | kubectl apply -f -
# =========================
# 2. 创建 ServiceAccount
# 3. 绑定命名空间管理员权限
# =========================
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: ${ACCOUNT}
namespace: ${NAMESPACE}
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ${ACCOUNT}
namespace: ${NAMESPACE}
subjects:
- kind: ServiceAccount
name: ${ACCOUNT}
namespace: ${NAMESPACE}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
EOF
# =========================
# 4. 创建短期 Token
# =========================
TOKEN="$(
kubectl -n "${NAMESPACE}" create token "${ACCOUNT}" \
--duration="${TOKEN_DURATION}"
)"
# =========================
# 5. 从当前 kubeconfig 提取集群连接信息
# =========================
SERVER="$(
kubectl config view --raw --minify \
-o jsonpath='{.clusters[0].cluster.server}'
)"
CA_DATA="$(
kubectl config view --raw --minify --flatten \
-o jsonpath='{.clusters[0].cluster.certificate-authority-data}'
)"
INSECURE="$(
kubectl config view --raw --minify \
-o jsonpath='{.clusters[0].cluster.insecure-skip-tls-verify}'
)"
TLS_SERVER_NAME="$(
kubectl config view --raw --minify \
-o jsonpath='{.clusters[0].cluster.tls-server-name}'
)"
PROXY_URL="$(
kubectl config view --raw --minify \
-o jsonpath='{.clusters[0].cluster.proxy-url}'
)"
CLUSTER_ALIAS="${NAMESPACE}-cluster"
CONTEXT_NAME="${ACCOUNT}@${NAMESPACE}"
# =========================
# 6. 生成独立 Kubeconfig
# =========================
{
cat <<EOF
apiVersion: v1
kind: Config
preferences: {}
clusters:
- name: ${CLUSTER_ALIAS}
cluster:
server: ${SERVER}
EOF
if [[ -n "${CA_DATA}" ]]; then
printf ' certificate-authority-data: %s\n' "${CA_DATA}"
elif [[ "${INSECURE}" == "true" ]]; then
printf ' insecure-skip-tls-verify: true\n'
fi
if [[ -n "${TLS_SERVER_NAME}" ]]; then
printf ' tls-server-name: %s\n' "${TLS_SERVER_NAME}"
fi
if [[ -n "${PROXY_URL}" ]]; then
printf ' proxy-url: %s\n' "${PROXY_URL}"
fi
cat <<EOF
users:
- name: ${ACCOUNT}
user:
token: ${TOKEN}
contexts:
- name: ${CONTEXT_NAME}
context:
cluster: ${CLUSTER_ALIAS}
user: ${ACCOUNT}
namespace: ${NAMESPACE}
current-context: ${CONTEXT_NAME}
EOF
} > "${KUBECONFIG_OUT}"
chmod 600 "${KUBECONFIG_OUT}"
echo
echo "Kubeconfig 已生成:${KUBECONFIG_OUT}"
echo
# =========================
# 7. 权限验证
# =========================
echo "本命名空间读取 Pod,应为 yes:"
kubectl --kubeconfig="${KUBECONFIG_OUT}" \
auth can-i get pods -n "${NAMESPACE}" || true
echo
echo "其他命名空间读取 Pod,应为 no:"
kubectl --kubeconfig="${KUBECONFIG_OUT}" \
auth can-i get pods -n default || true
echo
echo "读取集群节点,应为 no:"
kubectl --kubeconfig="${KUBECONFIG_OUT}" \
auth can-i list nodes || true
echo
echo "创建 ClusterRoleBinding,应为 no:"
kubectl --kubeconfig="${KUBECONFIG_OUT}" \
auth can-i create clusterrolebindings.rbac.authorization.k8s.io || true