使用serviceaccount制作kubeconfig文件

本文介绍如何使用Kubernetes的ServiceAccount和RBAC创建具有特定权限的kubeconfig文件,以便在开发过程中针对特定命名空间进行操作。通过具体示例,展示了如何限制kubeconfig仅能访问greenstock命名空间的pod资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

有时为了需要,我们需要给出一些具有特定集群权限的kubeconfig文件,这时我们可以通过使用serviceAccount来制作具有一定集群权限的kubeconfig

下面我们来使用这一技术创建一个只有greenstock命名空间权限的pod读取权限的kubeconfig

 

代码来源:https://gist.github.com/innovia/fbba8259042f71db98ea8d4ad19bd708

准备

1. 机器需要安装 jq

2. serviceAccount需要配置好rbac

创建步骤

1. 创建好rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: greenstock
  name: k8s-tester-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: greenstock
  name: greenstock-pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: k8s-tester-sa-rolebinding
  namespace: k8s-tester
subjects:
  - kind: ServiceAccount
    name: k8s-tester-sa
    namespace: greenstock
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: greenstock-pod-reader

 安装上述的文件 kubectl apply -f rbac.yaml

2.根据serviceaccount 生成kubeconfig

执行https://gist.github.com/innovia/fbba8259042f71db98ea8d4ad19bd708 这个里面的脚本,脚本内容如下 :

#!/bin/bash
set -e
set -o pipefail

# Add user to k8s using service account, no RBAC (must create RBAC after this script)
if [[ -z "$1" ]] || [[ -z "$2" ]]; then
 echo "usage: $0 <service_account_name> <namespace>"
 exit 1
fi

SERVICE_ACCOUNT_NAME=$1
NAMESPACE="$2"
KUBECFG_FILE_NAME="/tmp/kube/k8s-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-conf"
TARGET_FOLDER="/tmp/kube"

create_target_folder() {
    echo -n "Creating target directory to hold files in ${TARGET_FOLDER}..."
    mkdir -p "${TARGET_FOLDER}"
    printf "done"
}

create_service_account() {
    echo -e "\\nCreating a service account in ${NAMESPACE} namespace: ${SERVICE_ACCOUNT_NAME}"
    kubectl create sa "${SERVICE_ACCOUNT_NAME}" --namespace "${NAMESPACE}"
}

get_secret_name_from_service_account() {
    echo -e "\\nGetting secret of service account ${SERVICE_ACCOUNT_NAME} on ${NAMESPACE}"
    SECRET_NAME=$(kubectl get sa "${SERVICE_ACCOUNT_NAME}" --namespace="${NAMESPACE}" -o json | jq -r .secrets[].name)
    echo "Secret name: ${SECRET_NAME}"
}

extract_ca_crt_from_secret() {
    echo -e -n "\\nExtracting ca.crt from secret..."
    kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq \
    -r '.data["ca.crt"]' | base64 -D > "${TARGET_FOLDER}/ca.crt"
    printf "done"
}

get_user_token_from_secret() {
    echo -e -n "\\nGetting user token from secret..."
    USER_TOKEN=$(kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq -r '.data["token"]' | base64 -D)
    printf "done"
}

set_kube_config_values() {
    context=$(kubectl config current-context)
    echo -e "\\nSetting current context to: $context"

    CLUSTER_NAME=$(kubectl config get-contexts "$context" | awk '{print $3}' | tail -n 1)
    echo "Cluster name: ${CLUSTER_NAME}"

    ENDPOINT=$(kubectl config view \
    -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME}\")].cluster.server}")
    echo "Endpoint: ${ENDPOINT}"

    # Set up the config
    echo -e "\\nPreparing k8s-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-conf"
    echo -n "Setting a cluster entry in kubeconfig..."
    kubectl config set-cluster "${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}" \
    --server="${ENDPOINT}" \
    --certificate-authority="${TARGET_FOLDER}/ca.crt" \
    --embed-certs=true

    echo -n "Setting token credentials entry in kubeconfig..."
    kubectl config set-credentials \
    "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}" \
    --token="${USER_TOKEN}"

    echo -n "Setting a context entry in kubeconfig..."
    kubectl config set-context \
    "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}" \
    --cluster="${CLUSTER_NAME}" \
    --user="${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --namespace="${NAMESPACE}"

    echo -n "Setting the current-context in the kubeconfig file..."
    kubectl config use-context "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}"
}

create_target_folder
# create_service_account
get_secret_name_from_service_account
extract_ca_crt_from_secret
get_user_token_from_secret
set_kube_config_values

echo -e "\\nAll done! Test with:"
echo "KUBECONFIG=${KUBECFG_FILE_NAME} kubectl get pods"
echo "you should not have any permissions by default - you have just created the authentication part"
echo "You will need to create RBAC permissions"
KUBECONFIG=${KUBECFG_FILE_NAME} kubectl get pods

保存脚本名称为makekubecf.sh,执行命令是sh makekubecf.sh k8s-tester-sa greenstock

如果执行的时候遇到makekubecf.sh: 3: set: Illegal option -o pipefail,原因和解决方案可以参考https://my.oschina.net/u/1260221/blog/817458,主要就是切换成bash

3. 执行测试

假设上面 生成的脚本kubeconfig文件为config,执行kubectl get pod -n greensock --kubeconfig=./config

4. 开发小技巧

有时候呢,我们通过client-go在开发的时候,也可以通过这种方式来生成一个临时,符合我们的场景的serviceaccount,使用kubeconfigpath的方式来让我们的应用可以从集群外访问到我们已经开启了rbac的集群,具体的例子,可以查看 kubernetes-tester 项目,在项目中,我使用了一个“BuildConfigFromFlags”的方法,传入了kubeconfig文件,然后让应用获取到了指定serviceaccount的身份,也就是上面 的greenstock命令空间下的k8s-tester-sa从而方便了我们调试。

 

 

 

 

### 备份现有 kubeconfig 文件 为了防止意外修改或丢失当前的 `kubeconfig` 文件,在进行任何更改之前建议先备份该文件。可以通过简单的复制命令完成此操作: ```bash cp $HOME/.kube/config $HOME/.kube/config.bak ``` 这一步骤确保了原始配置的安全副本被保存下来。 ### 创建新的 kubeconfig 文件用于管理员 创建一个新的 `kubeconfig` 文件涉及几个具体的操作,包括初始化新文件以及向其中添加必要的上下文、用户和集群信息。以下是实现这一过程的方法: #### 初始化新的 kubeconfig 文件 首先,创建一个全新的 `kubeconfig` 文件作为基础: ```bash KUBECONFIG=$HOME/.kube/admin-config touch $HOME/.kube/admin-config ``` 这里指定了环境变量 `KUBECONFIG` 来指向即将使用的管理者的配置文件路径,并通过 `touch` 命令创建这个文件。 #### 合并多个 kubeconfig 文件到单个文件中 如果需要将其他已有的 `kubeconfig` 文件中的内容合并进来,则可以利用 `kubectl config view` 和 `--merge=true` 参数来达成目的。假设有一个额外的 `admin-cluster.kubeconfig` 文件想要加入到管理者的新配置里,执行如下指令即可: ```bash export KUBECONFIG=$HOME/.kube/admin-config:$HOME/path/to/extra/admin-cluster.kubeconfig kubectl config view --flatten > $HOME/.kube/temp-admin-config && mv $HOME/.kube/temp-admin-config $HOME/.kube/admin-config ``` 这段脚本的作用在于临时设置 `KUBECONFIG` 变量为两个文件路径组合的形式,接着调用 `kubectl config view` 查看所有配置并将它们展平(flatten)成单一版本的内容重定向至 `$HOME/.kube/temp-admin-config` 中;最后再移动覆盖回原位置成为最终版的 `admin-config` 文件[^1]。 #### 添加特定于管理员的身份验证信息和服务账户权限控制 考虑到安全性因素,应该专门为管理员角色设定独立的服务账号(Service Account),并通过绑定适当的角色(Role)/集群角色(ClusterRole)授予最小化所需访问权限。这样做的好处是可以更好地遵循最小特权原则(Principle of Least Privilege, PoLP)[^2]。 例如,可以在目标命名空间内创建服务账号并与自定义角色关联起来: ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: admin-sa --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: admin-binding subjects: - kind: ServiceAccount name: "admin-sa" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin ``` 上述 YAML 片段展示了如何声明一个名为 `admin-sa` 的服务账号及其对应的 `ClusterRoleBinding` 绑定关系,赋予其集群级别的管理员权限(`cluster-admin`)。请注意实际部署时应根据具体情况调整所授予权限范围大小。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值