BetaThis is a live doc! Anyone with edit access can make updates in real time without having to publish.
利用 1Password 保护 kubectl 凭证

直接将凭证(token 或证书)写入 Kubectl 配置文件(`~/.kube/config`)有些不安全,本文将凭证存入 1Password 中,并利用 exec 功能动态从 1Password 读取凭证(读取的过程中,1Password 会弹出二次确认信息)来保证不会轻易泄漏配置文件

不使用 1Password?Mac 用户也可以将信息存入 Keychain 然后使用 security 命令行工具读取大体操作与本文类似

准备配置文件

首先准备一份可以直接使用的配置文件,包括 cluster user context 节,例如

1apiVersion: v1 2clusters: 3- cluster: 4 certificate-authority-data: DATA+OMITTED 5 server: https://127.0.0.1:6443 6 name: default 7contexts: 8- context: 9 cluster: default 10 user: default 11 name: default 12current-context: default 13kind: Config 14preferences: {} 15users: 16- name: default 17 user: 18 client-certificate-data: DATA+OMITTED 19 client-key-data: DATA+OMITTED

我们只需要对 user 进行修改 —— 将 client-certificate-dataclient-key-data 变为动态读取(如果不是证书认证,这里则是 token

生成凭证描述 JSON

将用户凭证的部分单独提取出来(类似如下的部分,在原始配置的 users[0].user 下)

1client-certificate-data: DATA+OMITTED 2client-key-data: DATA+OMITTED

利用这一部分自行准备一份 JSON,类似于

1{ 2 "apiVersion": "client.authentication.k8s.io/v1beta1", 3 "kind": "ExecCredential", 4 "spec": { 5 "interactive": false 6 }, 7 "status": { 8 "clientCertificateData": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n", 9 "clientKeyData": "-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n" 10 } 11}

注意这里面的 status.clientCertificateDatastatus.clientKeyData 分别是由原来配置中的 yaml 的 client-certificate-dataclient-key-data 进行 base64 Decode 得来

(如果你不是使用证书认证而是使用 token,这里直接粘贴原始的 token 原文即可)

可以利用如下 JS 进行转换

1import { parse } from 'yaml' 2import {z} from 'zod' 3 4const schema = z.object({ 5 'client-certificate-data': z.string(), 6 'client-key-data': z.string() 7}) 8 9 10export async function main(input: string) { 11 const obj = schema.parse(parse(input)) 12 13 const clientCertificateData = atob(obj['client-certificate-data']); 14 const clientKeyData = atob(obj['client-key-data']); 15 16 const result = { 17 apiVersion: 'client.authentication.k8s.io/v1beta1', 18 kind: "ExecCredential", 19 spec: { 20 interactive: false, 21 }, 22 status: { 23 clientCertificateData, 24 clientKeyData 25 } 26 } 27 28 return JSON.stringify(result) 29} 30

存储到 1Password

创建一个 1Password 条目,新建一个密码类型的字段(假设明明为 k8s config)写入前一步准备的凭证 JSON,复制这个项目的 Private Share Link

image-20250104-122848.png

得到一行类似 https://start.1password.com/open/i?a=AAA&v=VVV&i=III 的链接,利用其中的 VVV(代表 Vault ID)和 III (代表 Item ID)的部分,构造一个 URL op://VVV/III/k8s config 备用(后面的 k8s config 和你的字段名称保持一致)

在命令行中输入 op read 'op://VVV/III/k8s config' 测试下能否正常读取到前面配置的 JSON

修改 kubeconfig

修改你的 kubeconfig 文件,将原来的

1user: 2 client-certificate-data: DATA+OMITTED 3 client-key-data: DATA+OMITTED

替换成

1user: 2 exec: 3 apiVersion: client.authentication.k8s.io/v1beta1 4 command: op 5 args: 6 - read 7 - 'op://VVV/III/k8s config' 8 interactiveMode: Always 9 provideClusterInfo: false

即可