k8s kubeconfig 通过SA创建生成脚本

总结摘要
通过ServiceAccount自动创建具有特定权限的kubeconfig文件

Kubernetes中通过ServiceAccount自动生成Kubeconfig文件

在Kubernetes集群管理中,我们经常需要为不同的用户或应用创建具有特定权限的访问凭证。本文将介绍如何通过ServiceAccount自动化创建具有只读权限的kubeconfig文件。

背景介绍

在Kubernetes中,ServiceAccount是为Pod中的进程提供身份标识的资源对象。通过RBAC授权机制,我们可以为ServiceAccount分配特定的权限。本文提供的脚本可以自动创建ServiceAccount、分配只读权限,并生成对应的kubeconfig文件。

脚本功能

  • 自动创建ServiceAccount:在指定命名空间中创建服务账号
  • RBAC权限配置:创建Role和RoleBinding,分配Pod只读权限
  • Kubeconfig生成:自动获取Token和集群信息,生成完整的kubeconfig文件
  • Kubernetes版本适配:兼容1.24+版本(需要手动创建Secret)
  • 清理功能:提供完整的资源清理脚本

创建Kubeconfig的脚本

以下脚本将自动创建一个具有Pod只读权限的ServiceAccount,并生成对应的kubeconfig文件。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/bin/bash
set -euo pipefail

# 配置变量
NAMESPACE="default"                         # 指定命名空间(按需修改)
SERVICE_ACCOUNT_NAME="pod-viewer"           # 账号名称(修正变量名)
KUBECONFIG_FILE="kubeconfig_${SERVICE_ACCOUNT_NAME}"

echo "=== 开始创建 Pod 只读权限的 ServiceAccount ==="
echo "命名空间: $NAMESPACE"
echo "服务账号: $SERVICE_ACCOUNT_NAME"
echo "Kubeconfig 输出文件: $KUBECONFIG_FILE"
echo ""

# 创建 ServiceAccount
echo "[1/6] 创建 ServiceAccount..."
kubectl -n $NAMESPACE create serviceaccount $SERVICE_ACCOUNT_NAME

# 创建 Role
echo "[2/6] 创建只读 Pod 的 Role..."
kubectl -n $NAMESPACE apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
EOF

# 创建 RoleBinding
echo "[3/6] 创建 RoleBinding..."
kubectl -n $NAMESPACE create rolebinding pod-reader-binding \
  --role=pod-reader \
  --serviceaccount=$NAMESPACE:$SERVICE_ACCOUNT_NAME

# 等待并获取 Secret
echo "[4/6] 处理 ServiceAccount Token..."
SECRET_NAME=""
for i in {1..5}; do
  SECRET_NAME=$(kubectl -n $NAMESPACE get serviceaccount $SERVICE_ACCOUNT_NAME -o jsonpath='{.secrets[0].name}' 2>/dev/null || true)
  [ -n "$SECRET_NAME" ] && break
  echo " - 等待 Secret 创建 ($i/10)..."
  sleep 1
done

if [ -z "$SECRET_NAME" ]; then
  echo " - Kubernetes 1.24+ 检测到无自动创建的 Secret,正在手动创建..."
  SECRET_NAME="${SERVICE_ACCOUNT_NAME}-token"
  kubectl -n $NAMESPACE apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: ${SECRET_NAME}
  annotations:
    kubernetes.io/service-account.name: ${SERVICE_ACCOUNT_NAME}
type: kubernetes.io/service-account-token
EOF
  kubectl -n $NAMESPACE patch serviceaccount $SERVICE_ACCOUNT_NAME \
    -p "{\"secrets\":[{\"name\":\"${SECRET_NAME}\"}]}"
fi

# 获取认证信息
echo "[5/6] 获取集群信息..."
SA_TOKEN=$(kubectl -n $NAMESPACE get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CA_CERT=$(kubectl -n $NAMESPACE get secret $SECRET_NAME -o jsonpath='{.data.ca\.crt}')

# 生成 kubeconfig
echo "[6/6] 生成 Kubeconfig 文件..."
cat > $KUBECONFIG_FILE <<EOF
apiVersion: v1
kind: Config
current-context: ${SERVICE_ACCOUNT_NAME}-context
clusters:
- name: default-cluster
  cluster:
    certificate-authority-data: ${CA_CERT}
    server: ${APISERVER}
contexts:
- name: ${SERVICE_ACCOUNT_NAME}-context
  context:
    cluster: default-cluster
    namespace: ${NAMESPACE}
    user: ${SERVICE_ACCOUNT_NAME}
users:
- name: ${SERVICE_ACCOUNT_NAME}
  user:
    token: ${SA_TOKEN}
EOF

echo ""
echo "=== 验证配置 ==="
echo "1. 检查 Context 配置:"
kubectl --kubeconfig=$KUBECONFIG_FILE config get-contexts

echo ""
echo "2. 测试 Pod 访问权限:"
kubectl --kubeconfig=$KUBECONFIG_FILE get pods

echo ""
echo "=== 操作完成 ==="
echo "生成的 Kubeconfig 文件: $KUBECONFIG_FILE"
echo "长期使用建议:"
echo "  export KUBECONFIG=\$PWD/$KUBECONFIG_FILE"

二、删除相关配置的脚本文件:

当不再需要这些资源时,可以使用以下脚本进行清理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

#!/bin/bash
set -euo pipefail

# 配置变量(必须与创建脚本保持一致)
NAMESPACE="default"                         # 命名空间
SERVICE_ACCOUNT_NAME="pod-viewer"           # 服务账号名称
KUBECONFIG_FILE="kubeconfig_${SERVICE_ACCOUNT_NAME}"  # kubeconfig 文件名

echo "=== 开始清理 Pod 只读权限资源 ==="
echo "命名空间: $NAMESPACE"
echo "服务账号: $SERVICE_ACCOUNT_NAME"
echo "Kubeconfig 文件: $KUBECONFIG_FILE"
echo ""

# 删除 RoleBinding
echo "[1/5] 删除 RoleBinding..."
kubectl -n $NAMESPACE delete rolebinding pod-reader-binding --ignore-not-found

# 删除 Role
echo "[2/5] 删除 Role..."
kubectl -n $NAMESPACE delete role pod-reader --ignore-not-found

# 删除 ServiceAccount 及相关 Secret
echo "[3/5] 删除 ServiceAccount 和关联的 Secret..."
kubectl -n $NAMESPACE delete serviceaccount $SERVICE_ACCOUNT_NAME --ignore-not-found
kubectl -n $NAMESPACE delete secret "${SERVICE_ACCOUNT_NAME}-token" --ignore-not-found

# 删除 kubeconfig 文件
echo "[4/5] 删除 Kubeconfig 文件..."
if [ -f "$KUBECONFIG_FILE" ]; then
  rm -v "$KUBECONFIG_FILE"
else
  echo " - 文件不存在: $KUBECONFIG_FILE"
fi

# 验证清理结果
echo "[5/5] 验证资源是否已清理..."
echo " - 检查 ServiceAccount:"
kubectl -n $NAMESPACE get serviceaccount $SERVICE_ACCOUNT_NAME 2>/dev/null || echo " - 已清理"

echo " - 检查 Role:"
kubectl -n $NAMESPACE get role pod-reader 2>/dev/null || echo " - 已清理"

echo " - 检查 RoleBinding:"
kubectl -n $NAMESPACE get rolebinding pod-reader-binding 2>/dev/null || echo " - 已清理"

echo ""
echo "=== 清理完成 ==="
echo "以下资源已被移除:"
echo "1. Role: pod-reader"
echo "2. RoleBinding: pod-reader-binding"
echo "3. ServiceAccount: $SERVICE_ACCOUNT_NAME"
echo "4. 关联的 Secret"
echo "5. Kubeconfig 文件: $KUBECONFIG_FILE"

使用方法

  1. 创建资源和kubeconfig文件
    1
    
    bash chmod +x create-kubeconfig.sh ./create-kubeconfig.sh
  2. 验证生成的kubeconfig
    1
    
    bash kubectl --kubeconfig=kubeconfig_pod-viewer get pods
  3. 清理资源
    1
    
    bash chmod +x cleanup.sh ./cleanup.sh