只读权限kubeconfig

1.23 集群生成只读权限kubeconfig

readonly-auth.yaml

# readonly-auth.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: read-only-user
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-only-clusterrole
rules:
- apiGroups: ["", "apps", "extensions", "batch", "networking.k8s.io"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-only-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: read-only-user
  namespace: default
roleRef:
  kind: ClusterRole
  name: read-only-clusterrole
  apiGroup: rbac.authorization.k8s.io

执行命令:

# 创建只读权限
kubectl apply -f readonly-auth.yaml

# 这会列出你 kubeconfig 中所有的集群名称
kubectl config get-clusters

CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}')
echo $CLUSTER_NAME

# 获取 server 地址
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
echo $SERVER

# 找到 Secret 的名字
SECRET_NAME=$(kubectl get serviceaccount read-only-user -n default -o jsonpath='{.secrets[0].name}')

# 提取并解码 Token
TOKEN=$(kubectl get secret $SECRET_NAME -n default -o jsonpath='{.data.token}' | base64 --decode)
echo $TOKEN

# 提取 CA 证书
CA_CERT=$(kubectl get secret $SECRET_NAME -n default -o jsonpath='{.data.ca\.crt}')
echo $CA_CERT

# 生成 kubeconfig 文件
cat > read-only.kubeconfig << EOF
apiVersion: v1
kind: Config
clusters:
- name: ${CLUSTER_NAME}
  cluster:
    certificate-authority-data: ${CA_CERT}
    server: ${SERVER}
users:
- name: read-only-user
  user:
    token: ${TOKEN}
contexts:
- name: read-only-context
  context:
    cluster: ${CLUSTER_NAME}
    user: read-only-user
current-context: read-only-context
EOF
cat read-only.kubeconfig

# 测试只读权限的 kubeconfig
kubectl --kubeconfig=read-only.kubeconfig get nodes
kubectl --kubeconfig=read-only.kubeconfig get pods -A

# 测试写操作是否被禁止 (应该失败)
kubectl --kubeconfig=read-only.kubeconfig delete pod some-pod-that-does-not-exist -n default

执行上述命令后,你将拥有一个名为 read-only.kubeconfig 的 kubeconfig 文件,使用该文件可以以只读权限访问 Kubernetes 集群。

1.24 集群生成只读权限kubeconfig

readonly-auth-1.24.yaml

# readonly-auth-1.24.yaml
# 创建一个专门用于只读权限的服务账户
apiVersion: v1
kind: ServiceAccount
metadata:
  name: read-only-user
  namespace: default
---
# !!! 1.24+ 关键步骤:手动创建 Secret 来保存令牌 !!!
apiVersion: v1
kind: Secret
metadata:
  name: read-only-user-secret # 自定义一个Secret名称
  namespace: default
  annotations:
    kubernetes.io/service-account.name: read-only-user # !!!关键注解:指定这个Secret属于哪个SA
type: kubernetes.io/service-account-token # !!!关键类型:指定Secret类型为SA token
---
# 定义一个集群范围的只读 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-only-clusterrole
rules:
- apiGroups: [""] # 核心 API 组,如 pods, services, nodes, configmaps 等
  resources: ["*"]
  verbs: ["get", "list", "watch"] # 只读权限
- apiGroups: ["apps", "extensions", "batch", "networking.k8s.io"] # 其他常用 API 组
  resources: ["*"] # deployments, daemonsets, jobs, ingresses 等
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list"]
---
# 将 ClusterRole 和 ServiceAccount 绑定起来
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-only-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: read-only-user
  namespace: default # 即使使用 ClusterRoleBinding,也需指定 SA 的命名空间
roleRef:
  kind: ClusterRole
  name: read-only-clusterrole
  apiGroup: rbac.authorization.k8s.io

执行命令:

# 创建只读权限
kubectl apply -f readonly-auth-1.24.yaml

# 查看 Secret 的详细信息,如果 'data' 部分有 'token' 和 'ca.crt',则表示已就绪
kubectl describe secret read-only-user-secret -n default

# 获取 token
TOKEN=$(kubectl get secret read-only-user-secret -n default -o jsonpath='{.data.token}' | base64 --decode)
echo $TOKEN

# 提取 CA 证书
export CA_CERT=$(kubectl get secret read-only-user-secret -n default -o jsonpath='{.data.ca\.crt}')
echo $CA_CERT

# 获取集群名称和 API Server 地址
# 获取当前上下文的集群名称
export CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}')
echo "Cluster Name: $CLUSTER_NAME"

# 获取当前上下文的 API Server 地址
export SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
echo "API Server: $SERVER"

# 生成 kubeconfig 文件
cat > read-only.kubeconfig << EOF
apiVersion: v1
kind: Config
preferences: {}
clusters:
- name: ${CLUSTER_NAME}
  cluster:
    server: ${SERVER}
    certificate-authority-data: ${CA_CERT}
users:
- name: read-only-user
  user:
    token: ${TOKEN}
contexts:
- name: read-only-context
  context:
    cluster: ${CLUSTER_NAME}
    user: read-only-user
current-context: read-only-context
EOF

cat read-only.kubeconfig

# 测试只读权限的 kubeconfig
kubectl --kubeconfig=read-only.kubeconfig get nodes
kubectl --kubeconfig=read-only.kubeconfig get pods -A
# 测试写操作是否被禁止 (应该失败)
kubectl --kubeconfig=read-only.kubeconfig delete pod some-pod-that-does-not-exist -n default