Menu Close

k8s中手动创建一个长期有效角色并获取该 Token 和 CA 证书

在 Kubernetes 中,无法创建真正“永久有效”的 Token,这是出于安全考虑的设计。但从 Kubernetes v1.24+ 开始,虽然默认的 ServiceAccount Token 不再自动生成 Secret,但你可以通过手动创建一个 不带自动过期时间的 Secret 来实现一个“长期可用”(可视为“永久”,直到你主动删除或轮换)的 Token。

⚠️ 注意:这违反了零信任和最小权限原则,仅建议用于测试、CI/CD 或受控环境。

✅ 目标

创建一个 ServiceAccount

手动为其创建一个 长期有效的 Secret Token(不使用 TokenRequest API,避免自动过期)

获取该 Token 和 CA 证书

实现“永久有效期”(除非手动删除或集群 CA 轮换)

🔧 步骤:创建永久 Token(基于 Secret)

  1. 创建 ServiceAccount

kubectl create serviceaccount git-runner -n default

  1. 手动创建 Secret(绑定到 SA,不设置过期时间)

创建文件 sa-token-secret.yaml:

apiVersion: v1

kind: Secret

metadata:

name: git-runner-token

namespace: default

annotations:

kubernetes.io/service-account.name: git-runner

type: kubernetes.io/service-account-token

注意:不要设置 expirationSeconds 字段,就不会自动过期

应用:

kubectl apply -f sa-token-secret.yaml

这个 Secret 将由 kube-controller-manager 自动填充 Token 内容。

  1. 等待 Token 被填充

kubectl get secret git-runner-token -n default -o jsonpath='{.data.token}’ | base64 –decode

如果输出为空,说明 Token 还未生成,等待几秒再试。

  1. 绑定权限(例如 cluster-admin)

kubectl create clusterrolebinding git-runner-admin \

–clusterrole=cluster-admin \

–serviceaccount=default:my-permanent-user

📦 获取你需要的信息

✅ 获取 Bearer Token

TOKEN=$(kubectl get secret git-runner-token -n default -o jsonpath='{.data.token}’ | base64 –decode)

echo $TOKEN

✅ 获取 Kubernetes CA 证书(Base64 编码)

CA_CERT=$(kubectl config view –raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}’)

echo $CA_CERT

✅ 验证 Token 是否“永久”

使用以下命令查看 Secret 的 Token 是否包含过期时间:

kubectl get secret git-runner-token -n default -o yaml

你会看到:

没有 expirationSeconds 字段 → 表示不会自动过期

只要 Secret 存在,Token 就有效

只有当 Secret 被删除、ServiceAccount 被删除、或集群 CA 证书轮换时,Token 才失效

✅ 因此,在实际使用中可视为“永久”。

🔄 自动化脚本(支持“永久 Token”)

#!/bin/bash

SA_NAME=”${1:-my-permanent-user}”

NAMESPACE=”${2:-default}”

echo “🚀 创建永久 Token 的 ServiceAccount: $SA_NAME”

1. 创建 SA

kubectl create serviceaccount “$SA_NAME” -n “$NAMESPACE” –dry-run=client -o yaml | kubectl apply -f –

2. 创建永久 Secret

cat <<EOF | kubectl apply -f –

apiVersion: v1

kind: Secret

metadata:

name: ${SA_NAME}-token namespace: $NAMESPACE

annotations:

kubernetes.io/service-account.name: $SA_NAME

type: kubernetes.io/service-account-token

EOF

3. 等待 Secret 就绪

echo “⏳ 等待 Token 生成…”

while ! kubectl get secret “${SA_NAME}-token” -n “$NAMESPACE” -o jsonpath='{.data.token}’ | base64 –decode &> /dev/null; do

sleep 1

done

4. 绑定权限

kubectl create clusterrolebinding “${SA_NAME}-admin” –clusterrole=cluster-admin –serviceaccount=”$NAMESPACE:$SA_NAME” –dry-run=client -o yaml | kubectl apply -f –

5. 输出结果

TOKEN=$(kubectl get secret “${SA_NAME}-token” -n “$NAMESPACE” -o jsonpath='{.data.token}’ | base64 –decode)

CA_CERT=$(kubectl config view –raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}’)

echo

echo “========================================”

echo “✅ 永久 Token 已创建”

echo “========================================”

echo “🔹 Bearer Token: $TOKEN”

echo “🔹 CA 证书 (Base64): $CA_CERT”

echo “💡 提示:此 Token 不会自动过期,除非 Secret 被删除或集群 CA 轮换”

echo “========================================”

⚠️ 安全警告

❌ 不要在生产环境使用,违背了安全最佳实践。

🔒 建议使用短生命周期 Token + 刷新机制(如 OIDC)。

🛑 如果泄露,必须手动删除 Secret 或 SA 来撤销访问。

重点:

这个获取的Kubernetes CA 证书(Base64 编码)和 kubectl get secret my-permanent-user-token -n default -o yaml查看的CA不一样

详细解释

  1. 你看到的两个 CA 证书分别来自哪里?
  1. 为什么 git-runner-token Secret 中的 ca.crt 可能不一样或为空?

Kubernetes 不保证 所有 kubernetes.io/service-account-token 类型的 Secret 都包含 ca.crt。

ca.crt 字段是 可选的,它的作用是:让 Pod 内的容器知道如何验证 API Server 的证书。

如果 Pod 运行在集群内部,kubelet 通常会通过其他方式提供 CA(如挂载 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt),所以 Secret 中的 ca.crt 可能被省略。

某些集群(如 kubeadm、EKS、k3s)行为不同,有的填充,有的不填充。

📌 重点:ca.crt 在 Secret 中的存在与否,不影响 Token 的有效性。

无觅评论,优化体验,加强品牌价值